Main/resources/[test]/okokCrafting/sv_utils.lua

590 lines
No EOL
16 KiB
Lua

QBCore = exports[Config.qbPrefix.."-core"]:GetCoreObject()
Webhook = ''
function getMoney(type, xPlayer)
local moneyCount = 0
if type == "cash" then
moneyCount = xPlayer.PlayerData.money.cash
else
moneyCount = xPlayer.PlayerData.money.bank
end
return moneyCount
end
function addMoney(type, value, xPlayer)
xPlayer.Functions.AddMoney(type, value)
end
function removeMoney(type, value, xPlayer)
xPlayer.Functions.RemoveMoney(type, value)
end
function addItem(xPlayer, item, amount, data)
xPlayer.Functions.AddItem(item, tonumber(amount))
end
function removeItem(xPlayer, item, amount)
xPlayer.Functions.RemoveItem(item, tonumber(amount))
end
function canCarryIt(item, amount, xPlayer)
if Config.UseOx_inventory then
return exports.ox_inventory:CanCarryItem(xPlayer.PlayerData.source, item, amount)
end
local totalWeight = QBCore.Player.GetTotalWeight(xPlayer.PlayerData.items)
local itemInfo = QBCore.Shared.Items[item:lower()]
if not itemInfo then
TriggerClientEvent('QBCore:Notify', xPlayer.PlayerData.source, 'This item doesn\'t exits', 'error')
return
end
amount = tonumber(amount)
if (totalWeight + (itemInfo['weight'] * amount)) <= 120000 then
return true
else
return false
end
end
function hasPermission(source)
local staff = false
for k,v in ipairs(Config.AdminGroups) do
if QBCore.Functions.HasPermission(source, v) then
staff = true
break
end
end
return staff
end
function MySQLexecute(query, values, func)
return MySQL.query(query, values, func)
end
function MySQLfetchAll(query, values, func)
return MySQL.query(query, values, func)
end
function giveXP(xPlayer, xp, workbench)
if Config.SameLevelForAllTables then
MySQLexecute('UPDATE players SET '..Config.xpColumnsName..' = xp+@xp WHERE citizenid = @identifier', {
['@identifier'] = xPlayer.PlayerData.citizenid,
['@xp'] = Config.DoubleXP and xp*2 or xp,
}, function (result)
TriggerClientEvent(Config.EventPrefix..':updateXP', xPlayer.PlayerData.source)
end)
else
MySQLexecute('UPDATE players SET '..Config.xpColumnsName..' = JSON_SET(xp, @table, JSON_EXTRACT(xp, @table) + @xp) WHERE citizenid = @identifier', {
['@identifier'] = xPlayer.PlayerData.citizenid,
['@xp'] = Config.DoubleXP and xp*2 or xp,
['@table'] = "$."..workbench,
}, function (result)
TriggerClientEvent(Config.EventPrefix..':updateXP', xPlayer.PlayerData.source)
end)
end
end
QBCore.Functions.CreateCallback(Config.EventPrefix..":inv2", function(source, cb, item, isMoney)
local xPlayer = QBCore.Functions.GetPlayer(source)
local itemS = {}
if isMoney == "false" then
isMoney = false
elseif isMoney == "true" then
isMoney = true
end
if isMoney then
local playerMoney = getMoney(item, xPlayer)
itemS.name = item
itemS.amount = playerMoney
else
itemS = xPlayer.Functions.GetItemByName(item)
if itemS == nil then
itemS = {
name = item,
amount = 0
}
end
if itemS.count ~= nil then
itemS.amount = itemS.count
end
end
cb(itemS)
end)
QBCore.Functions.CreateCallback(Config.EventPrefix..":maxCraft", function(source, cb, recipe, maxCraftAmount, isDisassemble, itemC, itmNeeded)
local _source = source
local xPlayer = QBCore.Functions.GetPlayer(_source)
local maxCraft = maxCraftAmount
local itemAmt = 0
if not isDisassemble then
for k,v in ipairs(recipe) do
local item = {}
local itemCount = 0
if v[4] then
itemCount = getMoney(v[1], xPlayer)
else
item = xPlayer.Functions.GetItemByName(v[1])
if item == nil then
item = {
name = v[1],
amount = 0
}
end
if item.count ~= nil then
item.amount = item.count
end
itemCount = item.amount
end
if itemCount > 0 then
local possibleToCraft = itemCount/tonumber(v[2])
if possibleToCraft > 0 then
if maxCraft > possibleToCraft then
maxCraft = possibleToCraft
end
else
maxCraft = 0
break
end
else
maxCraft = 0
break
end
end
else
local item = xPlayer.Functions.GetItemByName(itemC)
if item == nil then
item = {
name = itemC,
amount = 0
}
end
if item.count ~= nil then
item.amount = item.count
end
itemAmt = item.amount
if itemAmt > 0 then
local possibleToCraft = itemAmt/tonumber(itmNeeded)
if possibleToCraft > 0 then
if maxCraft > possibleToCraft then
maxCraft = possibleToCraft
end
else
maxCraft = 0
end
else
maxCraft = 0
end
end
cb(math.floor(maxCraft), itemAmt)
end)
local function normalizeRecipe(recipe)
local normalized = {}
for _, item in ipairs(recipe) do
local normalizedItem = { item[1], tonumber(item[2]), item[3] == "true" or item[3] == true, item[4] == "true" or item[4] == true }
table.insert(normalized, normalizedItem)
end
return normalized
end
local function compareRecipes(recipe1, recipe2)
if #recipe1 ~= #recipe2 then
return false
end
for i, item1 in ipairs(recipe1) do
local item2 = recipe2[i]
if item1[1] ~= item2[1] and item1[2] <= item2[2] then
return false
end
end
return true
end
function craftExistsInWorkbench(workbenchID, itemID, recipe)
for _, workbench in pairs(Config.Crafting) do
if workbench.tableID == workbenchID then
for _, craft in pairs(workbench.crafts) do
if Config.Crafts[craft] == nil then
print("Craft "..craft.." does not exist in Config.Crafts")
return false
end
if Config.Crafts[craft].item == itemID then
local normalizedCraftRecipe = normalizeRecipe(Config.Crafts[craft].recipe)
local normalizedInputRecipe = normalizeRecipe(recipe)
if compareRecipes(normalizedCraftRecipe, normalizedInputRecipe) then
return true
end
end
end
end
end
return false
end
QBCore.Functions.CreateCallback(Config.EventPrefix..":CanCraftItem", function(source, cb, itemID, recipe, itemName, amount, isItem, workbench, timeCraft, CraftQueues, xp, pc, isDis, itemData)
local xPlayer = QBCore.Functions.GetPlayer(source)
local canCraft = true
if not craftExistsInWorkbench(workbench, itemID, recipe) then
canCraft = false
end
if not isDis then
for k,v in pairs(recipe) do
if v[4] == "false" then
local item = xPlayer.Functions.GetItemByName(v[1])
if item == nil then
item = {
name = v[1],
amount = 0
}
end
if item.count ~= nil then
item.amount = item.count
end
if item.amount < v[2] then
canCraft = false
end
else
local playerMoney = getMoney(v[1], xPlayer)
if playerMoney < v[2] then
canCraft = false
end
end
end
else
local item = xPlayer.Functions.GetItemByName(itemID)
if item == nil then
item = {
name = itemID,
amount = 0
}
end
if item.count ~= nil then
item.amount = item.count
end
if tonumber(item.amount) < tonumber(amount) then
canCraft = false
end
end
if canCraft then
if not isDis then
for k,v in pairs(recipe) do
if v[3] == "true" then
if v[4] == "true" then
removeMoney(v[1], v[2], xPlayer)
else
removeItem(xPlayer, v[1], v[2])
end
end
end
else
removeItem(xPlayer, itemID, tonumber(amount))
end
local queue = CraftQueues
if queue ~= nil and queue[workbench] ~= nil then
queue[workbench][#queue[workbench]+1] = {
item = itemID,
recipe = recipe,
amount = amount,
isItem = isItem,
time = timeCraft,
itemName = itemName[itemID],
isDone = false,
isPending = true,
randomID = math.random(100000000, 999999999),
xp = xp,
sucPC = pc,
suc = true,
isDis = isDis,
data = itemData
}
MySQLexecute('UPDATE players SET '..Config.craftQueryColumnName..' = @okokcrafts WHERE citizenid = @identifier', {
['@identifier'] = xPlayer.PlayerData.citizenid,
['@okokcrafts'] = json.encode(queue),
}, function (result)
TriggerClientEvent(Config.EventPrefix..':notification', xPlayer.PlayerData.source, _L('added_to_queue').title, interp(_L('added_to_queue').text, {s1 = itemName[itemID]}), _L('added_to_queue').time, _L('added_to_queue').type)
if Webhook ~= "" then
data = {
playerid = xPlayer.PlayerData.source,
type = "start-craft",
item = itemName[itemID],
amount = amount,
}
discordWebhook(data)
end
cb(queue)
end)
else
if queue == nil then
queue = {}
end
queue[workbench] = {}
queue[workbench] = {
[1] = {
item = itemID,
recipe = recipe,
amount = amount,
isItem = isItem,
time = timeCraft,
itemName = itemName[itemID],
isDone = false,
isPending = true,
randomID = math.random(100000000, 999999999),
xp = xp,
sucPC = pc,
suc = true,
isDis = isDis,
data = itemData
}
}
MySQLexecute('UPDATE players SET '..Config.craftQueryColumnName..' = @okokcrafts WHERE citizenid = @identifier', {
['@identifier'] = xPlayer.PlayerData.citizenid,
['@okokcrafts'] = json.encode(queue),
}, function (result)
TriggerClientEvent(Config.EventPrefix..':notification', xPlayer.PlayerData.source, _L('added_to_queue').title, interp(_L('added_to_queue').text, {s1 = itemName[itemID]}), _L('added_to_queue').time, _L('added_to_queue').type)
if Webhook ~= "" then
data = {
playerid = xPlayer.PlayerData.source,
type = "start-craft",
item = itemName[itemID],
amount = amount,
}
discordWebhook(data)
end
cb(queue)
end)
end
else
TriggerClientEvent(Config.EventPrefix..':notification', xPlayer.PlayerData.source, _L('cant_craft').title, interp(_L('cant_craft').text, {s1 = itemName[itemID]}), _L('cant_craft').time, _L('cant_craft').type)
cb(false)
end
end)
RegisterServerEvent(Config.EventPrefix..':claimAll')
AddEventHandler(Config.EventPrefix..':claimAll', function(workbench, AllQueues)
local xPlayer = QBCore.Functions.GetPlayer(source)
local gotQueue = false
local CraftsQueue = {}
MySQLfetchAll('SELECT okokcrafts FROM players WHERE citizenid = @identifier', {
['@identifier'] = xPlayer.PlayerData.citizenid,
}, function (result)
if result[1] ~= nil then
local data = json.decode(result[1].okokcrafts)
if data ~= nil then
CraftsQueue = data
gotQueue = true
end
end
end)
while not gotQueue do
Citizen.Wait(100)
end
local queue = CraftsQueue[workbench]
local v = queue[1]
if v ~= nil then
if v.isDone then
if v.suc then
if not v.isDis then
local canCarry = false
if v.isItem then
if canCarryIt(v.item, v.amount, xPlayer) then
addItem(xPlayer, v.item, v.amount, v.data)
canCarry = true
end
else
if canCarryIt(v.item, v.amount, xPlayer) then
addItem(xPlayer, v.item, v.amount)
canCarry = true
end
end
if canCarry then
if Webhook ~= "" then
data = {
playerid = xPlayer.PlayerData.source,
type = "claim-craft",
item = v.itemName,
amount = v.amount,
}
discordWebhook(data)
end
if Config.UseXP then
giveXP(xPlayer, v.xp, workbench)
end
TriggerClientEvent(Config.EventPrefix..':removeItemsFromQueue', xPlayer.PlayerData.source, 1, workbench)
else
TriggerClientEvent(Config.EventPrefix..':notification', xPlayer.PlayerData.source, _L('cant_carry').title, _L('cant_carry').text, _L('cant_carry').time, _L('cant_carry').type)
TriggerClientEvent(Config.EventPrefix..':notification', xPlayer.PlayerData.source, _L('claimed_all_items').title, _L('claimed_all_items').text, _L('claimed_all_items').time, _L('claimed_all_items').type)
TriggerClientEvent(Config.EventPrefix..':resetClaimAllButton', xPlayer.PlayerData.source)
end
else
local canCarry = true
for k2,v2 in ipairs(v.recipe) do
if v2[4] == "false" or v2[4] == false then
if not canCarryIt(v2[1], v2[2], xPlayer) then
canCarry = false
end
end
end
if canCarry then
for k2,v2 in ipairs(v.recipe) do
if v2[4] == "true" or v2[4] == true then
addMoney(v2[1], v2[2], xPlayer)
else
addItem(xPlayer, v2[1], v2[2])
end
end
if Webhook ~= "" then
data = {
playerid = xPlayer.PlayerData.source,
type = "claim-craft",
item = v.itemName,
amount = v.amount,
}
discordWebhook(data)
end
if Config.UseXP then
giveXP(xPlayer, v.xp, workbench)
end
TriggerClientEvent(Config.EventPrefix..':removeItemsFromQueue', xPlayer.PlayerData.source, 1, workbench)
else
TriggerClientEvent(Config.EventPrefix..':notification', xPlayer.PlayerData.source, _L('cant_carry').title, _L('cant_carry').text, _L('cant_carry').time, _L('cant_carry').type)
TriggerClientEvent(Config.EventPrefix..':notification', xPlayer.PlayerData.source, _L('claimed_all_items').title, _L('claimed_all_items').text, _L('claimed_all_items').time, _L('claimed_all_items').type)
TriggerClientEvent(Config.EventPrefix..':resetClaimAllButton', xPlayer.PlayerData.source)
end
end
else
if Webhook ~= "" then
data = {
playerid = xPlayer.PlayerData.source,
type = "failed-craft",
item = v.itemName,
amount = v.amount,
}
discordWebhook(data)
end
if Config.GiveXPOnCraftFailed and Config.UseXP then
if Config.UseXP then
giveXP(xPlayer, v.xp, workbench)
end
end
TriggerClientEvent(Config.EventPrefix..':removeItemsFromQueue', xPlayer.PlayerData.source, 1, workbench)
end
end
end
end)
-------------------------- IDENTIFIERS
function ExtractIdentifiers(id)
local identifiers = {
steam = "",
ip = "",
discord = "",
license = "",
xbl = "",
live = ""
}
for i = 0, GetNumPlayerIdentifiers(id) - 1 do
local playerID = GetPlayerIdentifier(id, i)
if string.find(playerID, "steam") then
identifiers.steam = playerID
elseif string.find(playerID, "ip") then
identifiers.ip = playerID
elseif string.find(playerID, "discord") then
identifiers.discord = playerID
elseif string.find(playerID, "license") then
identifiers.license = playerID
elseif string.find(playerID, "xbl") then
identifiers.xbl = playerID
elseif string.find(playerID, "live") then
identifiers.live = playerID
end
end
return identifiers
end
-------------------------- WEBHOOK
function discordWebhook(data)
local color = '65352'
local category = 'default'
local item = ''
local amount = ''
local identifierlist = ExtractIdentifiers(data.playerid)
local identifier = identifierlist.license:gsub("license2:", "")
local discord = "<@"..identifierlist.discord:gsub("discord:", "")..">"
if data.type == 'start-craft' then
color = Config.StartCraftWebhookColor
category = 'Started a craft'
item = data.item
amount = data.amount
elseif data.type == 'cancel-craft' then
color = Config.CancelWebhookColor
category = 'Canceled a craft'
item = data.item
amount = data.amount
elseif data.type == 'claim-craft' then
color = Config.ClaimCraftWebhookColor
category = 'Claimed'
item = data.item
amount = data.amount
elseif data.type == 'failed-craft' then
color = Config.FailedCraftWebhookColor
category = 'Failed a craft'
item = data.item
amount = data.amount
end
local information = {
{
["color"] = color,
["author"] = {
["icon_url"] = Config.IconURL,
["name"] = Config.ServerName..' - Logs',
},
["title"] = 'CRAFTING',
["description"] = '**Action:** '..category..'\n**Item:** '..item..'\n**Amount:** '..amount..'\n\n**ID:** '..data.playerid..'\n**Identifier:** '..identifier..'\n**Discord:** '..discord,
["footer"] = {
["text"] = os.date(Config.DateFormat),
}
}
}
PerformHttpRequest(Webhook, function(err, text, headers) end, 'POST', json.encode({username = Config.BotName, embeds = information}), {['Content-Type'] = 'application/json'})
end