Inicio › Documentación › Instalación · origen_inventory

Instalación · origen_inventory

Sigue los pasos siguientes para instalar origen_inventory en tu servidor.


1. Añade el recurso a tu servidor

Copia la carpeta origen_inventory en tu directorio de recursos y añádela a tu server.cfg.

El orden de ensure es importante: todas las dependencias deben estar en marcha antes de origen_inventory.

cfg
# server.cfg
 
ensure oxmysql
ensure ox_lib
ensure qb-core            # or es_extended / qbx_core
 
# Optional integrations
ensure qs-smartphone-pro  # or lb-phone
ensure origen_clothing    # only if you use Clothes-As-Item
 
ensure origen_inventory

No arranques nunca origen_inventory antes que oxmysql y el núcleo de tu framework. Sin ellos, el driver de base de datos y la capa de bridge no se inicializarán y los inventarios no cargarán.


2. Sustituye tu inventario anterior

Si migras desde otro recurso de inventario, debes eliminarlo (o desactivarlo) antes de arrancar origen_inventory. Solo puede haber un proveedor de inventario activo a la vez.

Si otros scripts tuyos dependen de los exports de qb-inventory o ox_inventory, abre fxmanifest.lua y descomenta la línea provide correspondiente para que esas llamadas a exports se resuelvan en origen_inventory:

lua
-- Uncomment if you have old scripts that use qb-inventory
-- provide 'qb-inventory'
 
-- Uncomment if you have qbx_core installed
-- provide 'ox_inventory'

3. Importa el esquema SQL

Importa el fichero origen_inventory.sql en tu base de datos. Crea las cuatro tablas que necesita el recurso: gloveboxitems, stashitems, trunkitems, origen_customitems y origen_inventory_equipped_clothes.

sql
CREATE TABLE IF NOT EXISTS `gloveboxitems` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `plate` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
    `items` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
    `label` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    `slots` INT(11) NULL DEFAULT NULL,
    `personal` VARCHAR(255) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    `weight` INT(11) NULL DEFAULT NULL,
    `job` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    PRIMARY KEY (`plate`) USING BTREE,
    INDEX `id` (`id`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=152;
 
CREATE TABLE IF NOT EXISTS `stashitems` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `stash` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
    `items` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
    `label` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    `slots` INT(11) NULL DEFAULT NULL,
    `job` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    `personal` VARCHAR(255) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    `weight` INT(11) NULL DEFAULT NULL,
    PRIMARY KEY (`stash`) USING BTREE,
    INDEX `id` (`id`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
 
CREATE TABLE IF NOT EXISTS `trunkitems` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `plate` VARCHAR(255) NOT NULL COLLATE 'latin1_swedish_ci',
    `items` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
    `label` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    `personal` VARCHAR(255) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    `weight` INT(11) NULL DEFAULT NULL,
    `slots` INT(11) NULL DEFAULT NULL,
    `job` VARCHAR(100) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
    PRIMARY KEY (`plate`) USING BTREE,
    INDEX `id` (`id`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
 
DROP TABLE IF EXISTS `origen_customitems`;
CREATE TABLE `origen_customitems` (
    `name` VARCHAR(100) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `label` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `weight` INT(11) NOT NULL DEFAULT '0',
    `type` VARCHAR(50) NOT NULL DEFAULT 'item' COLLATE 'utf8mb4_unicode_ci',
    `image` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `unique` TINYINT(1) NOT NULL DEFAULT '0',
    `rarity` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
    `stack` TINYINT(1) NOT NULL DEFAULT '0',
    `close` TINYINT(1) NOT NULL DEFAULT '1',
    `server` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
    `client` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
    `decay` INT(11) NULL DEFAULT NULL,
    `buttons` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
    PRIMARY KEY (`name`) USING BTREE,
    CONSTRAINT `server` CHECK (json_valid(`server`)),
    CONSTRAINT `client` CHECK (json_valid(`client`)),
    CONSTRAINT `buttons` CHECK (json_valid(`buttons`))
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;
 
CREATE TABLE IF NOT EXISTS `origen_inventory_equipped_clothes` (
    `identifier` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `data` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
    `last_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`identifier`) USING BTREE,
    CONSTRAINT `data_json` CHECK (json_valid(`data`))
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;

El fichero de importación elimina y vuelve a crear origen_customitems. Si ya tienes objetos personalizados registrados, haz una copia de seguridad antes de volver a ejecutar el SQL.


4. Objetos

origen_inventory incluye su propio diccionario de objetos (config/items.lua y config/weapons.lua). Al sustituir tu inventario anterior:


5. Configuración del bridge de ESX

Este paso solo es necesario si usas ESX (es_extended). Los usuarios de QBCore y QBX pueden saltar al paso 6.

origen_inventory incluye dos ficheros de override que deben colocarse dentro de es_extended para que el framework delegue todas las llamadas de inventario en origen_inventory en lugar de en su inventario integrado.

Dónde colocar los ficheros

Copia ambos ficheros de la carpeta bridge/esx/overrides/ de origen_inventory en tu recurso es_extended:

Fichero de origen (dentro de origen_inventory) Destino (dentro de es_extended)
bridge/esx/overrides/origeninventory.lua es_extended/overrides/origeninventory.lua
bridge/esx/overrides/origeninventory_player.lua es_extended/overrides/origeninventory_player.lua

Después, asegúrate de que ambos ficheros están declarados en es_extended/fxmanifest.lua dentro de server_scripts:

lua
-- es_extended/fxmanifest.lua
server_scripts {
  -- ... existing entries ...
  'overrides/origeninventory.lua',
  'overrides/origeninventory_player.lua',
}

Qué hace cada fichero

origeninventory.lua — sobrescribe las funciones de objetos y de objetos utilizables de ESX para que las llamadas a ESX.GetItemLabel, ESX.RegisterUsableItem y ESX.UseItem se dirijan a origen_inventory en lugar del diccionario de ESX por defecto. También gestiona el dinero inicial de las cuentas y los objetos iniciales del inventario de los personajes nuevos.

lua
if Config.CustomInventory ~= "origen_inventory" then return end
 
MySQL.ready(function()
    TriggerEvent("__cfx_export_origen_inventory_Items", function(ref)
        if ref then
            ESX.Items = exports.origen_inventory:Items()
        end
    end)
end)
 
---@diagnostic disable-next-line: duplicate-set-field
ESX.GetItemLabel = function(itemName)
    local item = exports.origen_inventory:Items(itemName)
    if item then
        return item.label
    end
 
    print(('[^3WARNING^7] Attemting to get invalid Item -> ^5%s^7'):format(itemName))
end
 
---@diagnostic disable-next-line: duplicate-set-field
function ESX.RegisterUsableItem(item, cb)
    Core.UsableItemsCallbacks[item] = cb
    exports.origen_inventory:CreateUseableItem(item, cb)
end
 
---@diagnostic disable-next-line: duplicate-set-field
function ESX.UseItem(source, item, ...)
    local src, itm = source, item
    if type(src) == 'string' then item = src source = itm end
 
    if ESX.Items[item] then
        return exports['origen_inventory']:UseItem(item, source, ...)
    else
        print(('[^3WARNING^7] Item ^5"%s"^7 was used but does not exist!'):format(item))
    end
end
 
exports("GetUseablesItems", function()
    return Core.UsableItemsCallbacks
end)
 
function setPlayerInventory(playerId, xPlayer, inventory, isNew)
    if isNew then
        local shared = json.decode(GetConvar("inventory:accounts", '"money"'))
 
        for i = 1, #shared do
            local name = shared[i]
            local account = Config.StartingAccountMoney[name]
            if account then
                exports.origen_inventory:AddItem(playerId, name, account)
            end
        end
 
        if Config.StartingInventoryItems and type(Config.StartingInventoryItems) == "table" then
            for item, count in pairs(Config.StartingInventoryItems) do
                exports.origen_inventory:AddItem(playerId, item, count)
            end
        end
    end
end

origeninventory_player.lua — inyecta Core.PlayerFunctionOverrides.OrigenInventory, que sustituye los métodos de inventario del jugador por defecto (getInventory, addInventoryItem, removeInventoryItem, hasItem, addWeapon, canCarryItem, etc.) por sus equivalentes de origen_inventory. Así se garantiza que cualquier llamada interna de ESX que toque el inventario del jugador pase por origen_inventory.

lua
------ Dont touch this file unless you know what you are doing
------ This file is used to override the inventory functions
---
---
---- Origen_File_Version - 4
---
---
if Config.CustomInventory ~= "origen_inventory" then return end
 
Core.PlayerFunctionOverrides.OrigenInventory = {
  getInventory = function(self)
    return function(minimal)
      local inventory = exports.origen_inventory:GetPlayerInventory(self.source)
      return inventory
    end
  end,
 
  getLoadout = function(self)
    return function()
      return {}
    end
  end,
 
  getInventoryItem = function(self)
    return function(name, metadata)
      local item = exports.origen_inventory:getItem(self.source, name)
      if not item then
        return {
          count = 0,
        }
      end
      return item
    end
  end,
 
  addInventoryItem = function(self)
    return function(name, count, metadata, slot)
      return exports.origen_inventory:AddItem(self.source, name, count or 1, metadata, slot, true)
    end
  end,
 
  removeInventoryItem = function(self)
    return function(name, count, metadata, slot)
      return exports.origen_inventory:RemoveItem(self.source, name, count or 1, metadata, slot, false)
    end
  end,
 
  setInventoryItem = function(self)
    return function(name, count, metadata)
      return exports.origen_inventory:SetInventoryItems(self.source, name, count, metadata)
    end
  end,
 
  save = function(self)
    return function(inventory)
      Core.SavePlayer(self)
    end
  end,
 
  canCarryItem = function(self)
    return function(name, count, metadata)
      return exports['origen_inventory']:CanCarryItem(self.source, name, count)
    end
  end,
 
  canSwapItem = function(self)
    return function(firstItem, firstItemCount, testItem, testItemCount)
      return true
    end
  end,
 
  setMaxWeight = function(self)
    return function() end
  end,
 
  addWeapon = function(self)
    ---@param weaponName item weapon
    ---@param ammo amount
    return function(weaponName, ammo)
      return exports['origen_inventory']:GiveWeaponToPlayer(self.source, weaponName, ammo)
    end
  end,
 
  addWeaponComponent = function(self)
    return function() end
  end,
 
  addWeaponAmmo = function(self)
    return function() end
  end,
 
  updateWeaponAmmo = function(self)
    return function() end
  end,
 
  setWeaponTint = function(self)
    return function() end
  end,
 
  getWeaponTint = function(self)
    return function() end
  end,
 
  removeWeapon = function(self)
    return function() end
  end,
 
  removeWeaponComponent = function(self)
    return function() end
  end,
 
  removeWeaponAmmo = function(self)
    return function() end
  end,
 
  hasWeaponComponent = function(self)
    return function()
      return false
    end
  end,
 
  hasWeapon = function(self)
    return function()
      return false
    end
  end,
 
  hasItem = function(self)
    return function(name, metadata)
      return exports.origen_inventory:getItem(self.source, name, metadata)
    end
  end,
 
  getWeapon = function(self)
    return function() end
  end,
}

Ambos ficheros se protegen con if Config.CustomInventory ~= "origen_inventory" then return end, así que es seguro dejarlos en su sitio si algún día cambias de inventario: simplemente no harán nada.


6. Configura el recurso

Abre config.lua, config_sv.lua y los ficheros de la carpeta config/ y ajústalos a tu servidor. Consulta la página de Configuración para ver la lista completa de opciones.

Lo mínimo que debes revisar antes de salir en producción:


7. Verifica la instalación

Tras arrancar el servidor, entra con un jugador y comprueba que: