
Converting FiveM Scripts – ESX, QBCore, QBOX (Frame…
Los scripts gratuitos son útiles para comprobaciones rápidas. Para servidores de producción, compare los paquetes completos para servidores o los scripts de pago con mantenimiento, teniendo en cuenta el framework y el caso de uso.
Esta es una guía de conversión de scripts de FiveM sencilla, sin tonterías y que prioriza el código, que le muestra exactamente cómo Convertir scripts de FiveM Entre ESX, QBCore, QBOX (qbx_core) y configuraciones independientes de framework. Obtendrá asignaciones de API de tres vías, código de adaptador, pasos de migración de SQL (mysql-async → oxmysql), detalles de QBOX, listas de verificación de pruebas y consejos para el fortalecimiento de la producción.
TL;DR — Migración en 10 pasos
- Instantánea y puesta en escena: Realizar copias de seguridad de bases de datos/archivosPonga en marcha un servidor de pruebas local con el marco de destino.
- Identificar dependencias: inventory, target, menu/UI, callbacks, DB layer, centro access.
- Versiones y orden de los pines: oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → sus recursos.
- Leer la ruta del código: Encuentra todas las llamadas de jugadores, dinero, trabajos/deberes, inventario, devolución de llamada/evento y base de datos.
- API de mapas: Utilice las tablas de Rosetta a continuación para asignar ESX ↔ QBCore ↔ QBOX.
- Puentealo: Agregar un puente.lua Adaptador que detecta automáticamente el marco y normaliza las llamadas.
- Convertir devoluciones de llamadas: Devoluciones de llamadas ESX/QB → QBOX/ox_lib
lib.callback.*cuando sea necesario. - Migrar base de datos: Mover identificadores, cuentas, artículos, vehículos; cambiar a oxmysql
*.esperarestilo. - Eventos de endurecimiento: Validar
fuente, límites, grupos/trabajos, propiedad; nunca confíe en el cliente. - Control de calidad y lanzamiento: Ejecute las listas de verificación, etiquetas, registros de cambios y planes de reversión.
¿Es usted un desarrollador que busca una solución de adaptador? Consulte nuestro script adaptador gratuito aquí
1) Frameworks 101: ESX vs QBCore vs QBOX vs Standalone
Visión general de la arquitectura
| Categoría | ESX | QBCore | QBOX |
|---|---|---|---|
| Arquitectura / Acceso al núcleo | exportaciones['es_extended']:getSharedObject() → ESX | exportaciones['qb-core']:GetCoreObject() → QBCore | No hay ningún objeto central global; uso exportaciones.qbx_core:* Para jugadores, grupos y notificaciones |
| Objeto de jugador | ESX.GetPlayerFromId(origen) → xPlayer | QBCore.Functions.GetPlayer(src) → Jugador | exportaciones.qbx_core:GetPlayer(src) → Jugador con Datos del jugador |
| Identificadores | Históricamente identificador (licencia/steam) | ID de ciudadano como clave principal | ID de ciudadano como clave principal |
| Dinero Manejo | xPlayer.addMoney() / `addAccountMoney('banco' | 'dinero negro')` | `Player.Functions.AddMoney('efectivo' |
| Trabajos y deberes | xPlayer.job.name, .job.grade | Jugador.PlayerData.job.name, .nivel.de.grado, En servicio | Ayudantes de trabajo/grupo a través de exportaciones.qbx_core:* (controles de grupo, fijadores de tareas) |
| Inventario | ESX predeterminado / inventario_de_bueyes / inventario qb (recomendado: inventario_de_bueyes) | inventario qb / inventario_de_bueyes | inventario_de_bueyes recomendado |
| Devoluciones de llamadas | ESX.RegisterServerCallback / ESX.TriggerServerCallback | QBCore.Funciones.CreateCallback / Devolución de llamada del disparador | Preferir biblioteca de buey devoluciones de llamadas (lib.callback.register/await) o exportaciones de QBOX |
| Capa de base de datos | Viejo: MySQL asíncrono → Ahora: oxmysql (MySQL.query.await, MySQL.update.await) | oxmysql | oxmysql |
| Interfaz de usuario – Notificaciones | Notificación ESX | Notificar QB | QBOX notifica a los ayudantes o lib.notificar |
| IU – Menús | esx_menu_default / ox_lib:registerContext | menú qb / ox_lib:registerContext | ox_lib:registerContext / lib.inputDialog |
| UI – Sistema de destino | objetivo esx / objetivo_buey | objetivo qb / objetivo_buey | objetivo_buey recomendado |
¿En qué se diferencia QBOX?
- Nombre del recurso y exportaciones:
núcleo qbx(NoObtener objeto principal). - Se apoya en biblioteca de buey (devoluciones de llamadas, notificar) y oxmysql por defecto.
- Integrados para múltiples caracteres/colas/grupos; ayudantes con opiniones definidas para trabajos/tareas.

2) Pre-vuelo: Entorno y herramientas
- Servidor: actual Servidor FX artefactos, Lua 5.4, CFX
asegurarorden - Orden:
garantizar oxmysql→asegurar ox_lib→garantizar el marco→asegurar suRecurso - Editor: Código VS + Lua LS, aguja; opcional ripgrep para escaneos rápidos de patrones
- Configuración de prueba: instantánea de base de datos limpia; registro detallado; conjunto de datos pequeños y sembrados
- Patrones de búsqueda usarás:
ESX.xPlayer.QBCore.Datos del jugadornúcleo qbxexports.ox_inventorymysql%-asyncMySQL.
3) Rosetta Stone: ESX ↔ QBCore ↔ QBOX (Mapeo de tres vías)
Copiar y pegar una referencia fácil de usar. Úsala para reemplazar llamadas o conectar tu adaptador.
Núcleo y jugador
| Concepto | ESX | QBCore | QBOX |
|---|---|---|---|
| Obtener el núcleo | exportaciones['es_extended']:getSharedObject() | exportaciones['qb-core']:GetCoreObject() | (n/a — utilizar exportaciones) |
| Obtener jugador (src) | ESX.GetPlayerFromId(origen) | QBCore.Functions.GetPlayer(src) | exportaciones.qbx_core:GetPlayer(src) |
| Obtener por citizenid | (consulta personalizada) | QBCore.Functions.GetPlayerByCitizenId(id) | exportaciones.qbx_core:GetPlayerByCitizenId(id) (si está presente) |
Identificadores
| Concepto | ESX | QBCore | QBOX |
|---|---|---|---|
| Primario | identificador (licencia/steam) | ID de ciudadano | ID de ciudadano |
| Paso de peatones | mesa id_map(identificador, idciudadano) | mismo | mismo |
Dinero
| Acción | ESX | QBCore | QBOX |
|---|---|---|---|
| Añadir efectivo | xPlayer.addMoney(a) | Jugador.Funciones.AddMoney('efectivo', a) | Jugador.PlayerData.money.cash += a (vía adaptador + guardar) |
| Agregar banco | xPlayer.addAccountMoney('banco', a) | Jugador.Funciones.AddMoney('banco', a) | Jugador.PlayerData.money.bank += a (adaptador + guardar) |
| Añadir sucio | xPlayer.addAccountMoney('dinero_negro', a) | artículo o cuenta adicional (definido por el servidor) | Mapa de la billetera de artículos/alternativas (por ejemplo, cripto) (elección del adaptador) |
Trabajos, deberes, grupos
| Concepto | ESX | QBCore | QBOX |
|---|---|---|---|
| Leer trabajo | xPlayer.job.name, .calificación | Jugador.PlayerData.job.name, .nivel.de.grado | Jugador.PlayerData.job.* + ayudantes de grupo |
| De servicio | (varía) | Jugador.PlayerData.job.onduty | Establecer tarea/grupo de ayudantes a través de exportaciones |
| Comprobación de grupo | (Añadir) | (Añadir) | exportaciones.qbx_core:HasGroup(src, grupo) (ejemplo) |
Inventario
| Acción | ESX | QBCore | QBOX |
|---|---|---|---|
| Añadir artículo | xPlayer.addInventoryItem(n, c) | Jugador.Funciones.AddItem(n, c, ...) | preferir inventario_de_bueyes exportar mediante adaptador |
| inventario_de_bueyes | exportaciones.ox_inventario:* | exportaciones.ox_inventario:* | exportaciones.ox_inventario:* |
Devoluciones de llamadas
| Concepto | ESX | QBCore | QBOX |
|---|---|---|---|
| Registro del servidor | ESX.RegisterServerCallback | QBCore.Funciones.CreateCallback | lib.callback.register (buey_lib) |
| Desencadenante de cliente | ESX.TriggerServerCallback | QBCore.Funciones.TriggerCallback | lib.callback.await |
Capa de base de datos
| Concepto | ESX/QB (heredado) | oxmysql (objetivo) |
|---|---|---|
| Buscar | MySQL.Async.fetchAll(sql, parámetros, cb) | filas locales = MySQL.query.await(sql, {p1, ...}) |
| Actualizar | MySQL.Async.execute(sql, parámetros, cb) | aff local = MySQL.update.await(sql, {p1, ...}) |
UI / Notificar / Objetivo
| Concepto | ESX | QBCore | QBOX |
|---|---|---|---|
| Notificar | ESX.MostrarNotificación(msg) | QBCore.Functions.Notify(msg, tipo) | exportaciones.qbx_core:Notificar(...) o lib.notify({...}) |
| Menú | (varía) | menú qb | ox_lib:registerContext / entradas |
| Objetivo | (Añadir) | objetivo qb | objetivo_buey |
Consejo: favor biblioteca de buey, inventario_de_bueyes, objetivo_buey Mantenerse neutral en todos los marcos.
4) Tutorial A: ESX → QBCore (práctico)
Meta: Convierta un recurso de tienda simple de ESX a QBCore.
Paso 1 — Dependencias
- Asegurar
oxmysql,biblioteca de buey,núcleo qbse inician. - Si el script utiliza el inventario de ESX, migre a inventario_de_bueyes (recomendado) o asignar al inventario de QB.
Paso 2: Detectar el marco y agregar un puente
Crear puente.lua Para normalizar jugadores/dinero/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
Paso 3: Convertir devoluciones de llamadas
- ESX → QB: reemplazar
ESX.RegisterServerCallbackconQBCore.Funciones.CreateCallback. - Usos del cliente
QBCore.Funciones.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
Paso 4: Rutas de dinero e inventario
- Reemplazar
xPlayer.addAccountMoneyconJugador.Funciones.AñadirDinero(para QB) o adaptador. - Estandarice todos los cambios de inventario a través del adaptador.
Paso 5: Eventos (seguridad del lado del servidor)
RegisterNetEvent('tienda:comprar', function(item, amount) local src = source si tipo(item) ~= 'string' o tipo(amount) ~= 'number' entonces devuelve fin si amount < 1 o amount > 10 entonces devuelve fin local p = bridge.getPlayer(src) si no p entonces devuelve fin local precio = 100 * amount si no bridge.removeMoney(src, 'cash', price) entonces devuelve fin bridge.addItem(src, item, amount) bridge.notify(src, ('Compró %dx %s'):format(amount, item), 'success') fin)
Paso 6: Migración de la base de datos (identificadores, cuentas)
- Crear un paso de peatones
id_map(identificador, idciudadano). - Poblar
ID de ciudadanopara QB de ESXusuariostabla mediante regla de elección (columna existente o generada).
-- Ejemplo: crear cruce de caminos y relleno (personalizar según su esquema) CREATE TABLE IF NOT EXISTS id_map ( identifier VARCHAR(64) PRIMARY KEY, citizenid VARCHAR(64) NOT NULL UNIQUE ); -- Suponga que generó nuevos citizenids y los almacenó anteriormente 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 })
Paso 7 — Control de calidad
- Generar artículos, comprar/vender, asegurarse de que los saldos cambien correctamente.
- Verificar que las devoluciones de llamadas regresen bajo carga.
- Verifique que se conserven los metadatos del inventario.
5) Tutorial B: QBCore → ESX (práctico)
Advertencias clave:
- ESX utiliza cuentas para
banco/dinero negroEl dinero sucio del mariscal de campo del puerto artículo (si se usa) a la cuenta ESX o guárdelo como un elemento. - El esquema de trabajo difiere (grado vs. nivel). Mapéelo cuidadosamente.
Ejemplo: Asignación de dinero mediante adaptador
-- 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
Ejemplo: Conversión de devolución de llamada (servidor)
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 de verificación de pruebas
- Los trabajos y promociones persisten.
- Los saldos bancarios/sucios mutan según lo previsto.
- Validación de propiedad del vehículo y formatos de placas.
6) Tutorial C — QBCore ↔ QBOX (Práctico)
QBCore → QBOX
- Reemplazar
Funciones de QBCore.*conexportaciones.qbx_core:*o biblioteca de buey devoluciones de llamadas. - Jugador:
QBCore.Functions.GetPlayer(src)→exportaciones.qbx_core:GetPlayer(src). - Notificar:
QBCore.Funciones.Notificar→exportaciones.qbx_core:Notificarolib.notificar. - Deber/grupos: utilizar las exportaciones de QBOX (
Establecer tarea,HasGroup, etc.).
QBOX → QBCore
- Reemplazar
exportaciones.qbx_core:*conFunciones de QBCore.*equivalentes o su adaptador. - Reintroduzca las devoluciones de llamadas QB y los equivalentes de menú/objetivo según sea necesario.
Fragmentos de antes y después
-- Antes de (QB notify) QBCore.Functions.Notify('Hola', 'éxito') -- Después de (QBOX) exports.qbx_core:Notify(source, 'Hola', 'éxito') -- o lib.notify(source, { title = 'Hola', description = 'Bienvenido', type = 'éxito' })
-- Antes de (QB obtener jugador) Jugador local = QBCore.Functions.GetPlayer(src) -- Después de (QBOX) Jugador local = exports.qbx_core:GetPlayer(src)
7) Tutorial D — Framework → Independiente con adaptadores
Escribe tus guiones una vez y ejecutarlos en cualquier lugar:
- Crear una puente exponiendo una API estable:
obtenerJugador,obtenerIdentificador,agregar/quitar dinero,agregar/eliminar elemento,notificar,tieneGrupo,de servicio,devoluciones de llamadasenvoltura. - Detectar el marco en tiempo de ejecución (
núcleo qbx→núcleo qb→es_extendido→ninguno). - Usar biblioteca de buey para devoluciones de llamadas y notificaciones cuando no existe un ayudante de marco directo.
Respaldo independiente mínimo
-- 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) Rendimiento y seguridad (fortalecimiento de la producción)
Validación del lado del servidor (nunca confíes en el cliente)
- Validar tipos y límites en cada evento.
- Controlar propiedad, tiempos de reutilización, distancia (si es relevante), trabajo/grupo.
- Asegúrese de que el dinero no pueda entrar en números negativos; fije las cantidades.
- Comparar precio del lado del servidor; no acepte totales proporcionados por el cliente.
Estructura del evento
- Utilice uno evento del servidor por acción; no exponga las funciones de inventario/dinero en bruto a los clientes.
- Preferir devoluciones de llamadas para flujos de solicitud/respuesta.
Base de datos y rendimiento
- Cambiar a oxmysql esperar API; escrituras por lotes; evitar consultas por tick.
- Índice de columnas consultadas con frecuencia (
ID de ciudadano,identificador,lámina). - Almacenar en caché las listas de precios y configuraciones en la memoria; exportarlas a los clientes una vez y luego compararlas cuando haya cambios.
- Usar
Estado globalcon moderación; evitar actualizaciones en bucle activo.
9) Errores comunes y manual de depuración
- Arrogante
Obtener objeto principalexiste en QBOX → no lo hace; usarexportaciones.qbx_core:*. - Las devoluciones de llamadas nunca regresan después de migrar a QBOX → Las devoluciones de llamadas ESX/QB no están registradas; cambiar a
lib.callback.register/await. - Semántica del dinero sucio diferir → decidir artículo vs cuenta vs billetera alternativa y estandarizar en su adaptador.
- Supuestos de inventario mixto → normalizar en
inventario_de_bueyes. - Problemas con la orden de salida →
oxmysql→biblioteca de buey→ marco → sus recursos. - Desviación de metadatos del vehículo → Asegúrese de que las columnas JSON y los formatos de placa coincidan con el marco de destino.
10) Mejores prácticas de fxmanifest.lua
fx_version 'cerulean' juego 'gta5' lua54 'sí' 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' } -- dependencias (elige lo que uses): ox_lib, oxmysql, ox_inventory, qb-core O qbx_core O es_extended
- Declarar Lua 5.4 (
lua54 'sí'). - Mantener
escrow_ignoremínimo; nunca intente eludir el depósito de garantía.
11) Migración de datos: fragmentos de SQL (ejemplos)
Ajuste los nombres de tablas/columnas a su esquema. Ejecute siempre una copia primero.
Identificadores: ESX → QB/QBOX
-- Agregar citizenid a los usuarios de ESX si faltan ALTER TABLE users ADD COLUMN IF NOT EXISTS citizenid VARCHAR(64); -- Rellenar utilizando un generador determinista o una columna existente UPDATE users SET citizenid = LOWER(SUBSTRING(MD5(CONCAT(identifier,'-QB')),1,10)) WHERE citizenid IS NULL; -- Crear cruce de caminos 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;
Cuentas/Dinero
-- Ejemplo: convertir los saldos bancarios de ESX a la tabla de dinero QB (si su esquema QB lo almacena por separado) 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);
Vehículos
-- Normalizar las placas al formato de destino (ejemplo: 8 caracteres en la parte superior) UPDATE owned_vehicles SET plate = UPPER(LEFT(plate,8)); -- Asegurarse de que las columnas de metadatos JSON sean válidas UPDATE owned_vehicles SET mods = JSON_MERGE_PATCH('{}', mods) WHERE JSON_VALID(mods) = 0;
12) Adaptadores que puedes reutilizar (inicial)
Deje caer esto en
puente.luay se amplía según sus necesidades. Detecta automáticamente ESX/QB/QBOX y expone una API estable.
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) Listas de verificación finales (copiar y enviar)
A) Descubrimiento y prevuelo
- Instantánea de base de datos/archivos; crear un servidor de prueba
- Fijar artefactos y versiones de recursos; definir orden de inicio
- Dependencias de inventario/objetivo/menú enumeradas
- Decidir la estrategia de identificación (cruce de identificadores ciudadanos)
B) Auditoría de código
- Grep para ESX/QB/QBOX/ox_*/mysql‑async
- Enumere todas las llamadas de dinero/inventario/trabajo/obligaciones
- Lista de devoluciones de llamadas y eventos de servidor/cliente
C) Mapeo y diseño
- Elija la superficie del adaptador (jugador, identificadores, dinero, elementos, notificaciones, devoluciones de llamadas)
- Decide una estrategia para el dinero sucio (cuenta vs. artículo vs. billetera alternativa)
- Favorecer ox_lib/ox_inventory/ox_target
D) Migración de datos
- Construir un paso de peatones con identificación ciudadana
- Convertir cuentas/dinero
- Normalizar metadatos y placas de vehículos
- Cambiar a llamadas await de oxmysql
E) Pruebas de control de calidad
- Seguridad de eventos: tipos/límites/propiedad/tiempos de reutilización
- Devoluciones de llamada: valores de retorno bajo carga
- Metadatos de inventario conservados
- La lógica de los trabajos/tareas/grupos coincide con el diseño
F) Liberación y reversión
- Lanzamiento de etiqueta; registro de cambios
- Conservar la instantánea previa a la migración durante 7 a 14 días
- Monitorizar errores/latencia; indexar consultas activas
14) Preguntas frecuentes (con esquema JSON-LD)
P: ¿Puedo portar scripts de QBCore a QBOX sin una reescritura completa?
A: Con adaptadores y biblioteca de buey devoluciones de llamadas, la mayoría de los scripts solo necesitan reasignación de llamadas.
P: ¿Qué hago con el dinero negro/sucio?
A: Estandarizar en su adaptador: ESX → dinero negro Cuenta; QB → artículo o cuenta adicional; QBOX → artículo o billetera alternativa (p. ej., criptomonedas). Mantenga una estrategia para todo el proyecto.
P: ¿Por qué las devoluciones de llamadas se cuelgan después de migrar a QBOX?
A: Las devoluciones de llamadas de ESX/QB no se activarán en QBOX. Usar lib.callback.register/await.
P: ¿Cuál es la mejor manera de migrar MySQL-Async?
A: Reemplazar con oxmysql esperar API; eliminar pirámides de devolución de llamadas.
P: ¿Cómo convierto qb‑target a ox_target?
A: Reemplace las llamadas a la API addBoxZone/Entity una por una; las cargas útiles de los eventos se mantienen similares. Mantenga los nombres de los destinos estables.
15) Visuales (Sugerencias)
- Diagrama de flujo (Descubrir → Asignar → Adaptar → Migrar base de datos → Probar → Liberar)
- Diagrama de adaptadores: Script → Puente → Marco de trabajo (ESX/QB/QBOX)
- Tabla Rosetta: incluido arriba (exportar como CSV para descargas)
[Discover] → [Map APIs] → [Write Adapter] → [Migrate DB] → [Harden] → [QA] → [Release]
16) Legal y ético
- Respetar licencias (MIT/GPL/NC). No evitar el depósito en garantía o la ofuscación.
- Convierte únicamente los scripts que propio o tener permiso para adaptarse.
17) Descargables y referencia rápida
También puedes usar este convertidor (aunque no probado):
https://github.com/sledgehamm3r/ESX-QBCore-Converter
28) Próximos pasos
- Suelta el puente.lua en su recurso y comience a convertir primero sus scripts de mayor valor.
- Estandarizar en ox_lib + ox_inventory + ox_target + oxmysql permanecer agnóstico en cuanto al marco.
- Utilice las listas de verificación durante la revisión y el lanzamiento.
Lea también Migración de SQL e identificadores: Steam/license → citizenid y Cuentas → Money (ESX → QBCore/QBOX)






