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.
Configuraciones compatibles
Sección titulada «Configuraciones compatibles»| 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.
Detección
Sección titulada «Detección»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: oxLa detección se hace una sola vez, cuando arranca sl-marketplace, así que tu framework tiene que arrancar antes en server.cfg:
ensure oxmysqlensure screenshot-basicensure qbx_core # o es_extended / qb-core, y tu inventarioensure sl-marketplaceSi en la consola sale No framework detected, el marketplace ha arrancado demasiado pronto. Corrige el orden o fija Config.Framework.
Inventarios
Sección titulada «Inventarios»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.
Vehículos
Sección titulada «Vehículos»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.
El puente de framework
Sección titulada «El puente de framework»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.luaCada 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.
Funciones de servidor
Sección titulada «Funciones de servidor»| 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 trueendFunciones de cliente
Sección titulada «Funciones de cliente»| 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 |
Eventos que escuchan los adaptadores
Sección titulada «Eventos que escuchan los adaptadores»| 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.
Callbacks
Sección titulada «Callbacks»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.
Adaptarlo a un framework modificado
Sección titulada «Adaptarlo a un framework modificado»- Busca el adaptador de tu framework en
bridge/server/ybridge/client/. - Cambia solo el cuerpo de las funciones que necesites: por ejemplo, otra cuenta de efectivo o un export con otro nombre.
- Mantén los nombres de las funciones y lo que devuelven: el resto del script depende de ellos.
- Reinicia el recurso y comprueba en la consola las líneas
Framework:eInventory backend:.
Guarda una copia de tus cambios: una actualización sustituye los archivos de bridge/ igual que el resto del recurso.