# Exports, eventos e comandos

Tudo o que o recurso fivedash expõe para scripts e para o console, com exemplos em Lua: o export log, o evento fivedash:log e o comando fivedash.

Source: https://fivedash.fivex.gg/docs/pt/developers/exports-and-events

Esta página lista tudo o que o recurso `fivedash` oferece para os scripts da cidade e para o console do servidor. A lista é curta de propósito: um export para logs, um evento equivalente e um comando de console. O resto (whitelist, loja) acontece sozinho, pelo painel. É para quem desenvolve scripts.

## Antes de começar

* O recurso `fivedash` instalado, conectado e com o nome de pasta `fivedash`. Veja [Recurso FiveM](https://fivedash.fivex.gg/docs/pt/developers/fivem-resource).
* Para logs: o módulo **Logs** no plano e um log criado no painel, com a **Chave** que os scripts vão usar (ex.: `mortes`). Veja [Criar logs](https://fivedash.fivex.gg/docs/pt/logs/create-logs).
* Tudo aqui é **só do lado do servidor**. O recurso não tem export de cliente nem evento de rede.

## Resumo

| Nome                                 | Tipo                          | Lado                | Para quê                                        |
| ------------------------------------ | ----------------------------- | ------------------- | ----------------------------------------------- |
| `exports.fivedash:log(chave, dados)` | Export                        | Servidor            | Mandar um log para o FiveDash                   |
| `fivedash:log`                       | Evento local (`TriggerEvent`) | Servidor            | O mesmo que o export, para quem prefere eventos |
| `fivedash`                           | Comando de console            | Console do servidor | Estado, detecção, loja e logs                   |
| `fivedash:<framework>:loaded`        | Evento local emitido          | Servidor            | Interno: personagem carregado (veja abaixo)     |

## Export `log`

```lua
local ok = exports.fivedash:log(chave, dados)
```

| Parâmetro | Tipo            | O que é                                                                                                                                                                                               |
| --------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chave`   | string          | A **Chave** do log no FiveDash (**Logs → o log → Como mandar**). É convertida para minúsculas. Precisa ter de 2 a 32 caracteres: letras minúsculas, números, `-` e `_`, começando por letra ou número |
| `dados`   | table ou string | O conteúdo do log. Uma string vira a `message`                                                                                                                                                        |

**Retorno:** `true` quando o log entrou na fila de envio; `false` quando foi ignorado.

O export só confere a tabela e põe na fila: não faz rede nem consulta o banco. Pode chamar em cidade cheia sem medo, mas nunca dentro de loops por frame.

### Campos de `dados`

| Campo     | Tipo             | O que faz                                                                               | Limite                           |
| --------- | ---------------- | --------------------------------------------------------------------------------------- | -------------------------------- |
| `title`   | string           | O título do log                                                                         | 256 caracteres                   |
| `message` | string           | Texto livre, com quantas linhas quiser (`description` também é aceito)                  | 4.096 caracteres                 |
| `player`  | number ou table  | O `source` do jogador. O FiveDash põe o passaporte, o nome e os identificadores sozinho |                                  |
| `players` | table            | Vários jogadores, cada um com `label`                                                   | 10 jogadores                     |
| `fields`  | table            | Valores na ordem: `{ { "Item", "água" }, { "Qtd", 3 } }`                                | 25 campos; nome 256, valor 1.024 |
| `color`   | number ou string | Cor da faixa: `"#ff4d4f"`, `"0xff4d4f"` ou um número de `0` a `16777215`                |                                  |
| `coords`  | vector3 ou table | Onde aconteceu. Sem isso, vai a posição do primeiro jogador (`Coords` no `logs.lua`)    |                                  |
| `image`   | string           | Link `http(s)://` de uma imagem (um print)                                              | 2.048 caracteres                 |

Um log sem `title`, sem `message`, sem `fields` e sem jogadores é ignorado (retorna `false`).

### Jogadores

Cada jogador (em `player` ou dentro de `players`) pode ser:

| Forma               | Exemplo                                                  | Quando usar                                                                    |
| ------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Número (`source`)   | `player = source`                                        | O jogador está na cidade                                                       |
| Tabela com `source` | `{ source = alvo, label = "Vítima" }`                    | Na cidade, com um rótulo                                                       |
| Tabela com `id`     | `{ id = "1234", name = "João Silva", label = "Vítima" }` | Fora da cidade (o `id` é o passaporte; `passport` e `passaporte` também valem) |

Para um jogador na cidade, o recurso preenche: o passaporte (o ID do personagem da framework), o nome do personagem, o `source` e os identificadores listados em `Identifiers` no `logs.lua` (padrão `license` e `discord`). Sem personagem escolhido ainda, vai o nome do FiveM. O `label` tem até 40 caracteres.

### Formas de `fields`

```lua
-- Lista de pares, na ordem (recomendado)
fields = { { "Arma", "WEAPON_PISTOL" }, { "Distância", 12.5 } }

-- Com nome e valor, e inline
fields = { { name = "Arma", value = "WEAPON_PISTOL", inline = true } }

-- Par com inline como terceiro valor
fields = { { "Arma", "WEAPON_PISTOL", true } }

-- Tabela chave = valor (a ordem não é garantida)
fields = { Arma = "WEAPON_PISTOL", Distancia = 12.5 }
```

Valores podem ser texto, número ou booleano (booleano vira **Sim** / **Não**, no idioma da cidade). Tabelas viram JSON.

### Exemplos

Um jogador:

```lua
-- server.lua
RegisterNetEvent("meu-script:comprou", function(item, qtd)
    local src = source
    exports.fivedash:log("loja-npc", {
        title = "Compra na loja de conveniência",
        player = src,
        fields = { { "Item", item }, { "Qtd", qtd } },
    })
end)
```

Dois jogadores, com cor e coordenadas:

```lua
AddEventHandler("meu-script:morte", function(assassino, vitima, arma)
    exports.fivedash:log("mortes", {
        title = "Morte registrada",
        color = "#ff4d4f",
        players = {
            { source = assassino, label = "Assassino" },
            { source = vitima, label = "Vítima" },
        },
        fields = { { "Arma", arma } },
        coords = GetEntityCoords(GetPlayerPed(vitima)),
    })
end)
```

Só texto:

```lua
exports.fivedash:log("admin", "Restart programado em 5 minutos")
```

Com um print:

```lua
exports.fivedash:log("denuncias", {
    title = "Denúncia com print",
    player = source,
    message = "Jogador reportou um bug no mapa",
    image = "https://cdn.fivex.sh/cidade-exemplo/prints/print-0001.webp",
})
```

### Função segura

Crie uma função no topo do arquivo e use ela em todos os pontos. Assim o script não quebra se o `fivedash` estiver parado:

```lua
local function fivedashLog(data)
    if GetResourceState("fivedash") ~= "started" then return end
    exports.fivedash:log("mortes", data)
end

fivedashLog({ title = "Morte registrada", player = source })
```

> Na página do log, **Copiar prompt para IA** copia um prompt pronto (com a chave, todas as opções e essas regras) para colar numa IA junto com o seu script.

### Do lado do cliente

O export não existe no cliente, e os jogadores não conseguem mandar logs. Se a ação acontece no cliente, mande para um evento de servidor do seu script e chame o export lá. Use o `source` do evento para saber quem é o jogador: nunca confie num ID ou nome vindo do cliente.

```lua
-- client.lua
TriggerServerEvent("meu-script:abriuBau", bauId)

-- server.lua
RegisterNetEvent("meu-script:abriuBau", function(bauId)
    exports.fivedash:log("baus", {
        title = "Baú aberto",
        player = source,
        fields = { { "Baú", bauId } },
    })
end)
```

### Quando o log é ignorado

| Situação                                                           | O que acontece                                                           |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| `Enabled = false` no `logs.lua`                                    | Retorna `false`                                                          |
| O `config.lua` não tem `Key`                                       | Retorna `false`                                                          |
| Chave em formato inválido                                          | Retorna `false` e avisa no console uma vez: "Chave de log inválida em …" |
| Chave listada em `Disabled`                                        | Retorna `false`                                                          |
| Recurso fora de `AllowedResources` (quando a lista não está vazia) | Retorna `false`                                                          |
| Log vazio                                                          | Retorna `false`                                                          |
| Chave que ainda não existe no painel                               | Retorna `true` e fica na fila até o log ser criado                       |

## Evento `fivedash:log`

O mesmo que o export, para scripts que preferem eventos. É um evento **local do servidor**: dispare com `TriggerEvent` num script de servidor. `TriggerServerEvent` do cliente não chega nele.

```lua
TriggerEvent("fivedash:log", "mortes", {
    title = "Morte registrada",
    player = source,
    fields = { { "Arma", arma } },
})
```

Os parâmetros e regras são os mesmos do export. O evento não devolve nada.

## Comando `fivedash`

Só funciona no console do servidor (txAdmin ou terminal do FXServer). No chat do jogo é ignorado.

| Comando                                       | O que faz                                                                                                                                |
| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `fivedash` ou `fivedash status`               | Versão, framework, conexão com o painel, servidor, idioma, sincronizações e comandos, atualização esperando restart e entregas esperando |
| `fivedash detect` (ou `detectar`)             | Detecta a framework de novo e mostra a nota e as evidências                                                                              |
| `fivedash loja` (ou `store`)                  | Estado da loja: ligada, o que entrega, nome do ID, entregas esperando, entregues e falhas                                                |
| `fivedash loja entregar` (ou `store deliver`) | Roda agora as entregas de quem já está na cidade                                                                                         |
| `fivedash logs`                               | Estado dos logs: fila, enviados, descartados, ritmo, último envio e último erro                                                          |
| `fivedash logs teste <chave>` (ou `test`)     | Põe um log de teste na fila para o log com essa chave                                                                                    |

Exemplo de `fivedash`:

```bash
[FiveDash] FiveDash 0.6.0
[FiveDash]   · framework: QBCore
[FiveDash]   · painel: https://fivedash.fivex.gg (conectado)
[FiveDash]   · servidor no FiveDash: "Cidade Exemplo"
[FiveDash]   · idioma: Português (Brasil) (definido no FiveDash)
[FiveDash]   · syncs: 1520, comandos: 12
[FiveDash]   · loja: 2 entrega(s) esperando jogadores
[FiveDash]   · comandos: fivedash status, fivedash detect, fivedash loja, fivedash logs
```

Exemplo de teste de log:

```bash
fivedash logs teste mortes
[FiveDash] Log de teste para "mortes" na fila: chega no FiveDash em até 1 s.
```

## Variáveis dos comandos da loja

Nos produtos com entrega por **comando**, o recurso troca estas variáveis antes de rodar o comando no console:

| Variável    | Vira                                                                                                          |
| ----------- | ------------------------------------------------------------------------------------------------------------- |
| `{id}`      | O ID do personagem que recebe (passaporte, Citizen ID…). Se o comando usa `{id}` e não há ID, a entrega falha |
| `{discord}` | O ID do Discord do comprador                                                                                  |
| `{pedido}`  | O número do pedido                                                                                            |

`{id}` e `{discord}` só levam letras, números, `-` e `_`. Os comandos bloqueados e o `AllowedCommands` estão em [Recurso FiveM](https://fivedash.fivex.gg/docs/pt/developers/fivem-resource).

```bash
darmoedas {id} 500
```

## O que o recurso dispara

### Evento interno de personagem carregado

Na QBCore, no Qbox, no ESX, no ox_core e no vRP, o recurso acompanha qual personagem cada jogador está usando e emite um evento local de servidor quando o personagem carrega:

| Framework | Evento                    | Argumentos                            |
| --------- | ------------------------- | ------------------------------------- |
| QBCore    | `fivedash:qbcore:loaded`  | `characterId` (Citizen ID), `source`  |
| Qbox      | `fivedash:qbox:loaded`    | `characterId` (Citizen ID), `source`  |
| ESX       | `fivedash:esx:loaded`     | `characterId` (`users.id`), `source`  |
| ox_core   | `fivedash:ox-core:loaded` | `characterId` (State ID), `source`    |
| vRP       | `fivedash:vrp:loaded`     | `characterId` (ID da conta), `source` |

Na Creative, a loja usa o próprio `CharacterChosen` da base, e esse evento não existe.

> Esse evento é interno (é o gatilho das entregas da loja). Ele pode mudar entre versões sem aviso. Para os seus scripts, prefira os eventos da própria framework (`QBCore:Server:PlayerLoaded`, `esx:playerLoaded`…).

### Avisos na tela

Quando uma compra chega (`Notify = true` no `loja.lua`) ou é anunciada (`Announce = true`), o recurso dispara o evento de cliente de aviso da framework. Se a sua cidade troca o sistema de notificação, garanta que esse evento continue funcionando:

| Framework                  | Evento de cliente                                            |
| -------------------------- | ------------------------------------------------------------ |
| Creative Network Enchanted | `Notify` (título, mensagem, `"verde"` ou `"default"`, 10000) |
| vRP                        | `Notify` (`"sucesso"` ou `"importante"`, mensagem)           |
| QBCore                     | `QBCore:Notify`                                              |
| ESX                        | `esx:showNotification`                                       |
| Qbox e ox_core             | `ox_lib:notify`                                              |

### ACEs e grupos

O recurso roda estes comandos de console por conta própria:

| Comando                                                     | Quando                                                                  |
| ----------------------------------------------------------- | ----------------------------------------------------------------------- |
| `add_ace identifier.license:<license> <permissão> allow`    | Liberação na whitelist da QBCore e do Qbox                              |
| `remove_ace identifier.license:<license> <permissão> allow` | Remoção da whitelist da QBCore e do Qbox                                |
| `<comando do esx_whitelist> add/remove <license> whitelist` | Liberação e remoção no ESX                                              |
| `add_principal identifier.license:<license> group.<nome>`   | Grupo da loja que não é emprego (ESX e Qbox; `qbcore.<nome>` na QBCore) |
| `remove_principal …`                                        | Quando o grupo com prazo vence                                          |

Confira os grupos nos seus scripts com `IsPlayerAceAllowed(source, "<permissão>")` e dê as permissões no `server.cfg` (`add_ace group.vip vip allow`).

## O que não existe

* Não há export de cliente, evento de rede (`RegisterNetEvent`) nem callback.
* Não há export para a whitelist ou para a loja: elas são comandadas pelo painel.
* Não há export para a CDN. Para mandar arquivos, use a [API da CDN](https://fivedash.fivex.gg/docs/pt/developers/cdn-api).

## Perguntas frequentes

**O export retornou true, mas o log não apareceu.**
Confira se existe um log com essa **Chave** no painel. Logs com chave desconhecida esperam na fila até o log ser criado. Rode `fivedash logs` para ver a fila e o último erro.

**Posso chamar o export num loop?**
Evite. Um log por acontecimento. O recurso já junta os logs e manda em lotes, mas loops por frame enchem a fila (até 20.000 logs, depois os mais antigos saem).

**Funciona com scripts em JavaScript ou C#?**
Sim. Exports do FiveM funcionam entre linguagens: em JS, `exports.fivedash.log("mortes", { title: "…" })`.

## Próximos passos

[Criar logs](https://fivedash.fivex.gg/docs/pt/logs/create-logs)Crie o log e escolha a chave no painel.
[API de logs](https://fivedash.fivex.gg/docs/pt/developers/logs-api)Mande logs por HTTP, no formato do webhook do Discord.
[Recurso FiveM](https://fivedash.fivex.gg/docs/pt/developers/fivem-resource)Opções do logs.lua e do loja.lua.
[Frameworks](https://fivedash.fivex.gg/docs/pt/developers/frameworks)O que cada framework entrega e como é detectada.
