forked from Simnation/Main
242 lines
8.7 KiB
Lua
242 lines
8.7 KiB
Lua
---@param src number
|
|
---@param banLogType "banOpenOtherPlayerInventory" | "banGiveItemSelf" | "banGiveMinusAmount" | "banRemoveMinusAmount" | "banCustomShop" | "banOpeningOtherPlayerInventoryFromDistance" | "banClientOpenInventory"
|
|
---@param msg string
|
|
function ban(src, banLogType, msg)
|
|
banLog(src, banLogType, msg)
|
|
if config.kickPlayerWhenHackingDatected then DropPlayer(tostring(src), "Cheating For Inventory System") end
|
|
--[[
|
|
-- Example ban event
|
|
TriggerClientEvent("tgiann-anticheat:ban", src, { -- Example Code
|
|
adminMessage = msg,
|
|
ban = 131487,
|
|
kickMessage = "Cheating!"
|
|
}) ]]
|
|
end
|
|
|
|
---@param plate string
|
|
---@return string | false
|
|
function isPlayerVehicle(plate)
|
|
local table = config.framework == "qb" and "player_vehicles" or "owned_vehicles"
|
|
local owner = config.framework == "qb" and "citizenid" or "owner"
|
|
local result = MySQL.single.await('SELECT ' .. owner .. ' from ' .. table .. ' WHERE plate = ?', { plate })
|
|
return result and result[owner] or false
|
|
end
|
|
|
|
---@param src number
|
|
---@return boolean
|
|
function isAdmin(src)
|
|
if config.framework == "qb" then
|
|
return IsPlayerAceAllowed(tostring(src), "command") -- refarance: https://github.com/qbcore-framework/qb-adminmenu/blob/main/server/server.lua#L52
|
|
else
|
|
local xPlayer = tgiCore.getPlayer(src)
|
|
return xPlayer.getGroup(src) == "admin"
|
|
end
|
|
end
|
|
|
|
lib.callback.register("tgiann-inventory:server:isAdmin", isAdmin)
|
|
|
|
--- @param moneyType string
|
|
--- @return boolean, string | nil
|
|
function isMoneyItem(moneyType)
|
|
if not config.moneyAsItem.active then return false end
|
|
for itemName, mType in pairs(config.moneyAsItem.items[config.framework]) do
|
|
if mType == moneyType then
|
|
return true, itemName
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
exports("IsMoneyItem", isMoneyItem)
|
|
|
|
--- For money as item
|
|
---@param src number
|
|
---@param itemName string
|
|
local function setMoney(src, itemName)
|
|
if not config.moneyAsItem.active then return end
|
|
local moneyType = config.moneyAsItem.items[config.framework][itemName]
|
|
if not moneyType then return end
|
|
local pInventory = GetInventory(src, "player")
|
|
if not pInventory then return end
|
|
local xPlayer = tgiCore.getPlayer(src)
|
|
if not xPlayer then return end
|
|
local totalAmount = pInventory.Functions.GetItemTotalAmount(itemName)
|
|
if config.framework == "esx" then
|
|
xPlayer.setAccountMoney(moneyType, totalAmount, "inventory money as item", true)
|
|
elseif config.framework == "qb" then
|
|
if config.qbx then
|
|
exports["qbx_core"]:SetMoney(src, moneyType, totalAmount, "inventory money as item", true)
|
|
else
|
|
xPlayer.Functions.SetMoney(moneyType, totalAmount, "inventory money as item", true)
|
|
end
|
|
end
|
|
end
|
|
|
|
--- if the value is false, the use of the item is canceled
|
|
---@param src number
|
|
---@param itemData table
|
|
---@param itemSharedData table
|
|
---@diagnostic disable-next-line: unused-local
|
|
function useItemEditable(src, itemData, itemSharedData)
|
|
local decayableItemsData = IsDecayableItem(itemData.name)
|
|
if decayableItemsData then
|
|
local durability = itemData.info?.durability and GetDurabilityPercent(itemData.info.durability, decayableItemsData, os.time()) or 1
|
|
if durability <= 0 then
|
|
if config.removeDecayableItem then
|
|
RemoveItem(src, itemData.name, 1, itemData.slot)
|
|
end
|
|
tgiCore.notif(src, lang.cantUseThisItem, "error")
|
|
return false
|
|
end
|
|
end
|
|
|
|
if itemData.name == "myCustomUseItem" then
|
|
TriggerClientEvent('myCustomEvent', src, itemData.name)
|
|
return false -- We make it false because we do not want the main use item function to continue
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---@param src number
|
|
---@param itemData table
|
|
---@param amount number
|
|
function addItemDetect(src, itemData, amount)
|
|
if not itemData then return end
|
|
|
|
itemData.itemAddRemoveLog = "added"
|
|
TriggerClientEvent("tgiann-inventory:itemAddRemoveLog", src, itemData, amount)
|
|
|
|
if string.match(itemData.name:lower(), "weapon") then
|
|
TriggerClientEvent('inventory:client:addWeapon', src, true, true, itemData.slot)
|
|
else
|
|
if config.moneyAsItem.active then setMoney(src, itemData.name) end
|
|
TriggerClientEvent('tgiann-inventory:addedItem', src, itemData.name)
|
|
end
|
|
end
|
|
|
|
---@param src number
|
|
---@param itemData table
|
|
---@param amount number
|
|
function removeItemDetect(src, itemData, amount)
|
|
if not itemData then return end
|
|
|
|
itemData.itemAddRemoveLog = "removed"
|
|
TriggerClientEvent("tgiann-inventory:itemAddRemoveLog", src, itemData, amount)
|
|
|
|
if string.match(itemData.name:lower(), "weapon") then
|
|
TriggerClientEvent('inventory:client:removeWeapon', src, true, true, itemData.slot)
|
|
elseif itemData.name:lower() == "kemer" then
|
|
TriggerClientEvent('tgiann-hud:removeKemer', src)
|
|
elseif itemData.name:lower() == "megaphone" then
|
|
TriggerClientEvent('tgiann-megaphone:drop', src)
|
|
elseif itemData.name:lower() == "scooter" then
|
|
TriggerClientEvent('tgiann-scooter:drop', src)
|
|
else
|
|
if config.moneyAsItem then setMoney(src, itemData.name) end
|
|
TriggerClientEvent('tgiann-inventory:dropItem', src, itemData.name)
|
|
end
|
|
end
|
|
|
|
---@param payload { source:number, shopType: string, itemName: string, metadata: table, count:number, price: number }
|
|
function itemBought(payload)
|
|
buyItemLog(payload.shopType, payload.itemName, payload.count, payload.price, payload.source)
|
|
|
|
if config.tgiannServer and payload.shopType == "police" then
|
|
local itemName = payload.itemName
|
|
if string.find(itemName, "weapon") then
|
|
local label = itemList[itemName].label
|
|
local xPlayer = tgiCore.getPlayer(payload.source)
|
|
if not xPlayer then return end
|
|
MySQL.insert('INSERT INTO tgiann_mdt_shop (name, itemname, itemserial, time) VALUES (?, ?, ?, ?) ', { xPlayer.PlayerData.charinfo.firstname .. " " .. xPlayer.PlayerData.charinfo.lastname, label, payload.metadata.serie or "Eşya", os.time() })
|
|
end
|
|
end
|
|
end
|
|
|
|
---@param itemData table
|
|
---@param info? table
|
|
---@param Player? table
|
|
local function setQbItemInfo(itemData, info, Player)
|
|
if config.framework == "esx" then return info end
|
|
if itemData.name == "id_card" then
|
|
if Player then
|
|
info.citizenid = Player.PlayerData.citizenid
|
|
info.firstname = Player.PlayerData.charinfo.firstname
|
|
info.lastname = Player.PlayerData.charinfo.lastname
|
|
info.birthdate = Player.PlayerData.charinfo.birthdate
|
|
info.gender = Player.PlayerData.charinfo.gender
|
|
info.nationality = Player.PlayerData.charinfo.nationality
|
|
end
|
|
elseif itemData.name == "driver_license" then
|
|
if Player then
|
|
info.firstname = Player.PlayerData.charinfo.firstname
|
|
info.lastname = Player.PlayerData.charinfo.lastname
|
|
info.birthdate = Player.PlayerData.charinfo.birthdate
|
|
end
|
|
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"
|
|
end
|
|
return info
|
|
end
|
|
|
|
---@param itemData table
|
|
---@param info? table
|
|
---@param Player? table
|
|
function setItemInfo(itemData, info, Player)
|
|
if not info or info == "" or (type(info) == "table" and not next(info)) then
|
|
info = {}
|
|
local decayableItemsData = IsDecayableItem(itemData.name)
|
|
if itemData.name == config.jerryCan.item then
|
|
info = config.jerryCan.metadata
|
|
elseif decayableItemsData then
|
|
info.type = "decayableItems"
|
|
info.durability = os.time()
|
|
info.durabilitySecond = decayableItemsData
|
|
elseif itemData.type == 'weapon' then
|
|
info = {
|
|
serie = GetRandomItemId(),
|
|
durabilityPercent = 100,
|
|
ammo = 0,
|
|
usedTotalAmmo = 0
|
|
}
|
|
elseif GetResourceState("tgiann-food-jobs") == "started" and exports["tgiann-food-jobs"]:items()[itemData.name] and Player then
|
|
info = exports["tgiann-food-jobs"]:customItemMetadata(tgiCore.getSource(Player), tgiCore.getCid(Player))
|
|
elseif config.maxUseAmount[itemData.name] then
|
|
info.type = "maxUseAmount"
|
|
info.maxUseAmount = config.maxUseAmount[itemData.name].amount
|
|
elseif config.realisticArmor.active and config.realisticArmor.items[itemData.name] then
|
|
info.durabilityPercent = config.realisticArmor.items[itemData.name].armor
|
|
info.realisticArmor = true
|
|
else
|
|
info = setQbItemInfo(itemData, info, Player)
|
|
end
|
|
end
|
|
return info
|
|
end
|
|
|
|
for i = 1, #config.itemStash do
|
|
local stashData = config.itemStash[i]
|
|
tgiCore.CreateUseableItem(stashData.item, function(source, item)
|
|
local src = source
|
|
if openedAnySecondaryInventory(src) then
|
|
return tgiCore.notif(src, lang.closeInventoryFirst, "error", 5000)
|
|
end
|
|
if not item.info.id then
|
|
local xPlayer = tgiCore.getPlayer(src)
|
|
item.info = { id = stashData.item .. tgiCore.getCid(xPlayer) .. GetRandomItemId() }
|
|
UpdateItemMetadata(src, stashData.item, item.slot, item.info)
|
|
end
|
|
OpenInventory(src, "stash", item.info.id, {
|
|
maxweight = stashData.maxweight,
|
|
slots = stashData.slots,
|
|
whitelist = stashData.whitelist
|
|
})
|
|
end)
|
|
end
|