# Frameworks

Todas as frameworks que o recurso fivedash reconhece, como cada uma é detectada e o que funciona em cada uma (whitelist, loja e logs).

Source: https://fivedash.fivex.gg/docs/pt/developers/frameworks

O recurso `fivedash` não depende de nenhuma framework: ele descobre sozinho qual base a cidade usa e conversa com ela pelos exports, eventos e tabelas que ela já tem. Esta página mostra cada framework suportada, como ela é reconhecida e o que o FiveDash consegue fazer nela. É para quem administra o servidor e para quem desenvolve scripts.

## Antes de começar

* O recurso `fivedash` instalado e conectado. Veja [Recurso FiveM](https://fivedash.fivex.gg/docs/pt/developers/fivem-resource).
* Um driver MySQL iniciado (`oxmysql`, `ghmattimysql` ou `mysql-async`). A detecção olha as tabelas do banco, e a whitelist e a loja escrevem nele.
* `ensure fivedash` no `server.cfg` depois do banco e da framework. Se algum deles iniciar depois, o recurso detecta de novo sozinho.

## Resumo

| Framework                  | `Framework` no config.lua | Whitelist pelo FiveDash                        | O jogador digita na liberação                       | ID da loja     |
| -------------------------- | ------------------------- | ---------------------------------------------- | --------------------------------------------------- | -------------- |
| Creative Network Enchanted | `creative-enchanted`      | Sim                                            | O token mostrado ao conectar (ou o número da conta) | **Passaporte** |
| Qbox                       | `qbox`                    | Sim, pela whitelist do Qbox                    | Nada: vale o Discord                                | **Citizen ID** |
| QBCore                     | `qbcore`                  | Sim, pela whitelist da QBCore                  | Nada: vale o Discord                                | **Citizen ID** |
| ESX                        | `esx`                     | Sim, com o `esx_whitelist`                     | Nada: vale o Discord                                | **ID**         |
| ox_core                    | `ox-core`                 | Não (fica só no Discord)                       |                                                     | **State ID**   |
| vRP / vRPex                | `vrp`                     | Sim, se `vrp_users` tem a coluna `whitelisted` | O número da conta                                   | **ID**         |

Em todas, a loja entrega **grupo**, **veículo**, **dinheiro** (banco e carteira), **item** e **comando**. Comandos de console funcionam em qualquer framework, até sem nenhuma.

## Como a detecção funciona

1. No boot, o recurso espera até 30 segundos pelo driver do banco (`oxmysql` primeiro, depois `ghmattimysql`, depois `mysql-async`).
2. Cada framework conhecida dá uma nota de confiança de 0 a 100, olhando recursos iniciados, o manifesto, arquivos de configuração e colunas das tabelas.
3. Com `Framework = "auto"`, ganha a nota mais alta, se for pelo menos 50. Abaixo disso, nenhuma é usada e o console mostra "Nenhuma framework reconhecida".
4. Com `Framework` forçada (por exemplo `"qbox"`), vale essa, desde que ela seja encontrada. Se não for, o console mostra um erro com a lista de IDs válidos.
5. Quando um destes recursos inicia depois do `fivedash`, a detecção roda de novo: `vrp`, `qbx_core`, `qb-core`, `es_extended`, `ox_core`, `oxmysql`, `mysql-async`, `ghmattimysql`, `ox_inventory` e `qb-inventory`.

Para ver o que levou à escolha, rode no console do servidor:

```bash
fivedash detect
```

O console mostra `Framework detectada: QBCore`, a nota (`92% de certeza`), cada evidência (por exemplo `recurso qb-core iniciado` e `tabela players com citizenid`) e o driver (`banco via oxmysql`). Com `Debug = true` (ou `set fivedash_debug 1`), isso aparece em todo boot.

No painel, o resultado aparece no cartão **Conexão com o jogo** (**Servidor → Visão geral**): **Framework** e **Whitelist pelo FiveDash** (**Ativa**, **Indisponível** ou **Sem suporte ainda**). Problemas de configuração aparecem embaixo, em amarelo.

### Whitelist por Discord

Na QBCore, no Qbox e no ESX, a whitelist da própria base não mostra um ID para o jogador quando ele é barrado. Por isso a liberação vale para o Discord: o recurso guarda os identificadores de quem tenta entrar (`playerConnecting`) na tabela `fivedash_identities` e, na liberação, encontra as licenses ligadas àquele Discord.

> Nesse modo, o jogador precisa tentar entrar na cidade pelo menos uma vez (com o Discord aberto no PC) antes da liberação. Se o FiveDash ainda não viu nenhuma license com aquele Discord, a liberação volta como "não encontrado".

### Grupos fora dos empregos (ACE)

Na QBCore, no Qbox e no ESX, um grupo da loja que não é um emprego (ou gangue) da base vira um grupo ACE na license do comprador: `group.<nome>` no ESX e no Qbox, `qbcore.<nome>` na QBCore. O FXServer guarda ACEs só na memória, então o recurso grava em `fivedash_ace_groups` e reaplica a cada boot. Dê as permissões ao grupo no `server.cfg`:

```bash
add_ace group.vip vip allow
```

E confira nos scripts com `IsPlayerAceAllowed(source, "vip")`.

## Cada framework

### Creative

**Creative Network Enchanted** (vRP reescrito pela Creative Network). ID: `creative-enchanted`.

**Detecção**

| Evidência                                                         | Nota                       |
| ----------------------------------------------------------------- | -------------------------- |
| Recurso `vrp` iniciado com `creative_network` no `fxmanifest.lua` | 50 (obrigatório)           |
| `Liberation` definido em `vrp/config/Global.lua`                  | +10                        |
| `vrp/modules/base.lua` contém `Account[Liberation]`               | +15                        |
| Tabela `accounts` com `Whitelist`, `Discord`, `License` e `Token` | +25 (−20 se faltar alguma) |

**Whitelist**

* A liberação procura a conta pela coluna definida em `Liberation` no `vrp/config/Global.lua` (padrão da base: `Token`, 7 dígitos mostrados ao conectar). Se `Liberation` aponta para `id` (ou para uma coluna que não existe), vale o número da conta.
* Liberar grava `accounts.Whitelist = 1` e, quando o membro vem junto, `accounts.Discord`.
* Tirar grava `Whitelist = 0` nas contas com aquele ID ou aquele Discord e, se o painel pedir, derruba o jogador.
* O ID precisa ter de 1 a 12 dígitos (e não pode ser `0`).

**Loja** (ID: **Passaporte**, o `characters.id`)

| Tipo                | Como entrega                                                                                                                                                  | Precisa estar online? |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| Grupo               | `vRP.SetPermission`. O grupo precisa existir em `vrp/config/Groups.lua`                                                                                       | Não                   |
| Veículo             | Grava na tabela `vehicles` pela query da base. O modelo precisa existir em `vrp/config/Vehicle.lua`. Recusa se o passaporte já tem esse veículo               | Não                   |
| Dinheiro (banco)    | `vRP.GiveBank`                                                                                                                                                | Não                   |
| Dinheiro (carteira) | Item `dollar` no inventário                                                                                                                                   | Sim                   |
| Item                | `vRP.GenerateItem`. O item precisa existir em `vrp/config/Item.lua`. Mochila cheia: espera. Sem espaço livre, a base solta o item no chão, aos pés do jogador | Sim                   |

* Compra pelo Discord: procura `accounts.Discord` e pega o personagem mais recente da conta (ignora personagens com `Deleted = 1`).
* Entrega ao entrar: evento `CharacterChosen`.
* Aviso na tela: evento de cliente `Notify`.
* Logs: o passaporte vem do state bag `Passport` do jogador.

**Avisos que podem aparecer**

* `Liberation = "X"` não é uma coluna da tabela accounts: o FiveDash usa o número da conta (id).
* A whitelist da base está desligada (`Whitelisted = false` em `vrp/config/Global.lua`).
* Sem banco de dados: o `oxmysql` precisa iniciar antes do `fivedash`.

### Qbox

**Qbox** (`qbx_core`). ID: `qbox`.

**Detecção**

| Evidência                   | Nota |
| --------------------------- | ---- |
| Recurso `qbx_core` iniciado | 95   |

O Qbox também oferece `qb-core` por compatibilidade. Como a nota dele (95) é maior que a da QBCore, ele ganha.

**Whitelist** (a do próprio Qbox, por Discord)

* Lê `whitelist` e `whitelistPermission` em `qbx_core/config/server.lua`.
* Liberar dá a permissão de whitelist em cada license ligada ao Discord: `add_ace identifier.license:<license> <permissão> allow`. As liberações ficam em `fivedash_whitelist_grants` e voltam a cada boot.
* Tirar remove essas ACEs e, se o painel pedir, derruba o jogador.

> Se `whitelistPermission` for uma permissão de staff (`admin`, que é o padrão, `god`, `mod`, `superadmin`, `owner` ou `command`), a whitelist pelo FiveDash fica desligada: cada liberado viraria staff. Troque por uma permissão só da whitelist, como `'whitelisted'`, e dê ela à staff no `server.cfg`: `add_ace group.admin whitelisted allow`.

**Loja** (ID: **Citizen ID**)

| Tipo                        | Como entrega                                                                                                                                                           | Precisa estar online? |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| Grupo (emprego ou gangue)   | `AddPlayerToJob` / `AddPlayerToGang`. Use `police` ou `police.2` para o cargo 2                                                                                        | Não                   |
| Grupo (outro nome)          | Grupo ACE `group.<nome>` na license                                                                                                                                    | Não                   |
| Veículo                     | `qbx_vehicles` (`CreatePlayerVehicle`); sem ele, uma linha em `player_vehicles` na garagem `pillboxgarage`. O modelo precisa existir em `qbx_core/shared/vehicles.lua` | Não                   |
| Dinheiro (banco e carteira) | `AddMoney` (`bank` ou `cash`)                                                                                                                                          | Não                   |
| Item                        | `ox_inventory`                                                                                                                                                         | Sim                   |

* Compra pelo Discord: pega o personagem mais recente de uma license vista com aquele Discord.
* Entrega ao entrar: `QBCore:Server:PlayerLoaded`.
* Aviso na tela: evento de cliente `ox_lib:notify`.

**Avisos que podem aparecer**

* A whitelist do Qbox está desligada em `qbx_core/config/server.lua`: as liberações ficam salvas, mas qualquer um entra.
* O `ox_inventory` não está iniciado: os itens da loja só chegam com ele.

### QBCore

**QBCore** (`qb-core`). ID: `qbcore`.

**Detecção**

| Evidência                                 | Nota        |
| ----------------------------------------- | ----------- |
| Recurso `qb-core` iniciado                | 85          |
| Tabela `players` com a coluna `citizenid` | 92 no total |

**Whitelist** (a da própria QBCore, por Discord)

* Lê `QBCore.Config.Server.Whitelist` e `QBCore.Config.Server.WhitelistPermission` em `qb-core/config.lua`.
* Funciona igual ao Qbox: ACE `add_ace identifier.license:<license> <permissão> allow` em cada license do Discord, guardada em `fivedash_whitelist_grants` e reaplicada a cada boot.

> Com `WhitelistPermission = 'admin'` (o padrão) ou outra permissão de staff, a whitelist pelo FiveDash fica desligada. Troque por `'whitelisted'` e dê a permissão à staff: `add_ace group.admin whitelisted allow`.

**Loja** (ID: **Citizen ID**)

| Tipo                      | Como entrega                                                                                                                                          | Precisa estar online? |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| Grupo (emprego ou gangue) | Emprego de `QBCore.Shared.Jobs` ou gangue de `Shared.Gangs` (`police` ou `police.2`). O cargo precisa existir. Offline, o personagem salvo é alterado | Não                   |
| Grupo (outro nome)        | Grupo ACE `qbcore.<nome>` na license                                                                                                                  | Não                   |
| Veículo                   | Linha em `player_vehicles` (como o `qb-vehicleshop`), na garagem `pillboxgarage`. O modelo precisa existir em `qb-core/shared/vehicles.lua`           | Não                   |
| Dinheiro (banco)          | `AddMoney` online; offline, direto em `players.money`                                                                                                 | Não                   |
| Dinheiro (carteira)       | `AddMoney` com `cash`                                                                                                                                 | Sim                   |
| Item                      | `ox_inventory` se estiver rodando; senão `qb-inventory`; senão `AddItem` do jogador. O item precisa existir em `qb-core/shared/items.lua`             | Sim                   |

* Compra pelo Discord: personagem mais recente de uma license vista com aquele Discord.
* Entrega ao entrar: `QBCore:Server:PlayerLoaded`.
* Aviso na tela: evento de cliente `QBCore:Notify`.

**Avisos que podem aparecer**

* A whitelist da QBCore está desligada em `qb-core/config.lua`.
* Tabela `players` não encontrada: o `oxmysql` precisa iniciar antes do `fivedash`.

### ESX

**ESX** (`es_extended`). ID: `esx`.

**Detecção**

| Evidência                      | Nota |
| ------------------------------ | ---- |
| Recurso `es_extended` iniciado | 90   |

**Whitelist** (pelo `esx_whitelist`, por Discord)

* Precisa do `esx_whitelist` iniciado. O recurso usa o comando de console dele (o `Command` em `esx_whitelist/config/main.lua`, padrão `whitelist`): `whitelist add <license> whitelist` e `whitelist remove <license> whitelist`.
* Funciona nos modos `"identifier"` e `"both"` do `esx_whitelist`.

**Loja** (ID: **ID**, o `users.id`)

| Tipo                | Como entrega                                                                                                  | Precisa estar online? |
| ------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------- |
| Grupo (emprego)     | Emprego de `job_grades` (`police` ou `police.2`). Online, `setJob`; offline, direto em `users`                | Não                   |
| Grupo (outro nome)  | Grupo ACE `group.<nome>` na license                                                                           | Não                   |
| Veículo             | Linha em `owned_vehicles` (tipo `car`, guardado). Se a tabela `vehicles` existir, o modelo precisa estar nela | Não                   |
| Dinheiro (banco)    | `addAccountMoney` online; offline, direto em `users.accounts`                                                 | Não                   |
| Dinheiro (carteira) | `addAccountMoney` com `money`                                                                                 | Sim                   |
| Item                | `ox_inventory` se estiver rodando; senão o inventário do ESX (`canCarryItem` e `addInventoryItem`)            | Sim                   |

* A tabela `users` precisa ter a coluna `id` (ESX antigo não tem).
* Compra pelo Discord: personagem mais recente de uma license vista com aquele Discord (funciona com multicharacter, `char1:…`).
* Entrega ao entrar: `esx:playerLoaded`.
* Aviso na tela: evento de cliente `esx:showNotification`.

**Avisos que podem aparecer**

* Sem `esx_whitelist` iniciado: a whitelist fica só no Discord.
* O `esx_whitelist` está no modo `"discord"`: a lista de licenças só vale nos modos `"identifier"` e `"both"`.
* O `esx_whitelist` está desligado (`Config.Whitelist.Enabled = false`).
* Tabela `users` não encontrada, ou sem a coluna `id`.

### ox_core

**ox_core**. ID: `ox-core`.

**Detecção**

| Evidência                  | Nota |
| -------------------------- | ---- |
| Recurso `ox_core` iniciado | 90   |

**Whitelist:** o ox_core não tem whitelist própria, então ela fica só no Discord. No painel aparece **Indisponível**.

**Loja** (ID: **State ID**, como `AB1234`)

| Tipo                | Como entrega                                                                                                                                                                 | Precisa estar online? |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| Grupo               | Grupos do ox_core (`police` ou `police.2`; os cargos começam em 1). O grupo e o cargo precisam existir em `ox_group_grades`. Online, `setGroup`; offline, `character_groups` | Não                   |
| Veículo             | `CreateVehicle` do ox_core, guardado no local da convar `ox:defaultVehicleStore` (padrão `impound`)                                                                          | Não                   |
| Dinheiro (banco)    | `addBalance` na conta padrão do personagem                                                                                                                                   | Não                   |
| Dinheiro (carteira) | Item `money` do `ox_inventory`                                                                                                                                               | Sim                   |
| Item                | `ox_inventory`                                                                                                                                                               | Sim                   |

* Compra pelo Discord: personagem mais recente do usuário com aquele Discord (ou uma license2 vista com ele).
* Entrega ao entrar: `ox:playerLoaded`.
* Aviso na tela: evento de cliente `ox_lib:notify`.

**Aviso que pode aparecer:** o `ox_inventory` não está iniciado: itens e dinheiro em mãos só chegam com ele.

### vRP

**vRP** que não é da Creative (vRPex e forks como ZIRIX). ID: `vrp`.

**Detecção**

| Evidência                                                   | Nota                        |
| ----------------------------------------------------------- | --------------------------- |
| Recurso `vrp` iniciado, sem `creative_network` no manifesto | 55 (aparece como **vRP**)   |
| Tabela `vrp_users` existe                                   | 70 (aparece como **vRPex**) |

**Whitelist** (só se `vrp_users` tem a coluna `whitelisted`)

* O jogador digita o número da conta (`vrp_users.id`), que a base mostra quando barra a conexão.
* Liberar grava `vrp_users.whitelisted = 1`. Tirar grava `0` pelo ID e pelas contas com aquele Discord em `vrp_user_ids` e, se o painel pedir, derruba o jogador.

**Loja** (ID: **ID**, o `vrp_users.id`)

| Tipo                | Como entrega                                                                          | Precisa estar online? |
| ------------------- | ------------------------------------------------------------------------------------- | --------------------- |
| Grupo               | `addUserGroup`. O grupo precisa existir em `vrp/cfg/groups.lua`                       | Sim                   |
| Veículo             | Linha em `vrp_user_vehicles`. Recusa se o ID já tem esse veículo                      | Não                   |
| Dinheiro (banco)    | `giveBankMoney` online; offline, direto em `vrp_user_moneys.bank`                     | Não                   |
| Dinheiro (carteira) | `giveMoney`                                                                           | Sim                   |
| Item                | `giveInventoryItem`, conferindo o peso. O item precisa existir em `vrp/cfg/items.lua` | Sim                   |

* Compra pelo Discord: procura o `discord:` (e as licenses vistas com ele) em `vrp_user_ids`.
* Entrega ao entrar: `vRP:playerSpawn`.
* Aviso na tela: evento de cliente `Notify`.
* As chamadas usam o Proxy do vRP (`vRP:proxy`), o mesmo caminho dos scripts Lua com `Proxy.getInterface("vRP")`.

**Avisos que podem aparecer**

* A tabela `vrp_users` não tem a coluna `whitelisted`: a whitelist fica só no Discord.
* Tabela `vrp_users` não encontrada: o banco precisa iniciar antes do `fivedash`.

## Sem framework reconhecida

A conexão com o painel funciona normalmente. A whitelist fica só no Discord e a loja entrega só por comandos de console. Se a sua base é uma das acima, mas não foi reconhecida, rode `fivedash detect`, confira se ela iniciou antes do `fivedash` e, se precisar, force com `Framework` no `config.lua`.

## Perguntas frequentes

**Uso Qbox, mas o painel mostra QBCore.**
Confira se o `qbx_core` está iniciado antes do `fivedash`. O Qbox ganha da QBCore sempre que o `qbx_core` está rodando. Se precisar, use `Framework = "qbox"`.

**A liberação volta "não encontrado" na QBCore / Qbox / ESX.**
O FiveDash ainda não viu esse Discord tentando entrar na cidade. Peça para o jogador tentar conectar uma vez, com o Discord aberto, e libere de novo.

**Por que o item da loja fica "Aguardando o jogador entrar na cidade"?**
Itens e dinheiro na carteira precisam do jogador online em todas as frameworks. A entrega roda sozinha quando ele escolhe o personagem (depois do `SpawnDelay` do `loja.lua`).

**Minha framework é um fork. Funciona?**
Forks do vRP caem no adaptador `vrp`, e cada passo confere o que a base respondeu. Forks que mantêm os mesmos recursos e tabelas da QBCore ou do ESX também são reconhecidos.

## Próximos passos

[Recurso FiveM](https://fivedash.fivex.gg/docs/pt/developers/fivem-resource)Instalação, opções, convars e sincronização.
[Whitelist](https://fivedash.fivex.gg/docs/pt/discord/whitelist)Como a liberação funciona no Discord.
[Entrega no jogo](https://fivedash.fivex.gg/docs/pt/store/in-game-delivery)Como as compras chegam em cada framework.
[Exports, eventos e comandos](https://fivedash.fivex.gg/docs/pt/developers/exports-and-events)O que o recurso expõe para os seus scripts.
