# Frameworks

Every framework the fivedash resource recognizes, how each one is detected and what works on each (whitelist, store and logs).

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

The `fivedash` resource depends on no framework: it finds out on its own which base the city runs and talks to it through the exports, events and tables it already has. This page shows each supported framework, how it's recognized and what FiveDash can do on it. It's for server admins and script developers.

## Before you start

* The `fivedash` resource installed and connected. See [FiveM resource](https://fivedash.fivex.gg/docs/en/developers/fivem-resource).
* A MySQL driver started (`oxmysql`, `ghmattimysql` or `mysql-async`). Detection looks at database tables, and the whitelist and store write to it.
* `ensure fivedash` in `server.cfg` after the database and the framework. If one of them starts later, the resource detects again on its own.

## Summary

| Framework                  | `Framework` in config.lua | Whitelist via FiveDash                           | What the player types in the unlock                     | Store ID       |
| -------------------------- | ------------------------- | ------------------------------------------------ | ------------------------------------------------------- | -------------- |
| Creative Network Enchanted | `creative-enchanted`      | Yes                                              | The token shown when connecting (or the account number) | **Passport**   |
| Qbox                       | `qbox`                    | Yes, through Qbox's whitelist                    | Nothing: the Discord counts                             | **Citizen ID** |
| QBCore                     | `qbcore`                  | Yes, through QBCore's whitelist                  | Nothing: the Discord counts                             | **Citizen ID** |
| ESX                        | `esx`                     | Yes, with `esx_whitelist`                        | Nothing: the Discord counts                             | **ID**         |
| ox_core                    | `ox-core`                 | No (stays on Discord)                            |                                                         | **State ID**   |
| vRP / vRPex                | `vrp`                     | Yes, if `vrp_users` has the `whitelisted` column | The account number                                      | **ID**         |

On all of them, the store delivers **group**, **vehicle**, **money** (bank and wallet), **item** and **command**. Console commands work on any framework, even with none.

## How detection works

1. On boot, the resource waits up to 30 seconds for the database driver (`oxmysql` first, then `ghmattimysql`, then `mysql-async`).
2. Each known framework gives a confidence score from 0 to 100, looking at started resources, the manifest, config files and table columns.
3. With `Framework = "auto"`, the highest score wins, if it's at least 50. Below that, none is used and the console shows "No known framework found".
4. With a forced `Framework` (for example `"qbox"`), that one is used, as long as it's found. If it isn't, the console shows an error with the list of valid IDs.
5. When one of these resources starts after `fivedash`, detection runs again: `vrp`, `qbx_core`, `qb-core`, `es_extended`, `ox_core`, `oxmysql`, `mysql-async`, `ghmattimysql`, `ox_inventory` and `qb-inventory`.

To see what led to the choice, run in the server console:

```bash
fivedash detect
```

The console prints `Framework detected: QBCore`, the score (`92% sure`), each piece of evidence (for example `qb-core resource started` and `players table with citizenid`) and the driver (`database via oxmysql`). With `Debug = true` (or `set fivedash_debug 1`), this shows on every boot.

In the panel, the result shows on the **Game connection** card (**Server → Overview**): **Framework** and **Whitelist via FiveDash** (**Active**, **Unavailable** or **Not supported yet**). Setup problems show below, in amber.

### Whitelist by Discord

On QBCore, Qbox and ESX, the base's own whitelist doesn't show players an ID when it refuses them. So the unlock goes by Discord: the resource keeps the identifiers of whoever tries to join (`playerConnecting`) in the `fivedash_identities` table and, on an unlock, finds the licenses linked to that Discord.

> In this mode, the player must try to join the city at least once (with Discord open on their PC) before the unlock. If FiveDash hasn't seen any license with that Discord yet, the unlock comes back as "not found".

### Groups outside jobs (ACE)

On QBCore, Qbox and ESX, a store group that isn't one of the base's jobs (or gangs) becomes an ACE group on the buyer's license: `group.<name>` on ESX and Qbox, `qbcore.<name>` on QBCore. FXServer keeps ACEs in memory only, so the resource stores them in `fivedash_ace_groups` and re-applies them on every boot. Give the group its permissions in `server.cfg`:

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

And check them in scripts with `IsPlayerAceAllowed(source, "vip")`.

## Each framework

### Creative

**Creative Network Enchanted** (vRP rewritten by Creative Network). ID: `creative-enchanted`.

**Detection**

| Evidence                                                               | Score                       |
| ---------------------------------------------------------------------- | --------------------------- |
| `vrp` resource started with `creative_network` in its `fxmanifest.lua` | 50 (required)               |
| `Liberation` set in `vrp/config/Global.lua`                            | +10                         |
| `vrp/modules/base.lua` contains `Account[Liberation]`                  | +15                         |
| `accounts` table with `Whitelist`, `Discord`, `License` and `Token`    | +25 (−20 if any is missing) |

**Whitelist**

* The unlock looks the account up by the column set in `Liberation` in `vrp/config/Global.lua` (the base's default: `Token`, 7 digits shown when connecting). If `Liberation` points to `id` (or to a column that doesn't exist), the account number is used.
* Unlocking writes `accounts.Whitelist = 1` and, when the member comes with it, `accounts.Discord`.
* Removing writes `Whitelist = 0` on accounts with that ID or that Discord and, if the panel asks, drops the player.
* The ID must have 1 to 12 digits (and can't be `0`).

**Store** (ID: **Passport**, the `characters.id`)

| Type           | How it delivers                                                                                                                                               | Must be online? |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| Group          | `vRP.SetPermission`. The group must exist in `vrp/config/Groups.lua`                                                                                          | No              |
| Vehicle        | Writes to the `vehicles` table with the base's own query. The model must exist in `vrp/config/Vehicle.lua`. Refused if the character already has that vehicle | No              |
| Money (bank)   | `vRP.GiveBank`                                                                                                                                                | No              |
| Money (wallet) | The `dollar` item in the inventory                                                                                                                            | Yes             |
| Item           | `vRP.GenerateItem`. The item must exist in `vrp/config/Item.lua`. Full backpack: it waits. With no free slot, the base drops the item at the player's feet    | Yes             |

* Purchase by Discord: looks up `accounts.Discord` and takes the account's most recent character (skips characters with `Deleted = 1`).
* Delivery on join: `CharacterChosen` event.
* On-screen notice: client event `Notify`.
* Logs: the character ID comes from the player's `Passport` state bag.

**Warnings you may see**

* `Liberation = "X"` isn't a column of the accounts table: FiveDash uses the account number (id).
* The base's whitelist is off (`Whitelisted = false` in `vrp/config/Global.lua`).
* No database: `oxmysql` needs to start before `fivedash`.

### Qbox

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

**Detection**

| Evidence                    | Score |
| --------------------------- | ----- |
| `qbx_core` resource started | 95    |

Qbox also provides `qb-core` for compatibility. Since its score (95) is higher than QBCore's, it wins.

**Whitelist** (Qbox's own, by Discord)

* Reads `whitelist` and `whitelistPermission` in `qbx_core/config/server.lua`.
* Unlocking grants the whitelist permission on each license linked to the Discord: `add_ace identifier.license:<license> <permission> allow`. Unlocks are kept in `fivedash_whitelist_grants` and come back on every boot.
* Removing takes those ACEs away and, if the panel asks, drops the player.

> If `whitelistPermission` is a staff permission (`admin`, the default, `god`, `mod`, `superadmin`, `owner` or `command`), whitelist via FiveDash is turned off: every unlocked player would become staff. Change it to a whitelist-only permission, like `'whitelisted'`, and give it to staff in `server.cfg`: `add_ace group.admin whitelisted allow`.

**Store** (ID: **Citizen ID**)

| Type                    | How it delivers                                                                                                                                                   | Must be online? |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| Group (job or gang)     | `AddPlayerToJob` / `AddPlayerToGang`. Use `police` or `police.2` for grade 2                                                                                      | No              |
| Group (other name)      | ACE group `group.<name>` on the license                                                                                                                           | No              |
| Vehicle                 | `qbx_vehicles` (`CreatePlayerVehicle`); without it, a `player_vehicles` row in the `pillboxgarage` garage. The model must exist in `qbx_core/shared/vehicles.lua` | No              |
| Money (bank and wallet) | `AddMoney` (`bank` or `cash`)                                                                                                                                     | No              |
| Item                    | `ox_inventory`                                                                                                                                                    | Yes             |

* Purchase by Discord: takes the most recent character of a license seen with that Discord.
* Delivery on join: `QBCore:Server:PlayerLoaded`.
* On-screen notice: client event `ox_lib:notify`.

**Warnings you may see**

* Qbox's whitelist is off in `qbx_core/config/server.lua`: unlocks are saved, but anyone can join.
* `ox_inventory` isn't started: store items only arrive with it.

### QBCore

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

**Detection**

| Evidence                                    | Score       |
| ------------------------------------------- | ----------- |
| `qb-core` resource started                  | 85          |
| `players` table with the `citizenid` column | 92 in total |

**Whitelist** (QBCore's own, by Discord)

* Reads `QBCore.Config.Server.Whitelist` and `QBCore.Config.Server.WhitelistPermission` in `qb-core/config.lua`.
* Works like Qbox: ACE `add_ace identifier.license:<license> <permission> allow` on each license of the Discord, kept in `fivedash_whitelist_grants` and re-applied on every boot.

> With `WhitelistPermission = 'admin'` (the default) or another staff permission, whitelist via FiveDash is turned off. Change it to `'whitelisted'` and give the permission to staff: `add_ace group.admin whitelisted allow`.

**Store** (ID: **Citizen ID**)

| Type                | How it delivers                                                                                                                                       | Must be online? |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| Group (job or gang) | A job from `QBCore.Shared.Jobs` or a gang from `Shared.Gangs` (`police` or `police.2`). The grade must exist. Offline, the saved character is changed | No              |
| Group (other name)  | ACE group `qbcore.<name>` on the license                                                                                                              | No              |
| Vehicle             | A `player_vehicles` row (like `qb-vehicleshop`), in the `pillboxgarage` garage. The model must exist in `qb-core/shared/vehicles.lua`                 | No              |
| Money (bank)        | `AddMoney` online; offline, straight into `players.money`                                                                                             | No              |
| Money (wallet)      | `AddMoney` with `cash`                                                                                                                                | Yes             |
| Item                | `ox_inventory` if running; else `qb-inventory`; else the player's `AddItem`. The item must exist in `qb-core/shared/items.lua`                        | Yes             |

* Purchase by Discord: most recent character of a license seen with that Discord.
* Delivery on join: `QBCore:Server:PlayerLoaded`.
* On-screen notice: client event `QBCore:Notify`.

**Warnings you may see**

* QBCore's whitelist is off in `qb-core/config.lua`.
* `players` table not found: `oxmysql` needs to start before `fivedash`.

### ESX

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

**Detection**

| Evidence                       | Score |
| ------------------------------ | ----- |
| `es_extended` resource started | 90    |

**Whitelist** (through `esx_whitelist`, by Discord)

* Needs `esx_whitelist` started. The resource uses its console command (the `Command` in `esx_whitelist/config/main.lua`, default `whitelist`): `whitelist add <license> whitelist` and `whitelist remove <license> whitelist`.
* Works in `esx_whitelist`'s `"identifier"` and `"both"` modes.

**Store** (ID: **ID**, the `users.id`)

| Type               | How it delivers                                                                                       | Must be online? |
| ------------------ | ----------------------------------------------------------------------------------------------------- | --------------- |
| Group (job)        | A job from `job_grades` (`police` or `police.2`). Online, `setJob`; offline, straight into `users`    | No              |
| Group (other name) | ACE group `group.<name>` on the license                                                               | No              |
| Vehicle            | An `owned_vehicles` row (type `car`, stored). If the `vehicles` table exists, the model must be in it | No              |
| Money (bank)       | `addAccountMoney` online; offline, straight into `users.accounts`                                     | No              |
| Money (wallet)     | `addAccountMoney` with `money`                                                                        | Yes             |
| Item               | `ox_inventory` if running; else ESX's inventory (`canCarryItem` and `addInventoryItem`)               | Yes             |

* The `users` table must have the `id` column (old ESX doesn't).
* Purchase by Discord: most recent character of a license seen with that Discord (works with multicharacter, `char1:…`).
* Delivery on join: `esx:playerLoaded`.
* On-screen notice: client event `esx:showNotification`.

**Warnings you may see**

* `esx_whitelist` isn't started: the whitelist stays on Discord.
* `esx_whitelist` is in `"discord"` mode: the license list only works in `"identifier"` and `"both"` modes.
* `esx_whitelist` is off (`Config.Whitelist.Enabled = false`).
* `users` table not found, or without the `id` column.

### ox_core

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

**Detection**

| Evidence                   | Score |
| -------------------------- | ----- |
| `ox_core` resource started | 90    |

**Whitelist:** ox_core has no whitelist of its own, so it stays on Discord. The panel shows **Unavailable**.

**Store** (ID: **State ID**, like `AB1234`)

| Type           | How it delivers                                                                                                                                                  | Must be online? |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| Group          | ox_core groups (`police` or `police.2`; grades start at 1). The group and grade must exist in `ox_group_grades`. Online, `setGroup`; offline, `character_groups` | No              |
| Vehicle        | ox_core's `CreateVehicle`, stored at the place set by the `ox:defaultVehicleStore` convar (default `impound`)                                                    | No              |
| Money (bank)   | `addBalance` on the character's default account                                                                                                                  | No              |
| Money (wallet) | `ox_inventory`'s `money` item                                                                                                                                    | Yes             |
| Item           | `ox_inventory`                                                                                                                                                   | Yes             |

* Purchase by Discord: most recent character of the user with that Discord (or a license2 seen with it).
* Delivery on join: `ox:playerLoaded`.
* On-screen notice: client event `ox_lib:notify`.

**Warning you may see:** `ox_inventory` isn't started: store items and cash only arrive with it.

### vRP

**vRP** that isn't Creative's (vRPex and forks like ZIRIX). ID: `vrp`.

**Detection**

| Evidence                                                           | Score                   |
| ------------------------------------------------------------------ | ----------------------- |
| `vrp` resource started, without `creative_network` in the manifest | 55 (shows as **vRP**)   |
| `vrp_users` table exists                                           | 70 (shows as **vRPex**) |

**Whitelist** (only if `vrp_users` has the `whitelisted` column)

* The player types the account number (`vrp_users.id`), which the base shows when it refuses the connection.
* Unlocking writes `vrp_users.whitelisted = 1`. Removing writes `0` by ID and on the accounts with that Discord in `vrp_user_ids` and, if the panel asks, drops the player.

**Store** (ID: **ID**, the `vrp_users.id`)

| Type           | How it delivers                                                                  | Must be online? |
| -------------- | -------------------------------------------------------------------------------- | --------------- |
| Group          | `addUserGroup`. The group must exist in `vrp/cfg/groups.lua`                     | Yes             |
| Vehicle        | A `vrp_user_vehicles` row. Refused if the ID already has that vehicle            | No              |
| Money (bank)   | `giveBankMoney` online; offline, straight into `vrp_user_moneys.bank`            | No              |
| Money (wallet) | `giveMoney`                                                                      | Yes             |
| Item           | `giveInventoryItem`, checking weight. The item must exist in `vrp/cfg/items.lua` | Yes             |

* Purchase by Discord: looks up the `discord:` identifier (and the licenses seen with it) in `vrp_user_ids`.
* Delivery on join: `vRP:playerSpawn`.
* On-screen notice: client event `Notify`.
* Calls go through vRP's Proxy (`vRP:proxy`), the same path Lua scripts use with `Proxy.getInterface("vRP")`.

**Warnings you may see**

* The `vrp_users` table has no `whitelisted` column: the whitelist stays on Discord.
* `vrp_users` table not found: the database needs to start before `fivedash`.

## No framework recognized

The panel connection works normally. The whitelist stays on Discord and the store only delivers console commands. If your base is one of the above but wasn't recognized, run `fivedash detect`, check that it started before `fivedash` and, if needed, force it with `Framework` in `config.lua`.

## FAQ

**I use Qbox, but the panel shows QBCore.**
Check that `qbx_core` starts before `fivedash`. Qbox beats QBCore whenever `qbx_core` is running. If needed, use `Framework = "qbox"`.

**The unlock comes back "not found" on QBCore / Qbox / ESX.**
FiveDash hasn't seen that Discord trying to join the city yet. Ask the player to try connecting once, with Discord open, and unlock again.

**Why does a store item stay at "Waiting for the player to join the city"?**
Items and wallet money need the player online on every framework. The delivery runs on its own when they pick their character (after `SpawnDelay` in `loja.lua`).

**My framework is a fork. Does it work?**
vRP forks fall into the `vrp` adapter, and each step checks what the base answered. Forks that keep QBCore's or ESX's resource names and tables are recognized too.

## Next steps

[FiveM resource](https://fivedash.fivex.gg/docs/en/developers/fivem-resource)Install, options, convars and sync.
[Whitelist](https://fivedash.fivex.gg/docs/en/discord/whitelist)How unlocks work on Discord.
[In-game delivery](https://fivedash.fivex.gg/docs/en/store/in-game-delivery)How purchases arrive on each framework.
[Exports, events and commands](https://fivedash.fivex.gg/docs/en/developers/exports-and-events)What the resource exposes to your scripts.
