$ USD
  • $ USD
  • € EUR
  • Britse pond (£ GBP)
  • $ AUD
  • R$ BRL
  • CHF CHF
  • ¥ JPY
Converteren van FiveM Scripts – ESX, QBCore, QBOX (Frame…

Converteren van FiveM Scripts – ESX, QBCore, QBOX (Framework…

Dit is een code-first, no-nonsense gids voor het eenvoudig converteren van FiveM scripts die je precies laat zien hoe je Converteer FiveM Scripts tussen ESX, QBCore, QBOX (qbx_core) en framework-agnostische (standalone) opstellingen. Je krijgt drieweg API-mapping, adaptercode, SQL-migratiestappen (mysql-async → oxmysql), QBOX-specifieke zaken, testchecklists en productie-hardening tips.


TL;DR — Migratie in 10 stappen

  1. Snapshot & staging: Back-up DB\/bestanden. Start een lokale testserver op met het doelframework.
  2. Identificeer afhankelijkheden: inventory, target, menu\/UI, callbacks, DB-laag, core toegang.
  3. Vastzetten van versies & volgorde: oxmysql → ox_lib → framework (es_extended \/ qb-core \/ qbx_core) → jouw resources.
  4. Lees het codepad: Vind alle player, money, job\/duty, inventory, callback\/event en DB-aanroepen.
  5. Map API's: Gebruik de onderstaande Rosetta-tabellen om ESX ↔ QBCore ↔ QBOX te mappen.
  6. Overbrug het: Voeg een bridge.lua adapter die automatisch het framework detecteert en aanroepen normaliseert.
  7. Converteer callbacks: ESX\/QB callbacks → QBOX\/ox_lib lib.callback.* wanneer nodig.
  8. Migreer DB: Verplaats identifiers, accounts, items, voertuigen; schakel over naar oxmysql *.await stijl.
  9. evenementen harden: Valideer source, grenzen, groepen/taken, eigendom; vertrouw nooit de client.
  10. QA & release: Voer de checklists uit; tag, changelog en terugdraaiplan.

Ben je een ontwikkelaar die op zoek is naar een Adapter-oplossing? Bekijk hier onze gratis adapter-script


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

Architecturaal overzicht

CategorieESXQBCoreQBOX
Architectuur / Kern toegangexports['es_extended']:getSharedObject()ESXexports['qb-core']:GetCoreObject()QBCoreGeen globaal kernobject; gebruik exports.qbx_core:* voor speler, groepen en notificaties
SpelerobjectESX.GetPlayerFromId(src)xPlayerQBCore.Functions.GetPlayer(src)Playerexports.qbx_core:GetPlayer(src)Player met PlayerData
IdentificatorenHistorisch identifier (licentie\/steam)citizenid als primaire sleutelcitizenid als primaire sleutel
Geld AfhandelingxPlayer.addMoney() \/ `addAccountMoney(‘bank’‘black_money’)``Player.Functions.AddMoney(‘cash’
Banen & DienstxPlayer.job.name, .job.gradePlayer.PlayerData.job.name, .grade.level, OnDutyBaan\/groep helpers via exports.qbx_core:* (groepscontroles, dienstinstellers)
InventarisESX standaard \/ ox_inventory / qb-inventory (aanbevolen: ox_inventory)qb-inventory / ox_inventoryox_inventory aanbevolen
CallbacksESX.RegisterServerCallback / ESX.TriggerServerCallbackQBCore.Functions.CreateCallback / TriggerCallbackGeef de voorkeur aan ox_lib callbacks (lib.callback.register/await) of QBOX exports
Database LaagOud: mysql-async → Nu: oxmysql (MySQL.query.await, MySQL.update.await)oxmysqloxmysql
UI – MeldingenESX NotifyQB NotifyQBOX notify helpers or lib.notify
UI – Menu'sesx_menu_default / ox_lib:registerContextqb-menu / ox_lib:registerContextox_lib:registerContext / lib.inputDialog
UI – Doelsysteemesx_target / ox_targetqb-target / ox_targetox_target aanbevolen

Waar QBOX verschilt

  • Resourcenaam en exports: qbx_core (geen GetCoreObject).
  • Leunt op ox_lib (callbacks, notify) en oxmysql standaard.
  • Ingebouwde functies voor multicharacter/queue/groups; opiniegestuurde helpers voor jobs/dienst.

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

2) Preflight: Omgeving & Tools

  • Server: huidige FXServer artifacts, Lua 5.4, CFX ensure bestellen
  • Volgorde: ensure oxmysqlensure ox_libensure frameworkensure yourResource
  • Editor: VS Code + Lua LS, stylua; optioneel ripgrep voor snelle patroonscans
  • Test setup: schone database snapshot; uitgebreide logging; kleine seeded dataset
  • Zoekpatronen je zult gebruiken:
    • ESX. xPlayer. QBCore. PlayerData qbx_core exports.ox_inventory mysql%-async MySQL.

3) Rosetta Stone: ESX ↔ QBCore ↔ QBOX (Tri‑way Mapping)

Kopieer/plakvriendelijke referentie. Gebruik het om aanroepen te vervangen of je adapter te bedraden.

Core & Player

ConceptESXQBCoreQBOX
Haal de core opexports['es_extended']:getSharedObject()exports['qb-core']:GetCoreObject()(n.v.t. — gebruik exports)
Haal speler (src) opESX.GetPlayerFromId(src)QBCore.Functions.GetPlayer(src)exports.qbx_core:GetPlayer(src)
Verkrijgen op citizenid(aangepaste query)QBCore.Functions.GetPlayerByCitizenId(id)exports.qbx_core:GetPlayerByCitizenId(id) (indien aanwezig)

Identificatoren

ConceptESXQBCoreQBOX
Primairidentifier (licentie\/steam)citizenidcitizenid
Zebra crossingtabel id_map(identifier, citizenid)hetzelfdehetzelfde

Geld

ActieESXQBCoreQBOX
Voeg contant geld toexPlayer.addMoney(a)Player.Functions.AddMoney('cash', a)Player.PlayerData.money.cash += a (via adapter + opslaan)
Bank toevoegenxPlayer.addAccountMoney('bank', a)Player.Functions.AddMoney('bank', a)Player.PlayerData.money.bank += a (adapter + opslaan)
Add dirtyxPlayer.addAccountMoney('black_money', a)item of extra account (server-gedefinieerd)map naar item/alternatieve portemonnee (bijv., crypto) (adapterkeuze)

Jobs, Duty, Groepen

ConceptESXQBCoreQBOX
Lees baanxPlayer.job.name, .gradePlayer.PlayerData.job.name, .grade.levelPlayer.PlayerData.job.* + groep helpers
In dienst(varieert)Player.PlayerData.job.ondutySetJobDuty/groep helpers via exports
Group check(add-on)(add-on)exports.qbx_core:HasGroup(src, group) (voorbeeld)

Inventaris

ActieESXQBCoreQBOX
Item toevoegenxPlayer.addInventoryItem(n, c)Player.Functions.AddItem(n, c, ...)voorkeur ox_inventory export via adapter
ox_inventoryexports.ox_inventory:*exports.ox_inventory:*exports.ox_inventory:*

Callbacks

ConceptESXQBCoreQBOX
Server registerESX.RegisterServerCallbackQBCore.Functions.CreateCallbacklib.callback.register (ox_lib)
Client triggerESX.TriggerServerCallbackQBCore.Functions.TriggerCallbacklib.callback.await

DB Layer

ConceptESX/QB (legacy)oxmysql (target)
OphalenMySQL.Async.fetchAll(sql, params, cb)local rows = MySQL.query.await(sql, {p1, ...})
UpdateMySQL.Async.execute(sql, params, cb)local aff = MySQL.update.await(sql, {p1, ...})

UI / Notify / Target

ConceptESXQBCoreQBOX
MeldingESX.ShowNotification(msg)QBCore.Functions.Notify(msg, type)exports.qbx_core:Notify(...) of lib.notify({...})
Menu(varieert)qb-menuox_lib:registerContext / inputs
Doelwit(add-on)qb-targetox_target

Tip: favoriet ox_lib, ox_inventory, ox_target om neutraal te blijven over frameworks.


4) Tutorial A — ESX → QBCore (Praktisch)

Doel: Converteer een simpele shop resource van ESX naar QBCore.

Stap 1 — Afhankelijkheden

  • Zorg ervoor dat oxmysql, ox_lib, qb-core zijn gestart.
  • Als het script ESX inventaris gebruikt, migreer dan naar ox_inventory (aanbevolen) of map naar QB inventaris.

Stap 2 — Detecteer framework & voeg een bridge toe

Creëren bridge.lua om spelers/geld/inventaris te normaliseren:

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

Stap 3 — Converteer callbacks

  • ESX → QB: vervangen ESX.RegisterServerCallback met QBCore.Functions.CreateCallback.
  • Client gebruikt 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

Stap 4 — Geld & inventarispaden

  • Vervangen xPlayer.addAccountMoney met Player.Functions.AddMoney (voor QB) of adapter.
  • Standaardiseer alle inventariswijzigingen via de adapter.

Stap 5 — Gebeurtenissen (server-side beveiliging)

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)

Stap 6 — DB-migratie (identifiers, accounts)

  • Maak een crosswalk id_map(identifier, citizenid).
  • Vullen citizenid voor QB vanaf ESX users tabel via regel naar keuze (bestaande kolom of gegenereerd).
-- 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 })

Stap 7 — QA

  • Items spawnen, kopen/verkopen, zorgen dat saldi correct veranderen.
  • Verifieer callbacks onder belasting.
  • Controleer of inventaris-metadata behouden blijft.

5) Tutorial B — QBCore → ESX (Hands‑on)

Belangrijke kanttekeningen:

  • ESX gebruikt accounts voor bank/black_money. Port QB’s vuile geld item (indien gebruikt) naar ESX account of behoud het als item.
  • Job schema verschilt (grade vs level). Kaart zorgvuldig.

Voorbeeld: Geld toewijzen via adapter

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

Voorbeeld: Callback conversie (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

Test checklist

  • Functie/promoties blijven behouden.
  • Bank-/vuile saldi muteren zoals verwacht.
  • Voertuigbezit en kentekenformaten gevalideerd.

6) Tutorial C — QBCore ↔ QBOX (Praktisch)

QBCore → QBOX

  • Vervangen QBCore.Functions.* met exports.qbx_core:* of ox_lib callbacks.
  • Speler: QBCore.Functions.GetPlayer(src)exports.qbx_core:GetPlayer(src).
  • Melding: QBCore.Functions.Notifyexports.qbx_core:Notify of lib.notify.
  • Duty/groepen: gebruik QBOX exports (SetJobDuty, HasGroup, etc.).

QBOX → QBCore

  • Vervangen exports.qbx_core:* met QBCore.Functions.* equivalenten of uw adapter.
  • Herintroduceer QB callbacks en menu/target equivalenten indien nodig.

Voor-/na-fragmenten

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

Schrijf je scripts eenmalig en voer ze overal uit:

  • Maak een bridge een stabiele API blootstellen: getPlayer, getIdentifier, add/removeMoney, add/removeItem, notify, hasGroup, onDuty, callbacks wrapper.
  • Detect framework at runtime (qbx_coreqb-corees_extendednone).
  • Gebruik ox_lib voor callbacks en notificaties wanneer er geen directe framework helper bestaat.

Minimale standalone fallback

-- 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) Prestaties & Beveiliging (Productie Verharding)

Server-side validatie (vertrouw nooit de client)

  • Valideer types En bounds bij elke gebeurtenis.
  • Controleren eigendom, cooldowns, afstand (indien relevant), functie/groep.
  • Zorg ervoor dat geld niet negatief kan worden; bedragen begrenzen.
  • Vergelijk prijs server-side; accepteer geen door de client verstrekte totalen.

Event structuur

  • Gebruik er één server event per actie; stel geen ruwe inventaris/geld functies bloot aan clients.
  • Geef de voorkeur aan callbacks voor request/response flows.

DB & performance

  • Schakel over naar oxmysql await APIs; batch writes; vermijd per-tick queries.
  • Indexeer veel bevraagde kolommen (citizenid, identifier, plate).
  • Cache configuratie/prijslijsten in het geheugen; exporteer ze eenmalig naar clients, synchroniseer daarna bij wijzigingen.
  • Gebruik GlobalState spaarsam; vermijd hot‑loop updates.

9) Veelvoorkomende valkuilen & Debugging Playbook

  • Assuming GetCoreObject bestaat op QBOX → het doet het niet; gebruik exports.qbx_core:*.
  • Callbacks keren nooit terug na migratie naar QBOX → ESX/QB callbacks zijn niet geregistreerd; schakel over naar lib.callback.register/await.
  • Semantiek van vies geld verschil → beslis item vs account vs alt wallet en standaardiseer in je adapter.
  • Gemengde inventaris aannames → normalize on ox_inventory.
  • Start order issuesoxmysqlox_lib → framework → je resources.
  • Vehicle metadata drift → zorg ervoor dat JSON kolommen en kentekenplaatformaten overeenkomen met het doel framework.

10) fxmanifest.lua Best Practices

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
  • Declareren Lua 5.4 (lua54 'yes').
  • Houden escrow_ignore minimaal; probeer nooit escrow-bypass.

11) Gegevensmigratie: SQL Snippets (Voorbeelden)

Pas tabel/kolomnamen aan uw schema aan. Voer altijd eerst uit op een kopie.

Identifiers: 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;

Accounts/Geld

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

Voertuigen

-- 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) Adapters die je kunt hergebruiken (Starter)

Plaats dit in bridge.lua en breid uit naar behoefte. Het detecteert automatisch ESX/QB/QBOX en biedt een stabiele API.

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) Eindcontroles (Kopiëren & Verzenden)

A) Discovery & Preflight

  • Snapshot DB/bestanden; maak een staging server
  • Pin artefacten en resourceversies; definieer startvolgorde
  • Inventory/target/menu-afhankelijkheden vermeld
  • Bepaal de identifier strategie (citizenid crosswalk)

B) Code Audit

  • Grep voor ESX/QB/QBOX/ox_*/mysql‑async
  • Alle money/inventory/job/duty-aanroepen vermelden
  • List callbacks and server/client events

C) Mapping & Ontwerp

  • Kies adapteroppervlak (speler, id's, geld, items, melding, callbacks)
  • Beslis over dirty-money-strategie (account vs item vs alt wallet)
  • Geef de voorkeur aan ox_lib/ox_inventory/ox_target

D) Data Migratie

  • Bouw citizenid crosswalk
  • Accounts/money converteren
  • Normalise voertuigmetadata en kentekenplaten
  • Schakel over naar oxmysql await calls

E) QA Testen

  • Event-beveiliging: types/grenzen/eigendom/cooldowns
  • Callbacks: retourneer waarden onder belasting
  • Inventaris metadata behouden
  • Jobs/duty/group logica komt overeen met het ontwerp

F) Release & Rollback

  • Tag release; wijzigingenlogboek
  • Bewaar pre-migratie snapshot voor 7-14 dagen
  • Monitor fouten/latentie; indexer hot queries

14) FAQ (met JSON‑LD Schema)

V: Kan ik QBCore scripts naar QBOX porten zonder een volledige herschrijving?
A: Met adapters en ox_lib callbacks, de meeste scripts hebben alleen call-remapping nodig.

V: Wat doe ik met zwart/vuil geld?
A: Standaardiseer in uw adapter: ESX → black_money account; QB → item of extra account; QBOX → item of alternatieve portemonnee (bijv. crypto). Houd één strategie projectbreed aan.

V: Waarom blijven callbacks hangen na migratie naar QBOX?
A: ESX/QB callbacks zullen niet worden geactiveerd op QBOX. Gebruik lib.callback.register/await.

V: Beste manier om mysql‑async te migreren?
A: Vervang met oxmysql await APIs; verwijder callback-pyramides.

V: Hoe converteer ik qb‑target naar ox_target?
A: Vervang addBoxZone/Entity API aanroepen één-op-één; event payloads blijven vergelijkbaar. Houd doelnamen stabiel.

{ “@context”: “https://schema.org”, “@type”: “FAQPage”, “mainEntity”: [ { “@type”: “Question”, “name”: “Kan ik QBCore scripts naar QBOX porteren zonder een volledige herschrijving?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Met adapters en ox_lib callbacks, hebben de meeste scripts slechts aanpassing van aanroepen nodig.”} }, { “@type”: “Question”, “name”: “Wat doe ik met zwart/vuil geld?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Standaardiseer in uw adapter: ESX → black_money account; QB → item of extra account; QBOX → item of alternatieve portemonnee (bv. crypto).”} }, { “@type”: “Question”, “name”: “Waarom blijven callbacks hangen na het overstappen naar QBOX?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “ESX/QB callbacks zullen niet worden geactiveerd op QBOX. Gebruik lib.callback.register/await.”} }, { “@type”: “Question”, “name”: “Beste manier om mysql-async te migreren?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Vervang met oxmysql await APIs; verwijder callback piramides.”} }, { “@type”: “Question”, “name”: “Hoe converteer ik qb-target naar ox_target?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Vervang addBoxZone/Entity API aanroepen één-op-één; event payloads blijven vergelijkbaar. Houd target namen stabiel.”} } ] }

15) Visuele elementen (Suggesties)

  • Stroomdiagram (Ontdekken → Kaart → Aanpassen → Migreer DB → Testen → Publiceren)
  • Adapters Diagram: Script → Bridge → Framework (ESX/QB/QBOX)
  • Rosetta-tabel: hierboven inbegrepen (exporteer als CSV voor downloads)
[Discover] → [Map APIs] → [Write Adapter] → [Migrate DB] → [Harden] → [QA] → [Release]

16) Juridisch & Ethisch

  • Respecteer licenties (MIT/GPL/NC). Niet omzeil escrow of obfuscation.
  • Converteer alleen scripts die u eigen of heb toestemming om aan te passen.

17) Downloadables & Snelreferentie

U kunt deze converter ook gebruiken (niet getest):

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


28) Volgende Stappen

  • Laat de bridge.lua in uw resource en begin met het converteren van uw scripts met de hoogste waarde eerst.
  • Standaardiseren op ox_lib + ox_inventory + ox_target + oxmysql om framework-agnostisch te blijven.
  • Gebruik de checklists tijdens beoordeling en release.

Lees ook SQL & Identifiers Migration: steam/license → citizenid en Accounts → Money (ESX → QBCore/QBOX)