> 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
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://rowdevelopment.gitbook.io/docs/script-guides/row-inventory/qbox-install.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
