Économisez 20% dès aujourd'hui Utilisez le code BIENVENUE lors du paiement. ACCUEILLIR

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

  1. Instantané et mise en scène : Sauvegarder la base de données/les fichiers. Lancez un serveur de test local avec le framework cible.
  2. Identifier les dépendances : inventaire, cible, menu/interface utilisateur, rappels, couche de base de données, cœur accéder.
  3. Versions et ordre des broches : oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → vos ressources.
  4. 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.
  5. API de carte : Utilisez les tables Rosetta ci-dessous pour mapper ESX ↔ QBCore ↔ QBOX.
  6. Faites le pont : Ajouter un pont.lua adaptateur qui détecte automatiquement le framework et normalise les appels.
  7. Convertir les rappels : Rappels ESX/QB → QBOX/ox_lib lib.callback.* quand c'est nécessaire.
  8. Migrer la base de données : Déplacer les identifiants, les comptes, les articles, les véhicules ; passer à oxmysql *.attendre style.
  9. Durcir les événements : Valider source, limites, groupes/emplois, propriété ; ne faites jamais confiance au client.
  10. 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égorieESXQBCoreQBOX
Architecture / Accès au cœurexportations['es_extended']:getSharedObject()ESXexportations['qb-core']:GetCoreObject()QBCoreAucun objet de base global ; utiliser exportations.qbx_core:* pour les joueurs, les groupes et les notifications
Objet joueurESX.GetPlayerFromId(src)xPlayerQBCore.Functions.GetPlayer(src)Joueurexportations.qbx_core:GetPlayer(src)Joueur avec Données du joueur
IdentifiantsHistoriquement identifiant (licence/vapeur)citoyenid comme clé primairecitoyenid comme clé primaire
Argent ManutentionxPlayer.addMoney() / `addAccountMoney('banque''argent_noir')``Player.Functions.AddMoney('cash'
Emplois et devoirsxPlayer.job.name, .grade.de.travailJoueur.PlayerData.job.name, .niveau.scolaire, En serviceAides à l'emploi/au groupe via exportations.qbx_core:* (contrôles de groupe, responsables des tâches)
InventaireESX par défaut / ox_inventaire / qb-inventaire (recommandé: ox_inventaire)qb-inventaire / ox_inventaireox_inventaire recommandé
RappelsESX.RegisterServerCallback / ESX.TriggerServerCallbackQBCore.Functions.CreateCallback / TriggerCallbackPréférer ox_lib rappels (lib.callback.register/await) ou exportations QBOX
Couche de base de donnéesVieux: mysql-async → Maintenant : oxmysql (MySQL.query.await, MySQL.update.await)oxmysqloxmysql
Interface utilisateur – NotificationsNotification ESXQB NotifyQBOX avertit les assistants ou lib.notify
Interface utilisateur – Menusesx_menu_default / ox_lib:registerContextmenu qb / ox_lib:registerContextox_lib:registerContext / lib.inputDialog
Interface utilisateur – Système cibleesx_target / cible_oxcible qb / cible_oxcible_ox recommandé

En quoi QBOX diffère

  • Nom de la ressource et exportations : qbx_core (Non Obtenir 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.

Cadres FiveM : QBCore vs. ESX

2) Pré-vol : Environnement et outillage

  • Serveur: actuel Serveur FX artefacts, Lua 5.4, CFX assurer commande
  • Commande: assurer oxmysqlassurer ox_libassurer le cadreassurez 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 joueur qbx_core exports.ox_inventory mysql%-async MySQL.

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

ConceptESXQBCoreQBOX
Obtenir le noyauexportations['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

ConceptESXQBCoreQBOX
Primaireidentifiant (licence/vapeur)citoyenidcitoyenid
Passage cloutétableau id_map(identifiant, citizenid)mêmemême

Argent

ActionESXQBCoreQBOX
Ajouter de l'argentxPlayer.addMoney(a)Player.Functions.AddMoney('cash', a)Joueur.PlayerData.money.cash += a (via adaptateur + sauvegarde)
Ajouter une banquexPlayer.addAccountMoney('banque', a)Player.Functions.AddMoney('banque', a)Joueur.PlayerData.money.bank += a (adaptateur + sauvegarde)
Ajouter salexPlayer.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

ConceptESXQBCoreQBOX
Lire l'offre d'emploixPlayer.job.name, .gradeJoueur.PlayerData.job.name, .niveau.scolaireJoueur.PlayerData.job.* + aides de groupe
De garde(varie)Joueur.PlayerData.job.ondutyDéfinirJobDuty/group helpers via exports
Contrôle de groupe(Ajouter sur)(Ajouter sur)exports.qbx_core:HasGroup(src, groupe) (exemple)

Inventaire

ActionESXQBCoreQBOX
Ajouter un articlexPlayer.addInventoryItem(n, c)Player.Functions.AddItem(n, c, ...)préférer ox_inventaire exportation via adaptateur
ox_inventaireexportations.ox_inventory:*exportations.ox_inventory:*exportations.ox_inventory:*

Rappels

ConceptESXQBCoreQBOX
Registre du serveurESX.RegisterServerCallbackQBCore.Functions.CreateCallbacklib.callback.register (ox_lib)
Déclencheur clientESX.TriggerServerCallbackQBCore.Functions.TriggerCallbacklib.callback.await

Couche DB

ConceptESX/QB (hérité)oxmysql (cible)
Aller chercherMySQL.Async.fetchAll(sql, paramètres, cb)lignes locales = MySQL.query.await(sql, {p1, ...})
Mise à jourMySQL.Async.execute(sql, params, cb)local aff = MySQL.update.await(sql, {p1, ...})

Interface utilisateur / Notifier / Cible

ConceptESXQBCoreQBOX
NotifierESX.ShowNotification(msg)QBCore.Functions.Notify(msg, type)exportations.qbx_core:Notifier(...) ou lib.notify({...})
Menu(varie)menu qbox_lib:registerContext / entrées
Cible(Ajouter sur)cible qbcible_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-Noyau sont 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.RegisterServerCallback avec QBCore.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.addAccountMoney avec Player.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 citoyenid pour QB d'ESX utilisateurs tableau 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.* avec exportations.qbx_core:* ou ox_lib rappels.
  • Joueur: QBCore.Functions.GetPlayer(src)exportations.qbx_core:GetPlayer(src).
  • Notifier: QBCore.Fonctions.Notifyexports.qbx_core:Notifier ou lib.notify.
  • Fonction/groupes : utiliser les exportations QBOX (DéfinirJobDuty, HasGroup, etc.).

QBOX → QBCore

  • Remplacer exportations.qbx_core:* avec QBCore.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, rappels emballage.
  • Détecter le framework au moment de l'exécution (qbx_coreQB-Noyaues_extendedaucun).
  • 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 mondial avec parcimonie ; évitez les mises à jour en boucle à chaud.

9) Pièges courants et manuel de débogage

  • Supposant Obtenir l'objet de base existe sur QBOX → ça ne le fait pas ; utiliser exportations.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épartoxmysqlox_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_ignore minimal ; 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.lua et 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.

{ “@context”: “https://schema.org”, “@type”: “FAQPage”, “mainEntity”: [ { “@type”: “Question”, “name”: “Can I port QBCore scripts to QBOX without a full rewrite?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “With adapters and ox_lib callbacks, most scripts need only call remapping.”} }, { “@type”: “Question”, “name”: “What do I do with black/dirty money?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Standardize in your adapter: ESX → black_money account; QB → item or extra account; QBOX → item or alt wallet (e.g., crypto).”} }, { “@type”: “Question”, “name”: “Why do callbacks hang after moving to QBOX?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “ESX/QB callbacks won’t fire on QBOX. Use lib.callback.register/await.”} }, { “@type”: “Question”, “name”: “Best way to migrate mysql-async?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Replace with oxmysql await APIs; remove callback pyramids.”} }, { “@type”: “Question”, “name”: “How do I convert qb-target to ox_target?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Replace addBoxZone/Entity API calls one-for-one; event payloads remain similar. Keep target names stable.”} } ] }

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)

Luc
Luc

Je m'appelle Luke, je suis un joueur et j'adore écrire sur FiveM, GTA et le jeu de rôle. Je dirige une communauté de jeu de rôle et j'ai environ 10 ans d'expérience dans l'administration de serveurs.

Articles: 570