$ ABD Doları
  • $ ABD Doları
  • € AVRO
  • £ GBP
  • $ Avustralya Doları
  • R$ BRL
  • İsviçre Frangı İsviçre Frangı
  • ¥ Japon Yeni
FiveM Scripts – ESX, QBCore, QBOX (Çerçeve…

FiveM Scripts Dönüştürme – ESX, QBCore, QBOX (Çerçeve…

Bu, kod öncelikli, gereksiz detaylardan arındırılmış, FiveM betiklerini kolayca dönüştüren ve size tam olarak nasıl yapılacağını gösteren bir rehberdir. FiveM Scripts'yi dönüştürün ESX, QBCore, QBOX (qbx_core) ve framework‑agnostic (bağımsız) kurulumlar arasında. Üç yönlü API eşlemeleri, adaptör kodu, SQL geçiş adımları (mysql‑async → oxmysql), QBOX özellikleri, test kontrol listeleri ve canlıya alma sertleştirme ipuçları alacaksınız.


TL;DR — 10 Adımda Geçiş

  1. Anlık görüntü ve hazırlama: DB/dosyalarını yedekleyin. Hedef framework ile yerel bir test sunucusu başlatın.
  2. Bağımlılıkları belirleyin: envanter, hedef, menü/UI, geri çağırmalar, DB katmanı, çekirdek erişim.
  3. Sürümleri ve sıralamayı sabitleyin: oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → kaynaklarınız.
  4. Kod yolunu okuyun: Tüm oyuncu, para, iş/görev, envanter, geri çağırma/olay ve DB çağrılarını bulun.
  5. API'leri eşleyin: ESX ↔ QBCore ↔ QBOX'yi eşlemek için aşağıdaki Rosetta tablolarını kullanın.
  6. Köprüleyin: Bir ekleyin bridge.lua framework'ü otomatik algılayan ve çağrıları normalleştiren adaptör.
  7. Geri çağırmaları dönüştürün: ESX/QB geri çağırmaları → QBOX/ox_lib lib.callback.* gerekli olduğunda.
  8. DB'yi geçirin: Tanımlayıcıları, hesapları, öğeleri, araçları taşıyın; şuraya geçin: oxmysql *.await stil.
  9. Etkinlikleri sertleştirin: Doğrula source, sınırlar, gruplar\/işler, sahiplik; asla istemciye güvenme.
  10. QA ve yayın: Kontrol listelerini çalıştırın; etiket, değişiklik günlüğü ve geri alma planı.

Bir Adaptör çözümü arayan bir geliştirici misiniz? Ücretsiz adaptör betiğimize buradan göz atın


1) Çerçeveler 101: ESX vs QBCore vs QBOX vs Standalone

Mimari genel bakış

KategoriESXQBCoreQBOX
Mimari \/ Çekirdek Erişimiexports['es_extended']:getSharedObject()ESXexports['qb-core']:GetCoreObject()QBCoreKüresel bir çekirdek nesnesi yok; kullanın exports.qbx_core:* oyuncu, gruplar ve bildirimler için
Oyuncu NesnesiESX.GetPlayerFromId(src)xPlayerQBCore.Functions.GetPlayer(src)Playerexports.qbx_core:GetPlayer(src)Player ile PlayerData
TanımlayıcılarTarihsel olarak identifier (lisans/steam)citizenid birincil anahtar olarakcitizenid birincil anahtar olarak
Para YönetimixPlayer.addMoney() / `addAccountMoney(‘bank’‘black_money’)Player.Functions.AddMoney(‘cash’
İşler ve GörevxPlayer.job.name, .job.gradePlayer.PlayerData.job.name, .grade.level, OnDutyİş/grup yardımcıları aracılığıyla exports.qbx_core:* (grup kontrolleri, görev ayarlayıcıları)
EnvanterESX varsayılan / ox_inventory / qb-inventory (önerilen: ox_inventory)qb-inventory / ox_inventoryox_inventory tavsiye edilen
Geri çağrımlarESX.RegisterServerCallback / ESX.TriggerServerCallbackQBCore.Functions.CreateCallback / TriggerCallbackTercih etmek ox_lib geri aramalar (lib.callback.register/await) veya QBOX exports
Veritabanı KatmanıEski: mysql-async → Şimdi: oxmysql (MySQL.query.await, MySQL.update.await)oxmysqloxmysql
UI – BildirimlerESX BildirimQB NotifyQBOX bildirim yardımcıları veya lib.notify
UI – Menüleresx_menu_default / ox_lib:registerContextqb-menu / ox_lib:registerContextox_lib:registerContext / lib.inputDialog
UI – Hedef Sistemiesx_target / ox_targetqb-target / ox_targetox_target tavsiye edilen

QBOX'un farklı olduğu nokta

  • Kaynak adı ve dışa aktarımları: qbx_core (yok GetCoreObject).
  • Dayanır ox_kütüphane (geri aramalar, bildirim) ve oxmysql varsayılan olarak.
  • Çoklu karakter/kuyruk/gruplar için yerleşik özellikler; işler/görevler için görüş belirten yardımcılar.

FiveM Çerçeveleri: QBCore ve ESX
Converting FiveM Scripts – ESX, QBCore, QBOX (Frame... 3

2) Ön Kontrol: Ortam ve Araçlar

  • Sunucu: mevcut FXSunucusu artifact, Lua 5.4, CFX ensure sipariş
  • Sıra: ensure oxmysqlensure ox_libensure frameworkensure yourResource
  • Editör: VS Code + Lua LS, stylua; isteğe bağlı ripgrep hızlı desen taramaları için
  • Test kurulumu: temiz veritabanı anlık görüntüsü; ayrıntılı günlük kaydı; küçük tohum veri seti
  • Desenleri ara kullanacaksınız:
    • ESX. xPlayer. QBCore. PlayerData qbx_core exports.ox_inventory mysql%-async MySQL.

3) Rosetta Taşı: ESX ↔ QBCore ↔ QBOX (Üç Yönlü Eşleme)

Kopyala/yapıştır dostu referans. Çağrıları değiştirmek veya adaptörünüzü bağlamak için kullanın.

Core & Player

KavramESXQBCoreQBOX
Çekirdeği alexports['es_extended']:getSharedObject()exports['qb-core']:GetCoreObject()(uygun değil — exports kullanın)
Oyuncu al (src)ESX.GetPlayerFromId(src)QBCore.Functions.GetPlayer(src)exports.qbx_core:GetPlayer(src)
citizenid ile al(özel sorgu)QBCore.Functions.GetPlayerByCitizenId(id)exports.qbx_core:GetPlayerByCitizenId(id) (varsa)

Tanımlayıcılar

KavramESXQBCoreQBOX
Birincilidentifier (lisans/steam)citizenidcitizenid
Crosswalkmasa id_map(identifier, citizenid)AynıAynı

Para

AksiyonESXQBCoreQBOX
Nakit eklexPlayer.addMoney(a)Player.Functions.AddMoney('cash', a)Player.PlayerData.money.cash += a (adaptör + kaydetme yoluyla)
Banka eklexPlayer.addAccountMoney('bank', a)Player.Functions.AddMoney('bank', a)Player.PlayerData.money.bank += a (bağdaştırıcı + kaydet)
Kirli eklexPlayer.addAccountMoney('black_money', a)öğe veya ek hesap (sunucu tarafından tanımlanmış)öğe/alternatif cüzdan ile eşle (ör. crypto) (adaptör seçimi)

İşler, Görev, Gruplar

KavramESXQBCoreQBOX
İş okuxPlayer.job.name, .gradePlayer.PlayerData.job.name, .grade.levelPlayer.PlayerData.job.* + grup yardımcıları
Görevde(değişir)Player.PlayerData.job.ondutySetJobDuty/group yardımcıları exports aracılığıyla
Grup kontrolü(eklenti)(eklenti)exports.qbx_core:HasGroup(src, group) (örnek)

Envanter

AksiyonESXQBCoreQBOX
Öğe eklexPlayer.addInventoryItem(n, c)Player.Functions.AddItem(n, c, ...)tercih et ox_inventory bağdaştırıcı aracılığıyla export
öküz_envanteriexports.ox_inventory:*exports.ox_inventory:*exports.ox_inventory:*

Geri çağrımlar

KavramESXQBCoreQBOX
Sunucu kaydıESX.RegisterServerCallbackQBCore.Functions.CreateCallbacklib.callback.register (ox_lib)
İstemci tetikleyicisiESX.TriggerServerCallbackQBCore.Functions.TriggerCallbacklib.callback.await

DB Katmanı

KavramESX/QB (eski)oxmysql (hedef)
GetirMySQL.Async.fetchAll(sql, params, cb)local rows = MySQL.query.await(sql, {p1, ...})
GüncellemeMySQL.Async.execute(sql, params, cb)local aff = MySQL.update.await(sql, {p1, ...})

UI / Bildirim / Hedef

KavramESXQBCoreQBOX
BildirESX.ShowNotification(msg)QBCore.Functions.Notify(msg, type)exports.qbx_core:Notify(...) veya lib.notify({...})
Menü(değişir)qb-menuox_lib:registerContext / girdiler
Hedef(eklenti)qb-targetox_target

Uç: beğen ox_kütüphane, öküz_envanteri, öküz_hedefi çerçeveler arasında tarafsız kalmak için.


4) Eğitim A — ESX → QBCore (Uygulamalı)

Amaç: Basit bir dükkan kaynağını ESX'den QBCore'ye dönüştürün.

Adım 1 — Bağımlılıklar

  • Emin olmak oxmysql, ox_lib, qb-core başlatıldı.
  • Eğer betik ESX envanterini kullanıyorsa, şuna geçin: öküz_envanteri (önerilen) veya QB envanterine eşleyin.

Adım 2 — Framework'ü tespit et & bir köprü (bridge) ekle

Yaratmak bridge.lua oyuncuları/parayı/envanteri normalleştirmek için:

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

Adım 3 — Geri aramaları dönüştür

  • ESX → QB: değiştir ESX.RegisterServerCallback ile QBCore.Functions.CreateCallback.
  • İstemci kullanır QBCore.Functions.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)
if GetResourceState('qb-core') == 'started' then
 local QBCore = exports['qb-core']:GetCoreObject()
 QBCore.Functions.TriggerCallback('shop:getPrice', function(price)
 print('price', price)
 end, 'bread')
else
 local price = lib.callback.await('shop:getPrice', false, 'bread')
 print('price', price)
end

Adım 4 — Para ve envanter yolları

  • Yer değiştirmek xPlayer.addAccountMoney ile Player.Functions.AddMoney (QB için) veya bağdaştırıcı.
  • Tüm envanter değişikliklerini adaptör aracılığıyla standartlaştırın.

Adım 5 — Olaylar (sunucu tarafı güvenlik)

RegisterNetEvent('shop:buy', function(item, amount)
 local src = source
 if type(item) ~= 'string' or type(amount) ~= 'number' then return end
 if amount < 1 or amount > 10 then return end

 local p = bridge.getPlayer(src)
 if not p then return end

 local price = 100 * amount
 if not bridge.removeMoney(src, 'cash', price) then return end
 bridge.addItem(src, item, amount)
 bridge.notify(src, ('Bought %dx %s'):format(amount, item), 'success')
end)

Adım 6 — DB geçişi (tanımlayıcılar, hesaplar)

  • Bir çapraz referans (crosswalk) oluşturun id_map(identifier, citizenid).
  • Doldur citizenid QB için ESX'ten users seçim kuralına göre tablo (mevcut sütun veya oluşturulmuş).
-- Example: create crosswalk and backfill (customize to your schema)
CREATE TABLE IF NOT EXISTS id_map (
 identifier VARCHAR(64) PRIMARY KEY,
 citizenid VARCHAR(64) NOT NULL UNIQUE
);

-- Suppose you generated new citizenids and stored them earlier
INSERT IGNORE INTO id_map(identifier, citizenid)
SELECT u.identifier, u.citizenid FROM users u WHERE u.citizenid IS NOT NULL;

mysql‑async → oxmysql

-- before (mysql-async)
MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @id', {['@id'] = identifier}, function(rows) ... end)

-- after (oxmysql)
local rows = MySQL.query.await('SELECT * FROM users WHERE identifier = ?', { identifier })

Adım 7 — Kalite Güvencesi

  • Öğeleri oluşturun, satın alın/satın, bakiyelerin doğru değiştiğinden emin olun.
  • Geri aramaların yük altında döndüğünü doğrulayın.
  • Envanter metaverisinin korunduğunu kontrol edin.

5) Eğitim B — QBCore → ESX (Uygulamalı)

Anahtar uyarılar:

  • ESX kullanır hesaplar için bank/black_money. QB'nin kirli parasını taşıyın öğe (kullanılırsa) ESX hesabına veya öğe olarak saklayın.
  • İş şeması farklıdır (grade vs level). Dikkatlice eşleyin.

Örnek: Bağdaştırıcı aracılığıyla para eşleme

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

Örnek: Geri arama dönüştürme (sunucu)

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

Test kontrol listesi

  • İş atama/promosyonlar kalıcıdır.
  • Banka/kirli bakiyeler beklendiği gibi değişir.
  • Araç sahipliği ve plaka formatları doğrulandı.

6) Eğitim C — QBCore ↔ QBOX (Uygulamalı)

QBCore → QBOX

  • Yer değiştirmek QBCore.Functions.* ile exports.qbx_core:* veya ox_kütüphane geri aramalar.
  • Oyuncu: QBCore.Functions.GetPlayer(src)exports.qbx_core:GetPlayer(src).
  • Bildirim: QBCore.Functions.Notifyexports.qbx_core:Notify veya lib.notify.
  • Görev/gruplar: QBOX dışa aktarımlarını kullanın (SetJobDuty, HasGroup, vb.).

QBOX → QBCore

  • Yer değiştirmek exports.qbx_core:* ile QBCore.Functions.* eşdeğerleri veya adaptörünüz.
  • Gerektiğinde QB callback'lerini ve menü/hedef eşdeğerlerini yeniden tanıtın.

Önce/Sonra parçacıkları

-- Before (QB notify)
QBCore.Functions.Notify('Hello', 'success')

-- After (QBOX)
exports.qbx_core:Notify(source, 'Hello', 'success')
-- or
lib.notify(source, { title = 'Hello', description = 'Welcome', type = 'success' })
-- Before (QB get player)
local Player = QBCore.Functions.GetPlayer(src)

-- After (QBOX)
local Player = exports.qbx_core:GetPlayer(src)

7) Eğitim D — Çerçeve → Bağdaştırıcılarla Bağımsız

Betiklerinizi yazın bir kez ve bunları herhangi bir yerde çalıştırın:

  • Bir tane oluştur köprü kararlı bir API sunma: getPlayer, getIdentifier, add/removeMoney, add/removeItem, notify, hasGroup, onDuty, callbacks sarmalayıcı.
  • Çalışma zamanında çerçeveyi algıla (qbx_coreqb-corees_extendednone).
  • Kullanmak ox_kütüphane doğrudan bir çerçeve yardımcısı olmadığında geri aramalar ve bildirimler için.

Minimal bağımsız yedek (fallback)

-- 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) Performans ve Güvenlik (Üretim Sertleştirme)

Sunucu tarafı doğrulama (istemciye asla güvenme)

  • Doğrula tipler Ve sınırlar her olayda.
  • Kontrol etmek sahiplik, bekleme süreleri, mesafe (ilgiliyse), iş/grup.
  • Paranın negatif olamayacağından emin olun; tutarları sınırlayın.
  • Karşılaştır fiyat sunucu tarafı; istemci tarafından sağlanan toplamları kabul etmeyin.

Olay yapısı

  • Birini kullan sunucu olayı eylem başına; istemcilere ham envanter/para işlevlerini açığa çıkarmayın.
  • Tercih etmek geri çağırmalar (callbacks) istek/yanıt akışları için.

Veritabanı ve performans

  • Geçiş yapmak oxmysql await API'leri; toplu yazmalar; her tik sorgusundan kaçının.
  • Sık sorgulanan sütunları indeksleyin (citizenid, identifier, plate).
  • Yapılandırma/fiyat listelerini bellekte önbelleğe alın; istemcilere bir kez dışa aktarın, ardından değişiklik olduğunda farkını alın.
  • Kullanmak GlobalState idareli kullanın; sıcak döngü güncellemelerinden kaçının.

9) Yaygın Tuzaklar ve Hata Ayıklama Kılavuzu

  • Varsayarak GetCoreObject QBOX üzerinde mevcut → çalışmaz; kullanın exports.qbx_core:*.
  • Geri aramalar QBOX'ye geçiş yaptıktan sonra asla geri dönmez → ESX/QB geri çağrıları kaydedilmedi; şuna geçin: lib.callback.register/await.
  • Kirli para anlamları farklılık → öğe, hesap veya alternatif cüzdan arasında karar verin ve bağdaştırıcınızda standartlaştırın.
  • Karışık envanter varsayımları → normalleştirme ox_inventory.
  • Başlatma sırası sorunlarıoxmysqlox_lib → çerçeve → kaynaklarınız.
  • Araç meta verileri sürüklenmesi → hedef çerçeveyle eşleşen JSON sütunlarını ve plaka biçimlerini sağlayın.

10) fxmanifest.lua En İyi Uygulamalar

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

-- dependencies (pick what you use): ox_lib, oxmysql, ox_inventory, qb-core OR qbx_core OR es_extended
  • Bildir Lua5.4 (lua54 'yes').
  • Kale escrow_ignore minimal; asla escrow bypass'ı denemeyin.

11) Veri Taşıma: SQL Parçacıkları (Örnekler)

Tablo/sütun adlarını şemanıza göre ayarlayın. Her zaman önce bir kopyada çalıştırın.

Tanımlayıcılar: ESX → QB/QBOX

-- Add citizenid to ESX users if missing
ALTER TABLE users ADD COLUMN IF NOT EXISTS citizenid VARCHAR(64);

-- Populate using a deterministic generator or an existing column
UPDATE users SET citizenid = LOWER(SUBSTRING(MD5(CONCAT(identifier,'-QB')),1,10))
WHERE citizenid IS NULL;

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

Hesaplar/Para

-- Example: convert ESX bank balances to QB money table (if your QB schema stores it separately)
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);

Araçlar

-- Normalize plates to target format (example: 8 chars upper)
UPDATE owned_vehicles SET plate = UPPER(LEFT(plate,8));

-- Ensure JSON metadata columns are valid
UPDATE owned_vehicles SET mods = JSON_MERGE_PATCH('{}', mods) WHERE JSON_VALID(mods) = 0;

12) Yeniden Kullanabileceğiniz Adaptörler (Başlangıç)

Bunu içine bırakın bridge.lua ve ihtiyacınıza göre genişletin. ESX/QB/QBOX'u otomatik olarak algılar ve kararlı bir API sunar.

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) Son Kontrol Listeleri (Kopyala ve Yolla)

A) Keşif ve Ön Kontrol

  • Veritabanını/dosyaları anlık görüntüleyin; bir hazırlık sunucusu oluşturun
  • Yapıtları (artifacts) ve kaynak sürümlerini sabitleyin; başlatma sırasını tanımlayın
  • Envanter/hedef/menü bağımlılıkları listelendi
  • Tanımlayıcı stratejisine karar verin (citizenid geçişi)

B) Kod Denetimi

  • ESX/QB/QBOX/ox_*/mysql-async için grep yapın
  • Tüm para/envanter/iş/görev çağrılarını listeleyin
  • Geri çağırmaları ve sunucu/istemci olaylarını listele

C) Haritalama ve Tasarım

  • Adaptör yüzeyini seçin (player, ids, money, items, notify, callbacks)
  • Kirli para stratejisine karar verin (hesap vs öğe vs alternatif cüzdan)
  • ox_lib/ox_inventory/ox_target'yi tercih et

D) Veri Taşıma

  • citizenid çapraz başvuru tablosu oluşturun
  • Hesapları/parayı dönüştürün
  • Araç meta verilerini ve plakaları normalleştir
  • oxmysql await çağrılarına geçin

E) QA Testi

  • Olay güvenliği: türler/sınırlar/sahiplik/bekleme süreleri
  • Geri aramalar: Yük altında dönüş değerleri
  • Envanter meta verileri korundu
  • İş/görev/grup mantığı tasarımla eşleşiyor

F) Yayınlama ve Geri Alma

  • Sürüm etiketi; değişiklik günlüğü
  • 7-14 gün boyunca geçiş öncesi anlık görüntüyü sakla
  • Hataları/gecikmeyi izleyin; sıcak sorguları indexleyin

14) SSS (JSON-LD Şeması ile)

S: QBCore betiklerini tam bir yeniden yazma olmadan QBOX'ye taşıyabilir miyim?
A: Adaptörlerle ve ox_kütüphane geri çağırmalar (callbacks), çoğu betik yalnızca çağrı yeniden eşlemesi gerektirir.

S: Kara/kirli parayla ne yapmalıyım?
A: Adaptörünüzde standartlaştırın: ESX → black_money hesap; QB → öğe veya ek hesap; QBOX → öğe veya alternatif cüzdan (ör. kripto). Stratejiyi proje genelinde bir tane tutun.

S: QBOX'a geçtikten sonra geri çağırmalar neden takılı kalıyor?
A: ESX/QB callback'leri QBOX'da çalışmaz. Kullanın lib.callback.register/await.

S: mysql-async'i geçirmemin en iyi yolu nedir?
A: Bununla değiştirin oxmysql await API'leri; geri çağırma piramitlerini kaldırın.

S: qb-target'i ox_target'e nasıl dönüştürebilirim?
A: addBoxZone/Entity API çağrılarını birebir değiştirin; olay yükleri benzer kalır. Hedef adlarını sabit tutun.

{ “@context”: “https://schema.org”, “@type”: “FAQPage”, “mainEntity”: [ { “@type”: “Question”, “name”: “QBCore betiklerini tam bir yeniden yazma olmadan QBOX'ye aktarabilir miyim?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Adaptörler ve ox_lib geri aramaları ile çoğu betiğin yalnızca yeniden eşleme yapması gerekir.”} }, { “@type”: “Question”, “name”: “Kara/kirli parayla ne yapmalıyım?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Adaptörünüzde standartlaştırın: ESX → black_money hesabı; QB → öğe veya ek hesap; QBOX → öğe veya alternatif cüzdan (örneğin, kripto).”} }, { “@type”: “Question”, “name”: “QBOX'ye geçtikten sonra geri aramalar neden takılıyor?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “ESX/QB geri aramaları QBOX'de çalışmayacaktır. lib.callback.register/await kullanın.”} }, { “@type”: “Question”, “name”: “mysql-async'i geçirmek için en iyi yol nedir?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “oxmysql await APIs ile değiştirin; geri arama piramitlerini kaldırın.”} }, { “@type”: “Question”, “name”: “qb-target'yi ox_target'ye nasıl dönüştürürüm?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “addBoxZone/Entity API çağrılarını bire bir değiştirin; olay yükleri benzer kalır. Hedef adlarını sabit tutun.”} } ] }

15) Görseller (Öneriler)

  • Akış Şeması (Keşfet → Eşle → Uyarla → DB'yi Geçir → Test Et → Yayınla)
  • Adaptörler Diyagramı: Betik → Köprü → Çerçeve (ESX/QB/QBOX)
  • Rosetta Tablosu: yukarıda dahil edildi (indirmeler için CSV olarak dışa aktarın)
[Discover] → [Map APIs] → [Write Adapter] → [Migrate DB] → [Harden] → [QA] → [Release]

16) Yasal ve Etik

  • Lisanslara saygı gösterin (MIT/GPL/NC). Yapamaz escrow veya obfuscation'ı bypass etmeyin.
  • Yalnızca betikleri dönüştürün sahip olmak veya uyarlama izniniz olsun.

17) İndirilebilirler & Hızlı Başvuru

Şu dönüştürücüyü de kullanabilirsiniz (test edilmemiş olsa da):

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


28) Sonraki Adımlar

  • Bırak bridge.lua kaynağınıza ekleyin ve en yüksek değerli script'lerinizi dönüştürmeye başlayın.
  • Şu standarda geçin: ox_lib + ox_inventory + ox_target + oxmysql framework'ten bağımsız kalmak için.
  • Kontrol listelerini inceleme ve yayınlama sırasında kullanın.

Ayrıca oku SQL ve Tanımlayıcı Göçü: steam/lisans → citizenid ve Hesaplar → Para (ESX → QBCore/QBOX)