El sistema de Objetos perdidos guarda en el panel los items que un jugador pierde al morir (o en cualquier evento que tú definas). El staff puede ver el historial en el perfil del jugador y devolver cada objeto al almacén de devoluciones de ox_inventory, sin necesidad de que el jugador esté conectado.
¿Qué necesitas?
Adictos_WebLogsinstalado y sincronizado con el panel (ver instalación)ox_inventorycon un stash de devoluciones por jugador (recomendado; el panel envía los items ahí)- Un script de muerte/respawn que quite items al jugador y llame al export (ej.
esx_ambulancejob,qb-ambulancejob, script propio…)
Flujo completo
Tu script (muerte / respawn)
│ Quitas items del inventario
│ Armas array items[]
▼
Adictos_WebLogs:RegisterLostItems()
│ HTTP POST → panel
▼
api/fivem/lost-items.php (registro en BD)
│
▼
Panel → Perfil jugador → Logs → Objetos perdidos
│ Staff pulsa "Devolver"
▼
Adictos_WebLogs /add-to-stash → ox_inventory (devoluciones)Integración mínima (cualquier script)
Cuando el jugador pierda objetos, recógelos en una tabla antes de borrarlos del inventario y llama al export. Solo necesitas tres datos del jugador y la lista de items:
local function registrarObjetosPerdidos(xPlayer, items)
if #items == 0 then return end
if GetResourceState('Adictos_WebLogs') ~= 'started' then return end
exports['Adictos_WebLogs']:RegisterLostItems({
license = xPlayer.identifier, -- hex, sin prefijo license:
player_name = xPlayer.getName(), -- nombre IC (ESX) o equivalente
player_ooc = GetPlayerName(xPlayer.source),
items = items,
})
endFormato de cada item en el array
| Campo | Tipo | Descripción |
|---|---|---|
name | string | Identificador del item en ox_inventory (ej. bread, weapon_pistol) |
label | string | Nombre visible (opcional; si falta, se usa name) |
count | number | Cantidad perdida |
metadata | table | Metadatos de ox_inventory: durabilidad, serial, componentes, etc. (opcional) |
local items = {
{
name = 'bread',
label = 'Pan',
count = 5,
metadata = {},
},
{
name = 'weapon_pistol',
label = 'Pistola',
count = 1,
metadata = { durability = 72.5, serial = 'ABC-123' },
},
}
registrarObjetosPerdidos(xPlayer, items)RegisterLostItems tiene un cooldown de 60 segundos por jugador para evitar registros duplicados si tu script dispara el evento dos veces seguidas (respawn + callback, etc.). Si la segunda llamada cae dentro de ese margen, se ignora silenciosamente.Ejemplo con ox_inventory (ESX)
Patrón habitual en ESX: leer el inventario con ox_inventory, excluir items protegidos, quitarlos del jugador y registrar lo perdido. Usa la licencia (xPlayer.identifier) como identificador del panel:
local ox_inventory = exports.ox_inventory
local SLOTS = GetConvarInt('inventory:slots', 50)
-- Items que NUNCA se pierden al morir (ajusta a tu servidor)
local EXCLUIDOS = {
llavecayo = true,
anillo = true,
chapa = true,
adicoins = true,
}
function PerderObjetosAlMorir(xPlayer)
local src = xPlayer.source
local playerItems = ox_inventory:GetInventoryItems(src)
if not playerItems then return end
local itemsParaWeb = {}
for i = 1, SLOTS do
local slot = playerItems[i]
if slot and slot.count > 0 and not EXCLUIDOS[slot.name] then
local meta = slot.metadata or {}
table.insert(itemsParaWeb, {
name = slot.name,
label = slot.label or slot.name,
count = slot.count,
metadata = meta,
})
xPlayer.setInventoryItem(slot.name, 0)
end
end
if #itemsParaWeb > 0 and GetResourceState('Adictos_WebLogs') == 'started' then
exports['Adictos_WebLogs']:Log('death', 'items_lost', {
license = xPlayer.identifier,
playerName = xPlayer.name,
playerOOC = GetPlayerName(src),
items = itemsParaWeb,
details = 'Objetos perdidos por muerte - Total: ' .. #itemsParaWeb .. ' items',
})
exports['Adictos_WebLogs']:RegisterLostItems({
license = xPlayer.identifier,
player_name = xPlayer.name,
player_ooc = GetPlayerName(src),
items = itemsParaWeb,
})
end
endLlama a PerderObjetosAlMorir(xPlayer) desde el evento de muerte o respawn. En esx_ambulancejob es la función BorrarObjetos, invocada al respawn y al callback removeItemsAfterRPDeath.
Ejemplo con ox_inventory (QBCore)
En QBCore el flujo es el mismo, pero obtienes al jugador con QBCore.Functions.GetPlayer(source) y quitas items con ox_inventory:RemoveItem (no uses setInventoryItem, que es de ESX). Importante: envía la licencia Rockstar (PlayerData.license sin prefijo license:), no el citizenid — el panel indexa jugadores por licencia.
local QBCore = exports['qb-core']:GetCoreObject()
local ox_inventory = exports.ox_inventory
local SLOTS = GetConvarInt('inventory:slots', 50)
local EXCLUIDOS = {
id_card = true,
driver_license = true,
-- añade los items protegidos de tu servidor
}
local function stripLicense(lic)
if not lic then return nil end
return lic:gsub('license:', '')
end
function PerderObjetosAlMorir(src)
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local pd = Player.PlayerData
local license = stripLicense(pd.license)
local charinfo = pd.charinfo or {}
local playerName = ((charinfo.firstname or '') .. ' ' .. (charinfo.lastname or '')):match('^%s*(.-)%s*$')
local playerOOC = GetPlayerName(src)
local playerItems = ox_inventory:GetInventoryItems(src)
if not playerItems then return end
local itemsParaWeb = {}
for i = 1, SLOTS do
local slot = playerItems[i]
if slot and slot.count > 0 and not EXCLUIDOS[slot.name] then
local meta = slot.metadata or {}
table.insert(itemsParaWeb, {
name = slot.name,
label = slot.label or slot.name,
count = slot.count,
metadata = meta,
})
ox_inventory:RemoveItem(src, slot.name, slot.count, meta, slot.slot)
end
end
if #itemsParaWeb > 0 and GetResourceState('Adictos_WebLogs') == 'started' then
exports['Adictos_WebLogs']:Log('death', 'items_lost', {
license = license,
playerName = playerName,
playerOOC = playerOOC,
items = itemsParaWeb,
details = 'Objetos perdidos por muerte - Total: ' .. #itemsParaWeb .. ' items',
})
exports['Adictos_WebLogs']:RegisterLostItems({
license = license,
player_name = playerName,
player_ooc = playerOOC,
items = itemsParaWeb,
})
end
endLlama a PerderObjetosAlMorir(source) desde tu script de hospital/muerte (por ejemplo qb-ambulancejob, qb-hospital o un recurso propio) en el momento en que el jugador pierde el inventario al respawnear.
license (hex) y el array items con name, count y metadata si aplica.Log opcional (categoría death)
Además de RegisterLostItems, puedes registrar un log con Log() en la categoría death y acción items_lost. Eso deja constancia en Logs → GENERAL y en el historial del jugador, independiente de la pestaña Objetos perdidos. El campo items del log acepta la misma tabla de objetos.
Qué hace el panel
- Guarda cada muerte como un registro con fecha, expiración (30 días) y lista de items
- Muestra metadatos (durabilidad, serial, componentes…) cuando existen
- Permite devolver un item o todos los pendientes de un registro
- Los items devueltos van al stash devoluciones del jugador en ox_inventory (no al inventario directo)
- Marca cada item como devuelto y registra qué staff lo hizo
Dónde lo ve el staff
- 1Panel → buscar jugador → abrir su perfil.
- 2Pestaña Logs → sub-pestaña Objetos perdidos.
- 3Requiere permiso Ver logs (
viewlogs).
Comprobar que funciona
- 1Muere con un personaje que lleve items (no excluidos) y respawnea.
- 2En consola del servidor (con
DebugModeen WebLogs): mensajeObjetos perdidos registrados: N items. - 3Panel → perfil del jugador → Logs → Objetos perdidos: debe aparecer el registro con los items.
- 4Pulsa Devolver en un item y comprueba que llega al stash de devoluciones en el juego.
Resolución de problemas
| Síntoma | Causa habitual |
|---|---|
| No aparece nada en el panel | Adictos_WebLogs no está iniciado, la IP del servidor no coincide en Mis servidores, o el array items estaba vacío |
| Solo aparece en Logs GENERAL, no en Objetos perdidos | Llamaste a Log() pero no a RegisterLostItems() |
| Registro duplicado o incompleto | Dos eventos de muerte en menos de 60 s; el segundo fue ignorado por cooldown |
| Error al devolver desde el panel | Servidor FiveM offline, ox_inventory no disponible, o stash de devoluciones mal configurado |
| Items sin metadatos al devolver | No enviaste metadata en el array al registrar la pérdida |
| QBCore: no aparece en el perfil del jugador | Enviaste citizenid en lugar de la licencia Rockstar (PlayerData.license sin prefijo) |