fix(qb-core): add global CreateUsableItem alias for qs-inventory compatibility

qs-inventory apelează CreateUsableItem ca funcție globală, dar qb-core definea doar QBCore.Functions.CreateUseableItem (cu 'e'). Adăugat alias global + fix 16 stringuri sparte în items.lua care blocau parsarea.
This commit is contained in:
2026-04-02 00:08:19 +03:00
parent 096ccb6399
commit 978c9bc759
827 changed files with 3570 additions and 1015 deletions

View File

@@ -0,0 +1,195 @@
if Config.Framework ~= 'esx' then
return
end
ESX = exports['es_extended']:getSharedObject()
userTable = 'users'
Identifier = 'identifier'
VehicleTable = 'owned_vehicles'
es_extended = 'es_extended'
WeaponList = WeaponList
ItemList = FormatItems(ItemList)
StarterItems = {
['id_card'] = 1,
['water_bottle'] = 5,
['tosti'] = 5,
['phone'] = 1,
}
RegisterNetEvent('esx:playerLoaded', function(id, player)
local inventory = LoadInventory(id, player.identifier)
Inventories[id] = inventory
local player = GetPlayerFromId(id)
local money = GetItemTotalAmount(id, 'money')
local black_money = GetItemTotalAmount(id, 'black_money')
player.setAccountMoney('money', money, 'dropped')
player.setAccountMoney('black_money', black_money, 'dropped')
InitDrops(id)
InitPlacedItems(id)
end)
function RegisterServerCallback(name, cb)
ESX.RegisterServerCallback(name, cb)
end
function GetPlayerFromId(source)
return ESX.GetPlayerFromId(source)
end
function GetPlayerSourceFromIdentifier(identifier)
local player = ESX.GetPlayerFromIdentifier(identifier)
if not player then
return nil
end
return ESX.GetPlayerFromIdentifier(identifier).source
end
function GetPlayerFromIdentifier(identifier)
return ESX.GetPlayerFromIdentifier(identifier)
end
function PlayerIsAdmin(source)
if source == 0 then
return true
end
local player = GetPlayerFromId(source)
return player.getGroup() == 'admin' or player.getGroup() == 'superadmin'
end
function FrameworkGetPlayers()
return ESX.GetPlayers()
end
function GetPlayerIdentifier(source)
local player = GetPlayerFromId(source)
if not player then return Wait(100) end
return player.identifier
end
function GetJobName(source)
local player = GetPlayerFromId(source)
if not player then
Debug('Player not found', source)
return 'unemployed'
end
return player?.getJob().name
end
function GetJobGrade(source)
local player = GetPlayerFromId(source)
if not player then
Debug('Player not found', source)
return 0
end
return player.getJob().grade
end
function GetAccountMoney(source, account)
local player = GetPlayerFromId(source)
return player.getAccount(account).money
end
function SetAccountMoney(source, account)
local player = GetPlayerFromId(source)
return player.setAccountMoney(account)
end
function AddAccountMoney(source, account, amount)
local player = GetPlayerFromId(source)
if not player then
Debug('AddAccountMoney Player not found', source)
return
end
player.addAccountMoney(account, amount)
end
function GetItems(player)
return player.getInventory()
end
function GetItem(player, item)
return player.getInventoryItem(item)
end
function RemoveAccountMoney(source, account, amount)
local player = GetPlayerFromId(source)
player.removeAccountMoney(account, amount)
end
function GetUserName(identifier)
local query = 'SELECT firstname, lastname, dateofbirth, sex FROM users WHERE identifier = ?'
local queryParams = { identifier }
local result = MySQL.prepare.await(query, queryParams)
if result then
local fullName = result.firstname .. (result.lastname and ' ' .. result.lastname or '')
local userDetails = {
citizenid = nil,
firstname = result.firstname or 'Player',
lastname = result.lastname or '',
birthdate = result.dateofbirth,
gender = result.sex,
nationality = nil,
}
return fullName, userDetails
else
return '', {}
end
end
function IsVehicleOwnedAbleToOpen(plate, id)
local val = false
local Player = GetPlayerFromId(id)
if Player then
local result = MySQL.Sync.fetchAll('SELECT * FROM ' .. VehicleTable .. " WHERE `plate` = '" .. plate .. "' LIMIT 1")
if (result and result[1] ~= nil) then
if result[1].owner == Player.identifier then
val = true
else
val = false
end
else
val = true
end
return val
else
return val
end
end
AddEventHandler('esx:onAddInventoryItem', function(source, itemName, amount)
-- You can test this code here
-- Debug('Test event esx:onAddInventoryItem:', itemName)
end)
AddEventHandler('esx:onRemoveInventoryItem', function(source, itemName, amount)
-- You can test this code here
-- Debug('Test event esx:onRemoveInventoryItem:', itemName)
end)
-- Don't toch
Accounts = { black_money = 0, money = 0 }
RegisterServerEvent('qs-inventory:server:updateItem', function(item, data)
if source ~= 0 or source ~= '' then
return
end
if not ItemList[item] then
return
end
ItemList[item] = data
TriggerClientEvent('qs-inventory:client:updateItem', -1, item, data)
end)
---@param source number
---@param items table
function UpdateFrameworkInventory(source, items)
end

View File

@@ -0,0 +1,194 @@
if Config.Framework ~= 'qb' then
return
end
QBCore = exports['qb-core']:GetCoreObject()
userTable = 'players'
Identifier = 'citizenid'
VehicleTable = 'player_vehicles'
if not Config.QBX then
WeaponList = QBCore.Shared.Weapons
ItemList = FormatItems(QBCore.Shared.Items)
end
UseCashAsItem = true -- Choose whether to use money as an item
CashItem = 'cash' -- Choose the money item, it only works if I enable the configurable above
ListAccountsSteal = {
{ account = 'cash', name = 'Cash' },
-- { account = 'crypto' , name = 'Crypto' },
}
RegisterNetEvent('QBCore:Server:PlayerLoaded', function(Player)
InitDrops(Player.PlayerData.source)
InitPlacedItems(Player.PlayerData.source)
end)
function RegisterServerCallback(name, cb)
QBCore.Functions.CreateCallback(name, cb)
end
function GetPlayerFromId(source)
return QBCore.Functions.GetPlayer(source)
end
function GetPlayerSourceFromIdentifier(identifier)
local player = QBCore.Functions.GetPlayerByCitizenId(identifier)
if not player then
return nil
end
return player.PlayerData.source
end
function GetPlayerFromIdentifier(identifier)
return QBCore.Functions.GetPlayerByCitizenId(identifier)
end
function PlayerIsAdmin(source)
if source == 0 then
return true
end
return QBCore.Functions.HasPermission(source, 'god') or IsPlayerAceAllowed(source, 'command') or QBCore.Functions.HasPermission(source, 'admin')
end
function FrameworkGetPlayers()
return QBCore.Functions.GetPlayers()
end
function GetPlayerIdentifier(source)
local player = GetPlayerFromId(source)
return player?.PlayerData?.citizenid
end
function GetJobName(source)
local player = GetPlayerFromId(source)
return player.PlayerData.job.name
end
function GetJobGrade(source)
local player = GetPlayerFromId(source)
return player.PlayerData.job.grade.level
end
function GetAccountMoney(source, account)
local player = GetPlayerFromId(source)
if account == 'money' then account = 'cash' end
if account == 'black_money' then account = 'crypto' end
return player.PlayerData.money[account]
end
function AddAccountMoney(source, account, amount)
local player = GetPlayerFromId(source)
if account == 'money' then account = 'cash' end
player.Functions.AddMoney(account, amount)
end
function GetItems(player)
return player.PlayerData.items
end
function GetItem(player, item)
return player.Functions.GetItemsByName(item)
end
function RemoveAccountMoney(source, account, amount)
local player = GetPlayerFromId(source)
if account == 'money' then account = 'cash' end
Debug('account', account, amount)
player.Functions.RemoveMoney(account, amount)
end
function GetUserName(identifier)
local player = GetPlayerFromIdentifier(identifier)
if player then
return player.PlayerData.charinfo.firstname .. ' ' .. player.PlayerData.charinfo.lastname, {
citizenid = player.PlayerData.citizenid,
firstname = player.PlayerData.charinfo.firstname or 'Player',
lastname = player.PlayerData.charinfo.lastname or '',
birthdate = player.PlayerData.charinfo.birthdate,
gender = tonumber(player.PlayerData.charinfo.gender),
nationality = player.PlayerData.charinfo.nationality,
}
end
return '', {}
end
function IsVehicleOwnedAbleToOpen(plate, id)
local val = false
local Player = GetPlayerFromId(id)
if Player then
local result = MySQL.Sync.fetchAll('SELECT * FROM ' .. VehicleTable .. " WHERE `plate` = '" .. plate .. "' LIMIT 1")
if (result and result[1] ~= nil) then
if result[1].citizenid == Player?.PlayerData?.citizenid then
val = true
else
val = false
end
else
val = true
end
return val
else
return val
end
end
---@param source number
---@param items table
---@param doNotUpdateCash boolean -- Because of stupid race condition, inventory doesn't initialize the cash item when adding the item. So we need to update it manually.
function UpdateFrameworkInventory(source, items, doNotUpdateCash)
local player = GetPlayerFromId(source)
player.Functions.SetPlayerData('items', items)
if not doNotUpdateCash then
UpdateCashItem(source)
end
end
RegisterServerCallback(Config.InventoryPrefix .. ':server:checkDead', function(_, cb, id)
local Player = QBCore.Functions.GetPlayer(id)
cb(Player.PlayerData.metadata['isdead'])
end)
-- Don't toch
Accounts = { black_money = 0, money = 0 }
lib.callback.register('inventory:getQbClothing', function(source)
local identifier = GetPlayerIdentifier(source)
local result = MySQL.query.await('SELECT * FROM playerskins WHERE citizenid = ? AND active = ?', { identifier, 1 })
Debug('Get clothing for player', identifier)
if not result[1] then return false end
return result[1].skin
end)
lib.callback.register('inventory:saveQbClothing', function(source, skin)
local identifier = GetPlayerIdentifier(source)
local result = MySQL.query.await('SELECT * FROM playerskins WHERE citizenid = ? AND active = ?', { identifier, 1 })
if result[1] then
MySQL.query.await('UPDATE playerskins SET skin = ? WHERE citizenid = ? AND active = ?', { json.encode(skin), identifier, 1 })
else
MySQL.query.await('INSERT INTO playerskins (citizenid, skin, active) VALUES (?, ?, ?)', { identifier, json.encode(skin), 1 })
end
Debug('Saved clothing for player', identifier)
return true
end)
if not Config.QBX then
AddEventHandler('QBCore:Server:UpdateObject', function()
ItemList = FormatItems(QBCore.Shared.Items)
end)
end
RegisterNetEvent('inventory:consumables:addHunger', function(amount)
local src = source
local player = GetPlayerFromId(src)
player.Functions.SetMetaData('hunger', amount)
TriggerClientEvent('hud:client:UpdateNeeds', src, amount, player.PlayerData.metadata.thirst, amount)
end)
RegisterNetEvent('inventory:consumables:addThirst', function(amount)
local src = source
local player = GetPlayerFromId(src)
player.Functions.SetMetaData('thirst', amount)
TriggerClientEvent('hud:client:UpdateNeeds', src, player.PlayerData.metadata.hunger, amount)
end)

View File

@@ -0,0 +1,185 @@
function AddItem(source, item, amount, slot, info, data, created, lastinventory, disableAutoShowBox)
local originalamount <const> = tonumber(amount) or 1
local originalslot <const> = slot
local originalcreated <const> = created
local originaldata <const> = data
local originalinfo <const> = info
if not source then return Error('Could not find [source] in AddItem.') end
if not item then return Error('Could not find [item] in AddItem.') end
if type(amount) == 'number' and amount < 1 then
return Debug('You cannot give an item with an amount less than 1!')
end
local inventory = lastinventory or Inventories[source]
local totalUsedSlots, totalWeight = GetTotalUsedSlots(source)
local itemInfo = ItemList[item:lower()]
local time = os.time()
if not itemInfo then
return false
end
if not created then
itemInfo['created'] = time
else
itemInfo['created'] = created
end
if not itemInfo then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
return false
end
amount = tonumber(amount) or 1
slot = tonumber(slot) or GetFirstSlotByItem(inventory, item)
info = info or {}
itemInfo['created'] = created or time
if type(info) ~= 'table' then
info = {}
end
info.quality = info.quality or 100
if data then
info.showItemData = true
itemInfo['unique'] = true
end
if itemInfo['type'] == 'weapon' then
info.serie = info.serie or CreateSerialNumber()
info.quality = info.quality or 100
end
if NotStoredItems(item, source, amount) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:forceCloseInventory', source)
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_CANT_TAKE_MORE') .. ' ' .. itemInfo['label'], 'inform')
end
local newWeight = (totalWeight + (itemInfo['weight'] * amount))
if newWeight > Config.InventoryWeight.weight then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_TOO_HEAVY') .. ' ' .. itemInfo['label'], 'error')
end
if (slot and inventory[slot]) and (inventory[slot].name:lower() == item:lower()) and (itemInfo['type'] == 'item' and not itemInfo['unique']) then
inventory[slot].amount = inventory[slot].amount + amount
TriggerEvent('esx:onAddInventoryItem', source, item, amount)
TriggerClientEvent('esx:addInventoryItem', source, item, amount)
TriggerEvent('qb-inventory:server:itemAdded', source, item, amount, inventory[slot].amount)
TriggerClientEvent('qb-inventory:client:itemAdded', source, item, amount, inventory[slot].amount)
if inventory[slot] and inventory[slot].name == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if inventory[slot] and inventory[slot].name == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
if not ContainsItem(itemsToCheck, inventory[slot].name) then
Debug("Add item update slot Item added to player's inventory:", source, 'Item:', inventory[slot].name, 'Amount:', inventory[slot].amount, 'disable', disableAutoShowBox)
if not disableAutoShowBox then
local itemData = ItemList[inventory[slot].name]
itemData.count = amount
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'add')
end
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
return true
elseif not itemInfo['unique'] and slot or slot and inventory[slot] == nil then
inventory[slot] = ItemInfo({
name = itemInfo['name'],
amount = amount,
slot = slot,
info = info
})
TriggerEvent('esx:onAddInventoryItem', source, item, amount)
TriggerClientEvent('esx:addInventoryItem', source, item, amount)
TriggerEvent('qb-inventory:server:itemAdded', source, item, amount, amount)
TriggerClientEvent('qb-inventory:client:itemAdded', source, item, amount, amount)
if inventory[slot] and inventory[slot].name == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if inventory[slot] and inventory[slot].name == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
if not ContainsItem(itemsToCheck, inventory[slot].name) then
Debug("Add Item new slot ::: Item added to player's inventory:", source, 'Item:', inventory[slot].name, 'Amount:', inventory[slot].amount, 'disableauto', disableAutoShowBox)
if not disableAutoShowBox then
local itemData = ItemList[inventory[slot].name]
itemData.count = amount
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'add')
end
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
return true
elseif itemInfo['unique'] or (not slot or slot == nil) or itemInfo['type'] == 'weapon' then
local added = false
for _ = 1, amount do
for i = 1, Config.InventoryWeight.slots, 1 do
if inventory[i] == nil then
TriggerEvent('esx:onAddInventoryItem', source, item, 1)
TriggerClientEvent('esx:addInventoryItem', source, item, 1)
TriggerEvent('qb-inventory:server:itemAdded', source, item, amount, 1)
TriggerClientEvent('qb-inventory:client:itemAdded', source, item, amount, 1)
inventory[i] = ItemInfo({
name = itemInfo['name'],
amount = 1,
slot = i,
info = info
})
if inventory[slot] and inventory[slot].name == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if inventory[slot] and inventory[slot].name == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
if not ContainsItem(itemsToCheck, inventory[i].name) then
Debug("add item create new slot ::: added to player's inventory:", source, 'Item:', inventory[i].name, 'Amount:', inventory[i].amount, 'disable', disableAutoShowBox)
if not disableAutoShowBox then
local itemData = ItemList[inventory[i].name]
itemData.count = 1
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'add')
end
end
local nextAmmount <const> = originalamount - 1
if nextAmmount > 0 then
AddItem(source, item, nextAmmount, originalslot, originalinfo, originaldata, originalcreated, inventory)
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
added = true
break
end
end
if added then
break
end
end
return added
end
return false
end
exports('AddItem', AddItem)

View File

@@ -0,0 +1,5 @@
function AddToStash(stashId, slot, otherslot, itemName, amount, info, created)
return AddItemToOtherInventory('stash', stashId, slot, otherslot, itemName, amount, info, created)
end
exports('AddToStash', AddToStash)

View File

@@ -0,0 +1,104 @@
--[[
Usable items that you can edit; do not add more items here as its unnecessary with this method.
These are the core and essential items in the inventory, each carrying critical information.
Please avoid adding additional items here. Instead, add them in your other scripts
using the conventional RegisterUsableItem system.
]]
if not ItemList or not WeaponList then return end
-- Documents
CreateUsableItem('driver_license', function(source, item)
local playerPed = GetPlayerPed(source)
local playerCoords = GetEntityCoords(playerPed)
local players = FrameworkGetPlayers()
for _, v in pairs(players) do
v = tonumber(v)
local targetPed = GetPlayerPed(v)
local dist = #(playerCoords - GetEntityCoords(targetPed))
if dist < 3.0 then
TriggerClientEvent('chat:addMessage', v, {
template = '<div class="chat-message advert"><div class="chat-message-body"><strong>{0}:</strong><br><br> <strong>First Name:</strong> {1} <br><strong>Last Name:</strong> {2} <br><strong>Birth Date:</strong> {3} <br><strong>Licenses:</strong> {4}</div></div>',
args = {
'Drivers License',
item.info.firstname,
item.info.lastname,
item.info.birthdate,
item.info.type
}
}
)
end
end
end)
CreateUsableItem('id_card', function(source, item)
local playerPed = GetPlayerPed(source)
local playerCoords = GetEntityCoords(playerPed)
local players = FrameworkGetPlayers()
for _, v in pairs(players) do
v = tonumber(v)
local targetPed = GetPlayerPed(v)
local dist = #(playerCoords - GetEntityCoords(targetPed))
if dist < 3.0 then
TriggerClientEvent('chat:addMessage', v, {
template = '<div class="chat-message advert"><div class="chat-message-body"><strong>{0}:</strong><br><br><strong>CBN:</strong> {1} <br><strong>First Name:</strong> {2} <br><strong>Last Name:</strong> {3} <br><strong>Birthdate:</strong> {4} <br><strong>Gender:</strong> {5} <br><strong>Nationality:</strong> {6}</div></div>',
args = {
'ID Card',
item.info.citizenid or 'ID-Card ' .. math.random(11111, 99999),
item.info.firstname,
item.info.lastname,
item.info.birthdate,
item.info.gender or 'AH-64 Apache Helicopter',
item.info.nationality or 'No information',
}
}
)
end
end
end)
for k, v in pairs(Config.AmmoItems) do
if v.isForEveryWeapon then
CreateUsableItem(v.item, function(source, item)
TriggerClientEvent('weapons:client:masterAmmo', source, 1, item)
end)
else
CreateUsableItem(v.item, function(source, item)
TriggerClientEvent('weapons:client:AddAmmo', source, v.type, 10, item)
end)
end
end
for k, v in pairs(Config.WeaponAttachmentItems) do
CreateUsableItem(v.item, function(source, item)
if v.isUrlTint then
if not item.info.urltint then
TriggerClientEvent('weapons:client:ConfigureTint', source, item)
else
TriggerClientEvent('weapons:client:EquipAttachment', source, item, v.item)
end
else
TriggerClientEvent('weapons:client:EquipAttachment', source, item, v.attachment)
end
end)
end
--[[
-- Snippet when using an item and it is spent
CreateUsableItem('firstaid', function(source)
local item = GetItemByName(source, 'firstaid')
if item.info.quality >= 10 then
item.info.quality = item.info.quality - 10
print("Item:", item.name, "Slot:", item.slot, "Info:", json.encode(item.info))
SetItemMetadata(source, item.slot, item.info)
print("You used the item. Remaining durability:", item.info.quality)
else
print("The item is broken, you can't use it")
end
end)
]]

View File

@@ -0,0 +1,76 @@
local function TransferMoney(itemName, source, target)
if Config.Framework ~= 'esx' then return end
if itemName ~= 'money' and itemName ~= 'black_money' then return end
local Player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, itemName)
Player.setAccountMoney(itemName, money, 'dropped')
local targetPlayer = GetPlayerFromId(target)
local targetMoney = GetItemTotalAmount(target, itemName)
targetPlayer.setAccountMoney(itemName, targetMoney, 'dropped')
local itemType = (itemName == 'money') and 'Money' or 'Black money'
Debug(itemType .. ' sent by src: ' .. json.encode(money) .. ', target: ' .. json.encode(targetMoney))
end
RegisterServerEvent(Config.InventoryPrefix .. ':server:GiveItem', function(target, name, amount, slot)
local src = source
target = tonumber(target)
local dist = #(GetEntityCoords(GetPlayerPed(src)) - GetEntityCoords(GetPlayerPed(target)))
if src == target then return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANT_GIVE'), 'error') end
if dist > 2 then return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_GIVE_FAR'), 'error') end
local item = GetItemBySlot(src, slot)
if not item then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_GIVE_NOT_FOUND'), 'error')
return
end
if item.name ~= name then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_GIVE_INCORRECT'), 'error')
return
end
if not amount then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_TRADE_EMPTY_INPUT'), 'error')
end
if amount <= item.amount then
if amount == 0 then
amount = item.amount
end
if NotStoredItems(item.name, target, amount) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:forceCloseInventory', src)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANT_TAKE_MORE_OTHER') .. ' ' .. item.name, 'inform')
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', target, Lang('INVENTORY_NOTIFICATION_CANT_TAKE_MORE') .. ' ' .. item.name, 'inform')
end
if RemoveItem(src, item.name, amount, item.slot) then
if AddItem(target, item.name, amount, false, item.info, nil, item.created) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', target, Lang('INVENTORY_NOTIFICATION_GIVE_RECEIVED') .. ' ' .. amount .. ' ' .. item.label, 'inform')
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', target, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_GAVE') .. ' ' .. amount .. ' ' .. item.label, 'inform')
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
local itemObject = ItemList[item.name:lower()].object or Config.ItemDropObject
TriggerClientEvent(Config.InventoryPrefix .. ':client:giveAnim', src, itemObject)
TriggerClientEvent(Config.InventoryPrefix .. ':client:giveAnim', target)
TriggerClientEvent(Config.InventoryPrefix .. ':client:closeinv', target)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, item, amount, 'remove')
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', target, item, amount, 'add')
TransferMoney(item.name, src, target)
SendWebhook(Webhooks.giveitem, 'Give Item To Player (Trade)', 7393279, '**' .. GetPlayerName(src) .. '(id: ' .. src .. ') sent a item to player: ' .. target .. '!**\nName:** ' .. item.name .. '**\nAmount:** ' .. amount)
else
AddItem(src, item.name, amount, item.slot, item.info, nil, item.created)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_OTHER_INVENTORY_FULL'), 'error')
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, false)
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', target, false)
TriggerClientEvent(Config.InventoryPrefix .. ':client:closeinv', target)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_INVALID_AMOUNT'), 'error')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_INVALID_AMOUNT'), 'error')
end
end)

View File

@@ -0,0 +1,100 @@
local umIdCard = GetResourceState('um-idcard') == 'started'
function GiveItemToPlayer(source, item, amount)
local id = source
local identifier = GetPlayerIdentifier(id)
amount = tonumber(amount)
local itemData = ItemList[item:lower()]
local cardlist = { 'id_card', 'driver_license', 'weaponlicense', 'lawyerpass' }
if not identifier then return end
if itemData then
Debug('item list', itemData, 'list', ItemList)
local info = {}
if string.find(table.concat(cardlist, ','), itemData['name']) and umIdCard then
exports['um-idcard']:CreateMetaLicense(source, itemData['name'])
return
elseif itemData['name'] == 'id_card' then
local _, charinfo = GetUserName(identifier)
info.citizenid = charinfo.citizenid
info.firstname = charinfo.firstname
info.lastname = charinfo.lastname
info.birthdate = charinfo.birthdate
info.gender = Config.Genders[charinfo.gender]
info.nationality = charinfo.nationality
elseif itemData['name'] == 'weaponlicense' then
local _, charinfo = GetUserName(identifier)
info.firstname = charinfo.firstname
info.lastname = charinfo.lastname
info.birthdate = charinfo.birthdate
info.gender = Config.Genders[charinfo.gender]
elseif itemData['name'] == 'driver_license' then
local _, charinfo = GetUserName(identifier)
info.firstname = charinfo.firstname
info.lastname = charinfo.lastname
info.birthdate = charinfo.birthdate
info.type = 'Class C Driver License'
elseif itemData['name'] == 'harness' then
info.uses = 20
elseif itemData['name'] == 'markedbills' then
info.worth = math.random(5000, 10000)
elseif itemData['name'] == 'labkey' then
info.lab = exports['qb-methlab']:GenerateRandomLab()
elseif itemData['name'] == 'printerdocument' then
info.url = 'https://cdn.discordapp.com/attachments/870094209783308299/870104331142189126/Logo_-_Display_Picture_-_Stylized_-_Red.png'
elseif ItemList[itemData['name']]['decay'] and ItemList[itemData['name']]['decay'] > 0 then
info.quality = 100
-- Quasar Scripts :
-- Vehiclekeys
elseif itemData['name'] == 'plate' then
info.plate = GeneratePlate()
-- DLC Backpacks
elseif itemData['name'] == 'backpack' then
info.ID = 'backpack_' .. math.random(111111, 999999)
info.weight = 10000
info.slots = 10
elseif itemData['name'] == 'backpack2' then
info.ID = 'backpack_' .. math.random(111111, 999999)
info.weight = 10000
info.slots = 10
elseif itemData['name'] == 'paramedicbag' then
info.ID = 'paramedic_' .. math.random(111111, 999999)
info.weight = 10000
info.slots = 10
elseif itemData['name'] == 'briefcase' then
info.ID = 'briefcase_' .. math.random(111111, 999999)
info.weight = 10000
info.slots = 10
elseif itemData['name'] == 'tradingcard_psa' then
local psaId = tostring(RandomStr(3) .. RandomInt(2) .. RandomStr(1) .. RandomInt(2) .. RandomInt(3))
info.serial = psaId
elseif itemData['name'] == 'money' then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_MONEY_NO_ITEM'), 'error')
elseif itemData['name'] == 'cash' then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_MONEY_NO_ITEM'), 'error')
end
if itemData['type'] == 'weapon' then
info.serie = CreateSerialNumber()
info.quality = 100
info.ammo = amount == 1 and 0 or amount
if amount > 1000 then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_GIVEWEAPON_LIMIT'), 'error')
end
AddItem(id, itemData['name'], amount, false, info)
SendWebhook(Webhooks.admin, 'Give Weapon To Player (Admin)', 7393279, '**' .. GetPlayerName(source) .. ' (id: ' .. source .. ') sent a weapon!**\n**Name:** ' .. itemData['name'] .. '\n**Bullets:** ' .. amount)
return
end
if AddItem(id, itemData['name'], amount, false, info) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_GIVE_ITEM') .. ' ' .. amount .. ' ' .. itemData['label'], 'success')
SendWebhook(Webhooks.admin, 'Give Item To Player (Admin)', 7393279, '**' .. GetPlayerName(source) .. ' (id: ' .. source .. ') sent a item!**\n**Name:** ' .. itemData['name'] .. '\n**Amount:** ' .. amount)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_CANT_GIVE'), 'error')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
end
exports('GiveItemToPlayer', GiveItemToPlayer)

View File

@@ -0,0 +1,43 @@
--[[
We recommend not modifying anything on this side, the Starter Items
are all in your server/custom/framework/esx.lua, it won't work in
qb-core since that framework has its native ones that do it automatically.
]]
RegisterServerEvent(Config.InventoryPrefix .. ':server:GiveStarterItems')
AddEventHandler(Config.InventoryPrefix .. ':server:GiveStarterItems', function()
local src = source
if not StarterItems then
Debug('GiveStarterItems: No Starter Items found. Dont forget, this event is not supported in qb-core')
return
end
local identifier = GetPlayerIdentifier(src)
local info = {}
for k, v in pairs(StarterItems) do
if k == 'id_card' then
local _, charinfo = GetUserName(identifier)
info.citizenid = charinfo.citizenid
info.firstname = charinfo.firstname
info.lastname = charinfo.lastname
info.birthdate = charinfo.birthdate
info.gender = Config.Genders[charinfo.gender]
info.nationality = charinfo.nationality
elseif k == 'weaponlicense' then
local _, charinfo = GetUserName(identifier)
info.firstname = charinfo.firstname
info.lastname = charinfo.lastname
info.birthdate = charinfo.birthdate
info.gender = Config.Genders[charinfo.gender]
elseif k == 'driver_license' then
local _, charinfo = GetUserName(identifier)
info.firstname = charinfo.firstname
info.lastname = charinfo.lastname
info.birthdate = charinfo.birthdate
info.type = 'Class C Driver License'
end
Wait(1250)
AddItem(src, k, v, false, info)
end
end)

View File

@@ -0,0 +1,31 @@
function GiveWeaponToPlayer(source, item, amount)
local id = source
local identifier = GetPlayerIdentifier(id)
amount = tonumber(amount)
local itemData = ItemList[item:lower()]
if not identifier then return end
if itemData then
local info = {}
if itemData['type'] == 'weapon' then
info.serie = CreateSerialNumber()
info.quality = 100
info.ammo = amount
end
if itemData['type'] ~= 'weapon' then return end
if amount > 1000 then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_GIVEWEAPON_LIMIT'), 'error')
end
if AddItem(id, itemData['name'], 1, false, info) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_GIVE_ITEM') .. ' ' .. amount .. ' ' .. itemData['label'], 'success')
SendWebhook(Webhooks.admin, 'Give Weapon To Player (Admin)', 7393279, '**' .. GetPlayerName(source) .. ' (id: ' .. source .. ') sent a weapon!**\n**Name:** ' .. itemData['name'] .. '\n**Bullets:** ' .. amount)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_CANT_GIVE'), 'error')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
end
exports('GiveWeaponToPlayer', GiveWeaponToPlayer)

View File

@@ -0,0 +1,565 @@
RegisterNetEvent(Config.InventoryPrefix .. ':server:OpenInventory', function(name, id, other, entityModel, customLabel)
local src = source
local jobName = GetJobName(src)
local IsVehicleOwned = IsVehicleOwned(id)
Player(src).state:set('inv_busy', false, true)
local blocked = false
for k, v in pairs(searchingInventories) do
if v == src then
blocked = true
end
end
if blocked then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_INVENTORY_SEARCH_BUSY'), 'error')
end
Debug('The inventory was opened with id:', id)
if name and id then
local secondInv = {}
if name == 'stash' then
id = id:gsub('-', '_')
if Stashes[id] then
if Stashes[id].isOpen then
local Target = GetPlayerFromId(Stashes[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Stashes[id].isOpen, name, id, Stashes[id].label)
else
Stashes[id].isOpen = false
end
end
end
local maxweight = 1000000
local slots = 50
if other then
maxweight = other.maxweight or 1000000
slots = other.slots or 50
end
secondInv.name = 'stash-' .. id
secondInv.label = customLabel or id
secondInv.maxweight = maxweight
secondInv.inventory = {}
secondInv.slots = slots
if Stashes[id] and Stashes[id].isOpen then
return InventoryInUse(src)
else
local stashItems = GetOtherInventoryItems('stash', id)
if next(stashItems) then
secondInv.inventory = stashItems
Stashes[id] = {}
Stashes[id].items = stashItems
Stashes[id].isOpen = src
Stashes[id].label = secondInv.label
else
Stashes[id] = {}
Stashes[id].items = {}
Stashes[id].isOpen = src
Stashes[id].label = secondInv.label
end
end
elseif name == 'trunk' then
if Trunks[id] then
if Trunks[id].isOpen then
local Target = GetPlayerFromId(Trunks[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Trunks[id].isOpen, name, id, Trunks[id].label)
else
Trunks[id].isOpen = false
end
end
end
secondInv.name = 'trunk-' .. id
secondInv.label = Lang('INVENTORY_NUI_TRUNK_LABEL') .. '-' .. id
secondInv.maxweight = other.maxweight or 60000
secondInv.inventory = {}
secondInv.slots = other.slots or 50
if (Trunks[id] and Trunks[id].isOpen) or (SplitStr(id, 'PLZI')[2] and jobName ~= 'police') then
return InventoryInUse(src)
else
if Config.OpenTrunkAll and id then
local ownedItems = GetOtherInventoryItems('trunk', id)
if IsVehicleOwned and next(ownedItems) then
secondInv.inventory = ownedItems
Trunks[id] = {}
Trunks[id].items = ownedItems
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
elseif Trunks[id] and not Trunks[id].isOpen then
secondInv.inventory = Trunks[id].items
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
else
Trunks[id] = {}
Trunks[id].items = {}
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
end
else
if IsVehicleOwnedAbleToOpen(id, src) or (Config.OpenTrunkPolice and GetJobName(src) == 'police' and GetJobGrade(src) >= Config.OpenTrunkPoliceGrade) then
local ownedItems = GetOtherInventoryItems('trunk', id)
if IsVehicleOwned and next(ownedItems) then
secondInv.inventory = ownedItems
Trunks[id] = {}
Trunks[id].items = ownedItems
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
elseif Trunks[id] and not Trunks[id].isOpen then
secondInv.inventory = Trunks[id].items
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
else
Trunks[id] = {}
Trunks[id].items = {}
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:closeinv', src)
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_TRUNK_BLOCKED'), 'error')
end
end
end
elseif name == 'glovebox' then
if Gloveboxes[id] then
if Gloveboxes[id].isOpen then
local Target = GetPlayerFromId(Gloveboxes[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Gloveboxes[id].isOpen, name, id, Gloveboxes[id].label)
else
Gloveboxes[id].isOpen = false
end
end
end
secondInv.name = 'glovebox-' .. id
secondInv.label = Lang('INVENTORY_NUI_GLOVEBOX_LABEL') .. '-' .. id
secondInv.maxweight = other?.maxweight or 10000
secondInv.inventory = {}
secondInv.slots = other?.slots or 10
if Gloveboxes[id] and Gloveboxes[id].isOpen then
return InventoryInUse(src)
else
if Config.OpenGloveboxesAll then
local ownedItems = GetOtherInventoryItems('glovebox', id)
if Gloveboxes[id] and not Gloveboxes[id].isOpen then
secondInv.inventory = Gloveboxes[id].items
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
elseif IsVehicleOwned and next(ownedItems) then
secondInv.inventory = ownedItems
Gloveboxes[id] = {}
Gloveboxes[id].items = ownedItems
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
else
Gloveboxes[id] = {}
Gloveboxes[id].items = {}
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
end
else
if IsVehicleOwnedAbleToOpen(id, src) or (Config.OpenGloveboxesPolice and GetJobName(src) == 'police' and GetJobGrade(src) >= Config.OpenGloveboxesPoliceGrade) then
local ownedItems = GetOtherInventoryItems('glovebox', id)
if Gloveboxes[id] and not Gloveboxes[id].isOpen then
secondInv.inventory = Gloveboxes[id].items
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
elseif IsVehicleOwned and next(ownedItems) then
secondInv.inventory = ownedItems
Gloveboxes[id] = {}
Gloveboxes[id].items = ownedItems
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
else
Gloveboxes[id] = {}
Gloveboxes[id].items = {}
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:closeinv', src)
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_GLOVEBOX_BLOCKED'), 'error')
end
end
end
elseif name == 'shop' then
secondInv.name = 'itemshop-' .. id
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = SetupShopItems(other.items)
RegisteredShops[id] = {
name = id,
label = other.label,
coords = other.coords,
slots = #other.items,
items = secondInv.inventory,
account = other.type or 'money'
}
secondInv.slots = #other.items
Debug('The store you opened uses the account ' .. json.encode(RegisteredShops[id].account))
elseif name == 'selling' then
secondInv.name = 'selling-' .. id
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = SetupSellingItems(id, other.items)
SellItems[id] = {}
SellItems[id].items = other.items
secondInv.slots = #other.items
elseif name == 'garbage' then
if not entityModel then Debug('Model for garbage system not found') end
secondInv.name = 'garbage_' .. id
secondInv.label = Lang('INVENTORY_NUI_GARBAGE_LABEL') .. '-' .. id
secondInv.maxweight = 900000
if GarbageItems[id] == nil or GarbageItems[id].created < os.time() - Config.GarbageRefreshTime then
GarbageItems[id] = {
created = os.time(),
}
local items = {}
Config.GarbageItems[id] = Config.GarbageItemsForProp[entityModel].items[math.random(1, #Config.GarbageItemsForProp[entityModel].items)]
for a, x in pairs(Config.GarbageItems[id]) do
local itemInfo = ItemInfo(x)
if not itemInfo then
Error('There is an item that does not exist in this garbage store!')
goto continue
end
items[a] = table.clone(x)
items[a].amount = math.random(x.amount.min, x.amount.max)
::continue::
end
GarbageItems[id].items = items
end
secondInv.inventory = SetupGarbageItems(id, GarbageItems[id].items)
secondInv.slots = 30
elseif name == 'traphouse' then
secondInv.name = 'traphouse-' .. id
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = other.items
secondInv.slots = other.slots
elseif name == 'crafting' then
secondInv.name = 'crafting'
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = other.items
secondInv.slots = #other.items
elseif name == 'attachment_crafting' then
secondInv.name = 'attachment_crafting'
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = other.items
secondInv.slots = #other.items
elseif name == 'customcrafting' then
secondInv.name = 'customcrafting'
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = other.items
secondInv.slots = #other.items
elseif name == 'otherplayer' then
id = tonumber(id)
local OtherPlayer = GetPlayerFromId(id)
if OtherPlayer then
if Player(id).state.inv_busy then
return
end
secondInv.name = 'otherplayer-' .. id
secondInv.label = 'Player-' .. id
secondInv.maxweight = Config.InventoryWeight.weight
local items = {}
local accessToSixthSlot = Config.PoliceCanSeeSixthSlot and table.includes(Config.PoliceJobs, jobName)
for k, v in pairs(Inventories[id]) do
if k ~= 41 or accessToSixthSlot then
items[k] = v
end
end
secondInv.inventory = items
searchingInventories[src] = id
secondInv.slots = Config.InventoryWeight.slots
if not accessToSixthSlot then
secondInv.slots = secondInv.slots - 1
end
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', id, Lang('INVENTORY_NOTIFICATION_ROBBERY_WARNING'), 'inform')
Wait(250)
end
else
if Drops[id] then
if Drops[id].isOpen then
local Target = GetPlayerFromId(Drops[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Drops[id].isOpen, name, id, Drops[id].label)
else
Drops[id].isOpen = false
end
end
end
if Drops[id] and not Drops[id].isOpen then
secondInv.coords = Drops[id].coords
secondInv.name = 'dropped-' .. id
secondInv.label = 'Dropped-' .. tostring(id)
secondInv.maxweight = Config.DropWeight.weight
secondInv.inventory = Drops[id].items
secondInv.slots = Config.DropWeight.slots
Drops[id].isOpen = src
Drops[id].label = secondInv.label
Drops[id].createdTime = os.time()
else
return InventoryInUse(src)
end
end
Wait(0)
TriggerClientEvent(Config.InventoryPrefix .. ':client:OpenInventory', src, {}, Inventories[src], secondInv, name)
OpenedSecondInventories[src] = secondInv
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:OpenInventory', src, {}, Inventories[src])
end
end)
function OpenInventory(name, id, other, origin)
local src = origin
local player = GetPlayerFromId(src)
local jobName = GetJobName(src)
Player(src).state:set('inv_busy', false, true)
local blocked = false
for k, v in pairs(searchingInventories) do
if v == src then
blocked = true
end
end
if blocked then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_INVENTORY_SEARCH_BUSY'), 'error')
end
if name == 'shop' and Config.DisableShopGenerationOnClient then
Warning('Config.DisableShopGenerationOnClient is active, you need to use our server exports to create and open the shop. Invoking Resource:', GetInvokingResource())
return
end
Debug('The inventory was opened with id:', id)
if name and id then
local secondInv = {}
if name == 'stash' then
id = id:gsub('-', '_')
if Stashes[id] then
if Stashes[id].isOpen then
local Target = GetPlayerFromId(Stashes[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Stashes[id].isOpen, name, id, Stashes[id].label)
else
Stashes[id].isOpen = false
end
end
end
local maxweight = 1000000
local slots = 50
if other then
maxweight = other.maxweight or 1000000
slots = other.slots or 50
end
secondInv.name = 'stash-' .. id
secondInv.label = 'Stash-' .. id
secondInv.maxweight = maxweight
secondInv.inventory = {}
secondInv.slots = slots
if Stashes[id] and Stashes[id].isOpen then
secondInv.name = 'none-inv'
secondInv.label = 'Stash-None'
secondInv.maxweight = 1000000
secondInv.inventory = {}
secondInv.slots = 0
else
local stashItems = GetOtherInventoryItems('stash', id)
if next(stashItems) then
secondInv.inventory = stashItems
Stashes[id] = {}
Stashes[id].items = stashItems
Stashes[id].isOpen = src
Stashes[id].label = secondInv.label
else
Stashes[id] = {}
Stashes[id].items = {}
Stashes[id].isOpen = src
Stashes[id].label = secondInv.label
end
end
elseif name == 'trunk' then
if Trunks[id] then
if Trunks[id].isOpen then
local Target = GetPlayerFromId(Trunks[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Trunks[id].isOpen, name, id, Trunks[id].label)
else
Trunks[id].isOpen = false
end
end
end
secondInv.name = 'trunk-' .. id
secondInv.label = 'Trunk-' .. id
secondInv.maxweight = other.maxweight or 60000
secondInv.inventory = {}
secondInv.slots = other.slots or 50
if (Trunks[id] and Trunks[id].isOpen) or (SplitStr(id, 'PLZI')[2] and (jobName ~= 'police')) then
secondInv.name = 'none-inv'
secondInv.label = 'Trunk-None'
secondInv.maxweight = other.maxweight or 60000
secondInv.inventory = {}
secondInv.slots = 0
else
if id then
local ownedItems = GetOtherInventoryItems('trunk', id)
if IsVehicleOwned(id) and next(ownedItems) then
secondInv.inventory = ownedItems
Trunks[id] = {}
Trunks[id].items = ownedItems
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
elseif Trunks[id] and not Trunks[id].isOpen then
secondInv.inventory = Trunks[id].items
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
else
Trunks[id] = {}
Trunks[id].items = {}
Trunks[id].isOpen = src
Trunks[id].label = secondInv.label
end
end
end
elseif name == 'glovebox' then
if Gloveboxes[id] then
if Gloveboxes[id].isOpen then
local Target = GetPlayerFromId(Gloveboxes[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Gloveboxes[id].isOpen, name, id, Gloveboxes[id].label)
else
Gloveboxes[id].isOpen = false
end
end
end
secondInv.name = 'glovebox-' .. id
secondInv.label = 'Glovebox-' .. id
secondInv.maxweight = 10000
secondInv.inventory = {}
secondInv.slots = 5
if Gloveboxes[id] and Gloveboxes[id].isOpen then
secondInv.name = 'none-inv'
secondInv.label = 'Glovebox-None'
secondInv.maxweight = 10000
secondInv.inventory = {}
secondInv.slots = 0
else
local ownedItems = GetOtherInventoryItems('glovebox', id)
if Gloveboxes[id] and not Gloveboxes[id].isOpen then
secondInv.inventory = Gloveboxes[id].items
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
elseif IsVehicleOwned(id) and next(ownedItems) then
secondInv.inventory = ownedItems
Gloveboxes[id] = {}
Gloveboxes[id].items = ownedItems
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
else
Gloveboxes[id] = {}
Gloveboxes[id].items = {}
Gloveboxes[id].isOpen = src
Gloveboxes[id].label = secondInv.label
end
end
elseif name == 'shop' then
secondInv.name = 'itemshop-' .. id
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = SetupShopItems(other.items)
RegisteredShops[id] = {
name = id,
label = other.label,
coords = other.coords,
slots = #other.items,
items = secondInv.inventory,
account = other.type or 'money'
}
secondInv.slots = #other.items
elseif name == 'traphouse' then
secondInv.name = 'traphouse-' .. id
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = other.items
secondInv.slots = other.slots
elseif name == 'crafting' then
secondInv.name = 'crafting'
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = other.items
secondInv.slots = #other.items
elseif name == 'attachment_crafting' then
secondInv.name = 'attachment_crafting'
secondInv.label = other.label
secondInv.maxweight = 900000
secondInv.inventory = other.items
secondInv.slots = #other.items
elseif name == 'otherplayer' then
id = tonumber(id)
local OtherPlayer = GetPlayerFromId(id)
if OtherPlayer then
if Player(id).state.inv_busy then
return
end
secondInv.name = 'otherplayer-' .. id
secondInv.label = 'Player-' .. id
secondInv.maxweight = Config.InventoryWeight.weight
local items = {}
local accessToSixthSlot = Config.PoliceCanSeeSixthSlot and table.includes(Config.PoliceJobs, jobName)
for k, v in pairs(Inventories[id]) do
if k ~= 41 or accessToSixthSlot then
items[k] = v
end
end
secondInv.inventory = items
searchingInventories[src] = id
secondInv.slots = Config.InventoryWeight.slots
if not accessToSixthSlot then
secondInv.slots = secondInv.slots - 1
end
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', id, Lang('INVENTORY_NOTIFICATION_ROBBERY_WARNING'), 'inform')
Wait(250)
end
else
if Drops[id] then
if Drops[id].isOpen then
local Target = GetPlayerFromId(Drops[id].isOpen)
if Target then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckOpenState', Drops[id].isOpen, name, id, Drops[id].label)
else
Drops[id].isOpen = false
end
end
end
if Drops[id] and not Drops[id].isOpen then
secondInv.coords = Drops[id].coords
secondInv.name = id
secondInv.label = 'Dropped-' .. tostring(id)
secondInv.maxweight = 100000
secondInv.inventory = Drops[id].items
secondInv.slots = 30
Drops[id].isOpen = src
Drops[id].label = secondInv.label
Drops[id].createdTime = os.time()
else
secondInv.name = 'none-inv'
secondInv.label = 'Dropped-None'
secondInv.maxweight = 100000
secondInv.inventory = {}
secondInv.slots = 0
end
end
Wait(0)
TriggerClientEvent(Config.InventoryPrefix .. ':client:OpenInventory', src, {}, Inventories[src], secondInv, name)
OpenedSecondInventories[src] = secondInv
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:OpenInventory', src, {}, Inventories[src])
end
end
exports('OpenInventory', OpenInventory)

View File

@@ -0,0 +1,187 @@
local SmartphoneMetadata = GetResourceState('qs-smartphone-pro') == 'started'
function RemoveItem(source, item, amount, slot, metadata, disableAutoShowBox)
if not source then return Error('Could not find [source] in RemoveItem.') end
if not item then return Error('Could not find [item] in RemoveItem.') end
local inventory = Inventories[source]
amount = tonumber(amount) or 1
slot = tonumber(slot)
if ItemList[item] then
if slot then
if not inventory[slot] then return false end
if inventory[slot].amount > amount then
inventory[slot].amount = inventory[slot].amount - amount
TriggerEvent('esx:onRemoveInventoryItem', source, item, amount)
TriggerClientEvent('esx:removeInventoryItem', source, item, amount)
TriggerEvent('qb-inventory:server:itemRemoved', source, item, amount, inventory[slot].amount)
TriggerClientEvent('qb-inventory:client:itemRemoved', source, item, amount, inventory[slot].amount)
if not ContainsItem(itemsToCheck, item) then
Debug("Item removed to player's inventory:", source, 'Item:', item, 'Amount:', amount)
if not disableAutoShowBox then
local itemData = ItemList[item]
itemData.count = amount
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'remove')
end
end
if item == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if item == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
return true
elseif inventory[slot].amount == amount then
TriggerEvent('esx:onRemoveInventoryItem', source, item, amount)
TriggerClientEvent('esx:removeInventoryItem', source, item, amount)
TriggerEvent('qb-inventory:server:itemRemoved', source, item, amount, 0)
TriggerClientEvent('qb-inventory:client:itemRemoved', source, item, amount, 0)
inventory[slot] = nil
if not ContainsItem(itemsToCheck, item) then
Debug("Item removed to player's inventory:", source, 'Item:', item, 'Amount:', amount)
if not disableAutoShowBox then
local itemData = ItemList[item]
itemData.count = amount
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'remove')
end
end
if item == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if item == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
return true
end
else
local slots = GetSlotsByItem(inventory, item, metadata)
local amountToRemove = amount
if not slots then return false end
for _, _slot in pairs(slots) do
if inventory[_slot].amount > amountToRemove then
if SmartphoneMetadata then
exports['qs-smartphone-pro']:handleDeleteItem(source, inventory[_slot])
end
TriggerEvent('esx:onRemoveInventoryItem', source, item, amount)
TriggerClientEvent('esx:removeInventoryItem', source, item, amount)
inventory[_slot].amount = inventory[_slot].amount - amountToRemove
TriggerEvent('qb-inventory:server:itemRemoved', source, item, amount, inventory[_slot].amount)
TriggerClientEvent('qb-inventory:client:itemRemoved', source, item, amount, inventory[_slot].amount)
if not ContainsItem(itemsToCheck, item) then
Debug("Item removed to player's inventory:", source, 'Item:', item, 'Amount:', amount)
if not disableAutoShowBox then
local itemData = ItemList[item]
itemData.count = amount
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'remove')
end
end
if item == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if item == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
return true
elseif inventory[_slot].amount == amountToRemove then
if SmartphoneMetadata then
exports['qs-smartphone-pro']:handleDeleteItem(source, inventory[_slot])
end
TriggerEvent('esx:onRemoveInventoryItem', source, item, amount)
TriggerClientEvent('esx:removeInventoryItem', source, item, amount)
TriggerEvent('qb-inventory:server:itemRemoved', source, item, amount, 0)
TriggerClientEvent('qb-inventory:client:itemRemoved', source, item, amount, 0)
inventory[_slot] = nil
if not ContainsItem(itemsToCheck, item) then
Debug("Item removed to player's inventory:", source, 'Item:', item, 'Amount:', amount)
if not disableAutoShowBox then
local itemData = ItemList[item]
itemData.count = amount
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'remove')
end
end
if item == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if item == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
return true
else
local quantity = GetItemTotalAmount(source, inventory[_slot].name)
local _quantity = quantity - amountToRemove
inventory[_slot].amount = _quantity
SetInventoryItems(source, inventory[_slot].name, _quantity)
if SmartphoneMetadata then
exports['qs-smartphone-pro']:handleDeleteItem(source, inventory[_slot])
end
if not ContainsItem(itemsToCheck, item) then
Debug("Item removed to player's inventory:", source, 'Item:', item, 'Amount:', amount)
if not disableAutoShowBox then
local itemData = ItemList[item]
itemData.count = amount
TriggerClientEvent('qs-inventory:client:ItemBox', source, itemData, 'remove')
end
end
if item == 'money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'money')
player.setAccountMoney('money', money, 'dropped')
end
if item == 'black_money' and Config.Framework == 'esx' then
local player = GetPlayerFromId(source)
local money = GetItemTotalAmount(source, 'black_money')
player.setAccountMoney('black_money', money, 'dropped')
end
UpdateFrameworkInventory(source, inventory, true)
UpdateInventoryState(source)
return true
end
end
end
else
return false
end
return false
end
exports('RemoveItem', RemoveItem)

View File

@@ -0,0 +1,139 @@
local function getFirstItemInDrop(dropId)
local drop = Drops[dropId]
if drop and drop.items then
for k, v in pairs(drop.items) do
return v
end
end
return nil
end
function TimeoutFunction(wait, fn)
CreateThread(function()
Wait(wait)
fn()
end)
end
function SaveOtherInventories()
for inventoryName, inventory in pairs(UpdatedInventories) do
for id, updated in pairs(inventory) do
if updated then
SaveOtherInventory(inventoryName, id)
UpdatedInventories[inventoryName][id] = nil
end
end
end
end
---@param inventoryName OtherInventoryTypes
---@param id string
function SaveOtherInventory(inventoryName, id)
Debug('SaveOtherInventory', inventoryName, id)
if inventoryName == 'stash' then
SaveStashItems(id, Stashes[id].items)
elseif inventoryName == 'trunk' then
SaveOwnedVehicleItems(id, Trunks[id].items)
elseif inventoryName == 'glovebox' then
SaveOwnedGloveboxItems(id, Gloveboxes[id].items)
elseif inventoryName == 'clothes' then
local src = GetPlayerSourceFromIdentifier(id)
if not src then
Error('SaveOtherInventory', 'Player not found', id, 'inventoryName', inventoryName)
return
end
SaveClotheItems(id, GetClotheItems(src))
end
end
function HandleCloseSecondInventories(src, type, id)
local IsVehicleOwned = IsVehicleOwned(id)
Debug('HandleSaveSecondInventories', src, type, id, IsVehicleOwned)
if type == 'trunk' then
if not Trunks[id] then
Debug('Trunk id not found', id)
return
end
if Trunks[id].isOpen ~= src then
Debug('Player did not open this trunk', src, Trunks[id].isOpen)
return
end
if IsVehicleOwned then
SaveOwnedVehicleItems(id, Trunks[id].items)
end
Trunks[id].isOpen = false
elseif type == 'glovebox' then
if not Gloveboxes[id] then return end
if Gloveboxes[id].isOpen ~= src then
Debug('Player did not open this glovebox', src, Gloveboxes[id].isOpen)
return
end
if IsVehicleOwned then
SaveOwnedGloveboxItems(id, Gloveboxes[id].items)
end
Gloveboxes[id].isOpen = false
elseif type == 'stash' then
if not Stashes[id] then return end
if Stashes[id].isOpen ~= src then
Debug('Player did not open this stash', src, Stashes[id].isOpen)
return
end
SaveStashItems(id, Stashes[id].items)
Stashes[id].isOpen = false
elseif type == 'drop' then
if Drops[id] then
if Drops[id].isOpen ~= src then
Debug('Player did not open this drop', src, Drops[id].isOpen)
return
end
Drops[id].isOpen = false
if Drops[id].items == nil or next(Drops[id].items) == nil then
Drops[id] = nil
TimeoutFunction(500, function()
TriggerClientEvent(Config.InventoryPrefix .. ':client:RemoveDropItem', -1, id)
end)
else
local dropItemsCount = table.length(Drops[id].items)
local firstItem = getFirstItemInDrop(id)
local dropObject = Config.ItemDropObject
if firstItem then
dropObject = dropItemsCount == 1 and ItemList[firstItem.name:lower()].object or Config.ItemDropObject
end
TimeoutFunction(500, function()
TriggerClientEvent(Config.InventoryPrefix .. ':updateDropItems', -1, id, dropObject, dropItemsCount == 1 and firstItem or nil)
end)
end
end
elseif type == 'clothing' and Config.Clothing then
local identifier = GetPlayerIdentifier(src)
local clotheItems = GetClotheItems(src)
if not clotheItems then return end
SaveClotheItems(identifier, clotheItems)
end
end
RegisterNetEvent(Config.InventoryPrefix .. ':server:handleInventoryClosed', function(type, id)
local src = source
HandleCloseSecondInventories(src, type, id)
UpdateFrameworkInventory(src, Inventories[src])
end)
-- AddEventHandler('onResourceStop', function(resource)
-- if resource == GetCurrentResourceName() then
-- SaveOtherInventories()
-- end
-- end)
-- RegisterCommand('save-inventories', function(source, args)
-- if source ~= 0 then
-- return Error(source, 'This command can use only by console')
-- end
-- SaveOtherInventories()
-- end)
-- CreateThread(function()
-- while true do
-- Wait(Config.SaveInventoryInterval)
-- SaveOtherInventories()
-- end
-- end)

View File

@@ -0,0 +1,70 @@
function getPriceItemForSelling(name)
for k, v in pairs(Config.SellItems) do
for s, x in pairs(v.items) do
if x.name == name then
return x.price, v.blip.account
end
end
end
return false
end
RegisterNetEvent(Config.InventoryPrefix .. ':server:RemoveItem', function(itemName, count)
local src = source
RemoveItem(src, itemName, count)
end)
function SetupSellingItems(shop, shopItems)
local items = {}
if shopItems ~= nil and next(shopItems) ~= nil then
for k, item in pairs(shopItems) do
local itemInfo = ItemInfo(item)
if not itemInfo then return Error('There is an item that does not exist in this selling store!') end
itemInfo.price = item.price
items[item.slot] = itemInfo
end
end
return items
end
---@param src number
---@param fromInventory string
---@param fromSlot number
---@param fromAmount number
---@param toInventory string
---@param toSlot number
---@return boolean
function SellItemToSelling(src, fromInventory, fromSlot, fromAmount, toInventory, toSlot)
if fromInventory ~= 'player' and fromInventory ~= 'hotbar' then
Debug('You can not sell items from this inventory', fromInventory)
return false
end
local fromItemData = GetItemBySlot(src, fromSlot)
fromAmount = tonumber(fromAmount) and tonumber(fromAmount) or fromItemData.amount
if fromAmount == 0 then
Notification(src, Lang('INVENTORY_NOTIFICATION_SELLING_AMOUNT'), 'error')
return false
end
if not fromItemData or fromItemData.amount < fromAmount then
Debug('You do not have this item or not enough amount', fromItemData, fromAmount)
Notification(src, Lang('INVENTORY_NOTIFICATION_SELLING_BAD_ITEM'), 'error')
return false
end
local sell_id = SplitStr(toInventory, '-')[2]
local toItemData = SellItems[sell_id].items[toSlot]
if not toItemData or toItemData.name ~= fromItemData.name then
Debug('You can not sell this item to this slot', toItemData, fromItemData)
Notification(src, Lang('INVENTORY_NOTIFICATION_SELLING_BAD_ITEM'), 'error')
return false
end
RemoveItem(src, fromItemData.name, fromAmount, fromSlot)
local price, account = getPriceItemForSelling(fromItemData.name)
if not price then
return false
end
AddAccountMoney(src, account, price * fromAmount)
Notification(src, price * fromAmount .. ' ' .. Lang('INVENTORY_NOTIFICATION_SELLING_SUCCESS'), 'success')
SendWebhook(Webhooks.sell, 'Item Sale', 7393279, '**' .. GetPlayerName(src) .. '(id: ' .. src .. ') sold an item!**\n**Name:** ' .. fromItemData.name .. '\n**Price:** ' .. price * fromAmount .. '\n**Amount:** ' .. fromAmount)
Debug('Player is selling an item', src, fromItemData.name, fromAmount, price)
return true
end

View File

@@ -0,0 +1,990 @@
RegisterNetEvent(Config.InventoryPrefix .. ':server:SetInventoryData', function(fromInventory, toInventory, fromSlot, toSlot, fromAmount, toAmount, fromInventoryIsClothesInventory, toInventoryIsClothesInventory, craftingKey)
local src = source
local Player = GetPlayerFromId(src)
local identifier = GetPlayerIdentifier(src)
fromSlot = tonumber(fromSlot)
toSlot = tonumber(toSlot)
fromAmount = tonumber(fromAmount)
fromSlot = tonumber(fromSlot)
toSlot = tonumber(toSlot)
assert(fromSlot, 'fromSlot is nil')
assert(toSlot, 'toSlot is nil')
assert(fromAmount, 'fromAmount is nil')
if fromAmount < 0 then
SendWebhook(Webhooks.exploit, 'SetInventoryData (exploit attempt)', 7393279, ([[
Player: %s
Identifier: %s
Reason: Gave negative amount, its not possible.
Amount: %s
]]):format(GetPlayerName(src), identifier, fromAmount))
return Error('SetInventoryData', 'This player is trying to exploit the inventory. You can ban this player from the server.', src, 'identifier', identifier)
end
fromAmount = math.max(fromAmount, 1)
if (fromInventory == 'player' or fromInventory == 'hotbar') and (SplitStr(toInventory, '-')[1] == 'itemshop' or toInventory == 'crafting' or toInventory == 'customcrafting') then
return
end
if fromInventoryIsClothesInventory and toInventoryIsClothesInventory then
return
end
if (SplitStr(fromInventory, '-')[1] == 'selling') then
return
end
if fromInventoryIsClothesInventory then
local clotheItems = GetClotheItems(src)
local item = clotheItems[fromSlot]
if not item then
Error('SetInventoryData', 'Clothing', 'Item not found', src, fromSlot)
return
end
local itemIsClothPart = checkItemIsClothingPart(item.name)
if not itemIsClothPart then
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANT_MOVE'), 'inform')
return
end
local data = table.find(Config.ClothingSlots, function(v)
if v.slot == fromSlot then
return true
end
return false
end)
item.info.armor = GetPedArmour(GetPlayerPed(src))
if data then
TriggerClientEvent('inventory:takeoffClothing', src, data)
end
AddItem(src, item.name, 1, toSlot, item.info, nil, nil, nil, true)
RemoveFromClothes(identifier, fromSlot, item.name, 1)
TriggerClientEvent(Config.InventoryPrefix .. ':saveClothes', src)
return
elseif toInventoryIsClothesInventory then
local item = GetItemBySlot(src, fromSlot)
if not item then return end
local itemIsClothPart = checkItemIsClothingPart(item.name)
if not itemIsClothPart then
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANT_MOVE'), 'inform')
return
end
UseItem(item.name, src, item)
AddToClothes(identifier, item.name, item.info)
RemoveItem(src, item.name, 1, fromSlot, nil, true)
TriggerClientEvent(Config.InventoryPrefix .. ':saveClothes', src)
return
end
if SplitStr(toInventory, '-')[1] == 'selling' then
if fromInventory ~= 'player' and fromInventory ~= 'hotbar' then return end
local fromItemData = GetItemBySlot(src, fromSlot)
fromAmount = tonumber(fromAmount) and tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
local sell_id = SplitStr(toInventory, '-')[2]
local toItemData = SellItems[sell_id].items[toSlot]
Debug(toItemData.name, fromItemData.name)
if toItemData and toItemData.name == fromItemData.name then
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
local price, account = getPriceItemForSelling(fromItemData.name)
if not price then return end
if fromAmount == 0 then
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_SELLING_AMOUNT'), 'error')
end
AddAccountMoney(src, account, price * fromAmount)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, price * fromAmount .. ' ' .. Lang('INVENTORY_NOTIFICATION_SELLING_SUCCESS'), 'success')
SendWebhook(Webhooks.sell, 'Item Sale', 7393279, '**' .. GetPlayerName(src) .. '(id: ' .. src .. ') sold an item!**\n**Name:** ' .. fromItemData.name .. '\n**Price:** ' .. price * fromAmount .. '\n**Amount:** ' .. fromAmount)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_SELLING_BAD_ITEM'), 'error')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_SELLING_BAD_ITEM'), 'error')
end
return
end
if fromInventory == 'player' or fromInventory == 'hotbar' then
local fromItemData = GetItemBySlot(src, fromSlot)
fromAmount = tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
if toInventory == 'player' or toInventory == 'hotbar' then
local toItemData = GetItemBySlot(src, toSlot)
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. toItemData.name .. '\n**Amount:** ' .. toAmount .. ' with name: ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount)
end
else
print('Dupe Blocked - 1')
end
end
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
elseif SplitStr(toInventory, '-')[1] == 'otherplayer' then
local playerId = tonumber(SplitStr(toInventory, '-')[2])
local toItemData = Inventories[playerId][toSlot]
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
local itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.name ~= fromItemData.name then
RemoveItem(playerId, itemInfo['name'], toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, toItemData, toAmount, 'remove')
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
end
end
local itemInfo = ItemList[fromItemData.name:lower()]
AddItem(playerId, itemInfo['name'], fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
elseif SplitStr(toInventory, '-')[1] == 'trunk' then
local plate = SplitStr(toInventory, '-')[2]
local toItemData = Trunks[plate].items[toSlot]
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
local itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
Debug('trunk 132')
local success = RemoveItemFromOtherInventory('trunk', plate, toSlot, itemInfo['name'], toAmount, src)
if not success then
return Error('SetInventoryData', 'Trunk', 'Item not found', src, toSlot)
end
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**With name:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
end
else
print('Dupe Blocked - 3')
end
end
local itemInfo = ItemList[fromItemData.name:lower()]
AddItemToOtherInventory('trunk', plate, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.trunk, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in trunk!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
elseif SplitStr(toInventory, '-')[1] == 'glovebox' then
local plate = SplitStr(toInventory, '-')[2]
local toItemData = Gloveboxes[plate].items[toSlot]
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
local itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
Debug('trunk 159')
local success = RemoveItemFromOtherInventory('glovebox', plate, toSlot, itemInfo['name'], toAmount, src)
if not success then
return Error('SetInventoryData', 'Glovebox', 'Item not found', src, fromSlot)
end
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**With name:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
end
else
print('Dupe Blocked - 4')
end
end
local itemInfo = ItemList[fromItemData.name:lower()]
AddItemToOtherInventory('glovebox', plate, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.glovebox, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in glovebox!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
elseif SplitStr(toInventory, '-')[1] == 'stash' then
local stashId = SplitStr(toInventory, '-')[2]
local toItemData = Stashes[stashId].items[toSlot]
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
local itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
Debug('186')
local success = RemoveItemFromOtherInventory('stash', stashId, toSlot, toItemData.name, toAmount, src)
if not success then
return Error('SetInventoryData', 'Stash', 'Item not found', src, fromSlot)
end
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**With name:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Stash id:** ' .. stashId)
end
else
print('Dupe Blocked - 5')
end
end
local itemInfo = ItemList[fromItemData.name:lower()]
AddItemToOtherInventory('stash', stashId, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.stash, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in stash!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Stash id:** ' .. stashId)
elseif SplitStr(toInventory, '_')[1] == 'garbage' then
local garbageId = SplitStr(toInventory, '_')[2]
local toItemData = GarbageItems[garbageId].items[toSlot]
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
local itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
RemoveFromGarbage(garbageId, toSlot, itemInfo['name'], toAmount)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, toItemData, toAmount, 'remove')
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**With name:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Garbage id:** ' .. garbageId)
end
else
print('Dupe Blocked - 6')
end
end
local itemInfo = ItemList[fromItemData.name:lower()]
AddToGarbage(garbageId, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'])
SendWebhook(Webhooks.garbage, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in garbage!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Garbage id:** ' .. garbageId)
elseif SplitStr(toInventory, '-')[1] == 'traphouse' then
-- Traphouse
local traphouseId = SplitStr(toInventory, '_')[2]
local toItemData = exports['qb-traphouse']:GetInventoryData(traphouseId, toSlot)
local IsItemValid = exports['qb-traphouse']:CanItemBeSaled(fromItemData.name:lower())
if IsItemValid then
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
local itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
exports['qb-traphouse']:RemoveHouseItem(traphouseId, fromSlot, itemInfo['name'], toAmount)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, toItemData, toAmount, 'remove')
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**With name:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Traphouse id:** ' .. traphouseId)
end
else
print('Dupe Blocked - 7')
end
end
local itemInfo = ItemList[fromItemData.name:lower()]
exports['qb-traphouse']:AddHouseItem(traphouseId, toSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.swap, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in traphouse!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Traphouse id:** ' .. traphouseId)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANT_SELL'), 'error')
end
else
-- drop
toInventoryFormatter = SplitStr(toInventory, '-')[2]
toInventory = tonumber(toInventoryFormatter)
if toInventory == nil or toInventory == 0 then
CreateNewDrop(src, fromSlot, toSlot, fromAmount, fromItemData['created'])
Debug('[SetInventoryData, function CreateNewDrop]', fromSlot, toSlot, fromAmount, fromItemData['created'])
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
SendWebhook(Webhooks.drop, 'Create New Drop', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') create new drop!**\n**Name:** ' .. fromItemData['name'] .. '\n**Amount:** ' .. fromAmount)
else
local toItemData = Drops[toInventory].items[toSlot]
RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
if toItemData then
local itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
AddItem(src, toItemData.name, toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'add')
RemoveFromDrop(toInventory, fromSlot, itemInfo['name'], toAmount)
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**With name:** ' .. fromItemData.name .. '\n**mount:** ' .. fromAmount .. '\n**Drop id:** ' .. toInventory)
end
else
print('Dupe Blocked - 8')
end
end
local itemInfo = ItemList[fromItemData.name:lower()]
AddToDrop(toInventory, toSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'])
SendWebhook(Webhooks.drop, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in drop!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Drop id:** ' .. toInventory)
if itemInfo['name'] == 'radio' then
TriggerClientEvent('Radio.Set', src, false)
elseif itemInfo['name'] == 'money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'money')
Player.setAccountMoney('money', money, 'dropped')
elseif itemInfo['name'] == 'black_money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'black_money')
Player.setAccountMoney('black_money', money, 'dropped')
end
TriggerClientEvent(Config.InventoryPrefix .. ':ClearWeapons', src)
end
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_GIVE_DONT_HAVE'), 'error')
end
elseif SplitStr(fromInventory, '-')[1] == 'otherplayer' then
local playerId = tonumber(SplitStr(fromInventory, '-')[2])
local fromItemData = Inventories[playerId][fromSlot]
fromAmount = tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
local itemInfo = ItemList[fromItemData.name:lower()]
if toInventory == 'player' or toInventory == 'hotbar' then
local toItemData = GetItemBySlot(src, toSlot)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, fromItemData, fromAmount, 'remove')
RemoveItem(playerId, itemInfo['name'], fromAmount, fromSlot, nil, true)
SendWebhook(Webhooks.robbery, 'Deposit Item (robbery)', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in inventory (robbery)!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Otherplayer id:** ' .. playerId)
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', playerId, fromItemData.name)
if toItemData then
itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.name ~= fromItemData.name then
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'remove')
AddItem(playerId, itemInfo['name'], toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, toItemData, toAmount, 'add')
end
end
-- Weapon Parts
if fromItemData.type == 'weapon' and Config.CanStealWeaponParts then
local chance = math.random(1, 100)
if chance <= Config.WeaponPartStealChance then
Debug('The complete weapon was stolen with a probability of:', chance)
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
else
Debug('The theft of the weapon was failed with a probability of:', chance, 'random items added!')
RemoveItem(src, fromItemData.name, fromAmount, toSlot, nil, true)
for i = 1, 5 do
local randomItem = Config.AvailableWeaponParts[math.random(1, #Config.AvailableWeaponParts)]
AddItem(src, randomItem, math.random(1, 5))
end
Wait(200)
TriggerClientEvent(Config.InventoryPrefix .. ':client:forceCloseInventory', src)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_STEAL_BROKEN_WEAPON'), 'inform')
end
else
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'add')
end
-- Weapon Parts
else
local toItemData = Inventories[playerId][toSlot]
RemoveItem(playerId, itemInfo['name'], fromAmount, fromSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, fromItemData, fromAmount, 'remove')
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
RemoveItem(playerId, itemInfo['name'], toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, toItemData, toAmount, 'remove')
AddItem(playerId, itemInfo['name'], toAmount, fromSlot, toItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, toItemData, toAmount, 'add')
end
else
print('Dupe Blocked - 10')
end
end
itemInfo = ItemList[fromItemData.name:lower()]
AddItem(playerId, itemInfo['name'], fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', playerId, fromItemData, fromAmount, 'add')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
elseif SplitStr(fromInventory, '-')[1] == 'trunk' then
local plate = SplitStr(fromInventory, '-')[2]
local fromItemData = Trunks[plate].items[fromSlot]
fromAmount = tonumber(fromAmount) or fromItemData.amount
Debug('fromSlot', fromSlot, 'toSlot', toSlot, 'fromAmount', fromAmount, 'toAmount', toAmount)
if fromItemData and fromItemData.amount >= fromAmount then
local itemInfo = ItemList[fromItemData.name:lower()]
if toInventory == 'player' or toInventory == 'hotbar' then
Debug('380')
local toItemData = GetItemBySlot(src, toSlot)
local success = RemoveItemFromOtherInventory('trunk', plate, fromSlot, itemInfo['name'], fromAmount, src)
if not success then
return Error('SetInventoryData', 'Trunk', 'Item not found', src, fromSlot)
end
-- TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'remove')
SendWebhook(Webhooks.trunk, 'Remove Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') remove item from trunk!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
if toItemData then
itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'remove')
AddItemToOtherInventory('trunk', plate, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. toItemData.name .. '\n**Amount:** ' .. toAmount .. '\n**With item:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**Plate:** ' .. plate)
end
else
print('Dupe Blocked - 11')
end
end
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'add')
else
Debug('405')
local toItemData = Trunks[plate].items[toSlot]
local success = RemoveItemFromOtherInventory('trunk', plate, fromSlot, itemInfo['name'], fromAmount, src)
if not success then
return Error('SetInventoryData', 'Trunk', 'Item not found', src, fromSlot)
end
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
Debug('trunk 410')
RemoveItemFromOtherInventory('trunk', plate, toSlot, itemInfo['name'], toAmount, src)
AddItemToOtherInventory('trunk', plate, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
end
else
print('Dupe Blocked - 12')
end
end
itemInfo = ItemList[fromItemData.name:lower()]
AddItemToOtherInventory('trunk', plate, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.trunk, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in trunk!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
elseif SplitStr(fromInventory, '-')[1] == 'glovebox' then
local plate = SplitStr(fromInventory, '-')[2]
local fromItemData = Gloveboxes[plate].items[fromSlot]
fromAmount = tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
local itemInfo = ItemList[fromItemData.name:lower()]
if toInventory == 'player' or toInventory == 'hotbar' then
local toItemData = GetItemBySlot(src, toSlot)
Debug('439')
local success = RemoveItemFromOtherInventory('glovebox', plate, fromSlot, itemInfo['name'], fromAmount, src)
if not success then
return Error('SetInventoryData', 'Glovebox', 'Item not found', src, fromSlot)
end
SendWebhook(Webhooks.glovebox, 'Remove Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') remove item from glovebox!**\nName:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
if toItemData then
itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'remove')
AddItemToOtherInventory('glovebox', plate, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: *' .. src .. ')* swapped item!**\n**Name:** ' .. toItemData.name .. '\n**Amount:** ' .. toAmount .. '\n**With item:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. toAmount .. '\n**Plate:** ' .. plate)
end
else
print('Dupe Blocked - 13')
end
end
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'add')
else
local toItemData = Gloveboxes[plate].items[toSlot]
Debug('463')
local success = RemoveItemFromOtherInventory('glovebox', plate, fromSlot, itemInfo['name'], fromAmount, src)
if not success then
return Error('SetInventoryData', 'Glovebox', 'Item not found', src, fromSlot)
end
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
Debug('trunk 473')
RemoveItemFromOtherInventory('glovebox', plate, toSlot, itemInfo['name'], toAmount, src)
AddItemToOtherInventory('glovebox', plate, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
end
else
print('Dupe Blocked - 14')
end
end
itemInfo = ItemList[fromItemData.name:lower()]
AddItemToOtherInventory('glovebox', plate, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.glovebox, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in glovebox!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Plate:** ' .. plate)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
elseif SplitStr(fromInventory, '-')[1] == 'stash' then
local stashId = SplitStr(fromInventory, '-')[2]
local fromItemData = Stashes[stashId].items[fromSlot]
fromAmount = tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
local itemInfo = ItemList[fromItemData.name:lower()]
if toInventory == 'player' or toInventory == 'hotbar' then
local toItemData = GetItemBySlot(src, toSlot)
Debug('496')
local success = RemoveItemFromOtherInventory('stash', stashId, fromSlot, itemInfo['name'], fromAmount, src)
if not success then
return Error('SetInventoryData', 'Stash', 'Item not found', src, fromSlot)
end
SendWebhook(Webhooks.stash, 'Remove Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') remove item from stash!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Stash id:** ' .. stashId)
if toItemData then
itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'remove')
AddItemToOtherInventory('stash', stashId, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. toItemData.name .. '\n**Amount:** ' .. toAmount .. '\n**With item:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Stash id:** ' .. stashId)
end
else
print('Dupe Blocked - 15')
end
end
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'add')
else
local toItemData = Stashes[stashId].items[toSlot]
Debug('522')
local success = RemoveItemFromOtherInventory('stash', stashId, fromSlot, itemInfo['name'], fromAmount, src)
if not success then
return Error('SetInventoryData', 'Stash', 'Item not found', src, fromSlot)
end
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
Debug('532')
RemoveItemFromOtherInventory('stash', stashId, toSlot, itemInfo['name'], toAmount, src)
AddItemToOtherInventory('stash', stashId, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
end
else
print('Dupe Blocked - 16')
end
end
itemInfo = ItemList[fromItemData.name:lower()]
AddItemToOtherInventory('stash', stashId, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.stash, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in stash!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Stash id:** ' .. stashId)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
elseif SplitStr(fromInventory, '_')[1] == 'garbage' then
local garbageId = SplitStr(fromInventory, '_')[2]
local fromItemData = GarbageItems[garbageId].items[fromSlot]
fromAmount = tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
local itemInfo = ItemList[fromItemData.name:lower()]
if toInventory == 'player' or toInventory == 'hotbar' then
local toItemData = GetItemBySlot(src, toSlot)
RemoveFromGarbage(garbageId, fromSlot, itemInfo['name'], fromAmount)
SendWebhook(Webhooks.garbage, 'Remove Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') remove item from drop!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Garbage id:** ' .. garbageId)
if toItemData then
itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'remove')
AddToGarbage(garbageId, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'])
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** **' .. toItemData.name .. '\n**Amount:** ' .. toAmount .. '\n**With item:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Garbage id:** ' .. garbageId)
end
else
print('Dupe Blocked - 17')
end
end
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'add')
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
else
local toItemData = GarbageItems[garbageId].items[toSlot]
RemoveFromGarbage(garbageId, fromSlot, itemInfo['name'], fromAmount)
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
RemoveFromGarbage(garbageId, toSlot, itemInfo['name'], toAmount)
AddToGarbage(garbageId, fromSlot, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'])
end
else
print('Dupe Blocked - 18')
end
end
itemInfo = ItemList[fromItemData.name:lower()]
AddToGarbage(garbageId, toSlot, fromSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'])
SendWebhook(Webhooks.garbage, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in garbage!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Garbage id:** ' .. garbageId)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
elseif SplitStr(fromInventory, '-')[1] == 'traphouse' then
local traphouseId = SplitStr(fromInventory, '-')[2]
local fromItemData = exports['qb-traphouse']:GetInventoryData(traphouseId, fromSlot)
fromAmount = tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
local itemInfo = ItemList[fromItemData.name:lower()]
if toInventory == 'player' or toInventory == 'hotbar' then
local toItemData = GetItemBySlot(src, toSlot)
exports['qb-traphouse']:RemoveHouseItem(traphouseId, fromSlot, itemInfo['name'], fromAmount)
if toItemData then
itemInfo = ItemList[toItemData.name:lower()]
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'remove')
exports['qb-traphouse']:AddHouseItem(traphouseId, fromSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. toItemData.name .. '\n**Amount:** ' .. toAmount .. '\n**With item:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Stash id:** ' .. traphouseId)
end
else
print('Dupe Blocked - 19')
end
end
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'add')
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
else
local toItemData = exports['qb-traphouse']:GetInventoryData(traphouseId, toSlot)
exports['qb-traphouse']:RemoveHouseItem(traphouseId, fromSlot, itemInfo['name'], fromAmount)
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
exports['qb-traphouse']:RemoveHouseItem(traphouseId, toSlot, itemInfo['name'], toAmount)
exports['qb-traphouse']:AddHouseItem(traphouseId, fromSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'], src)
end
else
print('Dupe Blocked - 20')
end
end
itemInfo = ItemList[fromItemData.name:lower()]
exports['qb-traphouse']:AddHouseItem(traphouseId, toSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'], src)
SendWebhook(Webhooks.traphouse, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in traphouse!\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Traphouse id:** ' .. traphouseId)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
elseif SplitStr(fromInventory, '-')[1] == 'itemshop' then
local shopType = SplitStr(fromInventory, '-')[2]
local shop = RegisteredShops[shopType]
if not shop or not shop.items then return Error('SetInventoryData', 'Wrong shop setup', 'Shop not found', src, fromSlot) end
local itemData = shop.items[fromSlot]
if not itemData or not itemData.name then return Error('SetInventoryData', 'Wrong shop setup', 'Item not found', src, fromSlot) end
local itemInfo = ItemList[itemData.name:lower()]
local price = tonumber((itemData.price * fromAmount))
local money = GetAccountMoney(src, RegisteredShops[shopType].account or 'money')
if GetResourceState('ps_mdt') == 'started' then
local isWeapon = SplitStr(itemData.name, '_')[1] == 'weapon'
local identifier = GetPlayerIdentifier(src)
local InventoryFolder = 'nui://qs-inventory/html/images/'
if isWeapon then
itemData.info.serie = CreateSerialNumber()
itemData.info.quality = 100
exports['ps-mdt']:CreateWeaponInfo(itemData.info.serie, InventoryFolder .. itemData.image, itemData.description, GetUserName(identifier), itemData.type, itemData.name)
end
end
if itemData.name == 'tradingcard_psa' then
itemData.info = {
serial = CreateSerialNumber(),
}
end
if SplitStr(shopType, '_')[1] == 'Dealer' then
local isWeapon = SplitStr(itemData.name, '_')[1] == 'weapon'
if isWeapon then
price = tonumber(itemData.price)
if money >= price then
if NotStoredItems(itemData.name, src, 1) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:forceCloseInventory', source)
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_CANT_TAKE_MORE') .. ' ' .. itemInfo['label'], 'inform')
end
RemoveAccountMoney(src, 'money', price or 0)
itemData.info.serie = CreateSerialNumber()
itemData.info.quality = 100
AddItem(src, itemData.name, 1, toSlot, itemData.info, nil, nil, nil, true)
TriggerClientEvent('qb-drugs:client:updateDealerItems', src, itemData, 1)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, itemInfo['label'] .. ' ' .. Lang('INVENTORY_NOTIFICATION_BOUGHT'), 'success')
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. '** bought a ' .. itemInfo['label'] .. ' for €' .. price)
hook:trigger('buyItem', {
source = src,
itemName = itemData.name,
amount = 1,
metadata = itemData.info,
info = itemData.info,
externalMeta = {
shopType = shopType
}
})
if isWeapon then
TriggerClientEvent(Config.InventoryPrefix .. ':client:forceCloseInventory', src)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_MONEY'), 'error')
return
end
else
if money >= price then
if NotStoredItems(itemData.name, src, fromAmount) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:forceCloseInventory', source)
return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_CANT_TAKE_MORE') .. ' ' .. itemInfo['label'], 'inform')
end
RemoveAccountMoney(src, 'money', price or 0)
AddItem(src, itemData.name, fromAmount, toSlot, itemData.info, nil, nil, nil, true)
TriggerClientEvent('qb-drugs:client:updateDealerItems', src, itemData, fromAmount)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, itemInfo['label'] .. ' ' .. Lang('INVENTORY_NOTIFICATION_BOUGHT'), 'success')
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. '** bought a ' .. itemInfo['label'] .. ' for €' .. price)
hook:trigger('buyItem', {
source = src,
itemName = itemData.name,
amount = fromAmount,
metadata = itemData.info,
info = itemData.info,
externalMeta = {
shopType = shopType
}
})
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_MONEY'), 'error')
return
end
end
elseif SplitStr(shopType, '_')[1] == 'Itemshop' then
if money >= price then
RemoveAccountMoney(src, RegisteredShops[shopType].account, price or 0)
local isWeapon = SplitStr(itemData.name, '_')[1] == 'weapon'
if isWeapon then
itemData.info.serie = CreateSerialNumber()
itemData.info.quality = 100
end
AddItem(src, itemData.name, fromAmount, toSlot, itemData.info, nil, nil, nil, true)
TriggerEvent('qb-shops:server:UpdateShopItems', shopType, itemData, fromAmount)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, itemInfo['label'] .. ' ' .. Lang('INVENTORY_NOTIFICATION_BOUGHT'), 'success')
SendWebhook(Webhooks.bought, 'Shop item bought', 7393279, '**' .. GetPlayerName(src) .. '** bought a ' .. itemInfo['label'] .. ' for €' .. price)
hook:trigger('buyItem', {
source = src,
itemName = itemData.name,
amount = fromAmount,
metadata = itemData.info,
info = itemData.info,
externalMeta = {
shopType = shopType
}
})
if isWeapon then
TriggerClientEvent(Config.InventoryPrefix .. ':client:forceCloseInventory', src)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_MONEY'), 'error')
return
end
else
if money >= price then
RemoveAccountMoney(src, RegisteredShops[shopType].account, price or 0)
TriggerEvent('qb-shops:server:UpdateShopItems', shopType, itemData, fromAmount)
AddItem(src, itemData.name, fromAmount, toSlot, itemData.info, nil, nil, nil, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, itemInfo['label'] .. ' ' .. Lang('INVENTORY_NOTIFICATION_BOUGHT'), 'success')
SendWebhook(Webhooks.bought, 'Shop item bought', 7393279, '**' .. GetPlayerName(src) .. '** bought a ' .. itemInfo['label'] .. ' for €' .. price)
hook:trigger('buyItem', {
source = src,
itemName = itemData.name,
amount = fromAmount,
metadata = itemData.info,
info = itemData.info,
externalMeta = {
shopType = shopType
}
})
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_MONEY'), 'error')
return
end
end
elseif fromInventory == 'crafting' then
local itemData = OpenedSecondInventories[src].inventory[fromSlot]
if hasCraftItems(src, itemData.costs, fromAmount) then
if not NotStoredItems(itemData.name, src, fromAmount) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CraftItems', src, itemData.name, itemData.costs, itemData.points, fromAmount, toSlot, itemData.rep, itemData.time, itemData.chance)
SendWebhook(Webhooks.crafting, 'Crafting item', 7393279, '**' .. GetPlayerName(src) .. '**\nItem crafted:** ' .. itemData.name .. '\n**Timer:** ' .. itemData.time * fromAmount .. '\n**Amount:** ' .. fromAmount)
Debug('Started ' .. itemData.name .. ' with a delay time of ' .. itemData.time * fromAmount .. ', quantity ' .. fromAmount)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANT_TAKE_MORE') .. ' ' .. itemData.name, 'inform')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEMS'), 'error')
end
elseif fromInventory == 'customcrafting' then
local itemData = (CustomCraftingInfos)[fromSlot]
if hasCraftItems(src, itemData.costs, fromAmount) then
if not NotStoredItems(itemData.name, src, fromAmount) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:CraftItems', src, itemData.name, itemData.costs, itemData.points, fromAmount, toSlot, itemData.rep, itemData.time, itemData.chance)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANT_TAKE_MORE') .. ' ' .. itemData.name, 'inform')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', src, true)
TriggerClientEvent('qs-inventory:sendMessage', src, Lang('CRAFTING_ERROR'), 'error')
end
else
-- drop
fromInventoryFormatter = SplitStr(fromInventory, '-')[2]
fromInventory = tonumber(fromInventoryFormatter)
local fromItemData = Drops[fromInventory].items[fromSlot]
fromAmount = tonumber(fromAmount) or fromItemData.amount
if fromItemData and fromItemData.amount >= fromAmount then
local itemInfo = ItemList[fromItemData.name:lower()]
if toInventory == 'player' or toInventory == 'hotbar' then
local toItemData = GetItemBySlot(src, toSlot)
RemoveFromDrop(fromInventory, fromSlot, itemInfo['name'], fromAmount)
SendWebhook(Webhooks.drop, 'Remove Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') remove item from drop!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Drop id:** ' .. fromInventory)
if toItemData then
toAmount = tonumber(toAmount) and tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
RemoveItem(src, toItemData.name, toAmount, toSlot, nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, toItemData, toAmount, 'remove')
AddToDrop(fromInventory, toSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'])
SendWebhook(Webhooks.swap, 'Swapped Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') swapped item!**\n**Name:** ' .. toItemData.name .. '\n**Amount:** ' .. toAmount .. '\n**With item:** ' .. fromItemData.name .. '\n**Amount:** ' .. fromAmount .. '\n**Dropid:** ' .. fromInventory)
if itemInfo['name'] == 'radio' then
TriggerClientEvent('Radio.Set', src, false)
elseif itemInfo['name'] == 'money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'money')
Player.setAccountMoney('money', money, 'dropped')
elseif itemInfo['name'] == 'black_money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'black_money')
Player.setAccountMoney('black_money', money, 'dropped')
end
TriggerClientEvent(Config.InventoryPrefix .. ':ClearWeapons', src)
end
else
print('Dupe Blocked - 21')
end
end
AddItem(src, fromItemData.name, fromAmount, toSlot, fromItemData.info, nil, fromItemData['created'], nil, true)
TriggerEvent(Config.InventoryPrefix .. ':server:updateCash', src, fromItemData, fromAmount, 'add')
else
toInventoryFormatter = SplitStr(toInventory, '-')[2]
toInventory = tonumber(toInventoryFormatter)
local toItemData = Drops[toInventory].items[toSlot]
RemoveFromDrop(fromInventory, fromSlot, itemInfo['name'], fromAmount)
if toItemData then
toAmount = tonumber(toAmount) or toItemData.amount
if toItemData.amount >= toAmount then
if toItemData.name ~= fromItemData.name then
itemInfo = ItemList[toItemData.name:lower()]
RemoveFromDrop(toInventory, toSlot, itemInfo['name'], toAmount)
AddToDrop(fromInventory, fromSlot, itemInfo['name'], toAmount, toItemData.info, fromItemData['created'])
if itemInfo['name'] == 'radio' then
TriggerClientEvent('Radio.Set', src, false)
elseif itemInfo['name'] == 'money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'money')
Player.setAccountMoney('money', money, 'dropped')
elseif itemInfo['name'] == 'black_money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'black_money')
Player.setAccountMoney('black_money', money, 'dropped')
end
TriggerClientEvent(Config.InventoryPrefix .. ':ClearWeapons', src)
end
else
print('Dupe Blocked - 22')
end
end
itemInfo = ItemList[fromItemData.name:lower()]
AddToDrop(toInventory, toSlot, itemInfo['name'], fromAmount, fromItemData.info, fromItemData['created'])
SendWebhook(Webhooks.drop, 'Deposit Item', 7393279, '**' .. GetPlayerName(src) .. ' (id: ' .. src .. ') deposit item in drop!**\n**Name:** ' .. itemInfo['name'] .. '\n**Amount:** ' .. fromAmount .. '\n**Drop id:** ' .. toInventory)
if itemInfo['name'] == 'radio' then
TriggerClientEvent('Radio.Set', src, false)
elseif itemInfo['name'] == 'money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'money')
Player.setAccountMoney('money', money, 'dropped')
elseif itemInfo['name'] == 'black_money' and Config.Framework == 'esx' then
local money = GetItemTotalAmount(src, 'black_money')
Player.setAccountMoney('black_money', money, 'dropped')
end
TriggerClientEvent(Config.InventoryPrefix .. ':ClearWeapons', src)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_MISSING_ITEM'), 'error')
end
end
end)
-- In the future we will be use this. (In the W.I.P)
-- local function updateToItemData(src, inventoryType, toSlot, toAmount, fromItemData)
-- local toItemData = GetItemBySlot(src, toSlot)
-- if not toItemData then
-- Error('The player is trying to move an item that does not exist', src, 'inventoryType:', inventoryType, 'toSlot:', toSlot)
-- return false
-- end
-- toAmount = tonumber(toAmount) or toItemData.amount
-- if toItemData.amount < toAmount then
-- Error('The player is trying to move an item but the item does not have enough amount', src, 'toItemData:', toItemData, 'toAmount:', toAmount)
-- return false
-- end
-- if toItemData.name == fromItemData.name then
-- Error('The player is trying to move the same item', src, 'toItemData:', toItemData, 'fromItemData:', fromItemData)
-- return false
-- end
-- end
-- function SetInventoryData(fromInventory, toInventory, fromSlot, toSlot, fromAmount, toAmount, fromInventoryIsClothesInventory, toInventoryIsClothesInventory, craftingKey)
-- local src = source
-- local player = GetPlayerFromId(src)
-- fromSlot = tonumber(fromSlot)
-- toSlot = tonumber(toSlot)
-- if not fromSlot or not toSlot then return Error('SetInventoryData', 'fromSlot or toSlot is nil', src) end
-- local identifier = GetPlayerIdentifier(src)
-- if not identifier then return Error('SetInventoryData', 'Identifier is nil', src) end
-- if (fromInventory == 'player' or fromInventory == 'hotbar') and (SplitStr(toInventory, '-')[1] == 'itemshop' or toInventory == 'crafting' or toInventory == 'customcrafting') then
-- return Debug('SetInventoryData', 'Player', 'ItemShop', 'Crafting', src)
-- end
-- if fromInventoryIsClothesInventory and toInventoryIsClothesInventory then
-- return Debug('SetInventoryData', 'Clothing', 'Clothing', src)
-- end
-- if (SplitStr(fromInventory, '-')[1] == 'selling') then
-- return Debug('SetInventoryData', 'Selling', src)
-- end
-- if fromInventoryIsClothesInventory then
-- return RemoveClotheFromInventoryData(src, fromSlot, toSlot, identifier)
-- elseif toInventoryIsClothesInventory then
-- return AddClotheFromInventoryData(src, fromSlot, identifier)
-- end
-- local toInventorySplitted = SplitStr(toInventory, '-')[1]
-- if toInventorySplitted == 'selling' then
-- return SellItemToSelling(src, fromInventory, fromSlot, fromAmount, toInventory, toSlot)
-- end
-- if fromInventory == 'player' or fromInventory == 'hotbar' then
-- local fromItemData = GetItemBySlot(src, fromSlot)
-- fromAmount = tonumber(fromAmount) or fromItemData.amount
-- if not fromItemData or fromItemData.amount < fromAmount then
-- Error('The player is trying to move an item that does not exist or does not have enough amount', fromItemData, fromAmount)
-- Notification(src, Lang('INVENTORY_NOTIFICATION_GIVE_DONT_HAVE'), 'error')
-- return
-- end
-- local success = RemoveItem(src, fromItemData.name, fromAmount, fromSlot, nil, true)
-- if not success then
-- Error('The player is trying to move an item but remove item function return false', fromItemData, fromAmount, fromSlot)
-- Notification(src, Lang('INVENTORY_NOTIFICATION_GIVE_DONT_HAVE'), 'error')
-- return
-- end
-- TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, fromItemData.name)
-- end
-- end

View File

@@ -0,0 +1,34 @@
function UseItem(itemName, ...)
local itemData = GetUsableItem(itemName)
local source, item = table.unpack({ ... })
local _item = ItemList[itemName]
if not _item then
Error('Item not found in item list:', itemName)
return
end
if _item.job then
if not table.includes(_item.job, GetJobName(source)) then
Notification(source, Lang('INVENTORY_NOTIFICATION_ITEM_NOT_FOR_YOUR_JOB'), 'error')
return
end
end
-- print('client', _item.client)
if _item.client then
if _item.client?.removeAfterUse then
RemoveItem(source, itemName, 1, item.slot)
end
lib.callback.await('inventory:itemUsed', source, item)
end
TriggerEvent('inventory:usedItem', itemName, ...)
local callback = type(itemData) == 'table' and (rawget(itemData, '__cfx_functionReference') and itemData or itemData.cb or itemData.callback or itemData.func) or type(itemData) == 'function' and itemData
if not callback then return end
local success, result = pcall(callback, ...)
if not success then
Error('Error while using item:', itemName)
Error('Callback result:', result)
return
end
end
exports('UseItem', UseItem)

View File

@@ -0,0 +1,21 @@
RegisterNetEvent(Config.InventoryPrefix .. ':server:UseItemSlot', function(slot)
local src = source
local itemData = GetItemBySlot(src, slot)
if not itemData or not Config.UsableItemsFromHotbar then return end
local isBlocked = false
for _, blockedItem in ipairs(Config.BlockedItemsHotbar) do
if blockedItem == itemData.name then
isBlocked = true
break
end
end
if isBlocked then
Debug('The [' .. itemData.name .. '] item cannot be used from hotbar, check Config.BlockedItemsHotbar!')
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_CANNOT_BE_USED'), 'inform')
return
end
useItemSlot(src, itemData)
end)

View File

@@ -0,0 +1,133 @@
lib.callback.register('inventory:admin:getOnlinePlayers', function(source)
if not PlayerIsAdmin(source) then
return {}
end
local players = {}
local esxPlayers = FrameworkGetPlayers()
for _, playerId in ipairs(esxPlayers) do
local identifier = GetPlayerIdentifier(playerId)
if identifier then
table.insert(players, {
id = playerId,
name = GetPlayerName(playerId),
identifier = identifier,
coords = GetEntityCoords(GetPlayerPed(playerId))
})
end
end
return players
end)
-- Admin give item function
lib.callback.register('inventory:admin:giveItem', function(source, targetId, itemName, amount, metadata)
if not PlayerIsAdmin(source) then
return false, Lang('INVENTORY_ADMIN_NO_PERMISSION')
end
targetId = tonumber(targetId)
local targetPlayer = GetPlayerFromId(targetId)
if not targetPlayer then
return false, Lang('INVENTORY_ADMIN_TARGET_NOT_FOUND')
end
if not ItemList[itemName] then
return false, Lang('INVENTORY_ADMIN_INVALID_ITEM')
end
local itemData = ItemList[itemName]
local finalAmount = tonumber(amount) or 1
-- Check if item is unique and amount is more than 1
if itemData.unique and finalAmount > 1 then
return false, Lang('INVENTORY_ADMIN_ITEM_UNIQUE')
end
-- Parse metadata if provided
local parsedMetadata = {}
if metadata and metadata ~= '' then
local success, result = pcall(json.decode, metadata)
if success and type(result) == 'table' then
parsedMetadata = result
end
end
-- Give the item
local success = AddItem(targetId, itemName, finalAmount, false, parsedMetadata)
if success then
-- Log the action
local adminName = GetPlayerName(source)
local targetName = GetPlayerName(targetId)
local itemLabel = itemData.label
Debug(string.format('^3[ADMIN GIVEITEM]^7 %s (%d) gave %d x %s to %s (%d)',
adminName, source, finalAmount, itemLabel, targetName, targetId))
-- Send webhook if configured
if Webhooks and Webhooks.admin then
SendWebhook(Webhooks.admin, 'Admin Give Item', 7393279,
string.format('**%s** (ID: %d) gave **%d x %s** to **%s** (ID: %d)',
adminName, source, finalAmount, itemLabel, targetName, targetId))
end
-- Notify both players with string.format and Lang
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source,
string.format('%d x %s ' .. Lang('INVENTORY_ADMIN_NOTIFICATION_SUCCESSFULLY_GIVEN'), finalAmount, itemLabel), 'success')
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', targetId,
string.format(Lang('INVENTORY_ADMIN_NOTIFICATION_GIVEN_TO') .. ' %d x %s ', finalAmount, itemLabel), 'inform')
-- Update target player's inventory
TriggerClientEvent(Config.InventoryPrefix .. ':client:UpdatePlayerInventory', targetId, true)
return true, string.format('%d x %s ' .. Lang('INVENTORY_ADMIN_NOTIFICATION_RECEIVED'), finalAmount, itemLabel)
else
return false, Lang('INVENTORY_ADMIN_ITEM_NOT_GIVEN')
end
end)
RegisterCommand('admin_giveitem', function(source, args, rawCommand)
if not PlayerIsAdmin(source) then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_ADMIN_NO_PERMISSION'), 'error')
return
end
TriggerClientEvent('inventory:admin:openGiveItemInterface', source)
end, false)
-- Search players by name or ID
lib.callback.register('inventory:admin:searchPlayers', function(source, searchTerm)
if not PlayerIsAdmin(source) then
return {}
end
local players = {}
local esxPlayers = FrameworkGetPlayers()
local searchLower = string.lower(searchTerm or '')
for _, playerId in ipairs(esxPlayers) do
local identifier = GetPlayerIdentifier(playerId)
if identifier then
local playerName = GetPlayerName(playerId)
local playerNameLower = string.lower(playerName)
if searchLower == '' or
string.find(playerNameLower, searchLower, 1, true) or
tostring(playerId) == searchTerm or
string.find(string.lower(identifier), searchLower, 1, true) then
table.insert(players, {
id = playerId,
name = playerName,
identifier = identifier,
coords = GetEntityCoords(GetPlayerPed(playerId))
})
end
end
end
return players
end)

View File

@@ -0,0 +1,143 @@
RegisterCommand('searchplayer', function(source)
TriggerClientEvent(Config.InventoryPrefix .. ':client:search', source)
end, false)
RegisterCommand('openinventorytarget', function(source, args, rawCommand)
local Player = GetPlayerFromId(source)
local group = PlayerIsAdmin(source)
if args[1] and group then
local id = tonumber(args[1])
local targetPlayer = GetPlayerFromId(id)
if targetPlayer then
TriggerClientEvent(Config.InventoryPrefix .. ':client:OpenInventoryAdmin', source, id)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_PLAYER_OFFLINE'), 'error')
end
end
end)
RegisterCommand('giveitem', function(source, args)
local group = PlayerIsAdmin(source)
if not group then return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_ADMIN'), 'error') end
local id = tonumber(args[1])
local target = GetPlayerFromId(id)
local item = args[2]
local amount = tonumber(args[3]) or 1
if not target then return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_PLAYER_OFFLINE'), 'error') end
GiveItemToPlayer(id, item, amount)
end)
RegisterCommand('giveweapon', function(source, args)
local group = PlayerIsAdmin(source)
if not group then return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_ADMIN'), 'error') end
local id = tonumber(args[1])
local target = GetPlayerFromId(id)
local item = args[2]
local amount = tonumber(args[3]) or 1
if not target then return TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_PLAYER_OFFLINE'), 'error') end
GiveWeaponToPlayer(id, item, amount)
end)
RegisterCommand('clearinv', function(source, args)
local group = PlayerIsAdmin(source)
if not group then return end
local playerId = args[1] ~= '' and tonumber(args[1]) or source
local target = GetPlayerFromId(playerId)
if target then
ClearInventory(playerId)
SetCurrentPedWeapon(playerId, `WEAPON_UNARMED`, true)
RemoveAllPedWeapons(playerId, true)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_PLAYER_OFFLINE'), 'error')
end
end)
RegisterCommand('repairweapon', function(source, args)
local isAdmin = PlayerIsAdmin(source)
if not isAdmin then return end
TriggerClientEvent('weapons:client:SetWeaponQuality', source, tonumber(args[1]))
end, true)
RegisterCommand('randomitems', function(source, args)
local group = PlayerIsAdmin(source)
if not group then return end
local filteredItems = {}
for k, v in pairs(ItemList) do
if ItemList[k]['type'] ~= 'weapon' then
filteredItems[#filteredItems + 1] = v
end
end
for _ = 1, 10, 1 do
local randitem = filteredItems[math.random(1, #filteredItems)]
local amount = math.random(1, 10)
if randitem['unique'] then
amount = 1
end
if AddItem(source, randitem['name'], amount) then
Wait(500)
end
end
end, false)
RegisterCommand('dataitem', function(source)
local src = source
local group = PlayerIsAdmin(src)
if not group then return end
local plate = math.random(1111, 9999)
local model = 'Zentorno'
AddItem(src, 'lockpick', 1, nil, { Plate = plate, Model = model, Info = 'Is a good car!' }, true)
end, false)
RegisterCommand('resetinv', function(source, args)
if not PlayerIsAdmin(source) then return end
local invType = args[1]:lower()
table.remove(args, 1)
local invId = table.concat(args, ' ')
if invType and invId then
if invType == 'trunk' then
if Trunks[invId] then
Trunks[invId].isOpen = false
end
elseif invType == 'glovebox' then
if Gloveboxes[invId] then
Gloveboxes[invId].isOpen = false
end
elseif invType == 'stash' then
if Stashes[invId] then
Stashes[invId].isOpen = false
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_INVALID_TYPE'), 'error')
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', source, Lang('INVENTORY_NOTIFICATION_INVALID_ARGUMENTS'), 'error')
end
end)
RegisterCommand('checkitem', function(source)
local item = GetItemByName(source, 'tosti')
return print('Tosti item amount:', item and item.amount or 0)
end)
RegisterCommand('rob', function(source)
if Config.Framework == 'esx' then return end
TriggerClientEvent('police:client:RobPlayer', source)
end)
RegisterCommand('invitems', function(source)
if Config.Framework == 'qb' then return end
local playerId = tonumber(source)
local xPlayer = GetPlayerFromId(playerId)
local inventory = xPlayer.getInventory(playerId)
if not inventory or #inventory == 0 then
return print('Your inventory is empty')
end
for _, item in pairs(inventory) do
print('Item: ' .. item.name .. ' - Amount: ' .. item.count)
end
end)

View File

@@ -0,0 +1,56 @@
if GetResourceState('evo-k9-v2') ~= 'started' then
return
end
function evok9CheckPlayerInventoryItems(playerId)
return exports['qs-inventory']:GetInventory(playerId)
end
exports('evok9CheckPlayerInventoryItems', evok9CheckPlayerInventoryItems)
function evok9CheckInventoryItems(Identifier, InvType, cb)
if not Identifier or not InvType then
return cb({})
end
local queries = {
trunk = 'SELECT * FROM inventory_trunk WHERE plate = @identifier',
glovebox = 'SELECT * FROM inventory_glovebox WHERE plate = @identifier'
}
local query = queries[InvType]
if not query then
return cb({})
end
MySQL.Async.fetchAll(query, { ['@identifier'] = Identifier }, function(result)
if result[1] and result[1].items then
local items = json.decode(result[1].items) or {}
if type(items) ~= "table" then
return cb({})
end
local FormattedItems = {}
for _, v in pairs(items) do
table.insert(FormattedItems, {
name = v.name or 'unknown',
label = v.label or v.name or 'Unknown Item',
amount = v.amount or 1,
weight = v.weight or 0,
image = v.image or 'default.png',
unique = v.unique or false,
info = v.info or {},
slot = v.slot or 0
})
end
return cb(FormattedItems)
else
return cb({})
end
end)
end
exports('evok9CheckInventoryItems', evok9CheckInventoryItems)

View File

@@ -0,0 +1,33 @@
---@param item string
---@param source number
---@param amount number
function NotStoredItems(item, source, amount)
if not amount then
Debug('Amount not provided, set to 1', item, source)
amount = 1
end
local itemsWithCommonLimit = {
['backpack'] = true,
['backpack2'] = true,
['briefcase'] = true,
['paramedicbag'] = true
-- Add more backpack types here
}
local maxAllowed = Config.OnePerItem['backpack'] -- Default max for backpack
if itemsWithCommonLimit[item] then
local checkItem = GetItemTotalAmount(source, 'backpack')
Debug('Check unique item ' .. item .. ', you have ' .. checkItem .. ', max: ' .. maxAllowed)
return checkItem >= maxAllowed
end
maxAllowed = Config.OnePerItem[item]
if maxAllowed then
local checkItem = GetItemTotalAmount(source, item) + amount
Debug('Check unique item ' .. item .. ', you have ' .. checkItem .. ', max: ' .. maxAllowed)
return checkItem > maxAllowed
end
return false
end

View File

@@ -0,0 +1,24 @@
--[[
Welcome webhooks setup!
Here you will have the link to configure the admin webhooks,
you can modify them from server/custom/misc/SetInventoryData.lua.
]]
Webhooks = Webhooks or {}
Webhooks = {
['exploit'] = '',
['admin'] = '',
['bought'] = '',
['sell'] = '',
['swap'] = '',
['drop'] = '',
['stash'] = '',
['trunk'] = '',
['garbage'] = '',
['robbery'] = '',
['glovebox'] = '',
['giveitem'] = '',
['crafting'] = '',
['traphouse'] = '',
}

View File

@@ -0,0 +1,443 @@
local function IsWeaponBlocked(WeaponName)
local retval = false
for _, name in pairs(Config.DurabilityBlockedWeapons) do
if name == WeaponName then
retval = true
break
end
end
return retval
end
local function HasAttachment(component, attachments)
local retval = false
local key = nil
for k, v in pairs(attachments) do
if v.component == component then
key = k
retval = true
end
end
return retval, key
end
local function GetAttachmentType(attachments)
local attype = nil
for _, v in pairs(attachments) do
attype = v.type
end
return attype
end
function Split(s, delimiter)
if type(s) ~= 'string' then
Error('The other inventory name is broken! `s` is not a string. S is', s, 'Please fix it. it need to be a string.')
return {}
end
result = {};
if not s then return Wait(100) end
for match in (s .. delimiter):gmatch('(.-)' .. delimiter) do
table.insert(result, match);
end
return result;
end
RegisterNetEvent('weapons:reloadWeapon', function(ammoType)
local src = source
local player = GetPlayerFromId(src)
local items = GetItems(player)
if not ammoType then
Error('Your weapons.lua is broken! AMMO_TYPE is not found. Please follow our docs and use our qb-core if it needs!')
return
end
ammoType = type(ammoType) == 'table' and ammoType or { ammoType }
local ammoItems = {}
for k, v in pairs(ammoType) do
local item = table.find(Config.AmmoItems, function(item) return item.type == v end)
if item then
ammoItems[#ammoItems + 1] = item.item
end
end
local item
for k, v in pairs(items) do
if v.name == table.find(Config.AmmoItems, function(item) return item.isForEveryWeapon end).item then
item = v
break
end
if table.includes(ammoItems, v.name) then
item = v
break
end
end
if not item then
return
end
lib.callback.await('weapons:addAmmo', src, item)
end)
lib.callback.register('weapons:GetWeaponAmmoItem', function(source, ammoType, checkMaster)
local player = GetPlayerFromId(source)
local items = GetItems(player)
if not ammoType then
Error('Your weapons.lua is broken! AMMO_TYPE is not found. Please follow our docs and use our qb-core if it needs!')
return
end
ammoType = type(ammoType) == 'table' and ammoType or { ammoType }
local ammoItems = {}
for k, v in pairs(ammoType) do
local item = table.find(Config.AmmoItems, function(item) return item.type == v end)
if item then
ammoItems[#ammoItems + 1] = item.item
end
end
Debug('ammoType', ammoType)
for k, v in pairs(items) do
if checkMaster and v.name == table.find(Config.AmmoItems, function(item) return item.isForEveryWeapon end).item then
return v
end
if table.includes(ammoItems, v.name) then
return v
end
end
return false
end)
RegisterServerCallback('weapon:server:GetWeaponAmmo', function(source, cb, WeaponData)
local retval = 0
if WeaponData then
local ItemData = GetItemBySlot(source, WeaponData.slot)
if ItemData then
retval = ItemData.info.ammo and ItemData.info.ammo or 0
end
end
cb(retval, WeaponData.name)
end)
RegisterServerCallback('weapons:server:RemoveAttachment', function(source, cb, AttachmentData, ItemData)
local src = source
local Inventory = GetItems(GetPlayerFromId(src))
Debug('Attachmentdata', AttachmentData)
local AttachmentComponent = Config.WeaponAttachments[ItemData.name:upper()][AttachmentData.attachment]
if Inventory[ItemData.slot] then
if Inventory[ItemData.slot].info.attachments and next(Inventory[ItemData.slot].info.attachments) then
Debug('AttachmentComponent:', AttachmentComponent)
local HasAttach, key = HasAttachment(AttachmentComponent.component, Inventory[ItemData.slot].info.attachments)
if HasAttach then
if Inventory[ItemData.slot].info.tinturl and AttachmentComponent.item == 'weapontint_url' then
local info = {}
info.urltint = tostring(Inventory[ItemData.slot].info.tinturl)
AddItem(src, 'weapontint_url', 1, false, info)
end
if AttachmentComponent.item ~= 'weapontint_url' then
AddItem(src, AttachmentComponent.item, 1)
end
table.remove(Inventory[ItemData.slot].info.attachments, key)
SetItemMetadata(src, ItemData.slot, Inventory[ItemData.slot].info)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_ATTACHMENT_REMOVED') .. ' ' .. ItemList[AttachmentComponent.item].label, 'success')
cb(Inventory[ItemData.slot].info.attachments)
if Config.RemoveTintAfterRemoving then
if AttachmentData.tint or AttachmentData.tinturl then
Debug('An Tint was permanently removed')
RemoveItem(src, AttachmentData.item, 1)
end
end
Wait(200)
TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src, Inventory[ItemData.slot], false, AttachmentComponent.component)
TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src)
else
cb(false)
end
else
cb(false)
end
else
cb(false)
end
end)
RegisterServerCallback('weapons:server:RepairWeapon', function(source, cb, RepairPoint, data)
local src = source
local Player = GetPlayerFromId(src)
local identifier = GetPlayerIdentifier(src)
local minute = 60 * 1000
local Timeout = math.random(5 * minute, 10 * minute)
local WeaponData = WeaponList[GetHashKey(data.name)]
local items = GetItems(Player)
if items[data.slot] then
if items[data.slot].info.quality then
if items[data.slot].info.quality ~= 100 then
local cash = GetAccountMoney(src, 'money')
if cash >= Config.WeaponRepairCosts[WeaponData.weapontype] then
items[data.slot].info.quality = 100
SetItemMetadata(src, data.slot, items[data.slot].info)
TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, data.name)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_TEXT_REPAIR_REPAIRED'), 'error')
RemoveAccountMoney(src, 'money', Config.WeaponRepairCosts[WeaponData.weapontype])
cb(true)
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_MONEY'), 'error')
cb(false)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_BROKEN'), 'error')
cb(false)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_BROKEN'), 'error')
cb(false)
end
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_WEAPON'), 'error')
TriggerClientEvent('weapons:client:SetCurrentWeapon', src, {}, false)
cb(false)
end
end)
RegisterServerCallback('prison:server:checkThrowable', function(source, cb, weapon)
local Player = GetPlayerFromId(source)
if not Player then return cb(false) end
local throwable = false
for _, v in pairs(Config.Throwables) do
if WeaponList[weapon].name == 'weapon_' .. v then
RemoveItem(source, v, 1)
throwable = true
break
end
end
cb(throwable)
end)
RegisterNetEvent('weapons:server:UpdateWeaponAmmo', function(CurrentWeaponData, amount)
local src = source
local Player = GetPlayerFromId(src)
local items = GetItems(Player)
amount = tonumber(amount)
if CurrentWeaponData then
if items[CurrentWeaponData.slot] then
items[CurrentWeaponData.slot].info.ammo = amount
local success = SetItemMetadata(src, CurrentWeaponData.slot, items[CurrentWeaponData.slot].info)
Debug('weapons:server:UpdateWeaponAmmo', success)
else
Debug('CurrentWeaponData is nil')
end
else
Debug('CurrentWeaponData is nil')
end
end)
RegisterNetEvent('weapons:server:TakeBackWeapon', function(k)
local src = source
local itemdata = Config.WeaponRepairPoints[k].RepairingData.WeaponData
itemdata.info.quality = 100
AddItem(src, itemdata.name, 1, nil, itemdata.info)
Config.WeaponRepairPoints[k].IsRepairing = false
Config.WeaponRepairPoints[k].RepairingData = {}
TriggerClientEvent('weapons:client:SyncRepairShops', -1, Config.WeaponRepairPoints[k], k)
end)
---@param data ServerProgressBar
function ProgressBarSync(src, data)
return lib.callback.await('inventory:progressBarSync', src, data)
end
CreateUsableItem('weapon_repairkit', function(source, item)
local src = source
local Player = GetPlayerFromId(src)
local items = GetItems(Player)
local currentWeapon = lib.callback.await('weapons:client:GetCurrentWeapon', src)
if not currentWeapon then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_REPAIR_HANDS'), 'error')
return
end
if currentWeapon?.info?.quality == 100 then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_REPAIR_ERROR'), 'error')
return
end
local success = ProgressBarSync(src, {
label = Lang('INVENTORY_PROGRESS_REPAIR'),
name = 'weapon_repairkit',
duration = 1000,
useWhileDead = false,
canCancel = true,
disableControls = { move = true, car = true, mouse = false, combat = true },
})
if success then
RemoveItem(src, item.name, 1, item.slot)
local item = items[currentWeapon.slot]
if item.name == currentWeapon.name then
local quality = item.info.quality
item.info.quality = quality + Config.WeaponRepairItemAddition
if item.info.quality > 100 then
item.info.quality = 100
end
SetItemMetadata(src, currentWeapon.slot, item.info)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_TEXT_REPAIR_REPAIRED'), 'success')
else
Error('Item name and current weapon name do not match. probably player change the slot after use the weapon.')
end
Debug('current weapon', currentWeapon)
end
end)
RegisterNetEvent('weapons:server:SetWeaponQuality', function(data, hp)
local src = source
local Player = GetPlayerFromId(src)
local items = GetItems(Player)
local WeaponSlot = items[data.slot]
WeaponSlot.info.quality = hp
SetItemMetadata(src, data.slot, WeaponSlot.info)
end)
exports('GetCurrentWeapon', function(source)
local currentWeapon = lib.callback.await('weapons:client:GetCurrentWeapon', source)
return currentWeapon
end)
RegisterNetEvent('weapons:server:UpdateWeaponQuality', function(data, RepeatAmount, ammo)
local src = source
local Player = GetPlayerFromId(src)
local items = GetItems(Player)
local WeaponData = WeaponList[GetHashKey(data.name)]
local WeaponSlot = items[data.slot]
local DecreaseAmount = Config.DurabilityMultiplier[data.name] or 0.15
if WeaponSlot then
if not IsWeaponBlocked(WeaponData.name) then
if WeaponSlot.info.quality then
for _ = 1, RepeatAmount, 1 do
if data.name == 'weapon_petrolcan' then
local customQuality = ammo * 100
if customQuality >= 1 then
WeaponSlot.info.quality = customQuality / 4500
else
WeaponSlot.info.quality = 0
WeaponSlot.info.ammo = 0
TriggerClientEvent(Config.InventoryPrefix .. ':client:UseWeapon', src, data, false)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NEED_REPAIR'), 'inform')
end
end
if WeaponSlot.info.quality - DecreaseAmount > 0 then
WeaponSlot.info.quality = WeaponSlot.info.quality - DecreaseAmount
else
WeaponSlot.info.quality = 0
TriggerClientEvent(Config.InventoryPrefix .. ':client:UseWeapon', src, data, false)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NEED_REPAIR'), 'inform')
break
end
end
else
WeaponSlot.info.quality = 100
for _ = 1, RepeatAmount, 1 do
if WeaponSlot.info.quality - DecreaseAmount > 0 then
WeaponSlot.info.quality = WeaponSlot.info.quality - DecreaseAmount
else
WeaponSlot.info.quality = 0
TriggerClientEvent(Config.InventoryPrefix .. ':client:UseWeapon', src, data, false)
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NEED_REPAIR'), 'inform')
break
end
end
end
end
end
SetItemMetadata(src, data.slot, WeaponSlot.info)
end)
RegisterNetEvent('weapons:server:EquipAttachment', function(ItemData, CurrentWeaponData, AttachmentData, sendData)
local src = source
local Player = GetPlayerFromId(src)
local Inventory = GetItems(Player)
local GiveBackItem = nil
local tint = 'none'
if ItemData?.info?.urltint ~= nil then
tint = tostring(ItemData.info.urltint)
end
local attachmentInfo = table.find(Config.WeaponAttachmentItems, function(attachment)
return attachment.item == AttachmentData.item
end)
if not attachmentInfo then
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_ATTACHMENT_NOT_COMPATIBLE'), 'error')
return
end
AttachmentData.type = attachmentInfo.type
Debug('weapons:server:EquipAttachment', AttachmentData)
if Inventory[CurrentWeaponData.slot] then
if Inventory[CurrentWeaponData.slot].info.attachments and next(Inventory[CurrentWeaponData.slot].info.attachments) then
local currenttype = GetAttachmentType(Inventory[CurrentWeaponData.slot].info.attachments)
local HasAttach, key = HasAttachment(AttachmentData.component, Inventory[CurrentWeaponData.slot].info.attachments)
if not HasAttach then
if AttachmentData.type ~= nil and currenttype == AttachmentData.type then
for _, v in pairs(Inventory[CurrentWeaponData.slot].info.attachments) do
if v.type and v.type == currenttype then
GiveBackItem = tostring(v.item):lower()
table.remove(Inventory[CurrentWeaponData.slot].info.attachments, key)
end
end
end
Inventory[CurrentWeaponData.slot].info.attachments[#Inventory[CurrentWeaponData.slot].info.attachments + 1] = {
component = AttachmentData.component,
label = ItemList[AttachmentData.item].label,
item = AttachmentData.item,
type = AttachmentData.type,
tint = AttachmentData.tint,
urltint = tint
}
Inventory[CurrentWeaponData.slot].info.tinturl = tint
TriggerClientEvent('addAttachment', src, AttachmentData.component, tint)
SetItemMetadata(src, CurrentWeaponData.slot, Inventory[CurrentWeaponData.slot].info)
RemoveItem(src, ItemData.name, 1, ItemData.slot)
Debug('Attachment used: [' .. ItemData.name .. '], slot: [' .. json.encode(ItemData.slot) .. ']')
else
TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_ATTACHMENT_ALREADY') .. ' ' .. ItemList[AttachmentData.item].label .. ' ' .. Lang('INVENTORY_NOTIFICATION_ATTACHMENT_ON_YOUR'), 'error')
end
else
Inventory[CurrentWeaponData.slot].info.attachments = {}
Inventory[CurrentWeaponData.slot].info.attachments[#Inventory[CurrentWeaponData.slot].info.attachments + 1] = {
component = AttachmentData.component,
label = ItemList[AttachmentData.item].label,
item = AttachmentData.item,
type = AttachmentData.type,
tint = AttachmentData.tint,
urltint = tint
}
Inventory[CurrentWeaponData.slot].info.tinturl = tint
TriggerClientEvent('addAttachment', src, AttachmentData.component, tint)
SetItemMetadata(src, CurrentWeaponData.slot, Inventory[CurrentWeaponData.slot].info)
RemoveItem(src, ItemData.name, 1, ItemData.slot)
Debug('Attachment used: [' .. ItemData.name .. '], slot: [' .. json.encode(ItemData.slot) .. ']')
end
end
if GiveBackItem then
AddItem(src, GiveBackItem, 1)
Wait(100)
end
if sendData then
TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src, Inventory[CurrentWeaponData.slot], AttachmentData.component)
Wait(100)
TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src)
end
end)
RegisterNetEvent('weapons:server:removeWeaponAmmoItem', function(item)
local Player = GetPlayerFromId(source)
if not Player or type(item) ~= 'table' or not item.name or not item.slot then return end
RemoveItem(source, item.name, 1, item.slot)
end)
RegisterServerEvent('weapons:server:AddWeaponAmmo')
AddEventHandler('weapons:server:AddWeaponAmmo', function(CurrentWeaponData, amount)
local src = source
local amount = tonumber(amount)
local inventory = Inventories[src]
if CurrentWeaponData ~= nil then
if inventory[CurrentWeaponData.slot] ~= nil then
inventory[CurrentWeaponData.slot].info.ammo = amount
end
SetInventory(src, inventory)
end
end)