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ş
- Anlık görüntü ve hazırlama: DB/dosyalarını yedekleyin. Hedef framework ile yerel bir test sunucusu başlatın.
- Bağımlılıkları belirleyin: envanter, hedef, menü/UI, geri çağırmalar, DB katmanı, çekirdek erişim.
- Sürümleri ve sıralamayı sabitleyin: oxmysql → ox_lib → framework (es_extended / qb-core / qbx_core) → kaynaklarınız.
- Kod yolunu okuyun: Tüm oyuncu, para, iş/görev, envanter, geri çağırma/olay ve DB çağrılarını bulun.
- API'leri eşleyin: ESX ↔ QBCore ↔ QBOX'yi eşlemek için aşağıdaki Rosetta tablolarını kullanın.
- Köprüleyin: Bir ekleyin bridge.lua framework'ü otomatik algılayan ve çağrıları normalleştiren adaptör.
- Geri çağırmaları dönüştürün: ESX/QB geri çağırmaları → QBOX/ox_lib
lib.callback.*gerekli olduğunda. - DB'yi geçirin: Tanımlayıcıları, hesapları, öğeleri, araçları taşıyın; şuraya geçin: oxmysql
*.awaitstil. - Etkinlikleri sertleştirin: Doğrula
source, sınırlar, gruplar\/işler, sahiplik; asla istemciye güvenme. - 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ış
| Kategori | ESX | QBCore | QBOX |
|---|---|---|---|
| Mimari \/ Çekirdek Erişimi | exports['es_extended']:getSharedObject() → ESX | exports['qb-core']:GetCoreObject() → QBCore | Küresel bir çekirdek nesnesi yok; kullanın exports.qbx_core:* oyuncu, gruplar ve bildirimler için |
| Oyuncu Nesnesi | ESX.GetPlayerFromId(src) → xPlayer | QBCore.Functions.GetPlayer(src) → Player | exports.qbx_core:GetPlayer(src) → Player ile PlayerData |
| Tanımlayıcılar | Tarihsel olarak identifier (lisans/steam) | citizenid birincil anahtar olarak | citizenid birincil anahtar olarak |
| Para Yönetimi | xPlayer.addMoney() / `addAccountMoney(‘bank’ | ‘black_money’) | Player.Functions.AddMoney(‘cash’ |
| İşler ve Görev | xPlayer.job.name, .job.grade | Player.PlayerData.job.name, .grade.level, OnDuty | İş/grup yardımcıları aracılığıyla exports.qbx_core:* (grup kontrolleri, görev ayarlayıcıları) |
| Envanter | ESX varsayılan / ox_inventory / qb-inventory (önerilen: ox_inventory) | qb-inventory / ox_inventory | ox_inventory tavsiye edilen |
| Geri çağrımlar | ESX.RegisterServerCallback / ESX.TriggerServerCallback | QBCore.Functions.CreateCallback / TriggerCallback | Tercih 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) | oxmysql | oxmysql |
| UI – Bildirimler | ESX Bildirim | QB Notify | QBOX bildirim yardımcıları veya lib.notify |
| UI – Menüler | esx_menu_default / ox_lib:registerContext | qb-menu / ox_lib:registerContext | ox_lib:registerContext / lib.inputDialog |
| UI – Hedef Sistemi | esx_target / ox_target | qb-target / ox_target | ox_target tavsiye edilen |
QBOX'un farklı olduğu nokta
- Kaynak adı ve dışa aktarımları:
qbx_core(yokGetCoreObject). - 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.

2) Ön Kontrol: Ortam ve Araçlar
- Sunucu: mevcut FXSunucusu artifact, Lua 5.4, CFX
ensuresipariş - Sıra:
ensure oxmysql→ensure ox_lib→ensure framework→ensure 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.PlayerDataqbx_coreexports.ox_inventorymysql%-asyncMySQL.
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
| Kavram | ESX | QBCore | QBOX |
|---|---|---|---|
| Çekirdeği al | exports['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
| Kavram | ESX | QBCore | QBOX |
|---|---|---|---|
| Birincil | identifier (lisans/steam) | citizenid | citizenid |
| Crosswalk | masa id_map(identifier, citizenid) | Aynı | Aynı |
Para
| Aksiyon | ESX | QBCore | QBOX |
|---|---|---|---|
| Nakit ekle | xPlayer.addMoney(a) | Player.Functions.AddMoney('cash', a) | Player.PlayerData.money.cash += a (adaptör + kaydetme yoluyla) |
| Banka ekle | xPlayer.addAccountMoney('bank', a) | Player.Functions.AddMoney('bank', a) | Player.PlayerData.money.bank += a (bağdaştırıcı + kaydet) |
| Kirli ekle | xPlayer.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
| Kavram | ESX | QBCore | QBOX |
|---|---|---|---|
| İş oku | xPlayer.job.name, .grade | Player.PlayerData.job.name, .grade.level | Player.PlayerData.job.* + grup yardımcıları |
| Görevde | (değişir) | Player.PlayerData.job.onduty | SetJobDuty/group yardımcıları exports aracılığıyla |
| Grup kontrolü | (eklenti) | (eklenti) | exports.qbx_core:HasGroup(src, group) (örnek) |
Envanter
| Aksiyon | ESX | QBCore | QBOX |
|---|---|---|---|
| Öğe ekle | xPlayer.addInventoryItem(n, c) | Player.Functions.AddItem(n, c, ...) | tercih et ox_inventory bağdaştırıcı aracılığıyla export |
| öküz_envanteri | exports.ox_inventory:* | exports.ox_inventory:* | exports.ox_inventory:* |
Geri çağrımlar
| Kavram | ESX | QBCore | QBOX |
|---|---|---|---|
| Sunucu kaydı | ESX.RegisterServerCallback | QBCore.Functions.CreateCallback | lib.callback.register (ox_lib) |
| İstemci tetikleyicisi | ESX.TriggerServerCallback | QBCore.Functions.TriggerCallback | lib.callback.await |
DB Katmanı
| Kavram | ESX/QB (eski) | oxmysql (hedef) |
|---|---|---|
| Getir | MySQL.Async.fetchAll(sql, params, cb) | local rows = MySQL.query.await(sql, {p1, ...}) |
| Güncelleme | MySQL.Async.execute(sql, params, cb) | local aff = MySQL.update.await(sql, {p1, ...}) |
UI / Bildirim / Hedef
| Kavram | ESX | QBCore | QBOX |
|---|---|---|---|
| Bildir | ESX.ShowNotification(msg) | QBCore.Functions.Notify(msg, type) | exports.qbx_core:Notify(...) veya lib.notify({...}) |
| Menü | (değişir) | qb-menu | ox_lib:registerContext / girdiler |
| Hedef | (eklenti) | qb-target | ox_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-corebaş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.RegisterServerCallbackileQBCore.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.addAccountMoneyilePlayer.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
citizenidQB için ESX'tenusersseç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.*ileexports.qbx_core:*veya ox_kütüphane geri aramalar. - Oyuncu:
QBCore.Functions.GetPlayer(src)→exports.qbx_core:GetPlayer(src). - Bildirim:
QBCore.Functions.Notify→exports.qbx_core:Notifyveyalib.notify. - Görev/gruplar: QBOX dışa aktarımlarını kullanın (
SetJobDuty,HasGroup, vb.).
QBOX → QBCore
- Yer değiştirmek
exports.qbx_core:*ileQBCore.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,callbackssarmalayıcı. - Çalışma zamanında çerçeveyi algıla (
qbx_core→qb-core→es_extended→none). - 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
GlobalStateidareli kullanın; sıcak döngü güncellemelerinden kaçının.
9) Yaygın Tuzaklar ve Hata Ayıklama Kılavuzu
- Varsayarak
GetCoreObjectQBOX üzerinde mevcut → çalışmaz; kullanınexports.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ı →
oxmysql→ox_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_ignoreminimal; 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.luave 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.
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)
