Documentación / Objetos perdidos

Objetos perdidos

Registra items perdidos por muerte desde FiveM y devuélvelos al jugador desde el panel web.

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_WebLogs instalado y sincronizado con el panel (ver instalación)
  • ox_inventory con 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,
    })
end

Formato de cada item en el array

CampoTipoDescripción
namestringIdentificador del item en ox_inventory (ej. bread, weapon_pistol)
labelstringNombre visible (opcional; si falta, se usa name)
countnumberCantidad perdida
metadatatableMetadatos 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
end

Llama 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
end

Llama 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.

QBCore + qb-inventory (sin ox_inventory): el patrón de registro es idéntico — solo cambia cómo lees y quitas items. Sigue enviando 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

  1. 1Panel → buscar jugador → abrir su perfil.
  2. 2Pestaña Logs → sub-pestaña Objetos perdidos.
  3. 3Requiere permiso Ver logs (viewlogs).
Los registros caducan a los 30 días. Un cron del panel limpia los expirados automáticamente. Los ya devueltos pueden eliminarse antes según la política de retención del servidor.

Comprobar que funciona

  1. 1Muere con un personaje que lleve items (no excluidos) y respawnea.
  2. 2En consola del servidor (con DebugMode en WebLogs): mensaje Objetos perdidos registrados: N items.
  3. 3Panel → perfil del jugador → Logs → Objetos perdidos: debe aparecer el registro con los items.
  4. 4Pulsa Devolver en un item y comprueba que llega al stash de devoluciones en el juego.

Resolución de problemas

SíntomaCausa habitual
No aparece nada en el panelAdictos_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 perdidosLlamaste a Log() pero no a RegisterLostItems()
Registro duplicado o incompletoDos eventos de muerte en menos de 60 s; el segundo fue ignorado por cooldown
Error al devolver desde el panelServidor FiveM offline, ox_inventory no disponible, o stash de devoluciones mal configurado
Items sin metadatos al devolverNo enviaste metadata en el array al registrar la pérdida
QBCore: no aparece en el perfil del jugadorEnviaste citizenid en lugar de la licencia Rockstar (PlayerData.license sin prefijo)
No hace falta configurar nada extra en el panel para activar el sistema: las tablas se crean solas la primera vez que FiveM llama a la API. Solo necesitas el export en tu script de muerte.