Konwertuj skrypt ESX na QBCore (i odwrotnie): mapa funkcji i most

Portuj skrypt FiveM między ESX i QBCore: tabelę wspólnych wołań (gracz, pieniądze, praca, przedmioty, powiadomienia, callbacki) i plik mostu, który wspiera oba.

Masz skrypt napisany dla ESX i twój serwer uruchamia QBCore, lub odwrotnie. Większość skryptu to zwykły Lua i natives, które się nie zmieniają. Tylko wołania struktury robią, i są mniej niż się spodziewasz. Ten artykuł daje ci mapę, potem pokazuje jak izolować je w jednym pliku mostu.

Co zostaje i co się zmienia

Natives, NUI, twoje własne zdarzenia, pętle, cele i menu działają na każdej strukturze. Co się zmienia, to krótka lista:

  • jak otrzymujesz obiekt struktury
  • jak otrzymujesz gracza
  • pieniądze, prace i przedmioty
  • powiadomienia
  • przedmioty użyteczne i callbacki
  • tabele bazy danych dla graczy

Wyszukaj w skrypcie ESX. i xPlayer, i każde trafienie to coś do konwersji.

Mapa funkcji

Zadanie ESX Legacy QBCore
Pozyskaj obiekt ESX = exports['es_extended']:getSharedObject() local QBCore = exports['qb-core']:GetCoreObject()
Pozyskaj gracza (serwer) ESX.GetPlayerFromId(src) QBCore.Functions.GetPlayer(src)
Identyfikator gracza xPlayer.identifier Player.PlayerData.citizenid
Saldo gotówki xPlayer.getMoney() Player.PlayerData.money.cash
Dodaj gotówkę xPlayer.addMoney(n) Player.Functions.AddMoney('cash', n)
Usuń gotówkę xPlayer.removeMoney(n) Player.Functions.RemoveMoney('cash', n)
Dodaj bank xPlayer.addAccountMoney('bank', n) Player.Functions.AddMoney('bank', n)
Usuń bank xPlayer.removeAccountMoney('bank', n) Player.Functions.RemoveMoney('bank', n)
Nazwa pracy xPlayer.job.name Player.PlayerData.job.name
Stopień pracy xPlayer.job.grade Player.PlayerData.job.grade.level
Dodaj przedmiot xPlayer.addInventoryItem(name, n) Player.Functions.AddItem(name, n)
Usuń przedmiot xPlayer.removeInventoryItem(name, n) Player.Functions.RemoveItem(name, n)
Liczba przedmiotów xPlayer.getInventoryItem(name).count Player.Functions.GetItemByName(name) (nil jeśli żaden, potem .amount)
Przedmiot użyteczny ESX.RegisterUsableItem(name, function(src) end) QBCore.Functions.CreateUseableItem(name, function(src, item) end)
Powiadom (klient) ESX.ShowNotification(msg) QBCore.Functions.Notify(msg, 'success')
Powiadom (serwer) xPlayer.showNotification(msg) TriggerClientEvent('QBCore:Notify', src, msg, 'success')
Dane gracza (klient) ESX.GetPlayerData() QBCore.Functions.GetPlayerData()
Zdarzenie załadowania gracza esx:playerLoaded QBCore:Client:OnPlayerLoaded
Zdarzenie zmiany pracy esx:setJob QBCore:Client:OnJobUpdate
Callback serwera ESX.RegisterServerCallback QBCore.Functions.CreateCallback

Dwa szczegóły tripują ludzi. Typy pieniędzy: ESX ma money dla gotówki i bank, QBCore używa 'cash' i 'bank' jako pierwszy argument. I stopień: ESX daje zwykłą liczbę, QBCore tabelę, więc job.grade.level.

Callbacki, które każdy drugi skrypt używa, są porównywane szczegółowo w server callbacks on ESX, QBCore and ox_lib.

Baza danych

Tabele graczy się różnią, więc każde SELECT lub UPDATE na nich potrzebuje zmianę:

ESX QBCore
Gracze users players
Klucz gracza identifier (ciąg license:) citizenid
Pojazdy owned_vehicles player_vehicles

Skrypt, który przechowuje swoje własne dane, z własnymi tabelami, zwykle ciągle działa, dopóki kluczuje wiersze na wartości, którą możesz uzyskać z każdej struktury. Używanie identyfikatora licencji do tego działa na obu.

QBox

QBox jest bliżej do QBCore niż do ESX. Jego rdzeń to qbx_core, przechowuje warstwę kompatybilności dla exports['qb-core']:GetCoreObject(), i jego inwentarz to ox_inventory. Skrypt konwertowany na QBCore zwykle działa na QBox z kilkoma zmianami, oprócz wołań inwentarza.

Podejście pliku mostu

Jeśli skrypt musi działać na obu, nie zaśmiecaj go z if ESX then ... else ... end. Włóż każde wołanie struktury w jeden plik i miej resztę skryptu wołającą ten plik.

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

W manifeście, załaduj to przed plikami, które go używają:

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

Skrypt następnie czyta tak, i nigdy nie wspomina struktury:

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

Dodaj most klienta dla powiadomień i danych gracza w ten sam sposób. Gdy dodasz nową strukturę, taką jak QBox z qbx_core, dodajesz gałąź w moście, i skrypt zostaje takim, jaki jest.

Pamiętaj, że most działa tylko jeśli struktura się uruchamia pierwsza. Włóż ensure es_extended lub ensure qb-core ponad skrypt w server.cfg, i przeczytaj ESX is nil, jeśli obiekt wraca nil.

Lista kontrolna

Symptom Naprawa
attempt to index a nil value (global 'ESX') na QBCore Wołanie ESX pozostało; zamień je z mapy powyżej
Pieniądze lub praca zawsze nil Czytasz PlayerData na ESX, lub xPlayer.job na QBCore
Błędy liczby przedmiotów na QBCore GetItemByName wraca nil, gdy gracz nie ma żadnego; sprawdź to najpierw
Zła tabela w zapytaniu users i identifier na ESX, players i citizenid na QBCore
Callback nic nie zwraca Użyj dopasowanego rejestru i wyzwolenia wołań dla struktury
Potrzebuje obu struktur Przenieś każde wołanie struktury do pliku mostu

Szybkie odpowiedzi

Czy mogę konwertować każdy skrypt ESX na QBCore?

Skrypty, które używają struktury tylko dla graczy, pieniędzy, prac, przedmiotów i powiadomień konwertują się dobrze. Skrypty zbudowane wokół zasobów specyficznych dla struktury, takie jak esx_society lub qb-management, potrzebują też tych części przepisane.

Czy baza danych się zmienia, gdy przełączam strukturę?

Tak. ESX przechowuje graczy w users z identifier, a QBCore w players z citizenid. Zapytania i nazwy tabel w skrypcie muszą postępować zgodnie ze strukturą, którą uruchamiasz.

Czy plik mostu jest lepszy niż konwertowanie?

Jeśli potrzebujesz skryptu na obu strukturach, tak: zmieniasz jeden plik, nie cały skrypt. Jeśli uruchamiasz tylko jedną strukturę, konwertuj raz i porzuć inną gałąź.

Skrypty bez tego problemu

Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →Advanced BoostingBoosting pojazdów z tabletu: kontrakty od klasy D do S+, ekipy i kolejka na żywo.Zobacz skrypt →

Czytaj dalej