Conversione di FiveM Scripts – ESX, QBCore, QBOX (Frame…

Convertire FiveM Scripts – ESX, QBCore, QBOX (Framework…

Questa è una guida agli script FiveM di facile conversione, senza fronzoli e basata sul codice, che ti mostra esattamente come Converti gli script FiveM tra ESX, QBCore, QBOX (qbx_core) e configurazioni indipendenti dal framework (standalone). Riceverai mapping API a tre vie, codice adattatore, passaggi di migrazione SQL (mysql-async → oxmysql), specifiche di QBOX, checklist di test e suggerimenti per la protezione in produzione.


TL;DR — Migrazione in 10 passaggi

  1. Istantanea e messa in scena: Eseguire il backup del DB/fileAvviare un server di test locale con il framework di destinazione.
  2. Identificare le dipendenze: inventario, targeting, menu/UI, callback, layer DB, nucleo accesso.
  3. Versioni e ordine dei pin: oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → le tue risorse.
  4. Leggi il percorso del codice: Trova tutte le chiamate relative a giocatori, denaro, lavoro/compito, inventario, callback/eventi e DB.
  5. API della mappa: Utilizzare le tabelle Rosetta sottostanti per mappare ESX ↔ QBCore ↔ QBOX.
  6. Collegalo: Aggiungi un ponte.lua adattatore che rileva automaticamente il framework e normalizza le chiamate.
  7. Convertire le callback: Callback ESX/QB → QBOX/ox_lib lib.callback.* quando necessario.
  8. Migrazione DB: Sposta identificatori, account, oggetti, veicoli; passa a oxmysql *.await stile.
  9. Eventi di indurimento: Convalidare source, limiti, gruppi/lavori, proprietà; non fidarti mai del cliente.
  10. Controllo qualità e rilascio: Eseguire le checklist, i tag, il changelog e il piano di rollback.

Sei uno sviluppatore alla ricerca di una soluzione Adapter? Dai un'occhiata al nostro script adattatore gratuito qui


1) Framework 101: ESX vs QBCore vs QBOX vs Standalone

Panoramica architettonica

CategoriaESXQBCoreQBOX
Architettura / Accesso al coreexports['es_extended']:getSharedObject()ESXexports['qb-core']:GetCoreObject()QBCoreNessun oggetto core globale; utilizzare exports.qbx_core:* per giocatori, gruppi e notifiche
Oggetto giocatoreESX.GetPlayerFromId(src)xPlayerQBCore.Functions.GetPlayer(src)Playerexports.qbx_core:GetPlayer(src)Player con PlayerData
IdentificatoriStoricamente identifier (licenza/steam)citizenid come chiave primariacitizenid come chiave primaria
Soldi GestionexPlayer.addMoney() / `addAccountMoney('banca''denaro_nero')``Player.Functions.AddMoney('contanti'
Lavori e doverixPlayer.job.name, .job.gradePlayer.PlayerData.job.name, .grade.level, OnDutyAssistenti di lavoro/gruppo tramite exports.qbx_core:* (controlli di gruppo, addetti alla definizione dei doveri)
InventarioESX predefinito / ox_inventory / qb-inventory (raccomandato: ox_inventory)qb-inventory / ox_inventoryox_inventory raccomandato
RichiamateESX.RegisterServerCallback / ESX.TriggerServerCallbackQBCore.Functions.CreateCallback / TriggerCallbackPrefer ox_lib richiamate (lib.callback.register/await) o esportazioni QBOX
Livello di databaseVecchio: mysql-async → Adesso: oxmysql (MySQL.query.await, MySQL.update.await)oxmysqloxmysql
Interfaccia utente – NotificheNotifica ESXQB NotificaQBOX avvisa gli aiutanti o lib.notify
Interfaccia utente – Menuesx_menu_default / ox_lib:registerContextqb-menu / ox_lib:registerContextox_lib:registerContext / lib.inputDialog
UI – Sistema di destinazioneesx_target / ox_targetqb-target / ox_targetox_target raccomandato

Dove QBOX differisce

  • Nome della risorsa ed esportazioni: qbx_core (NO GetCoreObject).
  • Si appoggia su ox_lib (richiamate, notifiche) e oxmysql per impostazione predefinita.
  • Integrati per più caratteri/coda/gruppi; aiutanti personalizzati per lavori/compiti.

Framework FiveM: QBCore vs. ESX
Converting FiveM Scripts – ESX, QBCore, QBOX (Frame... 3

2) Preflight: Ambiente e strumenti

  • Server: attuale Server FX artefatti, Lua 5.4, CFX ensure ordine
  • Ordine: ensure oxmysqlensure ox_libensure frameworkensure yourResource
  • Redattore: VS Code + Lua LS, stilo; facoltativo ripgrep per scansioni rapide di modelli
  • Configurazione di prova: snapshot pulito del database; registrazione dettagliata; piccolo set di dati inizializzati
  • Modelli di ricerca userai:
    • ESX. xPlayer. QBCore. PlayerData qbx_core exports.ox_inventory mysql%-async MySQL.

3) Rosetta Stone: ESX ↔ QBCore ↔ QBOX (Mappatura a tre vie)

Copia/incolla il riferimento amichevole. Usalo per sostituire le chiamate o per collegare il tuo adattatore.

Core e Player

ConcettoESXQBCoreQBOX
Ottieni il nucleoexports['es_extended']:getSharedObject()exports['qb-core']:GetCoreObject()(n/d — usa le esportazioni)
Ottieni il giocatore (src)ESX.GetPlayerFromId(src)QBCore.Functions.GetPlayer(src)exports.qbx_core:GetPlayer(src)
Ottieni tramite citizenid(query personalizzata)QBCore.Functions.GetPlayerByCitizenId(id)exports.qbx_core:GetPlayerByCitizenId(id) (se presente)

Identificatori

ConcettoESXQBCoreQBOX
Primarioidentifier (licenza/steam)citizenidcitizenid
attraversamento pedonaletavolo id_map(identifier, citizenid)StessoStesso

Soldi

AzioneESXQBCoreQBOX
Aggiungi contantixPlayer.addMoney(a)Player.Functions.AddMoney('cash', a)Player.PlayerData.money.cash += a (tramite adattatore + salvataggio)
Aggiungi bancaxPlayer.addAccountMoney('bank', a)Player.Functions.AddMoney('bank', a)Player.PlayerData.money.bank += a (adattatore + risparmio)
Aggiungi sporcoxPlayer.addAccountMoney('black_money', a)elemento o account extra (definito dal server)mappa al portafoglio item/alt (ad esempio, crypto) (scelta dell'adattatore)

Lavori, doveri, gruppi

ConcettoESXQBCoreQBOX
Leggi il lavoroxPlayer.job.name, .gradePlayer.PlayerData.job.name, .grade.levelPlayer.PlayerData.job.* + aiutanti di gruppo
In servizio(varia)Player.PlayerData.job.ondutySetJobDuty/aiutanti di gruppo tramite esportazioni
Controllo di gruppo(Aggiungi su)(Aggiungi su)exports.qbx_core:HasGroup(src, group) (esempio)

Inventario

AzioneESXQBCoreQBOX
Aggiungi elementoxPlayer.addInventoryItem(n, c)Player.Functions.AddItem(n, c, ...)prefer ox_inventory esportare tramite adattatore
inventario_di_bueexports.ox_inventory:*exports.ox_inventory:*exports.ox_inventory:*

Richiamate

ConcettoESXQBCoreQBOX
Registro del serverESX.RegisterServerCallbackQBCore.Functions.CreateCallbacklib.callback.register (ox_lib)
Trigger del clienteESX.TriggerServerCallbackQBCore.Functions.TriggerCallbacklib.callback.await

Livello DB

ConcettoESX/QB (legacy)oxmysql (destinazione)
Andare a prendereMySQL.Async.fetchAll(sql, params, cb)local rows = MySQL.query.await(sql, {p1, ...})
AggiornamentoMySQL.Async.execute(sql, params, cb)local aff = MySQL.update.await(sql, {p1, ...})

Interfaccia utente / Notifica / Target

ConcettoESXQBCoreQBOX
NotificareESX.ShowNotification(msg)QBCore.Functions.Notify(msg, type)exports.qbx_core:Notify(...) O lib.notify({...})
Menu(varia)qb-menuox_lib:registerContext / input
Bersaglio(Aggiungi su)qb-targetox_target

Mancia: favore ox_lib, inventario_di_bue, bersaglio_ox per rimanere neutrali nei diversi framework.


4) Tutorial A — ESX → QBCore (pratico)

Obiettivo: Convertire una semplice risorsa del negozio da ESX a QBCore.

Fase 1 — Dipendenze

  • Garantire oxmysql, ox_lib, qb-core sono iniziati.
  • Se lo script utilizza l'inventario ESX, migrare a inventario_di_bue (consigliato) o mappare l'inventario QB.

Fase 2: Rileva il framework e aggiungi un bridge

Creare bridge.lua per normalizzare giocatori/denaro/inventario:

-- 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

Passaggio 3: convertire i callback

  • ESX → QB: sostituisci ESX.RegisterServerCallback con QBCore.Functions.CreateCallback.
  • Usi del cliente 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

Fase 4 — Percorsi di denaro e inventario

  • Sostituire xPlayer.addAccountMoney con Player.Functions.AddMoney (per QB) o adattatore.
  • Standardizzare tutte le modifiche di inventario tramite l'adattatore.

Fase 5 — Eventi (sicurezza lato server)

RegisterNetEvent('shop:buy', function(item, amount)
 local src = source
 if type(item) ~= 'string' or type(amount) ~= 'number' then return end
 if amount < 1 or amount > 10 then return end

 local p = bridge.getPlayer(src)
 if not p then return end

 local price = 100 * amount
 if not bridge.removeMoney(src, 'cash', price) then return end
 bridge.addItem(src, item, amount)
 bridge.notify(src, ('Bought %dx %s'):format(amount, item), 'success')
end)

Fase 6 — Migrazione del DB (identificatori, account)

  • Creare un attraversamento pedonale id_map(identifier, citizenid).
  • Popolare citizenid per QB da ESX users tabella tramite regola di scelta (colonna esistente o generata).
-- Example: create crosswalk and backfill (customize to your schema)
CREATE TABLE IF NOT EXISTS id_map (
 identifier VARCHAR(64) PRIMARY KEY,
 citizenid VARCHAR(64) NOT NULL UNIQUE
);

-- Suppose you generated new citizenids and stored them earlier
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 })

Fase 7 — Controllo qualità

  • Genera oggetti, acquista/vendi, assicurati che i saldi cambino correttamente.
  • Verificare che i callback vengano restituiti sotto carico.
  • Verificare che i metadati dell'inventario siano conservati.

5) Tutorial B — QBCore → ESX (pratico)

Avvertenze principali:

  • ESX utilizza conti per bank/black_moneySoldi sporchi del QB del Port articolo (se utilizzato) sull'account ESX o conservarlo come elemento.
  • Lo schema di lavoro è diverso (grado vs livello). Mappare con attenzione.

Esempio: mappatura del denaro tramite adattatore

-- 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

Esempio: conversione di callback (server)

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

Lista di controllo dei test

  • Le posizioni lavorative/promozioni persistono.
  • I saldi bancari/sporchi mutano come previsto.
  • Convalidati i formati di proprietà e targa del veicolo.

6) Tutorial C — QBCore ↔ QBOX (pratico)

QBCore → QBOX

  • Sostituire QBCore.Functions.* con exports.qbx_core:* O ox_lib richiami.
  • Giocatore: QBCore.Functions.GetPlayer(src)exports.qbx_core:GetPlayer(src).
  • Notifica: QBCore.Functions.Notifyexports.qbx_core:Notify O lib.notify.
  • Dovere/gruppi: utilizzare le esportazioni QBOX (SetJobDuty, HasGroup, ecc.).

QBOX → QBCore

  • Sostituire exports.qbx_core:* con QBCore.Functions.* equivalenti o il tuo adattatore.
  • Reintrodurre i callback QB e gli equivalenti menu/target secondo necessità.

Frammenti prima/dopo

-- Before (QB notify)
QBCore.Functions.Notify('Hello', 'success')

-- After (QBOX)
exports.qbx_core:Notify(source, 'Hello', 'success')
-- or
lib.notify(source, { title = 'Hello', description = 'Welcome', type = 'success' })
-- Before (QB get player)
local Player = QBCore.Functions.GetPlayer(src)

-- After (QBOX)
local Player = exports.qbx_core:GetPlayer(src)

7) Tutorial D — Framework → Standalone con adattatori

Scrivi i tuoi script una volta ed eseguirli ovunque:

  • Crea un ponte esponendo un'API stabile: getPlayer, getIdentifier, add/removeMoney, add/removeItem, notify, hasGroup, onDuty, callbacks involucro.
  • Rileva il framework in fase di esecuzione (qbx_coreqb-corees_extendednone).
  • Utilizzo ox_lib per callback e notifiche quando non esiste un helper framework diretto.

Fallback autonomo minimo

-- 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) Prestazioni e sicurezza (rafforzo della produzione)

Convalida lato server (non fidarti mai del client)

  • Convalidare tipi E limiti ad ogni evento.
  • Controllo proprietà, tempi di recupero, distanza (se pertinente), lavoro/gruppo.
  • Assicuratevi che il denaro non possa andare in negativo; limitate gli importi.
  • Confrontare prezzo lato server; non accettare totali forniti dal client.

Struttura dell'evento

  • Usane uno evento del server per azione; non esporre ai clienti funzioni di inventario/denaro non elaborate.
  • Prefer richiami per flussi di richiesta/risposta.

DB e prestazioni

  • Passa a oxmysql attendere le API; scrivere in batch; evitare query per tick.
  • Indicizza le colonne interrogate frequentemente (citizenid, identifier, plate).
  • Memorizza nella cache le configurazioni/listini prezzi; esportali ai clienti una volta, quindi confrontali in caso di modifica.
  • Utilizzo GlobalState con parsimonia; evitare aggiornamenti hot-loop.

9) Errori comuni e manuale di debug

  • Supponendo GetCoreObject esiste su QBOX → non lo fa; usa exports.qbx_core:*.
  • I callback non vengono più restituiti dopo la migrazione a QBOX → I callback ESX/QB non sono registrati; passare a lib.callback.register/await.
  • Semantica del denaro sporco differisci → decidi articolo vs account vs portafoglio alternativo e standardizza nel tuo adattatore.
  • Ipotesi di inventario miste → normalizza su ox_inventory.
  • Problemi con l'ordine di partenzaoxmysqlox_lib → framework → le tue risorse.
  • Deriva dei metadati del veicolo → assicurarsi che le colonne JSON e i formati delle piastre corrispondano al framework di destinazione.

10) Buone pratiche per fxmanifest.lua

fx_version 'cerulean'
game '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'
}

-- dependencies (pick what you use): ox_lib, oxmysql, ox_inventory, qb-core OR qbx_core OR es_extended
  • Dichiarare Lua 5.4 (lua54 'yes').
  • Mantenere escrow_ignore minimo; non tentare mai di aggirare il deposito a garanzia.

11) Migrazione dei dati: frammenti SQL (esempi)

Adatta i nomi delle tabelle/colonne al tuo schema. Eseguire sempre prima una copia.

Identificatori: ESX → QB/QBOX

-- Add citizenid to ESX users if missing
ALTER TABLE users ADD COLUMN IF NOT EXISTS citizenid VARCHAR(64);

-- Populate using a deterministic generator or an existing column
UPDATE users SET citizenid = LOWER(SUBSTRING(MD5(CONCAT(identifier,'-QB')),1,10))
WHERE citizenid IS NULL;

-- Create crosswalk
CREATE TABLE IF NOT EXISTS id_map (
 identifier VARCHAR(64) PRIMARY KEY,
 citizenid VARCHAR(64) NOT NULL UNIQUE
);
INSERT IGNORE INTO id_map(identifier, citizenid)
SELECT identifier, citizenid FROM users WHERE citizenid IS NOT NULL;

Conti/Denaro

-- Example: convert ESX bank balances to QB money table (if your QB schema stores it separately)
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);

Veicoli

-- Normalize plates to target format (example: 8 chars upper)
UPDATE owned_vehicles SET plate = UPPER(LEFT(plate,8));

-- Ensure JSON metadata columns are valid
UPDATE owned_vehicles SET mods = JSON_MERGE_PATCH('{}', mods) WHERE JSON_VALID(mods) = 0;

12) Adattatori riutilizzabili (principianti)

Lascialo cadere in bridge.lua ed espandibile in base alle tue esigenze. Rileva automaticamente ESX/QB/QBOX ed espone un'API stabile.

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) Liste di controllo finali (copia e spedizione)

A) Scoperta e pre-volo

  • Snapshot DB/file; creazione di un server di staging
  • Aggiungi artefatti e versioni delle risorse; definisci l'ordine di inizio
  • Elencate le dipendenze di inventario/obiettivo/menu
  • Decidere la strategia di identificazione (attraversamento pedonale cittadino)

B) Audit del codice

  • Grep per ESX/QB/QBOX/ox_*/mysql‑async
  • Elenca tutte le chiamate relative a denaro/inventario/lavoro/dovere
  • Elenca i callback e gli eventi server/client

C) Mappatura e progettazione

  • Scegli la superficie dell'adattatore (lettore, ID, denaro, oggetti, notifica, callback)
  • Decidere la strategia del denaro sporco (account vs articolo vs portafoglio alternativo)
  • Favorisci ox_lib/ox_inventory/ox_target

D) Migrazione dei dati

  • Costruire un attraversamento pedonale per i cittadini
  • Converti conti/denaro
  • Normalizzare i metadati e le targhe dei veicoli
  • Passa alle chiamate in attesa di oxmysql

E) Test di controllo qualità

  • Sicurezza degli eventi: tipi/limiti/proprietà/tempi di recupero
  • Callback: restituiscono valori sotto carico
  • Metadati di inventario conservati
  • La logica dei lavori/doveri/gruppi corrisponde al design

F) Rilascio e rollback

  • Rilascio tag; registro delle modifiche
  • Conserva lo snapshot pre-migrazione per 7-14 giorni
  • Monitora errori/latenza; indicizza le query più frequenti

14) FAQ (con schema JSON‑LD)

D: Posso trasferire gli script QBCore su QBOX senza una riscrittura completa?
UN: Con adattatori e ox_lib callback, la maggior parte degli script necessita solo del remapping delle chiamate.

D: Cosa faccio con il denaro sporco/nero?
UN: Standardizza nel tuo adattatore: ESX → black_money account; QB → oggetto o account extra; QBOX → oggetto o portafoglio alternativo (ad esempio, criptovaluta). Mantieni una strategia per l'intero progetto.

D: Perché le callback si bloccano dopo il passaggio a QBOX?
UN: I callback ESX/QB non verranno attivati su QBOX. Utilizzare lib.callback.register/await.

D: Qual è il modo migliore per migrare mysql-async?
UN: Sostituisci con oxmysql attendere le API; rimuovere le piramidi di callback.

D: Come faccio a convertire qb‑target in ox_target?
UN: Sostituisci le chiamate API addBoxZone/Entity una a una; i payload degli eventi rimangono simili. Mantieni stabili i nomi dei target.

{ “@context”: “https://schema.org”, “@type”: “FAQPage”, “mainEntity”: [ { “@type”: “Question”, “name”: “Posso portare gli script QBCore su QBOX senza una riscrittura completa?”, “acceptedAnswer”: { “@type”: “Answer”, “text”: “Con adattatori e callback ox_lib, la maggior parte degli script necessita solo di una rimappatura delle chiamate.” } }, { “@type”: “Question”, “name”: “Cosa faccio con i soldi neri/sporchi?”, “acceptedAnswer”: { “@type”: “Answer”, “text”: “Standardizza nel tuo adattatore: ESX → conto black_money; QB → oggetto o conto extra; QBOX → oggetto o portafoglio alternativo (es. crypto).” } }, { “@type”: “Question”, “name”: “Perché i callback si bloccano dopo lo spostamento su QBOX?”, “acceptedAnswer”: { “@type”: “Answer”, “text”: “I callback ESX/QB non verranno attivati su QBOX. Usa lib.callback.register/await.” } }, { “@type”: “Question”, “name”: “Miglior modo per migrare mysql-async?”, “acceptedAnswer”: { “@type”: “Answer”, “text”: “Sostituisci con oxmysql await APIs; rimuovi le piramidi di callback.” } }, { “@type”: “Question”, “name”: “Come converto qb-target in ox_target?”, “acceptedAnswer”: { “@type”: “Answer”, “text”: “Sostituisci le chiamate addBoxZone/Entity API uno a uno; i payload degli eventi rimangono simili. Mantieni stabili i nomi dei target.” } } ] }

15) Immagini (suggerimenti)

  • Diagramma di flusso (Scopri → Mappa → Adatta → Migra DB → Test → Rilascia)
  • Schema degli adattatori: Script → Bridge → Framework (ESX/QB/QBOX)
  • Tabella di Rosetta: incluso sopra (esporta come CSV per i download)
[Discover] → [Map APIs] → [Write Adapter] → [Migrate DB] → [Harden] → [QA] → [Release]

16) Legale ed etico

  • Rispettare le licenze (MIT/GPL/NC). Non bypassare l'escrow o l'offuscamento.
  • Converti solo gli script che Proprio o avere il permesso di adattare.

17) Scaricabili e guida di riferimento rapido

Puoi anche usare questo convertitore (non testato):

https://github.com/sledgehamm3r/ESX-QBCore-Converter


28) Prossimi passi

  • Lascia cadere il ponte.lua nella tua risorsa e inizia a convertire prima gli script di maggior valore.
  • Standardizzare su ox_lib + ox_inventory + ox_target + oxmysql per rimanere indipendenti dal framework.
  • Utilizzare le checklist durante la revisione e il rilascio.

Leggi anche Migrazione SQL e identificatori: steam/license → citizenid e Account → Money (ESX → QBCore/QBOX)