Convertendo scripts FiveM – ESX, QBCore, QBOX (Frame…

Este é um guia de scripts FiveM de conversão fácil e sem complicações, que mostra exatamente como Converter scripts FiveM entre ESX, QBCore, QBOX (qbx_core) e configurações agnósticas de framework (standalone). Você obterá mapeamentos de API tri-way, código de adaptador, etapas de migração de SQL (mysql-async → oxmysql), especificações do QBOX, listas de verificação de testes e dicas de reforço de produção.


TL;DR — Migração em 10 etapas

  1. Instantâneo e preparação: Fazer backup do banco de dados/arquivos. Crie um servidor de teste local com a estrutura de destino.
  2. Identificar dependências: inventário, destino, menu/IU, retornos de chamada, camada de banco de dados, essencial acesso.
  3. Versões e ordem dos pinos: oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → seus recursos.
  4. Leia o caminho do código: Encontre todas as chamadas de jogadores, dinheiro, trabalho/dever, inventário, retorno de chamada/evento e DB.
  5. APIs de mapas: Use as tabelas Rosetta abaixo para mapear ESX ↔ QBCore ↔ QBOX.
  6. Faça a ponte: Adicionar um ponte.lua adaptador que detecta automaticamente a estrutura e normaliza as chamadas.
  7. Converter retornos de chamada: Retornos de chamada ESX/QB → QBOX/ox_lib lib.callback.* quando necessário.
  8. Migrar BD: Mover identificadores, contas, itens, veículos; alternar para oxmysql *.aguarde estilo.
  9. Eventos de proteção: Validar fonte, limites, grupos/trabalhos, propriedade; nunca confie no cliente.
  10. QA e liberação: Execute as listas de verificação; tag, changelog e plano de reversão.

Você é um desenvolvedor que está procurando uma solução Adapter? Confira nosso script de adaptador gratuito aqui


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

Visão geral arquitetônica

CategoriaESXQBCoreQ-BOX (caixa de som)
Arquitetura / Acesso ao Núcleoexportações['es_extended']:getSharedObject()ESXexportações['qb-core']:GetCoreObject()QBCoreNenhum objeto central global; use exportações.qbx_core:* para jogadores, grupos e notificações
Objeto do JogadorESX.GetPlayerFromId(origem)xPlayerQBCore.Functions.GetPlayer(origem)Jogadorexportações.qbx_core:GetPlayer(origem)Jogador com Dados do Jogador
IdentificadoresHistoricamente identificador (licença/steam)identidade de cidadão como chave primáriaidentidade de cidadão como chave primária
Dinheiro ManuseioxPlayer.addMoney() / `addAccountMoney('banco''dinheiro_preto')``Player.Functions.AddMoney('dinheiro'
Empregos e deveresxPlayer.job.name, .nota de empregoJogador.DadosDoJogador.nomeDoTrabalho, .grau.nível, Em serviçoAjudantes de trabalho/grupo via exportações.qbx_core:* (verificações de grupo, definidores de tarefas)
InventárioESX padrão / inventário de bois / qb-inventário (recomendado: inventário de bois)qb-inventário / inventário de boisinventário de bois recomendado
Retornos de chamadaESX.RegisterServerCallback / ESX.TriggerServerCallbackQBCore.Funções.CriarRetornoDeChamada / GatilhoRetorno de chamadaPrefer boi_lib retornos de chamada (lib.callback.register/aguarde) ou exportações QBOX
Camada de Banco de DadosVelho: mysql-assíncrono → Agora: oxmysql (MySQL.query.await, MySQL.update.aguarde)oxmysqloxmysql
UI – NotificaçõesNotificação ESXQB NotificarQBOX notifica ajudantes ou lib.notificar
UI – Menusesx_menu_padrão / ox_lib:registerContextqb-menu / ox_lib:registerContextox_lib:registerContext / lib.inputDialog
UI – Sistema de destinoesx_target / boi_alvoqb-alvo / boi_alvoboi_alvo recomendado

Onde o QBOX difere

  • Nome do recurso e exportações: qbx_núcleo (não ObterCoreObject).
  • Apoia-se em boi_lib (retornos de chamada, notificação) e oxmysql por padrão.
  • Integrados para multicaracteres/filas/grupos; ajudantes opinativos para tarefas/deveres.

Estruturas FiveM: QBCore vs. ESX

2) Pré-voo: Ambiente e Ferramentas

  • Servidor: atual Servidor FX artefatos, Lua 5.4, CFX garantir ordem
  • Ordem: garantir oxmysqlgarantir ox_libgarantir estruturagaranta seu recurso
  • Editor: Código VS + Lua LS, estiletes; opcional ripgrep para varreduras rápidas de padrões
  • Configuração de teste: instantâneo limpo do banco de dados; registro detalhado; pequeno conjunto de dados inicializados
  • Padrões de pesquisa você usará:
    • ESX. xPlayer. QBCore. Dados do Jogador qbx_núcleo exports.ox_inventory mysql%-async MySQL.

3) Rosetta Stone: ESX ↔ QBCore ↔ QBOX (Mapeamento Tri-way)

Referência fácil de copiar e colar. Use-a para substituir chamadas ou conectar seu adaptador.

Núcleo e Jogador

ConceitoESXQBCoreQ-BOX (caixa de som)
Obtenha o núcleoexportações['es_extended']:getSharedObject()exportações['qb-core']:GetCoreObject()(n/a — usar exportações)
Obter jogador (origem)ESX.GetPlayerFromId(origem)QBCore.Functions.GetPlayer(origem)exportações.qbx_core:GetPlayer(origem)
Obter por citizenid(consulta personalizada)QBCore.Funções.GetPlayerByCitizenId(id)exportações.qbx_core:GetPlayerByCitizenId(id) (se presente)

Identificadores

ConceitoESXQBCoreQ-BOX (caixa de som)
Primárioidentificador (licença/steam)identidade de cidadãoidentidade de cidadão
Faixa de pedestresmesa id_map(identificador, id_cidadão)mesmomesmo

Dinheiro

AçãoESXQBCoreQ-BOX (caixa de som)
Adicionar dinheiroxPlayer.addMoney(a)Jogador.Funções.AdicionarMoney('dinheiro', a)Jogador.DadosDoJogador.dinheiro.dinheiro += a (via adaptador + salvar)
Adicionar bancoxPlayer.addAccountMoney('banco', a)Player.Functions.AddMoney('banco', a)Jogador.DadosDoJogador.dinheiro.banco += a (adaptador + salvar)
Adicionar sujoxPlayer.addAccountMoney('black_money', a)item ou conta extra (definida pelo servidor)mapa para item/carteira alternativa (por exemplo, criptografia) (escolha do adaptador)

Empregos, Deveres, Grupos

ConceitoESXQBCoreQ-BOX (caixa de som)
Ler trabalhoxPlayer.job.name, .notaJogador.DadosDoJogador.nomeDoTrabalho, .grau.nívelJogador.DadosDoJogador.trabalho.* + ajudantes de grupo
Em serviço(varia)Jogador.DadosDoJogador.trabalho.deverDefinir Tarefa/ajudantes de grupo via exportações
Verificação de grupo(adicionar)(adicionar)exports.qbx_core:HasGroup(origem, grupo) (exemplo)

Inventário

AçãoESXQBCoreQ-BOX (caixa de som)
Adicionar itemxPlayer.addInventoryItem(n, c)Jogador.Funções.AdicionarItem(n, c, ...)preferir inventário de bois exportar via adaptador
inventário de boisexportações.ox_inventory:*exportações.ox_inventory:*exportações.ox_inventory:*

Retornos de chamada

ConceitoESXQBCoreQ-BOX (caixa de som)
Registro do servidorESX.RegisterServerCallbackQBCore.Funções.CriarRetornoDeChamadalib.callback.register (ox_lib)
Gatilho do clienteESX.TriggerServerCallbackQBCore.Funções.TriggerCallbacklib.callback.aguarde

Camada DB

ConceitoESX/QB (legado)oxmysql (alvo)
BuscarMySQL.Async.fetchAll(sql, parâmetros, cb)linhas locais = MySQL.query.await(sql, {p1, ...})
AtualizarMySQL.Async.execute(sql, parâmetros, cb)aff local = MySQL.update.await(sql, {p1, ...})

UI / Notificar / Alvo

ConceitoESXQBCoreQ-BOX (caixa de som)
NotificarESX.ShowNotification(msg)QBCore.Functions.Notify(msg, tipo)exports.qbx_core:Notificar(...) ou lib.notificar({...})
Menu(varia)qb-menuox_lib:registerContext / entradas
Alvo(adicionar)qb-alvoboi_alvo

Dica: favor boi_lib, inventário de bois, boi_alvo para permanecer neutro em todas as estruturas.


4) Tutorial A — ESX → QBCore (Prático)

Meta: Converta um recurso de loja simples do ESX para QBCore.

Etapa 1 — Dependências

  • Garantir oxmysql, boi_lib, qb-núcleo são iniciados.
  • Se o script usar o inventário ESX, migre para inventário de bois (recomendado) ou mapear para o inventário do QB.

Etapa 2 — Detectar estrutura e adicionar uma ponte

Criar ponte.lua para normalizar jogadores/dinheiro/inventário:

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

Etapa 3 — Converter retornos de chamada

  • ESX → QB: substituir ESX.RegisterServerCallback com QBCore.Funções.CriarRetornoDeChamada.
  • Usos do cliente QBCore.Funções.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) se GetResourceState('qb-core') == 'started' então local QBCore = exports['qb-core']:GetCoreObject() QBCore.Functions.TriggerCallback('shop:getPrice', function(price) print('price', price) end, 'bread') senão local price = lib.callback.await('shop:getPrice', false, 'bread') print('price', price) end

Etapa 4 — Caminhos de dinheiro e inventário

  • Substituir xPlayer.addAccountMoney com Jogador.Funções.AdicionarDinheiro (para QB) ou adaptador.
  • Padronize todas as alterações de inventário por meio do adaptador.

Etapa 5 — Eventos (segurança do lado do servidor)

RegisterNetEvent('shop:buy', function(item, amount) local src = source se tipo(item) ~= 'string' ou tipo(amount) ~= 'number' então return end se valor < 1 ou valor > 10 então return end local p = bridge.getPlayer(src) se não for p então return end local preço = 100 * valor se não for bridge.removeMoney(src, 'cash', price) então return end bridge.addItem(src, item, amount) bridge.notify(src, ('Comprou %dx %s'):format(amount, item), 'success') end)

Etapa 6 — Migração do BD (identificadores, contas)

  • Crie uma faixa de pedestres id_map(identificador, id_cidadão).
  • povoar identidade de cidadão para QB da ESX Usuários tabela via regra de escolha (coluna existente ou gerada).
-- Exemplo: crie uma faixa de pedestres e preencha (personalize de acordo com seu esquema) CREATE TABLE IF NOT EXISTS id_map ( identifier VARCHAR(64) PRIMARY KEY, citizenid VARCHAR(64) NOT NULL UNIQUE ); -- Suponha que você gerou novos citizenids e os armazenou 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

-- antes (mysql-async) MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @id', {['@id'] = identifier}, function(rows) ... end) -- depois (oxmysql) local rows = MySQL.query.await('SELECT * FROM users WHERE identifier = ?', { identifier })

Etapa 7 — Controle de qualidade

  • Gere itens, compre/venda, garanta que os saldos sejam alterados corretamente.
  • Verifique se os retornos de chamada são retornados sob carga.
  • Verifique se os metadados do inventário são preservados.

5) Tutorial B — QBCore → ESX (Prático)

Principais advertências:

  • Usos do ESX contas para banco/dinheiro preto. Dinheiro sujo do Port QB item (se usado) para a conta ESX ou mantê-lo como um item.
  • O esquema de cargos varia (nível vs. série). Mapeie com cuidado.

Exemplo: Mapeamento de dinheiro via 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

Exemplo: Conversão de retorno de chamada (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 verificação de testes

  • O conjunto de empregos/promoções persiste.
  • Saldos bancários/sujos sofrem mutações conforme o esperado.
  • Propriedade do veículo e formatos de placas validados.

6) Tutorial C — QBCore ↔ QBOX (Prático)

QBCore → QBOX

  • Substituir QBCore.Funções.* com exportações.qbx_core:* ou boi_lib retornos de chamada.
  • Jogador: QBCore.Functions.GetPlayer(origem)exportações.qbx_core:GetPlayer(origem).
  • Notificar: QBCore.Funções.Notificarexports.qbx_core:Notificar ou lib.notificar.
  • Dever/grupos: usar exportações QBOX (Definir Tarefa, HasGroup, etc.).

QBOX → QBCore

  • Substituir exportações.qbx_core:* com QBCore.Funções.* equivalentes ou seu adaptador.
  • Reintroduza retornos de chamada do QB e equivalentes de menu/destino conforme necessário.

Trechos de antes/depois

-- Antes (QB notify) QBCore.Functions.Notify('Olá', 'sucesso') -- Depois (QBOX) exports.qbx_core:Notify(fonte, 'Olá', 'sucesso') -- ou lib.notify(fonte, { título = 'Olá', descrição = 'Bem-vindo', tipo = 'sucesso' })
-- Antes (QB obter jogador) local Player = QBCore.Functions.GetPlayer(src) -- Depois (QBOX) local Player = exports.qbx_core:GetPlayer(src)

7) Tutorial D — Framework → Autônomo com Adaptadores

Escreva seus roteiros uma vez e executá-los em qualquer lugar:

  • Criar um ponte expondo uma API estável: obter jogador, obterIdentificador, adicionar/remover dinheiro, adicionar/remover item, notificar, temGrupo, em serviço, retornos de chamada invólucro.
  • Detectar estrutura em tempo de execução (qbx_núcleoqb-núcleoes_extendidonenhum).
  • Usar boi_lib para retornos de chamada e notificações quando não existe nenhum auxiliar de estrutura direto.

Fallback autônomo 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) Desempenho e Segurança (Produção Reforçada)

Validação do lado do servidor (nunca confie no cliente)

  • Validar tipos e limites em todos os eventos.
  • Verificar propriedade, tempos de espera, distância (se relevante), trabalho/grupo.
  • Garanta que o dinheiro não fique negativo; limite os valores.
  • Comparar preço lado do servidor; não aceitar totais fornecidos pelo cliente.

Estrutura do evento

  • Use um evento do servidor por ação; não exponha funções brutas de estoque/dinheiro aos clientes.
  • Prefer retornos de chamada para fluxos de solicitação/resposta.

DB e desempenho

  • Mudar para oxmysql aguardar APIs; gravações em lote; evitar consultas por tick.
  • Indexar colunas frequentemente consultadas (identidade de cidadão, identificador, placa).
  • Armazene em cache as listas de preços/configurações na memória; exporte-as para os clientes uma vez e depois compare-as conforme a alteração.
  • Usar Estado Global com moderação; evite atualizações de loop ativo.

9) Armadilhas comuns e manual de depuração

  • Assumindo ObterCoreObject existe no QBOX → não; use exportações.qbx_core:*.
  • Os retornos de chamada nunca retornam após a migração para o QBOX → Os retornos de chamada ESX/QB não são registrados; alterne para lib.callback.register/aguarde.
  • Semântica do dinheiro sujo diferir → decidir item vs conta vs carteira alternativa e padronizar em seu adaptador.
  • Suposições de estoque misto → normalizar em inventário de bois.
  • Problemas com a ordem de iníciooxmysqlboi_lib → estrutura → seus recursos.
  • Desvio de metadados do veículo → garantir que as colunas JSON e os formatos de placa correspondam à estrutura de destino.

10) Melhores práticas do 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' } -- dependências (escolha a que você usar): ox_lib, oxmysql, ox_inventory, qb-core OU qbx_core OU es_extended
  • Declarar Lua 5.4 (lua54 'sim').
  • Manter escrow_ignore mínimo; nunca tente ignorar o depósito em garantia.

11) Migração de Dados: Snippets de SQL (Exemplos)

Ajuste os nomes das tabelas/colunas ao seu esquema. Execute sempre uma cópia primeiro.

Identificadores: ESX → QB/QBOX

-- Adicionar citizenid aos usuários do ESX se estiverem faltando ALTER TABLE users ADD COLUMN IF NOT EXISTS citizenid VARCHAR(64); -- Preencher usando um gerador determinístico ou uma coluna existente UPDATE users SET citizenid = LOWER(SUBSTRING(MD5(CONCAT(identifier,'-QB')),1,10)) WHERE citizenid IS NULL; -- Criar 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;

Contas/Dinheiro

-- Exemplo: converter saldos bancários ESX para a tabela de dinheiro QB (se o seu esquema QB os armazenar separadamente) 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);

Veículos

-- Normalizar placas para o formato de destino (exemplo: 8 caracteres superiores) ATUALIZAR owned_vehicles SET plate = UPPER(LEFT(plate,8)); -- Garantir que as colunas de metadados JSON sejam válidas ATUALIZAR owned_vehicles SET mods = JSON_MERGE_PATCH('{}', mods) ONDE JSON_VALID(mods) = 0;

12) Adaptadores que você pode reutilizar (Inicial)

Solte isso em ponte.lua e expanda conforme suas necessidades. Ele detecta automaticamente ESX/QB/QBOX e expõe uma API estável.

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 Verificação Finais (Copiar e Enviar)

A) Descoberta e Pré-voo

  • Snapshot DB/arquivos; criar um servidor de preparação
  • Fixar artefatos e versões de recursos; definir ordem de início
  • Dependências de inventário/alvo/menu listadas
  • Decidir estratégia de identificação (passagem de cidadão)

B) Auditoria de Código

  • Grep para ESX/QB/QBOX/ox_*/mysql‑async
  • Listar todas as chamadas de dinheiro/estoque/trabalho/dever
  • Listar retornos de chamada e eventos de servidor/cliente

C) Mapeamento e Design

  • Escolha a superfície do adaptador (jogador, IDs, dinheiro, itens, notificação, retornos de chamada)
  • Decidir a estratégia de dinheiro sujo (conta vs item vs carteira alternativa)
  • Favor ox_lib/ox_inventory/ox_target

D) Migração de Dados

  • Construir faixa de pedestres CitizenID
  • Converter contas/dinheiro
  • Normalizar metadados e placas de veículos
  • Mudar para chamadas await do oxmysql

E) Teste de QA

  • Segurança de eventos: tipos/limites/propriedade/tempos de espera
  • Callbacks: valores de retorno sob carga
  • Metadados de inventário preservados
  • A lógica de tarefas/deveres/grupos corresponde ao design

F) Liberação e reversão

  • Lançamento de tag; registro de alterações
  • Mantenha o instantâneo de pré-migração por 7 a 14 dias
  • Monitorar erros/latência; indexar consultas importantes

14) FAQ (com esquema JSON-LD)

P: Posso portar scripts do QBCore para o QBOX sem uma reescrita completa?
UM: Com adaptadores e boi_lib retornos de chamada, a maioria dos scripts precisa apenas de remapeamento de chamadas.

P: O que faço com dinheiro sujo/sujo?
UM: Padronize em seu adaptador: ESX → dinheiro preto conta; QB → item ou conta extra; QBOX → item ou carteira alternativa (ex.: criptomoedas). Mantenha uma estratégia para todo o projeto.

P: Por que os retornos de chamada travam depois de migrar para o QBOX?
UM: Os retornos de chamada ESX/QB não serão acionados no QBOX. Use lib.callback.register/aguarde.

P: Qual é a melhor maneira de migrar o mysql para o async?
UM: Substituir por oxmysql aguardar APIs; remover pirâmides de retorno de chamada.

P: Como faço para converter qb‑target em ox_target?
UM: Substituir as chamadas de API addBoxZone/Entity uma por uma; as cargas úteis dos eventos permanecem semelhantes. Manter os nomes dos alvos estáveis.

{ “@context”: “https://schema.org”, “@type”: “FAQPage”, “mainEntity”: [ { “@type”: “Question”, “name”: “Posso migrar scripts do QBCore para o QBOX sem reescrevê-los completamente?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Com adaptadores e callbacks do ox_lib, a maioria dos scripts precisa apenas de remapeamento de chamadas.”} }, { “@type”: “Question”, “name”: “O que faço com dinheiro sujo/ilegítimo?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Padronize em seu adaptador: ESX → conta black_money; QB → item ou conta extra; QBOX → item ou carteira alternativa (por exemplo, criptomoedas).”} }, { “@type”: “Question”, “name”: “Por que Os callbacks ficam travados após a migração para o QBOX?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Os callbacks do ESX/QB não serão disparados no QBOX. Use lib.callback.register/await.”} }, { “@type”: “Question”, “name”: “Qual a melhor maneira de migrar para o mysql-async?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Substitua pelas APIs await do oxmysql; remova as pirâmides de callbacks.”} }, { “@type”: “Question”, “name”: “Como faço para converter qb-target para ox_target?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Substitua as chamadas da API addBoxZone/Entity uma a uma; os payloads dos eventos permanecem semelhantes. Mantenha os nomes dos destinos estáveis.”} } ] }

15) Visuais (Sugestões)

  • Fluxograma (Descobrir → Mapear → Adaptar → Migrar BD → Testar → Liberar)
  • Diagrama de adaptadores: Script → Ponte → Estrutura (ESX/QB/QBOX)
  • Mesa Rosetta: incluído acima (exportar como CSV para downloads)
[Descobrir] → [Mapear APIs] → [Gravar Adaptador] → [Migrar BD] → [Reforçar] → [QA] → [Lançar]

16) Legal e Ético

  • Respeite as licenças (MIT/GPL/NC). Não ignorar custódia ou ofuscação.
  • Converta apenas scripts que você ter ou ter permissão para se adaptar.

17) Downloads e referência rápida

Você também pode usar este conversor (ainda não testado):

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


28) Próximos passos

  • Solte o ponte.lua em seu recurso e comece a converter seus scripts de maior valor primeiro.
  • Padronizar em ox_lib + ox_inventory + ox_target + oxmysql para permanecer agnóstico em relação à estrutura.
  • Use as listas de verificação durante a revisão e a liberação.

Leia também Migração de SQL e Identificadores: steam/license → citizenid e Contas → Dinheiro (ESX → QBCore/QBOX)

Lucas
Lucas

Eu sou Luke, sou um gamer e adoro escrever sobre FiveM, GTA e roleplay. Eu administro uma comunidade de roleplay e tenho cerca de 10 anos de experiência em administração de servidores.

Artigos: 570