Converting FiveM Scripts – ESX, QBCore, QBOX (Frame…
Il s'agit d'un guide de conversion de scripts FiveM simple et sans fioritures, basé sur le code, qui vous montre exactement comment procéder. Convertir les scripts FiveM entre ESX, QBCore, QBOX (qbx_core) et les configurations indépendantes du framework (autonomes). Vous découvrirez les mappages d'API tridirectionnels, le code de l'adaptateur, les étapes de migration SQL (mysql-async → oxmysql), les spécificités de QBOX, les listes de contrôle des tests et des conseils de renforcement de la production.
TL;DR — Migration en 10 étapes
- Instantané et mise en scène : Sauvegarder la base de données/les fichiers. Lancez un serveur de test local avec le framework cible.
- Identifier les dépendances : inventaire, cible, menu/interface utilisateur, rappels, couche de base de données, cœur accéder.
- Versions et ordre des broches : oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → vos ressources.
- Lisez le chemin du code : Recherchez tous les joueurs, l'argent, le travail/la tâche, l'inventaire, le rappel/l'événement et les appels DB.
- API de carte : Utilisez les tables Rosetta ci-dessous pour mapper ESX ↔ QBCore ↔ QBOX.
- Faites le pont : Ajouter un pont.lua adaptateur qui détecte automatiquement le framework et normalise les appels.
- Convertir les rappels : Rappels ESX/QB → QBOX/ox_lib
lib.callback.*quand c'est nécessaire. - Migrer la base de données : Déplacer les identifiants, les comptes, les articles, les véhicules ; passer à oxmysql
*.attendrestyle. - Durcir les événements : Valider
source, limites, groupes/emplois, propriété ; ne faites jamais confiance au client. - QA et publication : Exécutez les listes de contrôle ; balise, journal des modifications et plan de restauration.
Êtes-vous un développeur à la recherche d'une solution d'adaptateur ? Découvrez notre script d'adaptateur gratuit ici
1) Frameworks 101 : ESX vs QBCore vs QBOX vs Standalone
Aperçu architectural
| Catégorie | ESX | QBCore | QBOX |
|---|---|---|---|
| Architecture / Accès au cœur | exportations['es_extended']:getSharedObject() → ESX | exportations['qb-core']:GetCoreObject() → QBCore | Aucun objet de base global ; utiliser exportations.qbx_core:* pour les joueurs, les groupes et les notifications |
| Objet joueur | ESX.GetPlayerFromId(src) → xPlayer | QBCore.Functions.GetPlayer(src) → Joueur | exportations.qbx_core:GetPlayer(src) → Joueur avec Données du joueur |
| Identifiants | Historiquement identifiant (licence/vapeur) | citoyenid comme clé primaire | citoyenid comme clé primaire |
| Argent Manutention | xPlayer.addMoney() / `addAccountMoney('banque' | 'argent_noir')` | `Player.Functions.AddMoney('cash' |
| Emplois et devoirs | xPlayer.job.name, .grade.de.travail | Joueur.PlayerData.job.name, .niveau.scolaire, En service | Aides à l'emploi/au groupe via exportations.qbx_core:* (contrôles de groupe, responsables des tâches) |
| Inventaire | ESX par défaut / ox_inventaire / qb-inventaire (recommandé: ox_inventaire) | qb-inventaire / ox_inventaire | ox_inventaire recommandé |
| Rappels | ESX.RegisterServerCallback / ESX.TriggerServerCallback | QBCore.Functions.CreateCallback / TriggerCallback | Préférer ox_lib rappels (lib.callback.register/await) ou exportations QBOX |
| Couche de base de données | Vieux: mysql-async → Maintenant : oxmysql (MySQL.query.await, MySQL.update.await) | oxmysql | oxmysql |
| Interface utilisateur – Notifications | Notification ESX | QB Notify | QBOX avertit les assistants ou lib.notify |
| Interface utilisateur – Menus | esx_menu_default / ox_lib:registerContext | menu qb / ox_lib:registerContext | ox_lib:registerContext / lib.inputDialog |
| Interface utilisateur – Système cible | esx_target / cible_ox | cible qb / cible_ox | cible_ox recommandé |
En quoi QBOX diffère
- Nom de la ressource et exportations :
qbx_core(NonObtenir l'objet de base). - S'appuie sur ox_lib (rappels, notifier) et oxmysql par défaut.
- Intégrés pour les personnages multiples/files d'attente/groupes ; aides avisées pour les tâches/tâches.

2) Pré-vol : Environnement et outillage
- Serveur: actuel Serveur FX artefacts, Lua 5.4, CFX
assurercommande - Commande:
assurer oxmysql→assurer ox_lib→assurer le cadre→assurez votre ressource - Éditeur: VS Code + Lua LS, stylet; facultatif ripgrep pour des analyses rapides de motifs
- Configuration de test: instantané de base de données propre ; journalisation détaillée ; petit ensemble de données initialisées
- Modèles de recherche vous utiliserez :
Système de gestion de la sécurité.xPlayer.QBCore.Données du joueurqbx_coreexports.ox_inventorymysql%-asyncMySQL.
3) Rosetta Stone : ESX ↔ QBCore ↔ QBOX (mappage à trois voies)
Référence conviviale à copier/coller. Utilisez-la pour remplacer des appels ou connecter votre adaptateur.
Noyau et joueur
| Concept | ESX | QBCore | QBOX |
|---|---|---|---|
| Obtenir le noyau | exportations['es_extended']:getSharedObject() | exportations['qb-core']:GetCoreObject() | (n/a — utiliser les exportations) |
| Obtenir le joueur (src) | ESX.GetPlayerFromId(src) | QBCore.Functions.GetPlayer(src) | exportations.qbx_core:GetPlayer(src) |
| Obtenir par citizenid | (requête personnalisée) | QBCore.Functions.GetPlayerByCitizenId(id) | exports.qbx_core:GetPlayerByCitizenId(id) (si présent) |
Identifiants
| Concept | ESX | QBCore | QBOX |
|---|---|---|---|
| Primaire | identifiant (licence/vapeur) | citoyenid | citoyenid |
| Passage clouté | tableau id_map(identifiant, citizenid) | même | même |
Argent
| Action | ESX | QBCore | QBOX |
|---|---|---|---|
| Ajouter de l'argent | xPlayer.addMoney(a) | Player.Functions.AddMoney('cash', a) | Joueur.PlayerData.money.cash += a (via adaptateur + sauvegarde) |
| Ajouter une banque | xPlayer.addAccountMoney('banque', a) | Player.Functions.AddMoney('banque', a) | Joueur.PlayerData.money.bank += a (adaptateur + sauvegarde) |
| Ajouter sale | xPlayer.addAccountMoney('argent_noir', a) | élément ou compte supplémentaire (défini par le serveur) | mapper vers l'objet/portefeuille alternatif (par exemple, crypto) (choix de l'adaptateur) |
Emplois, devoirs, groupes
| Concept | ESX | QBCore | QBOX |
|---|---|---|---|
| Lire l'offre d'emploi | xPlayer.job.name, .grade | Joueur.PlayerData.job.name, .niveau.scolaire | Joueur.PlayerData.job.* + aides de groupe |
| De garde | (varie) | Joueur.PlayerData.job.onduty | DéfinirJobDuty/group helpers via exports |
| Contrôle de groupe | (Ajouter sur) | (Ajouter sur) | exports.qbx_core:HasGroup(src, groupe) (exemple) |
Inventaire
| Action | ESX | QBCore | QBOX |
|---|---|---|---|
| Ajouter un article | xPlayer.addInventoryItem(n, c) | Player.Functions.AddItem(n, c, ...) | préférer ox_inventaire exportation via adaptateur |
| ox_inventaire | exportations.ox_inventory:* | exportations.ox_inventory:* | exportations.ox_inventory:* |
Rappels
| Concept | ESX | QBCore | QBOX |
|---|---|---|---|
| Registre du serveur | ESX.RegisterServerCallback | QBCore.Functions.CreateCallback | lib.callback.register (ox_lib) |
| Déclencheur client | ESX.TriggerServerCallback | QBCore.Functions.TriggerCallback | lib.callback.await |
Couche DB
| Concept | ESX/QB (hérité) | oxmysql (cible) |
|---|---|---|
| Aller chercher | MySQL.Async.fetchAll(sql, paramètres, cb) | lignes locales = MySQL.query.await(sql, {p1, ...}) |
| Mise à jour | MySQL.Async.execute(sql, params, cb) | local aff = MySQL.update.await(sql, {p1, ...}) |
Interface utilisateur / Notifier / Cible
| Concept | ESX | QBCore | QBOX |
|---|---|---|---|
| Notifier | ESX.ShowNotification(msg) | QBCore.Functions.Notify(msg, type) | exportations.qbx_core:Notifier(...) ou lib.notify({...}) |
| Menu | (varie) | menu qb | ox_lib:registerContext / entrées |
| Cible | (Ajouter sur) | cible qb | cible_ox |
Conseil: service ox_lib, ox_inventaire, cible_ox pour rester neutre dans tous les cadres.
4) Tutoriel A — ESX → QBCore (pratique)
But: Convertissez une ressource de boutique simple d'ESX en QBCore.
Étape 1 — Dépendances
- Assurer
oxmysql,ox_lib,QB-Noyausont démarrés. - Si le script utilise l'inventaire ESX, migrez vers ox_inventaire (recommandé) ou mapper vers l'inventaire QB.
Étape 2 — Détecter le framework et ajouter un pont
Créer pont.lua pour normaliser les joueurs/l'argent/l'inventaire :
-- bridge.lua (ESX/QB/QBOX adapter)
local M = {}
local fw
CreateThread(function()
if GetResourceState('qbx_core') == 'started' then
fw = 'qbx'
elseif GetResourceState('qb-core') == 'started' then
fw = 'qb'
elseif GetResourceState('es_extended') == 'started' then
fw = 'esx'
else
fw = 'none'
end
end)
function M.getFramework()
return fw
end
function M.getPlayer(src)
if fw == 'qbx' then
return exports.qbx_core:GetPlayer(src)
elseif fw == 'qb' then
return exports['qb-core']:GetCoreObject().Functions.GetPlayer(src)
elseif fw == 'esx' then
return exports['es_extended']:getSharedObject().GetPlayerFromId(src)
end
end
local function saveQbox(src)
if fw == 'qbx' and exports.qbx_core and exports.qbx_core.Save then
exports.qbx_core:Save(src)
end
end
function M.addMoney(src, account, amount)
local p = M.getPlayer(src)
if not p or type(amount) ~= 'number' then return false end
if fw == 'qb' then
return p.Functions.AddMoney(account, amount)
elseif fw == 'esx' then
if account == 'cash' then
return p.addMoney(amount)
elseif account == 'bank' then
return p.addAccountMoney('bank', amount)
elseif account == 'black' or account == 'black_money' then
return p.addAccountMoney('black_money', amount)
end
elseif fw == 'qbx' then
local money = p.PlayerData and p.PlayerData.money or {}
account = account == 'black' and 'crypto' or account -- example mapping
money[account] = (money[account] or 0) + amount
saveQbox(src)
return true
end
return false
end
function M.removeMoney(src, account, amount)
return M.addMoney(src, account, -math.abs(amount))
end
function M.addItem(src, name, count, meta)
if GetResourceState('ox_inventory') == 'started' then
return exports.ox_inventory:AddItem(src, name, count, meta)
elseif fw == 'qb' then
return exports['qb-inventory']:AddItem(src, name, count, false, meta)
elseif fw == 'esx' then
local p = M.getPlayer(src)
return p and p.addInventoryItem(name, count)
elseif fw == 'qbx' then
return exports.ox_inventory:AddItem(src, name, count, meta)
end
end
function M.notify(src, msg, ntype)
if fw == 'qb' then
TriggerClientEvent('QBCore:Notify', src, msg, ntype or 'primary')
elseif fw == 'esx' then
TriggerClientEvent('esx:showNotification', src, msg)
elseif fw == 'qbx' then
if exports.qbx_core and exports.qbx_core.Notify then
exports.qbx_core:Notify(src, msg, ntype or 'info')
else
lib.notify(src, { title = 'Notice', description = msg })
end
else
print(('notify(%s): %s'):format(src, msg))
end
end
return M
Étape 3 — Convertir les rappels
- ESX → QB : remplacer
ESX.RegisterServerCallbackavecQBCore.Functions.CreateCallback. - Utilisations du client
QBCore.Functions.TriggerCallback.
-- server.lua (callback)
local bridge = require 'bridge'
local function getPrice(item)
return 100
end
if GetResourceState('qb-core') == 'started' then
local QBCore = exports['qb-core']:GetCoreObject()
QBCore.Functions.CreateCallback('shop:getPrice', function(source, cb, item)
cb(getPrice(item))
end)
else
-- fallback for QBOX/ESX via ox_lib
lib.callback.register('shop:getPrice', function(source, item)
return getPrice(item)
end)
end
-- client.lua (callback)
if GetResourceState('qb-core') == 'started' then
local QBCore = exports['qb-core']:GetCoreObject()
QBCore.Functions.TriggerCallback('shop:getPrice', function(price)
print('price', price)
end, 'bread')
else
local price = lib.callback.await('shop:getPrice', false, 'bread')
print('price', price)
end
Étape 4 — Chemins d'accès à l'argent et aux stocks
- Remplacer
xPlayer.addAccountMoneyavecPlayer.Functions.AddMoney(pour QB) ou adaptateur. - Standardisez tous les changements d'inventaire via l'adaptateur.
Étape 5 — Événements (sécurité côté serveur)
RegisterNetEvent('shop:buy', function(item, amount) local src = source si type(item) ~= 'string' ou type(amount) ~= 'number' alors renvoie fin si montant < 1 ou montant > 10 alors renvoie fin local p = bridge.getPlayer(src) si non p alors renvoie fin local prix = 100 * montant si non bridge.removeMoney(src, 'cash', price) alors renvoie fin bridge.addItem(src, item, amount) bridge.notify(src, ('Acheté %dx %s'):format(amount, item), 'success') fin)
Étape 6 — Migration de la base de données (identifiants, comptes)
- Créer un passage piéton
id_map(identifiant, citizenid). - Peupler
citoyenidpour QB d'ESXutilisateurstableau via règle de choix (colonne existante ou générée).
-- Exemple : créer un passage pour piétons et un remplissage (personnaliser selon votre schéma) CREATE TABLE IF NOT EXISTS id_map ( identifier VARCHAR(64) PRIMARY KEY, citizenid VARCHAR(64) NOT NULL UNIQUE ); -- Supposons que vous ayez généré de nouveaux citizenids et que vous les ayez stockés plus tôt INSERT IGNORE INTO id_map(identifier, citizenid) SELECT u.identifier, u.citizenid FROM users u WHERE u.citizenid IS NOT NULL;
mysql-async → oxmysql
-- before (mysql-async)
MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @id', {['@id'] = identifier}, function(rows) ... end)
-- after (oxmysql)
local rows = MySQL.query.await('SELECT * FROM users WHERE identifier = ?', { identifier })
Étape 7 — AQ
- Créez des objets, achetez/vendez, assurez-vous que les soldes changent correctement.
- Vérifiez que les rappels reviennent sous charge.
- Vérifiez que les métadonnées d’inventaire sont préservées.
5) Tutoriel B — QBCore → ESX (Pratique)
Principales mises en garde :
- Utilisations d'ESX comptes pour
banque/argent noir. L'argent sale du quart-arrière du port article (si utilisé) sur le compte ESX ou conservez-le en tant qu'élément. - Le schéma de poste diffère (grade vs niveau). Cartographiez-le soigneusement.
Exemple : mappage monétaire via un adaptateur
-- in bridge.lua, when fw == 'esx'
function M.qbToEsxMoney(account)
if account == 'cash' then return 'cash' end
if account == 'bank' then return 'bank' end
if account == 'black' or account == 'black_money' then return 'black_money' end
return account
end
Exemple : Conversion de rappel (serveur)
if GetResourceState('es_extended') == 'started' then
local ESX = exports['es_extended']:getSharedObject()
ESX.RegisterServerCallback('garage:getVehicles', function(source, cb)
local src = source
local p = bridge.getPlayer(src)
local rows = MySQL.query.await('SELECT * FROM owned_vehicles WHERE owner = ?', { p.identifier })
cb(rows)
end)
end
Liste de contrôle des tests
- Les offres d'emploi/promotions persistent.
- Les soldes bancaires/sales mutent comme prévu.
- Propriété du véhicule et formats de plaques validés.
6) Tutoriel C — QBCore ↔ QBOX (Pratique)
QBCore → QBOX
- Remplacer
QBCore.Functions.*avecexportations.qbx_core:*ou ox_lib rappels. - Joueur:
QBCore.Functions.GetPlayer(src)→exportations.qbx_core:GetPlayer(src). - Notifier:
QBCore.Fonctions.Notify→exports.qbx_core:Notifieroulib.notify. - Fonction/groupes : utiliser les exportations QBOX (
DéfinirJobDuty,HasGroup, etc.).
QBOX → QBCore
- Remplacer
exportations.qbx_core:*avecQBCore.Functions.*équivalents ou votre adaptateur. - Réintroduisez les rappels QB et les équivalents de menu/cible si nécessaire.
Extraits avant/après
-- Avant (QB notify) QBCore.Functions.Notify('Bonjour', 'success') -- Après (QBOX) exports.qbx_core:Notify(source, 'Bonjour', 'success') -- ou lib.notify(source, { title = 'Bonjour', description = 'Bienvenue', type = 'success' })
-- Avant (QB get player) local Player = QBCore.Functions.GetPlayer(src) -- Après (QBOX) local Player = exports.qbx_core:GetPlayer(src)
7) Tutoriel D — Framework → Autonome avec adaptateurs
Écrivez vos scripts une fois et les exécuter n'importe où :
- Créer un pont exposer une API stable :
obtenir le joueur,obtenir l'identifiant,ajouter/supprimer de l'argent,ajouter/supprimer un élément,notifier,aGroupe,en service,rappelsemballage. - Détecter le framework au moment de l'exécution (
qbx_core→QB-Noyau→es_extended→aucun). - Utiliser ox_lib pour les rappels et les notifications lorsqu'aucun assistant de framework direct n'existe.
Solution de secours autonome minimale
-- when fw == 'none'
function M.getPlayer(src)
-- implement a minimal table or reject actions gracefully
return { id = src }
end
function M.notify(src, msg)
print(('notify(%s): %s'):format(src, msg))
end
8) Performances et sécurité (renforcement de la production)
Validation côté serveur (ne jamais faire confiance au client)
- Valider types et bornes à chaque événement.
- Vérifier possession, temps de recharge, distance (le cas échéant), emploi/groupe.
- Assurez-vous que l'argent ne puisse pas devenir négatif ; limitez les montants.
- Comparer prix côté serveur ; n'acceptez pas les totaux fournis par le client.
Structure de l'événement
- Utilisez-en un événement serveur par action ; ne pas exposer les fonctions brutes d'inventaire/d'argent aux clients.
- Préférer rappels pour les flux de requêtes/réponses.
Base de données et performances
- Passer à oxmysql attendre les API ; écritures par lots ; éviter les requêtes par tick.
- Indexer les colonnes fréquemment interrogées (
citoyenid,identifiant,plaque). - Mettre en cache les listes de configuration/prix en mémoire ; les exporter une fois vers les clients, puis les différencier en cas de changement.
- Utiliser
État mondialavec parcimonie ; évitez les mises à jour en boucle à chaud.
9) Pièges courants et manuel de débogage
- Supposant
Obtenir l'objet de baseexiste sur QBOX → ça ne le fait pas ; utiliserexportations.qbx_core:*. - Les rappels ne reviennent jamais après la migration vers QBOX → Les rappels ESX/QB ne sont pas enregistrés ; passez à
lib.callback.register/await. - Sémantique de l'argent sale différer → décider élément vs compte vs portefeuille alternatif et standardiser dans votre adaptateur.
- Hypothèses d'inventaire mixtes → normaliser sur
ox_inventaire. - Problèmes d'ordre de départ →
oxmysql→ox_lib→ cadre → vos ressources. - Dérive des métadonnées du véhicule → s'assurer que les colonnes JSON et les formats de plaque correspondent au framework cible.
10) Meilleures pratiques pour fxmanifest.lua
fx_version 'cerulean' jeu 'gta5' lua54 'yes' shared_scripts { '@ox_lib/init.lua', 'bridge.lua', 'config.lua' } client_scripts { 'client/*.lua' } server_scripts { '@oxmysql/lib/MySQL.lua', 'server/*.lua' } escrow_ignore { 'bridge.lua', 'config.lua' } -- dépendances (choisissez ce que vous utilisez) : ox_lib, oxmysql, ox_inventory, qb-core OU qbx_core OU es_extended
- Déclarer Lua 5.4 (
lua54 'oui'). - Garder
escrow_ignoreminimal ; ne tentez jamais de contourner l'entiercement.
11) Migration de données : extraits SQL (exemples)
Ajustez les noms de table/colonne à votre schéma. Exécutez toujours d'abord une copie.
Identifiants : ESX → QB/QBOX
-- Ajouter citizenid aux utilisateurs ESX s'il est manquant ALTER TABLE utilisateurs ADD COLUMN IF NOT EXISTS citoyenid VARCHAR(64); -- Remplir à l'aide d'un générateur déterministe ou d'une colonne existante UPDATE utilisateurs SET citoyenid = LOWER(SUBSTRING(MD5(CONCAT(identifier,'-QB')),1,10)) WHERE citoyenid IS NULL; -- Créer un passage pour piétons CREATE TABLE IF NOT EXISTS id_map ( identifier VARCHAR(64) PRIMARY KEY, citoyenid VARCHAR(64) NOT NULL UNIQUE ); INSERT IGNORE INTO id_map(identifier, citoyenid) SELECT identifier, citoyenid FROM utilisateurs WHERE citoyenid IS NOT NULL;
Comptes/Argent
-- Exemple : convertir les soldes bancaires ESX en table monétaire QB (si votre schéma QB les stocke séparément) INSERT INTO player_money (citizenid, account, amount) SELECT m.citizenid, 'bank', a.money FROM ( SELECT u.citizenid, SUM(CASE WHEN account = 'bank' THEN money ELSE 0 END) AS money FROM user_accounts ua JOIN users u ON u.identifier = ua.identifier GROUP BY u.citizenid ) a JOIN users m ON m.citizenid = a.citizenid ON DUPLICATE KEY UPDATE amount = VALUES(amount);
Véhicules
-- Normaliser les plaques au format cible (exemple : 8 caractères supérieurs) UPDATE owned_vehicles SET plate = UPPER(LEFT(plate,8)); -- S'assurer que les colonnes de métadonnées JSON sont valides UPDATE owned_vehicles SET mods = JSON_MERGE_PATCH('{}', mods) WHERE JSON_VALID(mods) = 0;
12) Adaptateurs réutilisables (Starter)
Déposez ceci dans
pont.luaet s'adapte à vos besoins. Il détecte automatiquement ESX/QB/QBOX et propose une API stable.
local M = {}
local fw = 'none'
CreateThread(function()
if GetResourceState('qbx_core') == 'started' then fw = 'qbx'
elseif GetResourceState('qb-core') == 'started' then fw = 'qb'
elseif GetResourceState('es_extended') == 'started' then fw = 'esx' end
end)
function M.framework() return fw end
function M.player(src)
if fw == 'qbx' then return exports.qbx_core:GetPlayer(src)
elseif fw == 'qb' then return exports['qb-core']:GetCoreObject().Functions.GetPlayer(src)
elseif fw == 'esx' then return exports['es_extended']:getSharedObject().GetPlayerFromId(src) end
end
function M.identifier(src)
local p = M.player(src); if not p then return nil end
if fw == 'qb' or fw == 'qbx' then
return p.PlayerData and p.PlayerData.citizenid
elseif fw == 'esx' then
return p.identifier
end
end
function M.hasGroup(src, group)
if fw == 'qbx' and exports.qbx_core and exports.qbx_core.HasGroup then
return exports.qbx_core:HasGroup(src, group)
end
return false
end
function M.notify(src, msg, ntype)
if fw == 'qb' then
TriggerClientEvent('QBCore:Notify', src, msg, ntype or 'primary')
elseif fw == 'esx' then
TriggerClientEvent('esx:showNotification', src, msg)
elseif fw == 'qbx' then
if exports.qbx_core and exports.qbx_core.Notify then
exports.qbx_core:Notify(src, msg, ntype or 'info')
else
lib.notify(src, { description = msg })
end
end
end
return M
13) Listes de contrôle finales (copie et expédition)
A) Découverte et pré-vol
- Base de données/fichiers instantanés ; créer un serveur intermédiaire
- Épingler les artefacts et les versions des ressources ; définir l'ordre de démarrage
- Dépendances inventaire/cible/menu répertoriées
- Décider de la stratégie d'identification (passage piéton CitizenID)
B) Audit du code
- Grep pour ESX/QB/QBOX/ox_*/mysql‑async
- Énumérez tous les appels d'argent/d'inventaire/de travail/de devoir
- Lister les rappels et les événements serveur/client
C) Cartographie et conception
- Choisissez la surface de l'adaptateur (joueur, identifiants, argent, objets, notification, rappels)
- Décider de la stratégie à adopter pour gérer l'argent sale (compte, objet ou portefeuille alternatif)
- Privilégiez ox_lib/ox_inventory/ox_target
D) Migration des données
- Construire un passage piéton Citizenid
- Convertir des comptes/de l'argent
- Normaliser les métadonnées et les plaques des véhicules
- Passer aux appels d'attente oxmysql
E) Tests d'assurance qualité
- Sécurité des événements : types/limites/propriété/temps de recharge
- Rappels : valeurs de retour sous charge
- Métadonnées d'inventaire préservées
- La logique des tâches/fonctions/groupes correspond à la conception
F) Version et restauration
- Version de l'étiquette ; journal des modifications
- Conserver l'instantané de pré-migration pendant 7 à 14 jours
- Surveiller les erreurs/latences ; indexer les requêtes à chaud
14) FAQ (avec schéma JSON-LD)
Q : Puis-je porter des scripts QBCore vers QBOX sans réécriture complète ?
UN: Avec adaptateurs et ox_lib rappels, la plupart des scripts n'ont besoin que d'appeler le remappage.
Q : Que dois-je faire avec l’argent noir/sale ?
UN: Standardisez dans votre adaptateur : ESX → argent noir compte ; QB → article ou compte supplémentaire ; QBOX → article ou portefeuille alternatif (par exemple, crypto). Gardez une stratégie unique pour l'ensemble du projet.
Q : Pourquoi les rappels se bloquent-ils après le passage à QBOX ?
UN: Les rappels ESX/QB ne se déclenchent pas sur QBOX. Utilisez lib.callback.register/await.
Q : Quelle est la meilleure façon de migrer MySQL-async ?
UN: Remplacer par oxmysql attendre les API ; supprimer les pyramides de rappel.
Q : Comment convertir qb-target en ox_target ?
UN: Remplacez les appels d'API addBoxZone/Entity un par un ; les charges utiles des événements restent similaires. Conservez la stabilité des noms de cible.
15) Visuels (Suggestions)
- Organigramme (Découvrir → Cartographier → Adapter → Migrer la base de données → Tester → Publier)
- Diagramme des adaptateurs : Script → Pont → Framework (ESX/QB/QBOX)
- Table de Rosette : inclus ci-dessus (exporter au format CSV pour les téléchargements)
[Discover] → [Map APIs] → [Write Adapter] → [Migrate DB] → [Harden] → [QA] → [Release]
16) Légal et éthique
- Respecter les licences (MIT/GPL/NC). Ne pas contourner l'entiercement ou l'obfuscation.
- Convertissez uniquement les scripts que vous propre ou avoir la permission de s'adapter.
17) Téléchargements et références rapides
Vous pouvez également utiliser ce convertisseur (non testé cependant) :
https://github.com/sledgehamm3r/ESX-QBCore-Converter
28) Prochaines étapes
- Laissez tomber le pont.lua dans votre ressource et commencez par convertir vos scripts de plus grande valeur.
- Normaliser sur ox_lib + ox_inventory + ox_target + oxmysql pour rester indépendant du framework.
- Utilisez les listes de contrôle lors de la révision et de la publication.
Lire aussi Migration SQL et identifiants : Steam/license → citizenid et Comptes → Money (ESX → QBCore/QBOX)






