Ir al contenido

Frameworks

SL-Marketplace funciona en ESX Legacy, QBCore y Qbox con los mismos archivos. Al arrancar detecta qué framework usa tu servidor y a partir de ahí habla con él usando sus propias funciones y eventos. No necesitas una descarga distinta para cada framework.

Framework Recurso ID del jugador Efectivo Inventarios Vehículos en propiedad
ESX Legacy es_extended identifier cuenta money ox_inventory o inventario nativo de ESX owned_vehicles
QBCore qb-core citizenid cash ox_inventory o qb-inventory player_vehicles
Qbox qbx_core citizenid cash ox_inventory (Qbox lo exige) player_vehicles

oxmysql y screenshot-basic son obligatorios en los tres.

Config.Framework = 'auto' -- 'auto', 'esx', 'qb' o 'qbx'

Con 'auto', el recurso busca un qbx_core arrancado, luego qb-core y luego es_extended, y usa el primero que encuentra. Qbox se mira primero porque trae una capa de compatibilidad que también responde como qb-core.

El resultado aparece en la consola al arrancar:

[sl-marketplace] Framework: qbx
[marketplace] Inventory backend: ox

La detección se hace una sola vez, cuando arranca sl-marketplace, así que tu framework tiene que arrancar antes en server.cfg:

server.cfg
ensure oxmysql
ensure screenshot-basic
ensure qbx_core # o es_extended / qb-core, y tu inventario
ensure sl-marketplace

Si en la consola sale No framework detected, el marketplace ha arrancado demasiado pronto. Corrige el orden o fija Config.Framework.

Config.InventoryBackend = 'auto' -- 'auto', 'ox_inventory', 'esx' o 'qb-inventory'

Con 'auto', se usa ox_inventory siempre que esté arrancado, en cualquier framework. Si no, se usa el inventario del propio framework: el nativo de ESX en ESX y qb-inventory en QBCore. Qbox necesita siempre ox_inventory.

ox_inventory y qb-inventory funcionan por slots: cuando un vendedor anuncia un objeto, el marketplace retira exactamente el slot que eligió y conserva su metadata (número de serie del arma, munición, durabilidad…). El comprador recibe ese mismo objeto con esa misma metadata. Con el inventario nativo de ESX, las armas salen del loadout del jugador, con su munición y sus accesorios.

Los iconos de los objetos se cogen automáticamente de ox_inventory o qb-inventory; mira Config.ItemIcons.

Los jugadores pueden anunciar los vehículos que tienen en propiedad. Mientras un vehículo está anunciado lo custodia el marketplace: desaparece del garaje del vendedor y pasa al comprador cuando se vende. Si el vendedor cancela el anuncio, vuelve directamente a él; si el anuncio caduca, le espera en su buzón.

Framework Mientras está anunciado Al entregarse
ESX owned_vehicles.owner pasa a ser marketplace owner pasa a ser el identificador del nuevo dueño
QBCore / Qbox player_vehicles.citizenid y license se quedan vacíos citizenid y license pasan a ser los del nuevo dueño

En QBCore y Qbox no se puede poner marketplace como dueño, porque player_vehicles.citizenid tiene una clave foránea hacia players. En su lugar, el marketplace guarda en su propio anuncio quién es el vendedor.

Todo lo que depende del framework está en bridge/. El resto del script nunca llama directamente a ESX, QBCore o Qbox: llama a Framework.*, y el adaptador del framework detectado lo traduce.

bridge/
framework.lua detección (Config.Framework)
callback/server.lua callbacks cliente → servidor
callback/client.lua
server/esx.lua adaptador de servidor de cada framework
server/qb.lua
server/qbx.lua
client/esx.lua adaptador de cliente de cada framework
client/qb.lua
client/qbx.lua

Cada adaptador empieza con una comprobación como if Framework.Name ~= 'qb' then return end, así que solo se ejecuta el de tu framework. Los adaptadores van sin cifrar: puedes editarlos si tu framework está modificado.

Función Devuelve
Framework.Name 'esx', 'qb' o 'qbx'
Framework.GetPlayer(source) { source, identifier, job = { name, grade } } o nil
Framework.GetIdentifier(source) El identificador del jugador (identifier o citizenid)
Framework.GetSourceByIdentifier(identifier) El ID de servidor del jugador si está conectado, o nil
Framework.GetMoney(source) El efectivo que lleva encima
Framework.RemoveMoney(source, amount) true si tenía suficiente y se le ha quitado
Framework.AddMoney(source, amount) true si se le ha añadido
Framework.Notify(source, message, type) Muestra una notificación del framework ('info', 'success', 'error', 'warning')
Framework.OnPlayerLoaded(cb) Llama a cb(source) cuando un personaje termina de cargar
Framework.GetOwnedVehicles(identifier) Lista de { plate, model, data }
Framework.OwnsVehicle(identifier, plate) true o false
Framework.SetVehicleOwner(plate, from, to) Pasa un vehículo de un dueño a otro; 'marketplace' significa custodiado por el marketplace
Framework.GetItemNames() Nombres de los objetos del catálogo del framework, para las categorías automáticas

Framework.GetPlayer devuelve lo mismo en todos los frameworks, así que tu propio código en server/handlers.lua puede usarlo sin preocuparse de qué framework hay:

Handlers.CanCreateListing = function(data)
if data.category == 'weapons' then
local player = Framework.GetPlayer(data.actorSource)
if not player or player.job.name ~= 'police' then
return false, 'Solo la policía puede vender armas aquí'
end
end
return true
end
Función Qué hace
Framework.Notify(message, type) Muestra una notificación del framework
Framework.IsPlayerLoaded() true cuando el personaje ya ha cargado
Framework.OnPlayerLoaded(cb) Llama a cb() cuando carga el personaje
Framework.OnPlayerUnloaded(cb) Llama a cb() al cerrar sesión o cambiar de personaje
Framework Personaje cargado Cierre de sesión
ESX esx:playerLoaded esx:onPlayerLogout
QBCore / Qbox QBCore:Server:PlayerLoaded, QBCore:Client:OnPlayerLoaded QBCore:Client:OnPlayerUnload

Si tu multicharacter lanza otros eventos, cámbialos en el adaptador.

Las peticiones cliente → servidor usan el sistema de callbacks propio del marketplace (Callback.Register en el servidor, Callback.Trigger en el cliente), no el del framework. Funciona igual en los tres frameworks y no necesita dependencias extra como ox_lib.

  1. Busca el adaptador de tu framework en bridge/server/ y bridge/client/.
  2. Cambia solo el cuerpo de las funciones que necesites: por ejemplo, otra cuenta de efectivo o un export con otro nombre.
  3. Mantén los nombres de las funciones y lo que devuelven: el resto del script depende de ellos.
  4. Reinicia el recurso y comprueba en la consola las líneas Framework: e Inventory backend:.

Guarda una copia de tus cambios: una actualización sustituye los archivos de bridge/ igual que el resto del recurso.