Converti uno script ESX a QBCore (e viceversa): mappa delle funzioni e bridge

Porta uno script FiveM tra ESX e QBCore: una tabella delle chiamate comuni (giocatore, soldi, lavoro, articoli, notifiche, callback) e un file bridge che supporta entrambi.

Hai uno script scritto per ESX, e il tuo server esegue QBCore, o viceversa. La maggior parte dello script è Lua semplice e nativi che non cambiano. Solo le chiamate del framework cambiano, e ce ne sono meno di quello che ti aspetti. Questo articolo ti fornisce una mappa di esse, e poi mostra come isolarle in un file bridge.

Cosa rimane e cosa cambia

Nativi, NUI, i tuoi eventi, loop, target e menu funzionano su qualsiasi framework. Quello che cambia è una breve lista:

  • come ottenere l'oggetto del framework
  • come ottenere un giocatore
  • soldi, lavori e articoli
  • notifiche
  • articoli usabili e callback
  • le tabelle di database per i giocatori

Cerca nel script ESX. e xPlayer, e ogni hit è qualcosa da convertire.

Mappa delle funzioni

Attività ESX Legacy QBCore
Ottieni l'oggetto ESX = exports['es_extended']:getSharedObject() local QBCore = exports['qb-core']:GetCoreObject()
Ottieni un giocatore (server) ESX.GetPlayerFromId(src) QBCore.Functions.GetPlayer(src)
Identificatore del giocatore xPlayer.identifier Player.PlayerData.citizenid
Saldo contanti xPlayer.getMoney() Player.PlayerData.money.cash
Aggiungi contanti xPlayer.addMoney(n) Player.Functions.AddMoney('cash', n)
Rimuovi contanti xPlayer.removeMoney(n) Player.Functions.RemoveMoney('cash', n)
Aggiungi banca xPlayer.addAccountMoney('bank', n) Player.Functions.AddMoney('bank', n)
Rimuovi banca xPlayer.removeAccountMoney('bank', n) Player.Functions.RemoveMoney('bank', n)
Nome lavoro xPlayer.job.name Player.PlayerData.job.name
Grado lavoro xPlayer.job.grade Player.PlayerData.job.grade.level
Aggiungi articolo xPlayer.addInventoryItem(name, n) Player.Functions.AddItem(name, n)
Rimuovi articolo xPlayer.removeInventoryItem(name, n) Player.Functions.RemoveItem(name, n)
Conteggio articoli xPlayer.getInventoryItem(name).count Player.Functions.GetItemByName(name) (nil se nessuno, poi .amount)
Articolo usabile ESX.RegisterUsableItem(name, function(src) end) QBCore.Functions.CreateUseableItem(name, function(src, item) end)
Notifica (client) ESX.ShowNotification(msg) QBCore.Functions.Notify(msg, 'success')
Notifica (server) xPlayer.showNotification(msg) TriggerClientEvent('QBCore:Notify', src, msg, 'success')
Dati del giocatore (client) ESX.GetPlayerData() QBCore.Functions.GetPlayerData()
Evento di caricamento del giocatore esx:playerLoaded QBCore:Client:OnPlayerLoaded
Evento cambio lavoro esx:setJob QBCore:Client:OnJobUpdate
Callback del server ESX.RegisterServerCallback QBCore.Functions.CreateCallback

Due dettagli confondono le persone. Tipi di soldi: ESX ha money per contanti e bank, QBCore usa 'cash' e 'bank' come primo argomento. E il grado: ESX fornisce un numero semplice, QBCore una tabella, quindi job.grade.level.

I callback, che ogni secondo script usa, vengono confrontati in dettaglio in server callbacks on ESX, QBCore and ox_lib.

Il database

Le tabelle dei giocatori differiscono, quindi qualsiasi SELECT o UPDATE su di esse ha bisogno di un cambiamento:

ESX QBCore
Giocatori users players
Chiave del giocatore identifier (una stringa license:) citizenid
Veicoli owned_vehicles player_vehicles

Uno script che memorizza i suoi dati, con le sue proprie tabelle, di solito continua a funzionare, finché chiavi le righe su un valore che puoi ottenere da qualsiasi framework. Usare l'identificatore della licenza per quello funziona su entrambi.

QBox

QBox è più vicino a QBCore che a ESX. Il suo core è qbx_core, mantiene un livello di compatibilità per exports['qb-core']:GetCoreObject(), e il suo inventario è ox_inventory. Uno script convertito a QBCore di solito viene eseguito su QBox con pochi cambiamenti, a parte le chiamate di inventario.

L'approccio del file bridge

Se lo script deve essere eseguito su entrambi, non infarcirlo di if ESX then ... else ... end. Metti ogni chiamata del framework in un file, e fai che il resto dello script chiami quel file.

lua
-- bridge.lua (server)
Bridge = {}

local framework
if GetResourceState('es_extended') == 'started' then
    framework = 'esx'
    ESX = exports['es_extended']:getSharedObject()
elseif GetResourceState('qb-core') == 'started' then
    framework = 'qb'
    QBCore = exports['qb-core']:GetCoreObject()
end

function Bridge.GetPlayer(src)
    if framework == 'esx' then return ESX.GetPlayerFromId(src) end
    return QBCore.Functions.GetPlayer(src)
end

function Bridge.AddCash(src, amount)
    local player = Bridge.GetPlayer(src)
    if not player then return false end

    if framework == 'esx' then
        player.addMoney(amount)
    else
        player.Functions.AddMoney('cash', amount)
    end
    return true
end

function Bridge.GetJob(src)
    local player = Bridge.GetPlayer(src)
    if not player then return nil end

    if framework == 'esx' then
        return player.job.name, player.job.grade
    end
    return player.PlayerData.job.name, player.PlayerData.job.grade.level
end

Nel manifest, caricalo prima dei file che lo usano:

lua
server_scripts {
    'bridge.lua',
    'server.lua',
}

Lo script legge così, e non menziona mai un framework:

lua
RegisterNetEvent('my_script:pay', function()
    local src = source
    local job = Bridge.GetJob(src)
    if job == 'mechanic' then
        Bridge.AddCash(src, 100)
    end
end)

Aggiungi un client bridge per notifiche e dati di giocatore nello stesso modo. Quando aggiungi un nuovo framework, come QBox con qbx_core, aggiungi un ramo nel bridge, e lo script rimane come è.

Ricorda che un bridge funziona solo se il framework si avvia per primo. Metti ensure es_extended o ensure qb-core sopra lo script in server.cfg, e leggi ESX is nil se l'oggetto torna nil.

Checklist

Sintomo Soluzione
attempt to index a nil value (global 'ESX') su QBCore Una chiamata ESX è rimasta; sostituiscila dalla mappa sopra
Soldi o lavoro sempre nil Leggi PlayerData su ESX, o xPlayer.job su QBCore
Errori di conteggio articoli su QBCore GetItemByName restituisce nil quando il giocatore non ne ha; controllalo prima
Tabella sbagliata in una query users e identifier su ESX, players e citizenid su QBCore
Callback non restituisce nulla Usa le corrispondenti chiamate di register e trigger per il framework
Ha bisogno di entrambi i framework Sposta ogni chiamata del framework in un file bridge

Risposte rapide

Posso convertire qualsiasi script ESX a QBCore?

Gli script che usano solo il framework per giocatori, soldi, lavori, articoli e notifiche si convertono bene. Gli script costruiti attorno a risorse specifiche del framework, come esx_society o qb-management, hanno bisogno che anche quelle parti vengano riscritte.

Il database cambia quando passo da un framework all'altro?

Sì. ESX memorizza i giocatori in users con un identifier, e QBCore in players con un citizenid. Le query e i nomi delle tabelle nello script devono seguire il framework che esegui.

Un file bridge è meglio che convertire?

Se hai bisogno dello script su entrambi i framework, sì: modifichi un file, non l'intero script. Se esegui solo un framework, converti una volta e abbandona l'altro ramo.

Script senza questo problema

Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →

Continua a leggere