> For the complete documentation index, see [llms.txt](https://rowdevelopment.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rowdevelopment.gitbook.io/docs/script-guides/row-inventory/qbox-install.md).

# QBox Install

### Setup

1. **First, go to** <mark style="color:red;"><https://keymaster.fivem.net/></mark> **and download the purchased files.**
2. **We use this interact system in the inventory system. If you use our version, options like changing colors will work automatically, but you can also use the** [<mark style="color:red;">**project creator's version**</mark>](https://github.com/darktrovx/interact) **if you wish.**
3. **Upload the&#x20;**<mark style="color:red;">**"row-textUI"**</mark>**&#x20;file you downloaded from keymaster with the inventory and&#x20;**<mark style="color:red;">**other inventory files**</mark>**&#x20;to your server files.**
4. **Find the sql file in the&#x20;**<mark style="color:red;">**"row\_inventory"**</mark>**&#x20;file we gave you and read it.**
5. **You can change the language of the file in&#x20;**<mark style="color:red;">**row\_inventory/fxmanifest.lua**</mark>**.**
6. **Replace all&#x20;**<mark style="color:red;">**ox\_Inventory**</mark>**&#x20;exports in your package with&#x20;**<mark style="color:red;">**row\_inventory**</mark>**.**
7. **Replace all&#x20;**<mark style="color:red;">**ox\_inventory:currentWeapon**</mark>**&#x20;events with&#x20;**<mark style="color:red;">**qb-weapons:client:SetCurrentWeapon**</mark>**.**
8. **Replace all&#x20;**<mark style="color:red;">**@ox\_inventory.data.items**</mark>**&#x20;requires with&#x20;**<mark style="color:red;">**@row\_inventory.data.items.**</mark>

### Remove dependency of <mark style="color:red;">ox\_inventory</mark> from qbx\_core/server/main.lua ⇒ line 5

### Replace the function qbx\_core/server/player.lua ⇒ <mark style="color:red;">giveStarterItems</mark> with the following

```lua
local function giveStarterItems(source)
    for i = 1, #starterItems do
        local item = starterItems[i]
        if item.metadata and type(item.metadata) == 'function' then
            exports.row_inventory:AddItem(source, item.name, item.amount, item.metadata(source))
        else
            exports.row_inventory:AddItem(source, item.name, item.amount, item.metadata)
        end
    end
end
```

### Replace the function qbx\_core/server/player.lua ⇒ <mark style="color:red;">self.Functions.GetItemByName</mark> with the following

```lua
function self.Functions.GetItemByName(itemName)
        assert(not self.Offline, 'unsupported for offline players')
        return qbItemCompat(exports.row_inventory:GetItemByName(self.PlayerData.source, oxItemCompat(itemName)))
    end
```

### Replace the function qbx\_core/server/player.lua ⇒ <mark style="color:red;">self.Functions.GetItemsByName</mark> with the following

```lua
   function self.Functions.GetItemsByName(itemName)
        assert(not self.Offline, 'unsupported for offline players')
        return qbItemCompat(exports.row_inventory:GetItemsByName(self.PlayerData.source, oxItemCompat(itemName)))
    end
```

### Replace the function qbx\_core/server/player.lua ⇒  <mark style="color:red;">Save</mark> with the following

```lua
function Save(source)
    local ped = GetPlayerPed(source)
    local playerData = QBX.Players[source].PlayerData
    local playerState = Player(source)?.state
    local pcoords = playerData.position
    if not playerState.inApartment and not playerState.inProperty then
        local coords = GetEntityCoords(ped)
        pcoords = vec4(coords.x, coords.y, coords.z, GetEntityHeading(ped))
    end
    if not playerData then
        lib.print.error('QBX.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
        return
    end

    playerData.metadata.health = GetEntityHealth(ped)
    playerData.metadata.armor = GetPedArmour(ped)

    if playerState.isLoggedIn then
        playerData.metadata.hunger = playerState.hunger or 0
        playerData.metadata.thirst = playerState.thirst or 0
        playerData.metadata.stress = playerState.stress or 0
    end

    CreateThread(function()
        storage.upsertPlayerEntity({
            playerEntity = playerData,
            position = pcoords,
        })
    end)
    if GetResourceState('row_inventory') ~= 'missing' then exports['row_inventory']:SaveInventory(source) end
    assert(GetResourceState('qb-inventory') ~= 'started', 'qb-inventory is not compatible with qbx_core. use ox_inventory instead')
    lib.print.verbose(('%s PLAYER SAVED!'):format(playerData.name))
end
```

### Replace the  qbx\_core/server/player.lua ⇒ <mark style="color:red;">SaveOffline</mark> function with the following

```lua
function SaveOffline(playerData)
    if not playerData then
        lib.print.error('SaveOffline - PLAYERDATA IS EMPTY!')
        return
    end

    CreateThread(function()
        storage.upsertPlayerEntity({
            playerEntity = playerData,
            position = playerData.position.xyz
        })
    end)
    if GetResourceState('row_inventory') ~= 'missing' then exports['row_inventory']:SaveInventory(source) end
    assert(GetResourceState('qb-inventory') ~= 'started', 'qb-inventory is not compatible with qbx_core. use ox_inventory instead')
    lib.print.verbose(('%s OFFLINE PLAYER SAVED!'):format(playerData.name))
end


```

### Replace the local function qbx\_core/server/player.lua ⇒ <mark style="color:red;">emitMoneyEvents</mark> with the following

```lua
local function emitMoneyEvents(source, playerMoney, moneyType, amount, actionType, reason, difference)
    local isSet = actionType == 'set'
    local isRemove = actionType == 'remove'

    TriggerClientEvent('hud:client:OnMoneyChange', source, moneyType, isSet and math.abs(difference) or amount, isSet and difference < 0 or isRemove, reason)
    TriggerClientEvent('QBCore:Client:OnMoneyChange', source, moneyType, amount, actionType, reason)
    TriggerEvent('QBCore:Server:OnMoneyChange', source, moneyType, amount, actionType, reason)

    if moneyType == 'bank' and isRemove then
        TriggerClientEvent('qb-phone:client:RemoveBankMoney', source, amount)
    end

    local oxMoneyType = moneyType == 'cash' and 'money' or moneyType

    if accountsAsItems[oxMoneyType] then
        if actionType == "add" then
            exports.row_inventory:AddItem(source, oxMoneyType, amount, false, {}, reason or "emitMoneyAdd")
        elseif actionType == "remove" then
            exports.row_inventory:RemoveItem(source, oxMoneyType, amount, nil, reason or "emitMoneyRemove", true)
        elseif actionType == "set" then
            if difference and difference > 0 then
                exports.row_inventory:AddItem(source, oxMoneyType, difference, false, {}, reason or "emitMoneySet")
            elseif difference and difference < 0 then
                exports.row_inventory:RemoveItem(source, oxMoneyType, math.abs(difference), nil, reason or "emitMoneySet", true)
            end
        end
    end
end
```

### Replace the local function qbx\_core/server/player.lua ⇒ <mark style="color:red;">self.Functions.SetMoney</mark> with the following

```lua
function self.Functions.SetMoney(moneytype, amount, reason, isset)
        return SetMoney(self.PlayerData.source, moneytype, amount, reason,isset)
 end
```

### Replace the local function qbx\_core/server/player.lua ⇒ <mark style="color:red;">SetMoney</mark> with the following

```lua
function SetMoney(identifier, moneyType, amount, reason, isset)
    local player = type(identifier) == 'string' and (GetPlayerByCitizenId(identifier) or GetOfflinePlayer(identifier)) or GetPlayer(identifier)

    if not player then return false end

    reason = reason or 'unknown'
    amount = qbx.math.round(tonumber(amount) --[[@as number]])
    local oldAmount = player.PlayerData.money[moneyType]

    if amount < 0 or not oldAmount then return false end

    if not triggerEventHooks('setMoney', {
        source = player.PlayerData.source,
        moneyType = moneyType,
        amount = amount
    }) then return false end

    player.PlayerData.money[moneyType] = amount

    if player.Offline then
        SaveOffline(player.PlayerData)
    else
        UpdatePlayerData(identifier)

        local difference = amount - oldAmount
        local dirChange = difference < 0 and 'removed' or 'added'
        local absDifference = math.abs(difference)
        local tags = absDifference > 50000 and config.logging.role or {}
        local resource = GetInvokingResource() or cache.resource

        logger.log({
            source = resource,
            webhook = config.logging.webhook['playermoney'],
            event = 'SetMoney',
            color = difference < 0 and 'red' or 'green',
            tags = tags,
            message = ('**%s (citizenid: %s | id: %s)** $%s (%s) %s, new %s balance: $%s reason: %s'):format(GetPlayerName(player.PlayerData.source), player.PlayerData.citizenid, player.PlayerData.source, absDifference, moneyType, dirChange, moneyType, player.PlayerData.money[moneyType], reason),
        })
        if not isset then 
        emitMoneyEvents(player.PlayerData.source, player.PlayerData.money, moneyType, amount, 'set', reason, difference)
        end
    end

    return true
end
```

### Replace the qbx\_core/server/player.lua ⇒ function <mark style="color:red;">CheckPlayerData</mark> ⇒ <mark style="color:red;">playerData.items = {}</mark> <mark style="color:$info;">with the fallowing</mark>

```lua
   if GetResourceState('row_inventory') ~= 'missing' then
        playerData.items = exports['row_inventory']:LoadInventory(playerData.source, playerData.citizenid)
    else 
        playerData.items = {}
    end
```

10. **And finally edit the&#x20;**<mark style="color:red;">**server.cfg**</mark>**&#x20;initialization section like this.**

```lua
ensure interact
ensure row-textUI
ensure row_inventory
```
