
Konwersja FiveM Scripts – ESX, QBCore, QBOX (ramka…
Darmowe skrypty są wystarczające do szybkich kontroli. W przypadku serwerów produkcyjnych porównaj pełne pakiety serwerowe lub płatne skrypty, korzystając z frameworka i przypadku użycia.
To prosty przewodnik po konwersji skryptów FiveM, który pokazuje dokładnie, jak to zrobić, bez zbędnych zbędnych elementów i w którym najpierw piszemy kod. Konwertuj FiveM na Scripts między konfiguracjami ESX, QBCore, QBOX (qbx_core) i niezależnymi od frameworka (standalone). Otrzymasz mapowania API trójstronne, kod adaptera, kroki migracji SQL (mysql-async → oxmysql), szczegóły dotyczące QBOX, listy kontrolne testów i wskazówki dotyczące wzmacniania produkcji.
TL;DR — Migracja w 10 krokach
- Migawka i inscenizacja: Utwórz kopię zapasową bazy danych/plików. Uruchom lokalny serwer testowy z docelową strukturą.
- Zidentyfikuj zależności: inwentarz, cel, menu/UI, wywołania zwrotne, warstwa bazy danych, rdzeń dostęp.
- Wersje pinów i kolejność: oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → twoje zasoby.
- Przeczytaj ścieżkę kodu: Znajdź wszystkich graczy, pieniądze, zadania/obowiązki, ekwipunek, wywołania/wydarzenia i wywołania bazy danych.
- Interfejsy API map: Użyj poniższych tabel Rosetta, aby nanieść mapę ESX ↔ QBCore ↔ QBOX.
- Połącz to: Dodaj most.lua adapter, który automatycznie wykrywa strukturę i normalizuje wywołania.
- Konwertuj wywołania zwrotne: Wywołania zwrotne ESX/QB → QBOX/ox_lib
lib.callback.*gdy jest to potrzebne. - Migracja bazy danych: Przenieś identyfikatory, konta, elementy, pojazdy; przełącz na oxmysql
*.czekać nastyl. - Wydarzenia Harden: Uprawomocnić
źródło, granice, grupy/zadania, własność; nigdy nie ufaj klientowi. - Kontrola jakości i wydanie: Uruchom listy kontrolne, tagi, dziennik zmian i plan wycofania.
Czy jesteś programistą i szukasz rozwiązania w zakresie adapterów? Sprawdź nasz darmowy skrypt adaptera tutaj
1) Frameworki 101: ESX vs QBCore vs QBOX vs Standalone
Przegląd architektoniczny
| Kategoria | ESX | QBCore | QBOX |
|---|---|---|---|
| Architektura / Dostęp do rdzenia | eksporty['es_extended']:getSharedObject() → ESX | eksporty['qb-core']:GetCoreObject() → QBCore | Brak globalnego obiektu rdzeniowego; użyj eksporty.qbx_core:* dla graczy, grup i powiadomień |
| Obiekt gracza | ESX.GetPlayerFromId(źródło) → xPlayer | QBCore.Functions.GetPlayer(źródło) → Odtwarzacz | exports.qbx_core:GetPlayer(src) → Odtwarzacz z Dane gracza |
| Identyfikatory | Historycznie identyfikator (licencja/Steam) | obywatel jako klucz podstawowy | obywatel jako klucz podstawowy |
| Pieniądze Obsługiwanie | xPlayer.addMoney() / `addAccountMoney('bank'‘ | ‘'black_money')` | `Player.Functions.AddMoney('gotówka'‘ |
| Praca i obowiązki | xPlayer.job.name, .job.grade | Player.PlayerData.job.name, .poziom.klasy, Na służbie | Pomocnicy w pracy/grupie za pośrednictwem eksporty.qbx_core:* (kontrole grupowe, osoby ustalające obowiązki) |
| Spis | Domyślnie ESX / ox_inventory / qb-inwentarz (zalecony: ox_inventory) | qb-inwentarz / ox_inventory | ox_inventory zalecony |
| Wywołania zwrotne | ESX.RegisterServerCallback / ESX.TriggerServerCallback | QBCore.Funkcje.Utwórz wywołanie zwrotne / TriggerCallback | Woleć ox_lib wywołania zwrotne (lib.callback.register/await) lub eksportuje QBOX |
| Warstwa bazy danych | Stary: mysql-async → Teraz: oxmysql (MySQL.query.await, MySQL.update.await) | oxmysql | oxmysql |
| UI – Powiadomienia | ESX Powiadom | Powiadomienie QB | QBOX powiadomić pomocników lub lib.notify |
| UI – Menu | esx_menu_domyślne / ox_lib:registerContext | menu qb / ox_lib:registerContext | ox_lib:registerContext / lib.inputDialog |
| UI – System docelowy | esx_target / ox_target | cel qb / ox_target | ox_target zalecony |
Czym różni się QBOX
- Nazwa zasobu i eksporty:
rdzeń qbx(NIEPobierzCoreObject). - Pochyla się na ox_lib (oddzwonienia, powiadomienia) i oxmysql domyślnie.
- Wbudowane funkcje dla wielu postaci/kolejek/grup; pomocnicy wyrażający swoje zdanie w zakresie zadań/obowiązków.

2) Preflight: środowisko i narzędzia
- Serwer: aktualny Serwer FX artefakty, Lua 5.4, CFX
zapewnićzamówienie - Zamówienie:
upewnij się, że oxmysql→zapewnij ox_lib→zapewnić ramy→zapewnij sobie swoje zasoby - Redaktor: Kod VS + Lua LS, rysik; opcjonalnie ripgrep do szybkiego skanowania wzorów
- Konfiguracja testowa: czysta migawka bazy danych; szczegółowe rejestrowanie; mały zestaw danych zaszczepionych
- Wzory wyszukiwania użyjesz:
ESX.xPlayer.QBCore.Dane graczardzeń qbxeksporty.ox_inventorymysql%-asyncMySQL.
3) Kamień z Rosetty: ESX ↔ QBCore ↔ QBOX (mapowanie trójstronne)
Łatwe w użyciu narzędzie do kopiowania i wklejania. Użyj go, aby zastąpić połączenia telefoniczne lub podłączyć adapter.
Rdzeń i gracz
| Pojęcie | ESX | QBCore | QBOX |
|---|---|---|---|
| Zdobądź rdzeń | eksporty['es_extended']:getSharedObject() | eksporty['qb-core']:GetCoreObject() | (n/a — użyj eksportów) |
| Pobierz gracza (źródło) | ESX.GetPlayerFromId(źródło) | QBCore.Functions.GetPlayer(źródło) | exports.qbx_core:GetPlayer(src) |
| Uzyskaj za pomocą citizenid | (zapytanie niestandardowe) | QBCore.Functions.GetPlayerByCitizenId(id) | exports.qbx_core:GetPlayerByCitizenId(id) (jeśli występuje) |
Identyfikatory
| Pojęcie | ESX | QBCore | QBOX |
|---|---|---|---|
| Podstawowy | identyfikator (licencja/Steam) | obywatel | obywatel |
| Przejście dla pieszych | tabela id_map(identyfikator, id obywatela) | To samo | To samo |
Pieniądze
| Działanie | ESX | QBCore | QBOX |
|---|---|---|---|
| Dodaj gotówkę | xPlayer.addMoney(a) | Player.Functions.AddMoney('gotówka', a) | Gracz.PlayerData.money.cash += a (poprzez adapter + zapisz) |
| Dodaj bank | xPlayer.addAccountMoney('bank', a) | Player.Functions.AddMoney('bank', a) | Gracz.PlayerData.money.bank += a (adapter + zapisz) |
| Dodaj brudne | xPlayer.addAccountMoney('black_money', a) | element lub dodatkowe konto (zdefiniowane na serwerze) | mapuj do portfela przedmiotów/alternatywnego (np., krypto) (wybór adaptera) |
Praca, Obowiązek, Grupy
| Pojęcie | ESX | QBCore | QBOX |
|---|---|---|---|
| Przeczytaj pracę | xPlayer.job.name, .stopień | Player.PlayerData.job.name, .poziom.klasy | Gracz.DaneOdtwarzacza.zadanie.* + pomocnicy grupowi |
| Na służbie | (różnie) | Player.PlayerData.job.onduty | Ustaw obowiązki służbowe/pomocnicy grupowi poprzez eksporty |
| Kontrola grupowa | (dodatek) | (dodatek) | exports.qbx_core:HasGroup(src, group) (przykład) |
Spis
| Działanie | ESX | QBCore | QBOX |
|---|---|---|---|
| Dodaj element | xPlayer.addInventoryItem(n, c) | Player.Functions.AddItem(n, c, ...) | woleć ox_inventory eksport przez adapter |
| ox_inventory | eksporty.ox_inventory:* | eksporty.ox_inventory:* | eksporty.ox_inventory:* |
Wywołania zwrotne
| Pojęcie | ESX | QBCore | QBOX |
|---|---|---|---|
| Rejestr serwera | ESX.RegisterServerCallback | QBCore.Funkcje.Utwórz wywołanie zwrotne | lib.callback.register (ox_lib) |
| Wyzwalacz klienta | ESX.TriggerServerCallback | QBCore.Funkcje.Wywołanie zwrotne wyzwalacza | lib.callback.await |
Warstwa bazy danych
| Pojęcie | ESX/QB (starsza wersja) | oxmysql (cel) |
|---|---|---|
| Aportować | MySQL.Async.fetchAll(sql, parametry, cb) | wiersze lokalne = MySQL.query.await(sql, {p1, ...}) |
| Aktualizacja | MySQL.Async.execute(sql, parametry, cb) | lokalne aff = MySQL.update.await(sql, {p1, ...}) |
UI / Powiadom / Cel
| Pojęcie | ESX | QBCore | QBOX |
|---|---|---|---|
| Notyfikować | ESX.ShowNotification(msg) | QBCore.Functions.Notify(wiadomość, typ) | exports.qbx_core:Powiadom(...) Lub lib.notify({...}) |
| Menu | (różnie) | menu qb | ox_lib:registerContext / wejścia |
| Cel | (dodatek) | cel qb | ox_target |
Wskazówka: przychylność ox_lib, ox_inventory, ox_target zachować neutralność w różnych ramach.
4) Samouczek A — ESX → QBCore (praktyczny)
Bramka: Konwertuj prosty zasób sklepu z ESX na QBCore.
Krok 1 — Zależności
- Zapewnić
oxmysql,ox_lib,rdzeń qbsą rozpoczęte. - Jeśli skrypt używa inwentarza ESX, przeprowadź migrację do ox_inventory (zalecane) lub zmapuj do inwentarza QB.
Krok 2 — Wykryj strukturę i dodaj most
Tworzyć most.lua aby znormalizować graczy/pieniądze/ekwipunek:
-- 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
Krok 3 — Konwersja wywołań zwrotnych
- ESX → QB: wymień
ESX.RegisterServerCallbackzQBCore.Funkcje.Utwórz wywołanie zwrotne. - Klient używa
QBCore.Funkcje.Wywołanie zwrotne wyzwalacza.
-- 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 (wywołanie zwrotne) jeśli GetResourceState('qb-core') == 'started' wtedy lokalne QBCore = exports['qb-core']:GetCoreObject() QBCore.Functions.TriggerCallback('shop:getPrice', function(price) print('price', price) end, 'bread') w przeciwnym razie lokalne price = lib.callback.await('shop:getPrice', false, 'bread') print('price', price) end
Krok 4 — Ścieżki pieniężne i zapasy
- Zastępować
xPlayer.addAccountMoneyzFunkcje gracza.Dodaj pieniądze(dla QB) lub adapter. - Standaryzacja wszystkich zmian stanu magazynowego poprzez adapter.
Krok 5 — Wydarzenia (bezpieczeństwo po stronie serwera)
RegisterNetEvent('sklep:kup', funkcja(przedmiot, ilość) lokalne src = źródło jeśli typ(przedmiot) ~= 'ciąg' lub typ(kwota) ~= 'liczba' wtedy zwróć koniec jeśli ilość < 1 lub ilość > 10 wtedy zwróć koniec lokalne p = bridge.getPlayer(src) jeśli nie p wtedy zwróć koniec lokalne cena = 100 * ilość jeśli nie bridge.removeMoney(src, 'gotówka', cena) wtedy zwróć koniec bridge.addItem(src, przedmiot, ilość) bridge.notify(src, ('Kupiono %dx %s'):format(kwota, przedmiot), 'sukces') koniec)
Krok 6 — Migracja bazy danych (identyfikatory, konta)
- Utwórz przejście dla pieszych
id_map(identyfikator, id obywatela). - Zaludniać
obywateldla QB z ESXużytkownicytabeli za pomocą wybranej reguły (istniejąca kolumna lub wygenerowana).
-- Przykład: utwórz przejście dla pieszych i uzupełnij (dostosuj do swojego schematu) CREATE TABLE IF NOT EXISTS id_map ( identifier VARCHAR(64) PRIMARY KEY, citizenid VARCHAR(64) NOT NULL UNIQUE ); -- Załóżmy, że wygenerowałeś nowe citizenid i zapisałeś je wcześniej INSERT IGNORE INTO id_map(identifier, citizenid) SELECT u.identifier, u.citizenid FROM users u WHERE u.citizenid IS NOT NULL;
mysql‑async → oxmysql
-- przed (mysql-async) MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @id', {['@id'] = identifier}, function(rows) ... end) -- po (oxmysql) local rows = MySQL.query.await('SELECT * FROM users WHERE identifier = ?', { identifier })
Krok 7 — Kontrola jakości
- Twórz przedmioty, kupuj/sprzedawaj, upewniaj się, że saldo zmienia się prawidłowo.
- Sprawdź, czy wywołania zwrotne zwracają wartość pod obciążeniem.
- Sprawdź, czy metadane inwentarza są zachowane.
5) Samouczek B — QBCore → ESX (praktyczny)
Kluczowe ostrzeżenia:
- Zastosowania ESX konta Do
bank/czarne_pieniądze. Brudne pieniądze Port QB przedmiot (jeśli używane) na konto ESX lub zachowaj jako przedmiot. - Schematy stanowisk różnią się (stopień i poziom). Dokładnie je zaplanuj.
Przykład: Mapowanie pieniędzy za pomocą adaptera
-- 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
Przykład: Konwersja wywołania zwrotnego (serwer)
jeśli GetResourceState('es_extended') == 'started' wtedy lokalne ESX = exports['es_extended']:getSharedObject() ESX.RegisterServerCallback('garage:getVehicles', function(source, cb) lokalne src = source lokalne p = bridge.getPlayer(src) lokalne rows = MySQL.query.await('SELECT * FROM owned_vehicles WHERE owner = ?', { p.identifier }) cb(rows) koniec) koniec
Lista kontrolna testów
- Stanowiska pracy/awanse są kontynuowane.
- Salda bankowe/brudne zmieniają się zgodnie z oczekiwaniami.
- Potwierdzono własność pojazdu i format tablic rejestracyjnych.
6) Samouczek C — QBCore ↔ QBOX (praktyczny)
QBCore → QBOX
- Zastępować
QBCore.Funkcje.*zeksporty.qbx_core:*Lub ox_lib wywołania zwrotne. - Odtwarzacz:
QBCore.Functions.GetPlayer(źródło)→exports.qbx_core:GetPlayer(src). - Notyfikować:
QBCore.Funkcje.Powiadomienie→exports.qbx_core:PowiadomLublib.notify. - Obowiązki/grupy: użyj eksportów QBOX (
Ustaw obowiązki służbowe,Ma grupę, itp.).
QBOX → QBCore
- Zastępować
eksporty.qbx_core:*zQBCore.Funkcje.*odpowiedników lub adaptera. - W razie potrzeby ponownie wprowadź wywołania zwrotne QB i odpowiedniki menu/celów.
Fragmenty przed/po
-- Przed (powiadomienie QB) QBCore.Functions.Notify('Witaj', 'powodzenie') -- Po (QBOX) exports.qbx_core:Notify(source, 'Witaj', 'powodzenie') -- lub lib.notify(source, { title = 'Witaj', description = 'Witaj', type = 'success' })
-- Przed (QB pobierz gracza) lokalny Gracz = QBCore.Functions.GetPlayer(src) -- Po (QBOX) lokalny Gracz = exports.qbx_core:GetPlayer(src)
7) Samouczek D — Framework → Standalone z adapterami
Napisz swoje skrypty raz i uruchamiaj je wszędzie:
- Utwórz most udostępnianie stabilnego API:
pobierzOdtwarzacz,pobierzIdentyfikator,dodaj/usuń pieniądze,dodaj/usuń element,notyfikować,ma grupę,na służbie,wywołania zwrotneobwoluta. - Wykryj strukturę w czasie wykonywania (
rdzeń qbx→rdzeń qb→es_rozszerzony→nic). - Używać ox_lib do wywołań zwrotnych i powiadomień, gdy nie istnieje bezpośredni pomocnik struktury.
Minimalny samodzielny zapasowy
-- 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) Wydajność i bezpieczeństwo (wzmocnienie produkcji)
Walidacja po stronie serwera (nigdy nie ufaj klientowi)
- Uprawomocnić typy I miedza na każdym wydarzeniu.
- Sprawdzać własność, czasy odnowienia, dystans (jeśli dotyczy), praca/grupa.
- Upewnij się, że saldo środków pieniężnych nie stanie się ujemne i ogranicz kwoty.
- Porównywać cena po stronie serwera; nie akceptuj sum podanych przez klienta.
Struktura wydarzenia
- Użyj jednego zdarzenie serwerowe na akcję; nie udostępniaj klientom surowych funkcji dotyczących zapasów/pieniędzy.
- Woleć wywołania zwrotne dla przepływów żądanie/odpowiedź.
DB i wydajność
- Przełącz na oxmysql oczekuj na API, zapisuj wsadowo, unikaj zapytań per-tick.
- Indeksuj często wyszukiwane kolumny (
obywatel,identyfikator,płyta). - Zachowaj w pamięci podręcznej konfiguracje/listy cen; wyeksportuj je raz do klientów, a następnie aktualizuj w przypadku zmiany.
- Używać
GlobalStateoszczędnie; unikaj aktualizacji w pętli.
9) Typowe pułapki i podręcznik debugowania
- Zarozumiały
PobierzCoreObjectistnieje na QBOX → nie; użyjeksporty.qbx_core:*. - Po migracji do QBOX połączenia zwrotne nigdy nie powracają → Wywołania zwrotne ESX/QB nie są zarejestrowane; przełącz na
lib.callback.register/await. - Semantyka brudnych pieniędzy różnią się → zdecyduj, czy chcesz wybrać przedmiot, konto czy alternatywny portfel i ustandaryzuj go w swoim adapterze.
- Założenia dotyczące mieszanych zapasów → znormalizować na
ox_inventory. - Problemy z zamówieniem początkowym →
oxmysql→ox_lib→ framework → twoje zasoby. - Dryf metadanych pojazdu → upewnij się, że kolumny JSON i formaty tablic pasują do docelowej struktury.
10) Najlepsze praktyki fxmanifest.lua
fx_version 'cerulean' gra 'gta5' lua54 'tak' 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' } -- zależności (wybierz, których używasz): ox_lib, oxmysql, ox_inventory, qb-core LUB qbx_core LUB es_extended
- Ogłosić Lua 5.4 (
lua54 'tak''). - Trzymać
escrow_ignoreminimalne; nigdy nie próbuj ominąć depozytu.
11) Migracja danych: fragmenty kodu SQL (przykłady)
Dostosuj nazwy tabel/kolumn do swojego schematu. Zawsze najpierw uruchamiaj kopię.
Identyfikatory: ESX → QB/QBOX
-- Dodaj citizenid do użytkowników ESX, jeśli ich brakuje ALTER TABLE users ADD COLUMN IF NOT EXISTS citizenid VARCHAR(64); -- Wypełnij przy użyciu deterministycznego generatora lub istniejącej kolumny UPDATE users SET citizenid = LOWER(SUBSTRING(MD5(CONCAT(identifier,'-QB')),1,10)) WHERE citizenid IS NULL; -- Utwórz przejście 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;
Konta/Pieniądze
-- Przykład: konwersja sald bankowych ESX na tabelę pieniędzy QB (jeśli schemat QB przechowuje je osobno) 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);
Pojazdy
-- Normalizuj tablice rejestracyjne do formatu docelowego (przykład: 8 znaków u góry) UPDATE owned_vehicles SET plate = UPPER(LEFT(plate,8)); -- Upewnij się, że kolumny metadanych JSON są prawidłowe UPDATE owned_vehicles SET mods = JSON_MERGE_PATCH('{}', mods) WHERE JSON_VALID(mods) = 0;
12) Adaptery, które można ponownie wykorzystać (wersja startowa)
Wrzuć to do
most.luai rozszerzaj zgodnie ze swoimi potrzebami. Automatycznie wykrywa ESX/QB/QBOX i udostępnia stabilne 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) Ostateczne listy kontrolne (skopiuj i wyślij)
A) Odkrywanie i wstępny lot
- Utwórz migawkę bazy danych/plików; utwórz serwer przejściowy
- Przypnij artefakty i wersje zasobów; zdefiniuj kolejność początkową
- Wymieniono zależności ekwipunku/celu/menu
- Wybierz strategię identyfikacji (przejście dla pieszych z identyfikatorem obywatela)
B) Audyt kodu
- Grep dla ESX/QB/QBOX/ox_*/mysql‑async
- Wypisz wszystkie wezwania dotyczące pieniędzy/zapasów/pracy/obowiązków
- Wyświetlanie listy wywołań zwrotnych i zdarzeń serwera/klienta
C) Mapowanie i projektowanie
- Wybierz powierzchnię adaptera (gracz, identyfikatory, pieniądze, przedmioty, powiadomienia, wywołania zwrotne)
- Wybierz strategię dotyczącą brudnych pieniędzy (konto, przedmiot, alternatywny portfel)
- Preferuj ox_lib/ox_inventory/ox_target
D) Migracja danych
- Zbuduj przejście dla pieszych dla obywateli
- Konwersja kont/pieniędzy
- Normalizacja metadanych i tablic rejestracyjnych pojazdów
- Przełącz się na wywołania oczekujące Oxmysql
E) Testowanie QA
- Bezpieczeństwo zdarzeń: typy/granice/własność/czasy odnowienia
- Wywołania zwrotne: zwracanie wartości pod obciążeniem
- Zachowano metadane inwentarza
- Logika zadań/obowiązków/grupy pasuje do projektu
F) Wydanie i wycofanie
- Wydanie tagu; dziennik zmian
- Zachowaj migawkę przed migracją przez 7–14 dni
- Monitoruj błędy/opóźnienia; indeksuj gorące zapytania
14) FAQ (ze schematem JSON‑LD)
P: Czy mogę przenieść skrypty QBCore do QBOX bez konieczności całkowitego przepisania?
A: Z adapterami i ox_lib wywołania zwrotne, większość skryptów wymaga jedynie ponownego mapowania wywołań.
P: Co mam zrobić z czarnymi/brudnymi pieniędzmi?
A: Standaryzacja w adapterze: ESX → czarne_pieniądze Konto; QB → przedmiot lub konto dodatkowe; QBOX → przedmiot lub portfel alternatywny (np. kryptowaluty). Stosuj jedną strategię w całym projekcie.
P: Dlaczego po przejściu na wersję QBOX połączenia zwrotne zostają zawieszone?
A: Wywołania zwrotne ESX/QB nie będą działać na QBOX. Użyj lib.callback.register/await.
P: Jaki jest najlepszy sposób na migrację mysql‑async?
A: Zastąp przez oxmysql oczekuj na API; usuń piramidy wywołań zwrotnych.
P: Jak przekonwertować qb‑target na ox_target?
A: Zastąp wywołania API addBoxZone/Entity w stosunku jeden do jednego; ładunki zdarzeń pozostaną podobne. Zachowaj stabilne nazwy celów.
15) Wizualizacje (sugestie)
- Schemat blokowy (Odkryj → Mapa → Adaptacja → Migracja bazy danych → Testowanie → Wydanie)
- Schemat adapterów: Skrypt → Most → Struktura (ESX/QB/QBOX)
- Tabela Rosetta: dołączone powyżej (eksportuj jako plik CSV do pobrania)
[Odkryj] → [Interfejsy API map] → [Adapter zapisu] → [Migracja bazy danych] → [Wzmocnienie] → [Zapewnienie jakości] → [Wydanie]
16) Prawne i etyczne
- Szanuj licencje (MIT/GPL/NC). Nie ominąć depozyt lub zaciemnianie.
- Konwertuj tylko te skrypty, które własny lub uzyskać pozwolenie na adaptację.
17) Materiały do pobrania i szybki przewodnik
Możesz również użyć tego konwertera (nie testowałem):
https://github.com/sledgehamm3r/ESX-QBCore-Converter
28) Następne kroki
- Upuść most.lua do swojego zasobu i zacznij konwertować najpierw te skrypty, które mają największą wartość.
- Standaryzować na ox_lib + ox_inventory + ox_target + oxmysql pozostać niezależnym od ram.
- Korzystaj z list kontrolnych podczas przeglądu i wydania.
Przeczytaj także Migracja SQL i identyfikatorów: steam/license → citizenid i konta → pieniądze (ESX → QBCore/QBOX)






