263 lines
9.5 KiB
Lua
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
|