Sichern Sie sich heute 20%. Verwenden Sie beim Bezahlvorgang den Code WELCOME. WILLKOMMEN

So migrieren Sie ESX → QBCore richtig

Sie möchten einen reibungslosen Wechsel von ESX zu QBCore, ohne Datenverlust oder Systembeschädigung. Folgen Sie diesem Plan. Sie erhalten stabile Kennungen, OxMySQL-Abfragen und ox_lib-basierten Code.

Ziel: Verschieben Sie Ihren Server mit minimaler Ausfallzeit von ESX zu QBCore.



Voraussetzungen

  1. Werkzeuge
    1. GIT und ein separater Zweig für die Migration.
    2. MariaDB oder MySQL 8 mit aktivierten vollständigen Backups.
    3. Ein Staging-Server, der die Produktion spiegelt.
  2. Serverartefakte
    1. FXServer auf denselben Build wie die Produktion aktualisiert.
    2. QBCore Basisframework und Standardressourcen.
  3. Von Ihnen verwendete Bibliotheken
    1. oxmysql für die Datenbank.
    2. ox_lib für Rückrufe, UI-Helfer und Utility-Wrapper.

Schritt 1. Erstellen Sie einen Plan und einen Rollback-Punkt

  1. Produktionsänderungen einfrieren. Neue Skriptinstallationen und Datenbankschreibvorgänge stoppen, die zum Testen nicht erforderlich sind.
  2. Sichern Sie Ihren gesamten Datenbank-Dump als benannten Snapshot.
  3. Verzweigen Sie Ihr Server-Repository und erstellen Sie ein dediziertes Migration von ESX zu QBCore Zweig.
  4. Schreiben Sie ein Runbook. Fügen Sie Befehle zum Starten und Stoppen des Staging-Servers, zum Wiederherstellen der Datenbank und zum Ausführen von Integritätsprüfungen ein.

Schritt 2. Erstellen Sie eine saubere QBCore-Basis

  1. Stellen Sie eine neue QBCore-Basis für die Staging-Umgebung bereit.
  2. Lassen Sie nur das Nötigste aktiviert. Deaktivieren Sie Jobs, Inventare und benutzerdefinierte Skripts bis nach der Datenbankmigration.
  3. Installieren und starten Sie zuerst diese Ressourcen
    1. qb-kern
    2. qb-Fahrzeuge oder Ihre bevorzugten Ersatzprodukte
    3. oxmysql
    4. ox_lib

Schritt 3. Ersetzen Sie mysql-async durch oxmysql

Wenn noch verbleibende ESX-Skripte MySQL.Async, konvertieren Sie die Aufrufe in Oxmysql. Verwenden Sie einfaches Suchen und Ersetzen mit Überprüfung.

Häufige Konvertierungen

-- ESX mysql-async MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @id', {['@id'] = identifier}, function(rows) -- ... end)
-- QBCore oxmysql local rows = MySQL.query.await('SELECT * FROM players WHERE citizenid = ?', { citizenid }) -- rows ist eine Lua-Tabelle; Null- und Längenprüfungen direkt durchführen
-- ESX-Skalarbeispiel MySQL.Async.fetchScalar('SELECT COUNT(1) FROM owned_vehicles', {}, function(count) -- ... end)
-- oxmysql skalare lokale Anzahl = MySQL.scalar.await('SELECT COUNT(1) FROM player_vehicles')
-- ESX insert MySQL.Async.execute('INSERT INTO addon_account VALUES (@owner, @name, @money)', { ['@owner'] = Kennung, ['@name'] = Name, ['@money'] = Geld })
--oxmysql insert MySQL.prepare.await('INSERT INTO player_accounts (citizenid, name, amount) VALUES (?, ?, ?)', { citizenid, name, amount })

Hinweise

  1. Bevorzugen Abfrage.warten, Skalar.warten, Und vorbereiten.warten für einen sauberen Durchfluss.
  2. Verwenden Sie vorbereitete Anweisungen für Schreibvorgänge.

Schritt 4. ESX-Datenstrukturen QBCore zuordnen

Sie verschieben Spieleridentitäten und eigene Entitäten. Verwenden Sie diese Referenz zum Zuordnen von Tabellen.

ESX-TabelleSchlüsselspalteQBCore-TabelleSchlüsselspalteHinweise
BenutzerKennungSpielerBürger-IDKonvertieren Sie Kennungen und erstellen Sie Bürger-ID für jede Zeile
eigene_FahrzeugeEigentümerSpielerfahrzeugeBürger-IDKonvertieren Sie Plattengehäuse und JSON-Nutzdaten
DatenspeicherdatenEigentümerSpielermetadatenBürger-IDWenn Sie JSON speichern, führen Sie die Zusammenführung sorgfältig durch
Addon-KontodatenEigentümerSpielerkontenBürger-IDOrdnen Sie Kontonamen dem QBCore-Banking oder Bargeld zu
Addon_InventarartikelEigentümerSpielerinventareBürger-IDWenn Sie umziehen nach ox_inventory, separat migrieren

Sie können benutzerdefinierte Tabellen beibehalten. Passen Sie nur Fremdschlüssel an, die auf ESX-Kennungen verweisen.


Schritt 5. Kennungen stabilisieren

ESX speichert häufig eine CFX-Kennung wie Lizenz: xxxx oder historisch Dampf:xxxxQBCore verwendet Bürger-ID als stabiler Player-Schlüssel und behält die Laufzeitkennungen nur zur Authentifizierung.

Du wirst

  1. Erstellen Sie ein Bürger-ID für jeden Spieler.
  2. Verknüpfen Sie alte Kennungen mit dem neuen Datensatz.
  3. Führen Sie eine Nachschlagetabelle für Support und Audits.

SQL-Bootstrap

Führen Sie dies auf einer Kopie Ihrer ESX-Datenbank aus, um QBCore-Tabellen vorzubereiten.

-- 1) Erstellen Sie eine Spielertabelle, falls diese fehlt. Passen Sie sie an Ihr QBCore-Schema an. CREATE TABLE IF NOT EXISTS players (citizenid VARCHAR(11) PRIMARY KEY, license VARCHAR(64) UNIQUE, identifiers JSON NOT NULL, name VARCHAR(64), charinfo JSON NOT NULL, metadata JSON NOT NULL, money JSON NOT NULL, job JSON NOT NULL, position VARCHAR(128) DEFAULT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 2) Eine Hilfsfunktion, die in SQL mit einem deterministischen Generator äquivalent wäre, wäre komplex. -- Stellen Sie stattdessen die Zuordnung in einer separaten Tabelle bereit und generieren Sie citizenid in Lua. CREATE TABLE IF NOT EXISTS legacy_identifier_map (Lizenz VARCHAR(64) PRIMARY KEY, Steam VARCHAR(64) NULL, fivem VARCHAR(64) NULL, Discord VARCHAR(64) NULL, Xbl VARCHAR(64) NULL, Live-ID VARCHAR(64) NULL, Citizen-ID VARCHAR(11) UNIQUE); – 3) Seeden Sie die Zuordnung von ESX-Benutzern INSERT INTO legacy_identifier_map (Lizenz) SELECT DISTINCT REPLACE(Kennung, „Kennung:“, „“) FROM Benutzer WHERE Kennung LIKE „Lizenz:%“ ODER Kennung LIKE „Steam:%“;

CitizenID generieren und Spieler in Lua einfügen

Einmal auf der Staging-Plattform ausführen. Zuerst sichern.

-- server/migrate_identifiers.lua local QBCore = exports['qb-core']:GetCoreObject() lokale Funktion generateCitizenId() lokaler Zeichensatz = {} für c = 65, 90 mache table.insert(charset, string.char(c)) Ende für n = 48, 57 mache table.insert(charset, string.char(n)) Ende math.randomseed(GetGameTimer()) lokale ID = {} für i = 1, 11 mache id[i] = Zeichensatz[math.random(1, #charset)] Ende return table.concat(id) Ende lokale Zeilen = MySQL.query.await('SELECT license FROM legacy_identifier_map WHERE citizenid IS NULL') für _, r in ipairs(Zeilen) mache lokale citizenid = generateCitizenId() MySQL.prepare.await('UPDATE legacy_identifier_map SET citizenid = ? WHERE license = ?', { citizenid, r.license }) end -- Spieler aus ESX-Benutzern erstellen local users = MySQL.query.await([[SELECT u.identifier, u.firstname, u.lastname, u.dateofbirth, u.sex, u.height FROM users u]]) for _, u in ipairs(users) do local license = u.identifier local map = MySQL.single.await('SELECT citizenid FROM legacy_identifier_map WHERE license = ?', { license }) if map and map.citizenid then local name = string.format('%s %s', u.firstname or 'John', u.lastname or 'Doe') local charinfo = json.encode({ firstname = u.firstname, lastname = u.lastname, birthdate = u.dateofbirth, gender = u.sex, height = u.height }) lokale Metadaten = json.encode({ Hunger = 100, Durst = 100 }) lokales Geld = json.encode({ Bargeld = 0, Bank = 0, Krypto = 0 }) lokaler Job = json.encode({ Name = 'arbeitslos', Bezeichnung = 'Arbeitslos', Klasse = { Name = '0', Stufe = 0 }}) MySQL.prepare.await('INSERT IGNORE INTO players (citizenid, Lizenz, Kennungen, Name, Charinfo, Metadaten, Geld, Job) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', { map.citizenid, Lizenz, json.encode({ Lizenz = Lizenz }), Name, Charinfo, Metadaten, Geld, Job }) end end print('Kennungsmigration abgeschlossen')

Eigene Fahrzeuge bewegen

INSERT IGNORE INTO player_vehicles (citizenid, plate, vehicle, garage, state) SELECT m.citizenid, UPPER(JSON_UNQUOTE(JSON_EXTRACT(v.vehicle, '$.plate'))), v.vehicle, 'legion', 1 FROM owned_vehicles v JOIN legacy_identifier_map m ON m.license = v.owner;

Validieren Sie Zufallsstichproben im Spiel. Überprüfen Sie Kennzeichenformate und Garagen.


Schritt 6. Portieren Sie ESX-Code mit ox_lib auf QBCore

Ersetzen Sie die ESX-Laufzeit-API durch QBCore-Äquivalente. Verwenden Sie ox_lib für Rückrufe und Benachrichtigungen.

Spielerobjekt

-- ESX lokaler xPlayer = ESX.GetPlayerFromId(src) xPlayer.addMoney(100)
-- QBCore lokaler Player = QBCore.Functions.GetPlayer(src) Player.Functions.AddMoney('cash', 100)

Jobs

-- ESX-Jobprüfung, wenn xPlayer.getJob().name == 'Polizei', dann -- ... Ende
-- QBCore-Jobprüfung lokaler Job = Player.PlayerData.job, wenn Job und Job.name == „Polizei“, dann -- ... Ende

Rückrufe und Benutzeroberfläche

-- ESX-Server-Rückruf ESX.RegisterServerCallback('resource:getData', function(source, cb) cb({ ok = true }) end)
-- ox_lib Rückruf lib.callback.register('resource:getData', Funktion(Quelle) return { ok = true } Ende)
-- Benachrichtigung lib.notify(Quelle, { Titel = 'Job', Beschreibung = 'Beförderung gewährt', Typ = 'Erfolg' })

Befehle

-- ESX RegisterCommand('pay', function(src, args) local amount = tonumber(args[1]) oder 0 xPlayer.removeMoney(amount) end)
-- QBCore mit Berechtigungen QBCore.Commands.Add('pay', 'Bar bezahlen', {{name = 'amount', help = 'Amount'}}, false, function(src, args) local amount = tonumber(args[1]) oder 0 local Player = QBCore.Functions.GetPlayer(src) Player.Functions.RemoveMoney('cash', amount) end)

Schritt 7. Inventar und Artikel

Wenn Sie von es_extended Vorräte zu qb-inventar oder ox_inventory, behandeln Sie dies als separate Untermigration.

  1. Artikelzusätze einfrieren.
  2. Exportieren Sie die Artikelstammliste.
  3. Ordnen Sie Elementnamen eins zu eins zu.
  4. Migrieren Sie Spielerinventare stapelweise. Validieren Sie Stapelgrößen und -gewichte.

Beispiel für eine CSV-Elementzuordnung

esx_name,qb_name,Notizen Brot,Brot, Wasser,Wasser,Dietrich,Dietrich,

Schritt 8. Testen und Ausrollen

  1. Komponententests
    1. Testen Sie die Kennungssuche für eine zufällige Gruppe von Spielern.
    2. Testen Sie Geldtransfers, Jobwechsel und Fahrzeugbesitz.
  2. Gameplay-Tests
    1. Spawnen Sie Spieler mit alten ESX-Kennungen und bestätigen Sie die automatische Zuordnung.
    2. Führen Sie einen Polizeidienstablauf, einen Ladenüberfall und einen Autokauf durch.
  3. Leistungstests
    1. Verwenden resmon um CPU und Speicher zu überwachen.
    2. Bestätigen Sie, dass die Anzahl der DB-Abfragen nach der Oxmysql-Konvertierung gesunken ist.
  4. Rollout-Plan
    1. Verschieben Sie die Staging-Datenbank während eines Wartungsfensters in die Produktion.
    2. Kündigen Sie eine 60-minütige Ausfallzeit an.
    3. Überwachen Sie Protokolle auf fehlende Kennungen und Fremdschlüsselfehler.

Fehlerbehebung

  1. Doppelte Bürger
    1. Ursache: Die Migration wird zweimal ausgeführt.
    2. Fix. Erzwingen Sie eindeutige Schlüssel auf Bürger-ID und verwenden INSERT IGNORE während der Aussaat.
  2. Fehlende Fahrzeuge
    1. Ursache: Eigentümerschlüssel stimmt nicht überein zwischen owned_vehicles.owner Und legacy_identifier_map.license.
    2. Behebung. Normalisieren Sie die Eigentümerwerte und führen Sie die Fahrzeugeingabe für die betroffenen Kennzeichen erneut aus.
  3. Spieler spawnen ohne Inventar
    1. Ursache: Bestandsmigration übersprungen.
    2. Behebung. Erstellen Sie die Bestandszuordnung neu und importieren Sie sie erneut.
  4. Skripte schlagen fehl mit MySQL.Async nicht gefunden
    1. Ursache: Das Skript hängt immer noch von mysql-async ab.
    2. Behebung. Ersetzen Sie die Aufrufe durch oxmysql und entfernen Sie mysql-async vom Server.

Checkliste für die Umstellung

  1. Sichern Sie die Produktionsdatenbank mit einem Zeitstempel.
  2. Stoppen Sie den Server und sperren Sie den Beitritt von Spielern.
  3. Stellen Sie den endgültigen Staging-Dump in der Produktion wieder her.
  4. Stellen Sie QBCore Build bereit mit qb-kern, oxmysql, ox_lib zuerst in der Reihenfolge der Gewährleistung.
  5. Führen Sie das Skript zur Identifizierungsseeding einmal aus.
  6. Aktivieren Sie konvertierte Skripte nur, wenn ihre Abfragen auf Oxmysql erfolgen.
  7. Öffnen Sie den Server erneut und beobachten Sie die Protokolle 30 Minuten lang.
  8. Veröffentlichen Sie einen Rollback-Plan, wenn kritische Fehler auftreten.

Anhang A. Beispiel fxmanifest für Migrationshelfer

fx_version 'cerulean' Spiel 'gta5' lua54 'ja' Serverskripte { '@oxmysql/lib/MySQL.lua', '@ox_lib/init.lua', 'server/migrate_identifiers.lua' }

Anhang B. Sichere JSON-Helfer

local function safeDecode(jsonStr, fallback)
  if type(jsonStr) ~= 'string' or jsonStr == '' then return fallback end
  local ok, result = pcall(json.decode, jsonStr)
  if not ok then return fallback end
  return result
end

Was Sie erreicht haben

  1. Stabile Spieleraufzeichnungen eingegeben von Bürger-ID.
  2. Eine saubere Oxmysql-Schicht mit vorbereiteten Anweisungen und Wartezeiten.
  3. ESX-Code mithilfe von ox_lib-Rückrufen und -Dienstprogrammen auf QBCore portiert.
  4. Ein versionierter Plan, den Sie für zukünftige Server wiederholen können.

  1. Framework-Konvertierungs-Hub. https://fivemx.com/framework-conversion
  2. MySQL Async-zu-Oxmysql-Anleitung. https://fivemx.com/mysql-async-to-oxmysql
  3. Migration von SQL-Kennungen. https://fivemx.com/sql-identifiers-migration
  4. Adaptermuster für Skriptports. https://fivemx.com/adapter-patterns
  5. Schnellstart zur QBCore-Installation. https://fivemx.com/how-to-install-qbcore
  6. Checkliste zur Skriptkonvertierung. https://fivemx.com/converting-fivem-scripts
  7. QBOX mit Ox-Stack-Übersicht. https://fivemx.com/qbox-ox-stack
  8. Resmon und Leistung. https://fivemx.com/how-to-use-resmon-in-fivem-optimize-resources

Externe Referenzen

  1. QBCore-Rahmenwerk
  2. Oxmysql-Dokumentation.
  3. ox_lib-Dokumentation.
  4. CFX.re-Kennungsreferenz.

Lukas
Lukas

Ich bin Luke, ein Gamer und schreibe gerne über FiveM, GTA und Rollenspiele. Ich betreibe eine Rollenspiel-Community und habe etwa 10 Jahre Erfahrung in der Verwaltung von Servern.

Artikel570