Scripts/resources/[hp]/hp_vehicleshop/server/functions.lua
2024-12-29 20:48:41 +01:00

263 lines
9.5 KiB
Lua

--- Function that executes database queries
---
--- @param query: The SQL query to execute
--- @param params: Parameters for the SQL query (in table form)
--- @param type ("insert" | "update" | "query" | "scalar" | "single" | "prepare"): Parameters for the SQL query (in table form)
--- @return query any Results of the SQL query
Koci.Server.ExecuteSQLQuery = function(query, params, type)
if type == "insert" then
return MySQL.insert.await(query, params)
elseif type == "update" then
return MySQL.update.await(query, params)
elseif type == "query" then
return MySQL.query.await(query, params)
elseif type == "scalar" then
return MySQL.scalar.await(query, params)
elseif type == "single" then
return MySQL.single.await(query, params)
elseif type == "prepare" then
return MySQL.prepare.await(query, params)
else
error("Invalid queryType: " .. tostring(type or "?"))
end
end
---@param system ("esx_notify" | "qb_notify" | "custom_notify") System to be used
---@param source number Player source id
---@param type string inform / success / error
---@param title string Notification text
---@param text? string (optional) description, custom notify.
---@param duration? number (optional) Duration in miliseconds, custom notify.
---@param icon? string (optional) icon.
Koci.Server.SendNotify = function(source, type, title, text, duration, icon)
system = Config.NotifyType
if not duration then duration = 1000 end
if system == "qb_notify" then
if Config.FrameWork == "qb" then
TriggerClientEvent("QBCore:Notify", source, title, type, duration)
else
Utils.Functions.debugPrint("error", "QB not found.")
end
elseif system == "esx_notify" then
if Config.FrameWork == "esx" then
TriggerClientEvent("esx:showNotification", source, title, type, duration)
else
Utils.Functions.debugPrint("error", "ESX not found.")
end
elseif system == "custom_notify" then
Utils.Functions.CustomNotify(source, title, type, text, duration, icon)
else
Utils.Functions.debugPrint("error", "An error occurred.")
end
end
--- Gets a player by their source ID, based on the configured framework.
--- @param source number The source ID of the player.
--- @return table|nil Player The player data if found, or nil if not found.
Koci.Server.GetPlayerBySource = function(source)
if Config.FrameWork == "esx" then
return Koci.Framework.GetPlayerFromId(source)
elseif Config.FrameWork == "qb" then
return Koci.Framework.Functions.GetPlayer(source)
end
end
--- Sets a players Routing Bucket. Used for handling testdrives.
--- @param source number The source ID of the player.
--- @param bucketNumber number The bucket number to set.
RegisterNetEvent("kociserver:setPlayerRoutingBucket")
AddEventHandler("kociserver:setPlayerRoutingBucket", function(bucketNumber)
local source = source
SetPlayerRoutingBucket(source, bucketNumber)
end)
--- Gets the balance of a specific account type for a player, based on the configured framework.
--- @param type string The type of account for which the balance is requested.
--- @param Player table The player data.
--- @return number balance The account balance.
Koci.Server.PlayerHasItem = function(Player, itemName)
local playerSource = Config.FrameWork == "esx" and Player.source or Player.PlayerData.source
if Config.InventoryType == "ox_inventory" then
local itemCount = exports.ox_inventory:GetItemCount(playerSource, itemName)
return itemCount > 0, itemCount
elseif Config.InventoryType == "qb_inventory" then
local items = Player.Functions.GetItemsByName(itemName)
local itemCount = 0
for _, item in pairs(items) do
if item.amount then
itemCount = itemCount + item.amount
end
end
return itemCount > 0, itemCount
elseif Config.InventoryType == "custom" then
local itemCount = CustomInventory.GetItemCount(playerSource, itemName)
return itemCount > 0, itemCount
end
end
Koci.Server.ExecuteSQLQuery = function(query, params, type)
if type == "insert" then
return MySQL.insert.await(query, params)
elseif type == "update" then
return MySQL.update.await(query, params)
elseif type == "query" then
return MySQL.query.await(query, params)
elseif type == "scalar" then
return MySQL.scalar.await(query, params)
elseif type == "single" then
return MySQL.single.await(query, params)
elseif type == "prepare" then
return MySQL.prepare.await(query, params)
else
error("Invalid queryType: " .. tostring(type or "?"))
end
end
Koci.Server.GenerateCustomPlate = function()
math.randomseed(GetGameTimer())
local function getRandomElement(list)
return list[math.random(#list)]
end
local function getRandomLetter()
return getRandomElement(Config.Plate.Letters)
end
local function getRandomNumber()
return tostring(math.random(0, 9))
end
local function generatePlate()
local plateLetters = ""
for i = 1, Config.Plate.NumberOfLetters do
plateLetters = plateLetters .. getRandomLetter()
end
local plateNumbers = ""
for i = 1, Config.Plate.NumberOfNumbers do
plateNumbers = plateNumbers .. getRandomNumber()
end
local plate = string.upper(plateLetters .. plateNumbers)
if #plate > 8 then
plate = plate:sub(1, 8)
end
if Koci.Server.IsPlateTaken(plate) then
return generatePlate()
end
return plate
end
return generatePlate()
end
exports("GenerateCustomPlate", Koci.Server.GenerateCustomPlate)
Koci.Server.IsPlateTaken = function(plate)
local tableName = Config.PlayerVehiclesDB
local result = Koci.Server.ExecuteSQLQuery("SELECT plate FROM " .. tableName .. " WHERE plate = :plate LIMIT 1", {
plate = plate
}, "single")
if not result then
return false
else
return true
end
end
Koci.Server.CheckPlayerMoney = function(xPlayer, amount, type, extra)
if type == "cash" then
if extra.gallery.isMoneyAnItem.status then
local s, count = Koci.Server.PlayerHasItem(xPlayer, extra.gallery.isMoneyAnItem.item)
if s and count >= amount then
return true
else
return false
end
else
local b = xPlayer.PlayerData.money.cash
return tonumber(b) >= tonumber(amount)
end
elseif type == "bank" then
local b = xPlayer.PlayerData.money.bank
return tonumber(b) >= tonumber(amount)
end
end
Koci.Server.PlayerRemoveItem = function(Player, itemName, itemCount)
local playerSource = Config.FrameWork == "esx" and Player.source or Player.PlayerData.source
if Config.InventoryType == "qb_inventory" then
local result = Player.Functions.RemoveItem(itemName, itemCount)
return result
elseif Config.InventoryType == "ox_inventory" then
local result = exports.ox_inventory:RemoveItem(playerSource, itemName, itemCount)
return result
elseif Config.InventoryType == "custom" then
local result = CustomInventory.RemoveItem(playerSource, itemName, itemCount)
return result
end
end
Koci.Server.PlayerRemoveMoney = function(Player, spot, amount)
local result = Player.Functions.RemoveMoney(spot, amount)
return result
end
Koci.Server.CheckRemainingRentDay = function(Player, plate)
plate = string.upper(plate)
local owner = Config.FrameWork == "esx" and Player.identifier or Player.PlayerData.citizenid
local row = Koci.Server.ExecuteSQLQuery(
"SELECT * FROM `0r_rented_vehicles` WHERE owner = ? AND plate = ?",
{ owner, plate },
"single"
)
if not row then
return {
message = _t("rent.dont_own")
}
end
local currentTimestamp = os.time()
local rentalDuration = os.difftime(currentTimestamp, row.created_at / 1000)
local totalSeconds = row.rented_day * 24 * 60 * 60 - rentalDuration
local days = math.floor(totalSeconds / (24 * 60 * 60))
local hours = math.floor((totalSeconds % (24 * 60 * 60)) / 3600)
local minutes = math.floor((totalSeconds % 3600) / 60)
return {
message = _t("rent.remaining_time", days, hours, minutes)
}
end
Koci.Server.VehicleRentExtend = function(Player, plate, day)
day = tonumber(day or 1)
plate = string.upper(plate or "")
local owner = Config.FrameWork == "esx" and Player.identifier or Player.PlayerData.citizenid
local row = Koci.Server.ExecuteSQLQuery(
"SELECT * FROM `0r_rented_vehicles` WHERE owner = ? AND plate = ?",
{ owner, plate },
"single"
)
if not row then
return {
message = _t("rent.dont_own")
}
end
local price = math.floor(row.daily_fee * day)
local checkPlayerMoney = Koci.Server.CheckPlayerMoney(
Player,
price,
"bank"
)
if not checkPlayerMoney then
return {
message = _t("purchase.dont_have_enough_money")
}
end
local newRentedDay = tonumber(row.rented_day) + day
Koci.Server.ExecuteSQLQuery(
"UPDATE `0r_rented_vehicles` SET rented_day = ? WHERE owner = ? AND plate = ?",
{ newRentedDay, owner, plate },
"update"
)
Koci.Server.PlayerRemoveMoney(Player, "bank", price)
return {
message = _t("rent.been_extended", day, newRentedDay)
}
end