Parent : [[INDEX-FIVEM-FRAMEWORK]]
FiveM - Dual Framework Bridge Functions : ESX/QBCore wrapper unifié
Problème
Un script doit fonctionner avec ESX et QBCore mais les APIs diffèrent : xPlayer.getMoney() vs player.PlayerData.money.cash, ESX.GetPlayerFromId vs QBCore.Functions.GetPlayer.
Solution
Abstraction complète avec fonctions wrapper GetPlayer, GetPlayerIdentifier, GetPlayerName, GetPlayerCash/Bank, Add/Remove Money, centralisées dans un fichier bridge.
-- bridge.lua
local FrameworkName = nil
local Framework = nil
local function DetectFramework()
if GetResourceState('es_extended') == 'started' then
FrameworkName = 'esx'
Framework = exports['es_extended']:getSharedObject()
elseif GetResourceState('qb-core') == 'started' then
FrameworkName = 'qbcore'
Framework = exports['qb-core']:GetCoreObject()
end
end
-- Attendre le chargement du framework
CreateThread(function()
while FrameworkName == nil do
DetectFramework()
Wait(1000)
end
print('[^2INFO^7] Framework detected: ' .. FrameworkName)
end)
-- Player getters
function GetPlayer(source)
if FrameworkName == 'esx' then
return Framework.GetPlayerFromId(source)
elseif FrameworkName == 'qbcore' then
return Framework.Functions.GetPlayer(source)
end
end
function GetPlayerIdentifier(player)
if FrameworkName == 'esx' then
return player.getIdentifier()
elseif FrameworkName == 'qbcore' then
return player.PlayerData.citizenid
end
end
function GetPlayerName(player)
if FrameworkName == 'esx' then
return player.getName()
elseif FrameworkName == 'qbcore' then
return player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname
end
end
-- Money getters/setters
function GetPlayerCash(player)
if FrameworkName == 'esx' then
return player.getMoney()
elseif FrameworkName == 'qbcore' then
return player.PlayerData.money.cash
end
end
function GetPlayerBank(player)
if FrameworkName == 'esx' then
return player.getAccount('bank').money
elseif FrameworkName == 'qbcore' then
return player.PlayerData.money.bank
end
end
function AddPlayerMoney(player, amount, moneyType)
moneyType = moneyType or 'cash'
if FrameworkName == 'esx' then
if moneyType == 'cash' then
player.addMoney(amount)
else
player.addAccountMoney(moneyType, amount)
end
elseif FrameworkName == 'qbcore' then
player.Functions.AddMoney(moneyType, amount)
end
end
function RemovePlayerMoney(player, amount, moneyType)
moneyType = moneyType or 'cash'
if FrameworkName == 'esx' then
if moneyType == 'cash' then
player.removeMoney(amount)
else
player.removeAccountMoney(moneyType, amount)
end
elseif FrameworkName == 'qbcore' then
player.Functions.RemoveMoney(moneyType, amount)
end
end
-- Notification
function Notify(source, msg, type)
if FrameworkName == 'esx' then
TriggerClientEvent('esx:showNotification', source, msg)
elseif FrameworkName == 'qbcore' then
TriggerClientEvent('QBCore:Notify', source, msg, type or 'primary')
end
end
Pourquoi
- Un seul fichier bridge à modifier si l'API change
- Le reste du script utilise
GetPlayer,AddPlayerMoney→ framework-agnostic - Détection automatique au démarrage
Quant l'utiliser
- Scripts multi-framework (commercial, open-source)
- Scripts internes qui pourraient migrer de framework
Quand NE PAS l'utiliser
- Scripts ESX-only ou QB-only (overhead inutile)
Exemples
Correct
-- Usage dans le script métier
RegisterNetEvent('banking:transfer')
AddEventHandler('banking:transfer', function(targetId, amount)
local src = source
local sender = GetPlayer(src)
local receiver = GetPlayer(targetId)
if not sender or not receiver then return end
local senderBank = GetPlayerBank(sender)
if senderBank < amount then
Notify(src, 'Solde insuffisant', 'error')
return
end
RemovePlayerMoney(sender, amount, 'bank')
AddPlayerMoney(receiver, amount, 'bank')
Notify(src, ('Transféré $%s'):format(amount), 'success')
Notify(targetId, ('Reçu $%s'):format(amount), 'success')
end)
Incorrect
-- Hardcodé ESX → incompatible QBCore
RegisterNetEvent('banking:transfer')
AddEventHandler('banking:transfer', function(target, amount)
local xPlayer = ESX.GetPlayerFromId(source)
local xTarget = ESX.GetPlayerFromId(target)
if xPlayer.getAccount('bank').money >= amount then
xPlayer.removeAccountMoney('bank', amount)
xTarget.addAccountMoney('bank', amount)
end
end)
Références
- omes_banking/server.lua L1-80
- omes_banking/client.lua L1-80
- KNOW-PAT-084 (Framework Bridge Auto-Detect)