From 48ce1b7425ac8ab879684f8df0a2d18759ff5f96 Mon Sep 17 00:00:00 2001 From: DokaDoka Date: Wed, 19 Jan 2022 17:07:39 +1100 Subject: [PATCH] refactor: use oxmysql plus general improvements refactor(vehicleshop): rewrite PayRent chore(vehicleshop): enable lua 5.4 refactor(vehicleshop): convert mysql-async to oxmysql refactor(vehicleshop): improve loops and make functions more generic refactor(society): convert mysql-async to oxmysql refactor(lscustom): convert mysql-async to oxmysql refactor(addonaccount): convert mysql-async to oxmysql refactor(billing): convert mysql-async to oxmysql fix(identity): broken locale function refactor(identity): convert mysql-async to oxmysql refactor(ambulancejob): convert mysql-async to oxmysql refactor(datastore): convert mysql-async to oxmysql refactor(policejob): convert mysql-async to oxmysql --- [esx]/esx_identity/server/main.lua | 112 ++---- .../server/classes/addonaccount.lua | 18 +- [esx_addons]/esx_addonaccount/server/main.lua | 66 ++-- .../esx_ambulancejob/client/vehicle.lua | 37 +- [esx_addons]/esx_ambulancejob/server/main.lua | 58 +-- [esx_addons]/esx_billing/server/main.lua | 63 ++-- .../server/classes/datastore.lua | 11 +- [esx_addons]/esx_datastore/server/main.lua | 65 ++-- [esx_addons]/esx_license/server/main.lua | 78 +--- [esx_addons]/esx_lscustom/server/main.lua | 31 +- [esx_addons]/esx_policejob/client/vehicle.lua | 52 ++- [esx_addons]/esx_policejob/server/main.lua | 101 ++---- [esx_addons]/esx_society/server/main.lua | 54 ++- [esx_addons]/esx_vehicleshop/client/main.lua | 15 +- [esx_addons]/esx_vehicleshop/client/utils.lua | 2 - [esx_addons]/esx_vehicleshop/fxmanifest.lua | 2 + [esx_addons]/esx_vehicleshop/server/main.lua | 340 ++++++++---------- 17 files changed, 415 insertions(+), 690 deletions(-) diff --git a/[esx]/esx_identity/server/main.lua b/[esx]/esx_identity/server/main.lua index 6133d663..c3612bbd 100644 --- a/[esx]/esx_identity/server/main.lua +++ b/[esx]/esx_identity/server/main.lua @@ -9,17 +9,16 @@ if Config.UseDeferrals then Citizen.Wait(100) if identifier then - MySQL.query('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result[1] then - if result[1].firstname then + MySQL.single('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = ?', {identifier}, + function(result) + if result then + if result.firstname then playerIdentity[identifier] = { - firstName = result[1].firstname, - lastName = result[1].lastname, - dateOfBirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height + firstName = result.firstname, + lastName = result.lastname, + dateOfBirth = result.dateofbirth, + sex = result.sex, + height = result.height } deferrals.done() @@ -107,17 +106,16 @@ elseif not Config.UseDeferrals then Citizen.Wait(40) if identifier then - MySQL.query('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result[1] then - if result[1].firstname then + MySQL.single('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = ?', {identifier}, + function(result) + if result then + if result.firstname then playerIdentity[identifier] = { - firstName = result[1].firstname, - lastName = result[1].lastname, - dateOfBirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height + firstName = result.firstname, + lastName = result.lastname, + dateOfBirth = result.dateofbirth, + sex = result.sex, + height = result.height } alreadyRegistered[identifier] = true @@ -225,17 +223,16 @@ elseif not Config.UseDeferrals then end) function checkIdentity(xPlayer) - MySQL.query('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) - if result[1] then - if result[1].firstname then + MySQL.single('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = ?', {identifier}, + function(result) + if result then + if result.firstname then playerIdentity[xPlayer.identifier] = { - firstName = result[1].firstname, - lastName = result[1].lastname, - dateOfBirth = result[1].dateofbirth, - sex = result[1].sex, - height = result[1].height + firstName = result.firstname, + lastName = result.lastname, + dateOfBirth = result.dateofbirth, + sex = result.sex, + height = result.height } alreadyRegistered[xPlayer.identifier] = true @@ -284,7 +281,7 @@ if Config.EnableCommands then ESX.RegisterCommand('chardel', 'user', function(xPlayer, args, showError) if xPlayer and xPlayer.getName() then if Config.UseDeferrals then - xPlayer.kick(_('deleted_identity')) + xPlayer.kick(_U('deleted_identity')) Citizen.Wait(1500) deleteIdentity(xPlayer) xPlayer.showNotification(_U('deleted_character')) @@ -367,61 +364,16 @@ function deleteIdentity(xPlayer) end function saveIdentityToDatabase(identifier, identity) - MySQL.update.await('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', { - ['@identifier'] = identifier, - ['@firstname'] = identity.firstName, - ['@lastname'] = identity.lastName, - ['@dateofbirth'] = identity.dateOfBirth, - ['@sex'] = identity.sex, - ['@height'] = identity.height - }) + MySQL.update.await('UPDATE users SET firstname = ?, lastname = ?, dateofbirth = ?, sex = ?, height = ? WHERE identifier = ?', {identity.firstName, identity.lastName, identity.dateOfBirth, identity.sex, identity.height. identifier}) end function deleteIdentityFromDatabase(xPlayer) - MySQL.update.await('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height , skin = @skin WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier, - ['@firstname'] = NULL, - ['@lastname'] = NULL, - ['@dateofbirth'] = NULL, - ['@sex'] = NULL, - ['@height'] = NULL, - ['@skin'] = NULL - }) + MySQL.query.await('UPDATE users SET firstname = ?, lastname = ?, dateofbirth = ?, sex = ?, height = ?, skin = ? WHERE identifier = ?', {nil, nil, nil, nil, nil, xPlayer.identifier}) if Config.FullCharDelete then - MySQL.update.await('UPDATE addon_account_data SET money = 0 WHERE account_name = @account_name AND owner = @owner', { - ['@account_name'] = 'bank_savings', - ['@owner'] = xPlayer.identifier - }) + MySQL.update.await('UPDATE addon_account_data SET money = 0 WHERE account_name IN (?) AND owner = ?', {{'bank_savings', 'caution'}, xPlayer.identifier}) - MySQL.update.await('UPDATE addon_account_data SET money = 0 WHERE account_name = @account_name AND owner = @owner', { - ['@account_name'] = 'caution', - ['@owner'] = xPlayer.identifier - }) - - MySQL.update.await('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_ears', - ['@owner'] = xPlayer.identifier - }) - - MySQL.update.await('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_glasses', - ['@owner'] = xPlayer.identifier - }) - - MySQL.update.await('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_helmet', - ['@owner'] = xPlayer.identifier - }) - - MySQL.update.await('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', { - ['@data'] = '\'{}\'', - ['@name'] = 'user_mask', - ['@owner'] = xPlayer.identifier - }) + MySQL.prepare.await('UPDATE datastore_data SET data = ? WHERE name IN (?) AND owner = ?', {'\'{}\'', {'user_ears', 'user_glasses', 'user_helmet', 'user_mask'}, xPlayer.identifier}) end end diff --git a/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua b/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua index 40de8452..9d8fe21a 100644 --- a/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua +++ b/[esx_addons]/esx_addonaccount/server/classes/addonaccount.lua @@ -8,37 +8,25 @@ function CreateAddonAccount(name, owner, money) self.addMoney = function(m) self.money = self.money + m self.save() - - TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end self.removeMoney = function(m) self.money = self.money - m self.save() - - TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end self.setMoney = function(m) self.money = m self.save() - - TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end self.save = function() if self.owner == nil then - MySQL.update('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name', { - ['@account_name'] = self.name, - ['@money'] = self.money - }) + MySQL.update('UPDATE addon_account_data SET money = ? WHERE account_name = ?', {self.name, self.money}) else - MySQL.update('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name AND owner = @owner', { - ['@account_name'] = self.name, - ['@money'] = self.money, - ['@owner'] = self.owner - }) + MySQL.update('UPDATE addon_account_data SET money = ? WHERE account_name = ? AND owner = ?', {self.name, self.money, self.owner}) end + TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) end return self diff --git a/[esx_addons]/esx_addonaccount/server/main.lua b/[esx_addons]/esx_addonaccount/server/main.lua index c785c001..39a580fe 100644 --- a/[esx_addons]/esx_addonaccount/server/main.lua +++ b/[esx_addons]/esx_addonaccount/server/main.lua @@ -1,41 +1,33 @@ local AccountsIndex, Accounts, SharedAccounts = {}, {}, {} -MySQL.ready(function() - local result = MySQL.query.await('SELECT * FROM addon_account') +AddEventHandler('onResourceStart', function(resourceName) + if resourceName == GetCurrentResourceName() then + local accounts = MySQL.query.await('SELECT * FROM addon_account LEFT JOIN addon_account_data ON addon_account.name = addon_account_data.account_name UNION SELECT * FROM addon_account RIGHT JOIN addon_account_data ON addon_account.name = addon_account_data.account_name') - for i=1, #result, 1 do - local name = result[i].name - local label = result[i].label - local shared = result[i].shared - - local result2 = MySQL.query.await('SELECT * FROM addon_account_data WHERE account_name = @account_name', { - ['@account_name'] = name - }) - - if shared == 0 then - table.insert(AccountsIndex, name) - Accounts[name] = {} - - for j=1, #result2, 1 do - local addonAccount = CreateAddonAccount(name, result2[j].owner, result2[j].money) - table.insert(Accounts[name], addonAccount) - end - else - local money = nil - - if #result2 == 0 then - MySQL.update.await('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, NULL)', { - ['@account_name'] = name, - ['@money'] = 0 - }) - - money = 0 + local newAccounts = {} + for i = 1, #accounts do + local account = accounts[i] + if account.shared == 0 then + if not Accounts[account.name] then + AccountsIndex[#AccountsIndex + 1] = account.name + Accounts[account.name] = {} + end + Accounts[account.name][#Accounts[account.name] + 1] = CreateAddonAccount(account.name, account.owner, account.money) else - money = result2[1].money + if account.money then + SharedAccounts[account.name] = CreateAddonAccount(account.name, nil, account.money) + else + newAccounts[#newAccounts + 1] = {account.name, 0} + end end + end - local addonAccount = CreateAddonAccount(name, nil, money) - SharedAccounts[name] = addonAccount + if next(newAccounts) then + MySQL.prepare('INSERT INTO addon_account_data (account_name, money) VALUES (?, ?)', newAccounts) + for i = 1, #newAccounts do + local newAccount = newAccounts[i] + SharedAccounts[newAccount[1]] = CreateAddonAccount(newAccount[1], nil, 0) + end end end end) @@ -68,17 +60,13 @@ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local account = GetAccount(name, xPlayer.identifier) if account == nil then - MySQL.update('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, @owner)', { - ['@account_name'] = name, - ['@money'] = 0, - ['@owner'] = xPlayer.identifier - }) + MySQL.insert('INSERT INTO addon_account_data (account_name, money, owner) VALUES (?, ?, ?)', {name, 0, xPlayer.identifier}) account = CreateAddonAccount(name, xPlayer.identifier, 0) - table.insert(Accounts[name], account) + Accounts[name][#Accounts[name] + 1] = account end - table.insert(addonAccounts, account) + addonAccounts[#addonAccounts + 1] = account end xPlayer.set('addonAccounts', addonAccounts) diff --git a/[esx_addons]/esx_ambulancejob/client/vehicle.lua b/[esx_addons]/esx_ambulancejob/client/vehicle.lua index a14a6b33..77abead7 100644 --- a/[esx_addons]/esx_ambulancejob/client/vehicle.lua +++ b/[esx_addons]/esx_ambulancejob/client/vehicle.lua @@ -109,17 +109,17 @@ function OpenVehicleSpawnerMenu(type, hospital, part, partNum) end function StoreNearbyVehicle(playerCoords) - local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} - - if #vehicles > 0 then - for k,v in ipairs(vehicles) do + local vehicles, plates, index = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {}, {} + if next(vehicles) then + for i = 1, #vehicles do + local vehicle = vehicles[i] + -- Make sure the vehicle we're saving is empty, or else it wont be deleted - if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then - table.insert(vehiclePlates, { - vehicle = v, - plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) - }) + if GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) then + local plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) + plates[#plates + 1] = plate + index[plate] = vehicle end end else @@ -127,11 +127,11 @@ function StoreNearbyVehicle(playerCoords) return end - ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(storeSuccess, foundNum) - if storeSuccess then - local vehicleId = vehiclePlates[foundNum] + ESX.TriggerServerCallback('esx_ambulancejob:storeNearbyVehicle', function(plate) + if plate then + local vehicleId = index[plate] local attempts = 0 - ESX.Game.DeleteVehicle(vehicleId.vehicle) + ESX.Game.DeleteVehicle(vehicleId) isBusy = true Citizen.CreateThread(function() @@ -142,7 +142,7 @@ function StoreNearbyVehicle(playerCoords) end) -- Workaround for vehicle not deleting when other players are near it. - while DoesEntityExist(vehicleId.vehicle) do + while DoesEntityExist(vehicleId) do Citizen.Wait(500) attempts = attempts + 1 @@ -153,9 +153,10 @@ function StoreNearbyVehicle(playerCoords) vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0) if #vehicles > 0 then - for k,v in ipairs(vehicles) do - if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then - ESX.Game.DeleteVehicle(v) + for i = 1, #vehicles do + local vehicle = vehicles[i] + if ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) == plate then + ESX.Game.DeleteVehicle(vehicle) break end end @@ -167,7 +168,7 @@ function StoreNearbyVehicle(playerCoords) else ESX.ShowNotification(_U('garage_has_notstored')) end - end, vehiclePlates) + end, plates) end function GetAvailableVehicleSpawnPoint(hospital, part, partNum) diff --git a/[esx_addons]/esx_ambulancejob/server/main.lua b/[esx_addons]/esx_ambulancejob/server/main.lua index 5b828998..6ef0e4d1 100644 --- a/[esx_addons]/esx_ambulancejob/server/main.lua +++ b/[esx_addons]/esx_ambulancejob/server/main.lua @@ -178,14 +178,8 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb if xPlayer.getMoney() >= price then xPlayer.removeMoney(price) - MySQL.update('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (@owner, @vehicle, @plate, @type, @job, @stored)', { - ['@owner'] = xPlayer.identifier, - ['@vehicle'] = json.encode(vehicleProps), - ['@plate'] = vehicleProps.plate, - ['@type'] = type, - ['@job'] = xPlayer.job.name, - ['@stored'] = true - }, function (rowsChanged) + MySQL.insert('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (?, ?, ?, ?, ?, ?)', {xPlayer.identifier, json.encode(vehicleProps), vehicleProps.plate, type, xPlayer.job.name, true}, + function (rowsChanged) cb(true) end) else @@ -194,46 +188,32 @@ ESX.RegisterServerCallback('esx_ambulancejob:buyJobVehicle', function(source, cb end end) -ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(source, cb, nearbyVehicles) +ESX.RegisterServerCallback('esx_ambulancejob:storeNearbyVehicle', function(source, cb, plates) local xPlayer = ESX.GetPlayerFromId(source) - local foundPlate, foundNum - for k,v in ipairs(nearbyVehicles) do - local result = MySQL.query.await('SELECT plate FROM owned_vehicles WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = v.plate, - ['@job'] = xPlayer.job.name - }) + local plate = MySQL.single.await('SELECT plate FROM owned_vehicles WHERE owner = ? AND plate IN (?) AND job = ?', {xPlayer.identifier, plates, xPlayer.job.name}) - if result[1] then - foundPlate, foundNum = result[1].plate, k - break - end - end - - if not foundPlate then - cb(false) - else - MySQL.update('UPDATE owned_vehicles SET `stored` = true WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = foundPlate, - ['@job'] = xPlayer.job.name - }, function (rowsChanged) + if plate then + MySQL.update('UPDATE owned_vehicles SET `stored` = true WHERE owner = ? AND plate = ? AND job = ?', {xPlayer.identifier, plate, xPlayer.job.name}, + function(rowsChanged) if rowsChanged == 0 then cb(false) else - cb(true, foundNum) + cb(plate) end end) + else + cb(false) end end) function getPriceFromHash(vehicleHash, jobGrade, type) local vehicles = Config.AuthorizedVehicles[type][jobGrade] - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == vehicleHash then - return v.price + for i = 1, #vehicles do + local vehicle = vehicles[i] + if GetHashKey(vehicles.model) == vehicleHash then + return vehicle.price end end @@ -306,9 +286,8 @@ end) ESX.RegisterServerCallback('esx_ambulancejob:getDeathStatus', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.scalar('SELECT is_dead FROM users WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(isDead) + MySQL.scalar.await('SELECT is_dead FROM users WHERE identifier = ?', {xPlayer.identifier}, + function(isDead) if isDead then print(('[esx_ambulancejob] [^2INFO^7] "%s" attempted combat logging'):format(xPlayer.identifier)) @@ -323,9 +302,6 @@ AddEventHandler('esx_ambulancejob:setDeathStatus', function(isDead) local xPlayer = ESX.GetPlayerFromId(source) if type(isDead) == 'boolean' then - MySQL.update.await('UPDATE users SET is_dead = @isDead WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier, - ['@isDead'] = isDead - }) + MySQL.update('UPDATE users SET is_dead = ? WHERE identifier = ?', {isDead, xPlayer.identifier}) end end) diff --git a/[esx_addons]/esx_billing/server/main.lua b/[esx_addons]/esx_billing/server/main.lua index b1338ce9..1a0d2920 100644 --- a/[esx_addons]/esx_billing/server/main.lua +++ b/[esx_addons]/esx_billing/server/main.lua @@ -7,25 +7,13 @@ AddEventHandler('esx_billing:sendBill', function(playerId, sharedAccountName, la if amount > 0 and xTarget then TriggerEvent('esx_addonaccount:getSharedAccount', sharedAccountName, function(account) if account then - MySQL.update('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', { - ['@identifier'] = xTarget.identifier, - ['@sender'] = xPlayer.identifier, - ['@target_type'] = 'society', - ['@target'] = sharedAccountName, - ['@label'] = label, - ['@amount'] = amount - }, function(rowsChanged) + MySQL.insert('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)', {xTarget.identifier, xPlayer.identifier, 'society', sharedAccountName, label, amount}, + function(rowsChanged) xTarget.showNotification(_U('received_invoice')) end) else - MySQL.update('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (@identifier, @sender, @target_type, @target, @label, @amount)', { - ['@identifier'] = xTarget.identifier, - ['@sender'] = xPlayer.identifier, - ['@target_type'] = 'player', - ['@target'] = xPlayer.identifier, - ['@label'] = label, - ['@amount'] = amount - }, function(rowsChanged) + MySQL.insert('INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)', {xTarget.identifier, xPlayer.identifier, 'player', xPlayer.identifier, label, amount}, + function(rowsChanged) xTarget.showNotification(_U('received_invoice')) end) end @@ -36,9 +24,8 @@ end) ESX.RegisterServerCallback('esx_billing:getBills', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.query('SELECT amount, id, label FROM billing WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) + MySQL.query('SELECT amount, id, label FROM billing WHERE identifier = ?', {xPlayer.identifier}, + function(result) cb(result) end) end) @@ -47,9 +34,8 @@ ESX.RegisterServerCallback('esx_billing:getTargetBills', function(source, cb, ta local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.query('SELECT amount, id, label FROM billing WHERE identifier = @identifier', { - ['@identifier'] = xPlayer.identifier - }, function(result) + MySQL.query('SELECT amount, id, label FROM billing WHERE identifier = ?', {xPlayer.identifier}, + function(result) cb(result) end) else @@ -60,19 +46,17 @@ end) ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.query('SELECT sender, target_type, target, amount FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(result) - if result[1] then - local amount = result[1].amount - local xTarget = ESX.GetPlayerFromIdentifier(result[1].sender) + MySQL.single('SELECT sender, target_type, target, amount FROM billing WHERE id = ?', {billId}, + function(result) + if result then + local amount = result.amount + local xTarget = ESX.GetPlayerFromIdentifier(result.sender) - if result[1].target_type == 'player' then + if result.target_type == 'player' then if xTarget then if xPlayer.getMoney() >= amount then - MySQL.update('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.query('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeMoney(amount) xTarget.addMoney(amount) @@ -84,9 +68,8 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) cb() end) elseif xPlayer.getAccount('bank').money >= amount then - MySQL.update('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.query('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeAccountMoney('bank', amount) xTarget.addAccountMoney('bank', amount) @@ -109,9 +92,8 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) else TriggerEvent('esx_addonaccount:getSharedAccount', result[1].target, function(account) if xPlayer.getMoney() >= amount then - MySQL.update('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.query('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeMoney(amount) account.addMoney(amount) @@ -125,9 +107,8 @@ ESX.RegisterServerCallback('esx_billing:payBill', function(source, cb, billId) cb() end) elseif xPlayer.getAccount('bank').money >= amount then - MySQL.update('DELETE FROM billing WHERE id = @id', { - ['@id'] = billId - }, function(rowsChanged) + MySQL.query('DELETE FROM billing WHERE id = ?', {billId}, + function(rowsChanged) if rowsChanged == 1 then xPlayer.removeAccountMoney('bank', amount) account.addMoney(amount) diff --git a/[esx_addons]/esx_datastore/server/classes/datastore.lua b/[esx_addons]/esx_datastore/server/classes/datastore.lua index 720dfa9f..8a72cff5 100644 --- a/[esx_addons]/esx_datastore/server/classes/datastore.lua +++ b/[esx_addons]/esx_datastore/server/classes/datastore.lua @@ -68,16 +68,9 @@ function CreateDataStore(name, owner, data) local timeoutCallback = ESX.SetTimeout(10000, function() if self.owner == nil then - MySQL.update('UPDATE datastore_data SET data = @data WHERE name = @name', { - ['@data'] = json.encode(self.data), - ['@name'] = self.name, - }) + MySQL.update('UPDATE datastore_data SET data = ? WHERE name = ?', {json.encode(self.data), self.name}) else - MySQL.update('UPDATE datastore_data SET data = @data WHERE name = @name and owner = @owner', { - ['@data'] = json.encode(self.data), - ['@name'] = self.name, - ['@owner'] = self.owner, - }) + MySQL.update('UPDATE datastore_data SET data = / WHERE name = ? and owner = ?', {json.encode(self.data), self.name, self.owner}) end end) diff --git a/[esx_addons]/esx_datastore/server/main.lua b/[esx_addons]/esx_datastore/server/main.lua index 84e40c07..d1eafd78 100644 --- a/[esx_addons]/esx_datastore/server/main.lua +++ b/[esx_addons]/esx_datastore/server/main.lua @@ -1,41 +1,33 @@ local DataStores, DataStoresIndex, SharedDataStores = {}, {}, {} -MySQL.ready(function() - local result = MySQL.query.await('SELECT * FROM datastore') +AddEventHandler('onResourceStart', function(resourceName) + if resourceName == GetCurrentResourceName() then + local dataStore = MySQL.query.await('SELECT * FROM datastore_data LEFT JOIN datastore ON datastore_data.name = datastore.name UNION SELECT * FROM datastore_data RIGHT JOIN datastore ON datastore_data.name = datastore.name') - for i=1, #result, 1 do - local name, label, shared = result[i].name, result[i].label, result[i].shared - local result2 = MySQL.query.await('SELECT * FROM datastore_data WHERE name = @name', { - ['@name'] = name - }) - - if shared == 0 then - table.insert(DataStoresIndex, name) - DataStores[name] = {} - - for j=1, #result2, 1 do - local storeName = result2[j].name - local storeOwner = result2[j].owner - local storeData = (result2[j].data == nil and {} or json.decode(result2[j].data)) - local dataStore = CreateDataStore(storeName, storeOwner, storeData) - - table.insert(DataStores[name], dataStore) - end - else - local data - - if #result2 == 0 then - MySQL.update.await('INSERT INTO datastore_data (name, owner, data) VALUES (@name, NULL, \'{}\')', { - ['@name'] = name - }) - - data = {} + local newData = {} + for i = 1, #dataStore do + local data = dataStore[i] + if data.shared == 0 then + if not DataStores[data.name] then + DataStoresIndex[#DataStoresIndex + 1] = data.name + DataStores[data.name] = {} + end + DataStores[data.name][#DataStores[data.name] + 1] = CreateDataStore(data.name, data.owner, data.data) else - data = json.decode(result2[1].data) + if data.data then + SharedDataStores[data.name] = CreateDataStore(data.name, nil, data.data) + else + newData[#newData + 1] = {data.name, '\'{}\''} + end end + end - local dataStore = CreateDataStore(name, nil, data) - SharedDataStores[name] = dataStore + if next(newData) then + MySQL.prepare('INSERT INTO datastore_data (name, data) VALUES (?, ?)', newData) + for i = 1, #newData do + local new = newData[i] + SharedDataStores[new[1]] = CreateDataStore(new[1], nil, new[2]) + end end end end) @@ -80,14 +72,9 @@ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) local dataStore = GetDataStore(name, xPlayer.identifier) if not dataStore then - MySQL.update('INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', { - ['@name'] = name, - ['@owner'] = xPlayer.identifier, - ['@data'] = '{}' - }) + MySQL.insert('INSERT INTO datastore_data (name, owner, data) VALUES (?, ?, ?)', {name, xPlayer.identifier, '{}'}) - dataStore = CreateDataStore(name, xPlayer.identifier, {}) - table.insert(DataStores[name], dataStore) + DataStores[name][#DataStores[name] + 1] = CreateDataStore(name, xPlayer.identifier, {}) end end end) diff --git a/[esx_addons]/esx_license/server/main.lua b/[esx_addons]/esx_license/server/main.lua index 40ec3a44..fd9aa613 100644 --- a/[esx_addons]/esx_license/server/main.lua +++ b/[esx_addons]/esx_license/server/main.lua @@ -2,10 +2,8 @@ function AddLicense(target, type, cb) local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.update('INSERT INTO user_licenses (type, owner) VALUES (@type, @owner)', { - ['@type'] = type, - ['@owner'] = xPlayer.identifier - }, function(rowsChanged) + MySQL.insert('INSERT INTO user_licenses (type, owner) VALUES (?, ?)', {type, xPlayer.identifier}, + function(rowsChanged) if cb then cb() end @@ -21,10 +19,8 @@ function RemoveLicense(target, type, cb) local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.update('DELETE FROM user_licenses WHERE type = @type AND owner = @owner', { - ['@type'] = type, - ['@owner'] = xPlayer.identifier - }, function(rowsChanged) + MySQL.query('DELETE FROM user_licenses WHERE type = ? AND owner = ?', {type, Player.identifier}, + function(rowsChanged) if cb then cb() end @@ -37,48 +33,18 @@ function RemoveLicense(target, type, cb) end function GetLicense(type, cb) - MySQL.query('SELECT label FROM licenses WHERE type = @type', { - ['@type'] = type - }, function(result) - local data = { - type = type, - label = result[1].label - } - - cb(data) + MySQL.scalar('SELECT label FROM licenses WHERE type = ?', {type}, + function(result) + cb({type = type, label = result}) end) end function GetLicenses(target, cb) local xPlayer = ESX.GetPlayerFromId(target) - MySQL.query('SELECT type FROM user_licenses WHERE owner = @owner', { - ['@owner'] = xPlayer.identifier - }, function(result) - local licenses, asyncTasks = {}, {} - - for i=1, #result, 1 do - local scope = function(type) - table.insert(asyncTasks, function(cb) - MySQL.query('SELECT label FROM licenses WHERE type = @type', { - ['@type'] = type - }, function(result2) - table.insert(licenses, { - type = type, - label = result2[1].label - }) - - cb() - end) - end) - end - - scope(result[i].type) - end - - Async.parallel(asyncTasks, function(results) - cb(licenses) - end) + MySQL.query('SELECT user_licenses.type, licenses.label FROM user_licenses LEFT JOIN licenses ON user_licenses.type = licenses.type WHERE owner = ?', {xPlayer.identifier}, + function(result) + cb(result) end) end @@ -86,11 +52,9 @@ function CheckLicense(target, type, cb) local xPlayer = ESX.GetPlayerFromId(target) if xPlayer then - MySQL.query('SELECT COUNT(*) as count FROM user_licenses WHERE type = @type AND owner = @owner', { - ['@type'] = type, - ['@owner'] = xPlayer.identifier - }, function(result) - if tonumber(result[1].count) > 0 then + MySQL.scalar('SELECT type FROM user_licenses WHERE type = ? AND owner = ?', {type, xPlayer.identifier}, + function(result) + if result then cb(true) else cb(false) @@ -102,19 +66,9 @@ function CheckLicense(target, type, cb) end function GetLicensesList(cb) - MySQL.query('SELECT type, label FROM licenses', { - ['@type'] = type - }, function(result) - local licenses = {} - - for i=1, #result, 1 do - table.insert(licenses, { - type = result[i].type, - label = result[i].label - }) - end - - cb(licenses) + MySQL.query('SELECT type, label FROM licenses', {}, + function(result) + cb(result) end) end diff --git a/[esx_addons]/esx_lscustom/server/main.lua b/[esx_addons]/esx_lscustom/server/main.lua index cdbad83f..b56debf0 100644 --- a/[esx_addons]/esx_lscustom/server/main.lua +++ b/[esx_addons]/esx_lscustom/server/main.lua @@ -37,17 +37,13 @@ RegisterServerEvent('esx_lscustom:refreshOwnedVehicle') AddEventHandler('esx_lscustom:refreshOwnedVehicle', function(vehicleProps) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.query('SELECT vehicle FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = vehicleProps.plate - }, function(result) - if result[1] then - local vehicle = json.decode(result[1].vehicle) + MySQL.single('SELECT vehicle FROM owned_vehicles WHERE plate = ?', {vehicleProps.plate}, + function(result) + if result then + local vehicle = json.decode(result.vehicle) if vehicleProps.model == vehicle.model then - MySQL.update('UPDATE owned_vehicles SET vehicle = @vehicle WHERE plate = @plate', { - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps) - }) + MySQL.update('UPDATE owned_vehicles SET vehicle = ? WHERE plate = ?', {vehicleProps.plate, json.encode(vehicleProps)}) else print(('esx_lscustom: %s attempted to upgrade vehicle with mismatching vehicle model!'):format(xPlayer.identifier)) end @@ -57,20 +53,7 @@ end) ESX.RegisterServerCallback('esx_lscustom:getVehiclesPrices', function(source, cb) if not Vehicles then - MySQL.query('SELECT * FROM vehicles', {}, function(result) - local vehicles = {} - - for i=1, #result, 1 do - table.insert(vehicles, { - model = result[i].model, - price = result[i].price - }) - end - - Vehicles = vehicles - cb(Vehicles) - end) - else - cb(Vehicles) + Vehicles = MySQL.query.await('SELECT model, price FROM vehicles', {}) end + cb(Vehicles) end) \ No newline at end of file diff --git a/[esx_addons]/esx_policejob/client/vehicle.lua b/[esx_addons]/esx_policejob/client/vehicle.lua index 2a0d04b4..5497f978 100644 --- a/[esx_addons]/esx_policejob/client/vehicle.lua +++ b/[esx_addons]/esx_policejob/client/vehicle.lua @@ -118,17 +118,17 @@ function OpenVehicleSpawnerMenu(type, station, part, partNum) end function StoreNearbyVehicle(playerCoords) - local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} - - if #vehicles > 0 then - for k,v in ipairs(vehicles) do + local vehicles, plates, index = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {}, {} + if next(vehicles) then + for i = 1, #vehicles do + local vehicle = vehicles[i] + -- Make sure the vehicle we're saving is empty, or else it wont be deleted - if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then - table.insert(vehiclePlates, { - vehicle = v, - plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) - }) + if GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) then + local plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) + plates[#plates + 1] = plate + index[plate] = vehicle end end else @@ -136,27 +136,22 @@ function StoreNearbyVehicle(playerCoords) return end - ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(storeSuccess, foundNum) - if storeSuccess then - local vehicleId = vehiclePlates[foundNum] + ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(plate) + if plate then + local vehicleId = index[plate] local attempts = 0 - ESX.Game.DeleteVehicle(vehicleId.vehicle) - IsBusy = true + ESX.Game.DeleteVehicle(vehicleId) + local isBusy = true Citizen.CreateThread(function() - BeginTextCommandBusyspinnerOn('STRING') - AddTextComponentSubstringPlayerName(_U('garage_storing')) - EndTextCommandBusyspinnerOn(4) - - while IsBusy do - Citizen.Wait(100) + while isBusy do + Citizen.Wait(0) + drawLoadingText(_U('garage_storing'), 255, 255, 255, 255) end - - BusyspinnerOff() end) -- Workaround for vehicle not deleting when other players are near it. - while DoesEntityExist(vehicleId.vehicle) do + while DoesEntityExist(vehicleId) do Citizen.Wait(500) attempts = attempts + 1 @@ -167,21 +162,22 @@ function StoreNearbyVehicle(playerCoords) vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0) if #vehicles > 0 then - for k,v in ipairs(vehicles) do - if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then - ESX.Game.DeleteVehicle(v) + for i = 1, #vehicles do + local vehicle = vehicles[i] + if ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) == plate then + ESX.Game.DeleteVehicle(vehicle) break end end end end - IsBusy = false + isBusy = false ESX.ShowNotification(_U('garage_has_stored')) else ESX.ShowNotification(_U('garage_has_notstored')) end - end, vehiclePlates) + end, plates) end function GetAvailableVehicleSpawnPoint(station, part, partNum) diff --git a/[esx_addons]/esx_policejob/server/main.lua b/[esx_addons]/esx_policejob/server/main.lua index 15c0fa64..c482973d 100644 --- a/[esx_addons]/esx_policejob/server/main.lua +++ b/[esx_addons]/esx_policejob/server/main.lua @@ -198,41 +198,33 @@ ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, end) ESX.RegisterServerCallback('esx_policejob:getFineList', function(source, cb, category) - MySQL.query('SELECT * FROM fine_types WHERE category = @category', { - ['@category'] = category - }, function(fines) + MySQL.query('SELECT * FROM fine_types WHERE category = ?', {category}, + function(fines) cb(fines) end) end) ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, plate) - MySQL.query('SELECT owner FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - local retrivedInfo = {plate = plate} - - if result[1] then - local xPlayer = ESX.GetPlayerFromIdentifier(result[1].owner) - - -- is the owner online? - if xPlayer then - retrivedInfo.owner = xPlayer.getName() - cb(retrivedInfo) - elseif Config.EnableESXIdentity then - MySQL.query('SELECT firstname, lastname FROM users WHERE identifier = @identifier', { - ['@identifier'] = result[1].owner - }, function(result2) - if result2[1] then - retrivedInfo.owner = ('%s %s'):format(result2[1].firstname, result2[1].lastname) - cb(retrivedInfo) - else - cb(retrivedInfo) - end - end) - else - cb(retrivedInfo) + local retrivedInfo = { + plate = plate + } + if Config.EnableESXIdentity then + MySQL.single('SELECT users.firstname, users.lastname FROM owned_vehicles JOIN users ON owned_vehicles.owner = users.identifier WHERE plate = ?', {plate}, + function(result) + if result then + retrivedInfo.owner = ('%s %s'):format(result.firstname, result.lastname) + end + cb(retrivedInfo) + end) + else + MySQL.scalar('SELECT owner FROM owned_vehicles WHERE plate = ?', {plate}, + function(owner) + if owner then + local xPlayer = ESX.GetPlayerFromIdentifier(owner) + if xPlayer then + retrivedInfo.owner = xPlayer.getName() + end end - else cb(retrivedInfo) end end) @@ -278,7 +270,7 @@ ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, store.set('weapons', weapons) cb() - end) + end) end) ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, cb, weaponName) @@ -371,14 +363,8 @@ ESX.RegisterServerCallback('esx_policejob:buyJobVehicle', function(source, cb, v if xPlayer.getMoney() >= price then xPlayer.removeMoney(price) - MySQL.update('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (@owner, @vehicle, @plate, @type, @job, @stored)', { - ['@owner'] = xPlayer.identifier, - ['@vehicle'] = json.encode(vehicleProps), - ['@plate'] = vehicleProps.plate, - ['@type'] = type, - ['@job'] = xPlayer.job.name, - ['@stored'] = true - }, function (rowsChanged) + MySQL.insert('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (?, ?, ?, ?, ?, ?)', { xPlayer.identifier, json.encode(vehicleProps), vehicleProps.plate, type, xPlayer.job.name, true}, + function (rowsChanged) cb(true) end) else @@ -387,47 +373,32 @@ ESX.RegisterServerCallback('esx_policejob:buyJobVehicle', function(source, cb, v end end) -ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, cb, nearbyVehicles) +ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, cb, plates) local xPlayer = ESX.GetPlayerFromId(source) - local foundPlate, foundNum - for k,v in ipairs(nearbyVehicles) do - local result = MySQL.query.await('SELECT plate FROM owned_vehicles WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = v.plate, - ['@job'] = xPlayer.job.name - }) + local plate = MySQL.single.await('SELECT plate FROM owned_vehicles WHERE owner = ? AND plate IN (?) AND job = ?', {xPlayer.identifier, plates, xPlayer.job.name}) - if result[1] then - foundPlate, foundNum = result[1].plate, k - break - end - end - - if not foundPlate then - cb(false) - else - MySQL.update('UPDATE owned_vehicles SET `stored` = true WHERE owner = @owner AND plate = @plate AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = foundPlate, - ['@job'] = xPlayer.job.name - }, function (rowsChanged) + if plate then + MySQL.update('UPDATE owned_vehicles SET `stored` = true WHERE owner = ? AND plate = ? AND job = ?', {xPlayer.identifier, plate, xPlayer.job.name}, + function(rowsChanged) if rowsChanged == 0 then - print(('esx_policejob: %s has exploited the garage!'):format(xPlayer.identifier)) cb(false) else - cb(true, foundNum) + cb(plate) end end) + else + cb(false) end end) function getPriceFromHash(vehicleHash, jobGrade, type) local vehicles = Config.AuthorizedVehicles[type][jobGrade] - for k,v in ipairs(vehicles) do - if GetHashKey(v.model) == vehicleHash then - return v.price + for i = 1, #vehicles do + local vehicle = vehicles[i] + if GetHashKey(vehicles.model) == vehicleHash then + return vehicle.price end end diff --git a/[esx_addons]/esx_society/server/main.lua b/[esx_addons]/esx_society/server/main.lua index d1dca900..139c9f8c 100644 --- a/[esx_addons]/esx_society/server/main.lua +++ b/[esx_addons]/esx_society/server/main.lua @@ -9,18 +9,20 @@ function GetSociety(name) end end -MySQL.ready(function() - local result = MySQL.query.await('SELECT * FROM jobs', {}) +AddEventHandler('onResourceStart', function(resourceName) + if resourceName == GetCurrentResourceName() then + local result = MySQL.query.await('SELECT * FROM jobs', {}) - for i=1, #result, 1 do - Jobs[result[i].name] = result[i] - Jobs[result[i].name].grades = {} - end + for i = 1, #result, 1 do + Jobs[result[i].name] = result[i] + Jobs[result[i].name].grades = {} + end - local result2 = MySQL.query.await('SELECT * FROM job_grades', {}) + local result2 = MySQL.query.await('SELECT * FROM job_grades', {}) - for i=1, #result2, 1 do - Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] + for i = 1, #result2, 1 do + Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] + end end end) @@ -108,11 +110,8 @@ AddEventHandler('esx_society:washMoney', function(society, amount) if amount and amount > 0 and account.money >= amount then xPlayer.removeAccountMoney('black_money', amount) - MySQL.update('INSERT INTO society_moneywash (identifier, society, amount) VALUES (@identifier, @society, @amount)', { - ['@identifier'] = xPlayer.identifier, - ['@society'] = society, - ['@amount'] = amount - }, function(rowsChanged) + MySQL.insert('INSERT INTO society_moneywash (identifier, society, amount) VALUES (?, ?, ?)', {xPlayer.identifier, society, amount}, + function(rowsChanged) xPlayer.showNotification(_U('you_have', ESX.Math.GroupDigits(amount))) end) else @@ -188,15 +187,14 @@ ESX.RegisterServerCallback('esx_society:getEmployees', function(source, cb, soci }) end - local query = "SELECT identifier, job_grade FROM `users` WHERE `job`=@job ORDER BY job_grade DESC" + local query = "SELECT identifier, job_grade FROM `users` WHERE `job`= ? ORDER BY job_grade DESC" if Config.EnableESXIdentity then - query = "SELECT identifier, job_grade, firstname, lastname FROM `users` WHERE `job`=@job ORDER BY job_grade DESC" + query = "SELECT identifier, job_grade, firstname, lastname FROM `users` WHERE `job`= ? ORDER BY job_grade DESC" end - MySQL.query(query, { - ['@job'] = society - }, function(result) + MySQL.query(query, {society}, + function(result) for k, row in pairs(result) do local alreadyInTable local identifier = row.identifier @@ -270,11 +268,8 @@ ESX.RegisterServerCallback('esx_society:setJob', function(source, cb, identifier cb() else - MySQL.update('UPDATE users SET job = @job, job_grade = @job_grade WHERE identifier = @identifier', { - ['@job'] = job, - ['@job_grade'] = grade, - ['@identifier'] = identifier - }, function(rowsChanged) + MySQL.update('UPDATE users SET job = ?, job_grade = ? WHERE identifier = ?', {job, grade, identifier}, + function(rowsChanged) cb() end) end @@ -289,11 +284,8 @@ ESX.RegisterServerCallback('esx_society:setJobSalary', function(source, cb, job, if xPlayer.job.name == job and xPlayer.job.grade_name == 'boss' then if salary <= Config.MaxSalary then - MySQL.update('UPDATE job_grades SET salary = @salary WHERE job_name = @job_name AND grade = @grade', { - ['@salary'] = salary, - ['@job_name'] = job, - ['@grade'] = grade - }, function(rowsChanged) + MySQL.update('UPDATE job_grades SET salary = ? WHERE job_name = ? AND grade = ?', {salary, job, grade}, + function(rowsChanged) Jobs[job].grades[tostring(grade)].salary = salary local xPlayers = ESX.GetExtendedPlayers('job', job) @@ -380,10 +372,8 @@ function WashMoneyCRON(d, h, m) xPlayer.showNotification(_U('you_have_laundered', ESX.Math.GroupDigits(result[i].amount))) end - MySQL.update('DELETE FROM society_moneywash WHERE id = @id', { - ['@id'] = result[i].id - }) end + MySQL.query('DELETE FROM society_moneywash', {}) end) end diff --git a/[esx_addons]/esx_vehicleshop/client/main.lua b/[esx_addons]/esx_vehicleshop/client/main.lua index db7c6264..8435b328 100644 --- a/[esx_addons]/esx_vehicleshop/client/main.lua +++ b/[esx_addons]/esx_vehicleshop/client/main.lua @@ -2,10 +2,11 @@ local HasAlreadyEnteredMarker, IsInShopMenu = false, false local CurrentAction, CurrentActionMsg, LastZone, currentDisplayVehicle, CurrentVehicleData local CurrentActionData, Vehicles, Categories = {}, {}, {} -function getVehicleLabelFromModel(model) - for k,v in ipairs(Vehicles) do - if v.model == model then - return v.name +function getVehicleFromModel(model) + for i = 1, #Vehicles do + local vehicle = Vehicles[i] + if vehicle.model == model then + return vehicle end end @@ -82,7 +83,7 @@ function ReturnVehicleProvider() for k,v in ipairs(vehicles) do local returnPrice = ESX.Math.Round(v.price * 0.75) - local vehicleLabel = getVehicleLabelFromModel(v.vehicle) + local vehicleLabel = getVehicleFromModel(v.vehicle).label table.insert(elements, { label = ('%s [%s]'):format(vehicleLabel, _U('generic_shopitem', ESX.Math.GroupDigits(returnPrice))), @@ -143,7 +144,7 @@ function OpenShopMenu() end for i=1, #Vehicles, 1 do - if IsModelInCdimage(GetHashKey(Vehicles[i].model)) then + if IsModelInCdimage(joaat(Vehicles[i].model)) then table.insert(vehiclesByCategory[Vehicles[i].category], Vehicles[i]) else print(('[esx_vehicleshop] [^3ERROR^7] Vehicle "%s" does not exist'):format(Vehicles[i].model)) @@ -289,7 +290,7 @@ function OpenShopMenu() end function WaitForVehicleToLoad(modelHash) - modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) + modelHash = (type(modelHash) == 'number' and modelHash or joaat(modelHash)) if not HasModelLoaded(modelHash) then RequestModel(modelHash) diff --git a/[esx_addons]/esx_vehicleshop/client/utils.lua b/[esx_addons]/esx_vehicleshop/client/utils.lua index 88a30d50..277f2ecf 100644 --- a/[esx_addons]/esx_vehicleshop/client/utils.lua +++ b/[esx_addons]/esx_vehicleshop/client/utils.lua @@ -50,7 +50,6 @@ end function GetRandomNumber(length) Citizen.Wait(0) - math.randomseed(GetGameTimer()) if length > 0 then return GetRandomNumber(length - 1) .. NumberCharset[math.random(1, #NumberCharset)] else @@ -60,7 +59,6 @@ end function GetRandomLetter(length) Citizen.Wait(0) - math.randomseed(GetGameTimer()) if length > 0 then return GetRandomLetter(length - 1) .. Charset[math.random(1, #Charset)] else diff --git a/[esx_addons]/esx_vehicleshop/fxmanifest.lua b/[esx_addons]/esx_vehicleshop/fxmanifest.lua index 0fbc8c70..884cca1d 100644 --- a/[esx_addons]/esx_vehicleshop/fxmanifest.lua +++ b/[esx_addons]/esx_vehicleshop/fxmanifest.lua @@ -2,6 +2,8 @@ fx_version 'adamant' game 'gta5' +lua54 'yes' + description 'ESX Vehicle Shop' version 'legacy' diff --git a/[esx_addons]/esx_vehicleshop/server/main.lua b/[esx_addons]/esx_vehicleshop/server/main.lua index 9646b085..f7792a93 100644 --- a/[esx_addons]/esx_vehicleshop/server/main.lua +++ b/[esx_addons]/esx_vehicleshop/server/main.lua @@ -14,35 +14,30 @@ Citizen.CreateThread(function() end) function RemoveOwnedVehicle(plate) - MySQL.update('DELETE FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }) + MySQL.query('DELETE FROM owned_vehicles WHERE plate = ?', {plate}) end AddEventHandler('onResourceStart', function(resourceName) - if resourceName == GetCurrentResourceName() then - MySQL.ready(function() SQLVehiclesAndCategories() end) - end + if resourceName == GetCurrentResourceName() then + SQLVehiclesAndCategories() + end end) function SQLVehiclesAndCategories() - MySQL.query('SELECT * FROM `vehicle_categories`', {}, function(_categories) - categories = _categories + categories = MySQL.query.await('SELECT * FROM vehicle_categories', {}) - MySQL.query('SELECT * FROM `vehicles`', {}, function(_vehicles) - vehicles = _vehicles + vehicles = MySQL.query.await('SELECT * FROM vehicles', {}) - GetVehiclesAndCategories(categories, vehicles) - end) - - end) + GetVehiclesAndCategories(categories, vehicles) end function GetVehiclesAndCategories(categories, vehicles) - for k,v in ipairs(vehicles) do - for k2,v2 in ipairs(categories) do - if v2.name == v.category then - vehicles[k].categoryLabel = v2.label + for i = 1, #vehicles do + local vehicle = vehicles[i] + for j = 1, #categories do + local category = categories[j] + if category.name == vehicle.catetgory then + vehicle.categoryLabel = category.label break end end @@ -53,10 +48,11 @@ function GetVehiclesAndCategories(categories, vehicles) TriggerClientEvent('esx_vehicleshop:sendVehicles', -1, vehicles) end -function getVehicleLabelFromModel(model) - for k,v in ipairs(vehicles) do - if v.model == model then - return v.name +function getVehicleFromModel(model) + for i = 1, #vehicles do + local vehicle = vehicles[i] + if vehicle.model == model then + return vehicle end end @@ -68,34 +64,19 @@ AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, ve local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) if xPlayer.job.name == 'cardealer' and xTarget then - MySQL.query('SELECT id FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = model - }, function(result) - if result[1] then - local id = result[1].id - - MySQL.update('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) + MySQL.scalar('SELECT id FROM cardealer_vehicles WHERE vehicle = ?', {model}, + function(id) + if id then + MySQL.query('DELETE FROM cardealer_vehicles WHERE id = ?', {id}, + function(rowsChanged) if rowsChanged == 1 then - MySQL.update('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', { - ['@owner'] = xTarget.identifier, - ['@plate'] = vehicleProps.plate, - ['@vehicle'] = json.encode(vehicleProps) - }, function(rowsChanged) + MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {xTarget.identifier, vehicleProps.plate, json.encode(vehicleProps)}, + function(rowsChanged) xPlayer.showNotification(_U('vehicle_set_owned', vehicleProps.plate, xTarget.getName())) xTarget.showNotification(_U('vehicle_belongs', vehicleProps.plate)) end) - local dateNow = os.date('%Y-%m-%d %H:%M') - - MySQL.update('INSERT INTO vehicle_sold (client, model, plate, soldby, date) VALUES (@client, @model, @plate, @soldby, @date)', { - ['@client'] = xTarget.getName(), - ['@model'] = label, - ['@plate'] = vehicleProps.plate, - ['@soldby'] = xPlayer.getName(), - ['@date'] = dateNow - }) + MySQL.insert('INSERT INTO vehicle_sold (client, model, plate, soldby, date) VALUES (?, ?, ?, ?, ?)', {xTarget.getName(), label, vehicleProps.plate, xPlayer.getName(), os.date('%Y-%m-%d %H:%M')}) end end) end @@ -114,24 +95,14 @@ AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, rentPric local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) if xPlayer.job.name == 'cardealer' and xTarget then - MySQL.query('SELECT id, price FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = vehicle - }, function(result) - if result[1] then - local price = result[1].price - - MySQL.update('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = result[1].id - }, function(rowsChanged) + MySQL.single('SELECT id, price FROM cardealer_vehicles WHERE vehicle = ?', {vehicle}, + function(result) + if result then + MySQL.query('DELETE FROM cardealer_vehicles WHERE id = ?', {result.id}, + function(rowsChanged) if rowsChanged == 1 then - MySQL.update('INSERT INTO rented_vehicles (vehicle, plate, player_name, base_price, rent_price, owner) VALUES (@vehicle, @plate, @player_name, @base_price, @rent_price, @owner)', { - ['@vehicle'] = vehicle, - ['@plate'] = plate, - ['@player_name'] = xTarget.getName(), - ['@base_price'] = price, - ['@rent_price'] = rentPrice, - ['@owner'] = xTarget.identifier - }, function(rowsChanged2) + MySQL.insert('INSERT INTO rented_vehicles (vehicle, plate, player_name, base_price, rent_price, owner) VALUES (?, ?, ?, ?, ?, ?)', {vehicle, plate, xTarget.getName(), result.price, rentPrice, xTarget.identifier}, + function(rowsChanged2) xPlayer.showNotification(_U('vehicle_set_rented', plate, xTarget.getName())) end) end @@ -194,22 +165,12 @@ end) ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, model, plate) local xPlayer = ESX.GetPlayerFromId(source) - local modelPrice - - for k,v in ipairs(vehicles) do - if model == v.model then - modelPrice = v.price - break - end - end + local modelPrice = getVehicleFromModel(model).price if modelPrice and xPlayer.getMoney() >= modelPrice then xPlayer.removeMoney(modelPrice) - MySQL.update('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (@owner, @plate, @vehicle)', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = plate, - ['@vehicle'] = json.encode({model = GetHashKey(model), plate = plate}) + MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {xPlayer.identifier, plate, json.encode({model = joaat(model), plate = plate}) }, function(rowsChanged) xPlayer.showNotification(_U('vehicle_belongs', plate)) cb(true) @@ -229,24 +190,15 @@ ESX.RegisterServerCallback('esx_vehicleshop:buyCarDealerVehicle', function(sourc local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.job.name == 'cardealer' then - local modelPrice - - for k,v in ipairs(vehicles) do - if model == v.model then - modelPrice = v.price - break - end - end + local modelPrice = getVehicleFromModel(model).price if modelPrice then TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) if account.money >= modelPrice then account.removeMoney(modelPrice) - MySQL.update('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { - ['@vehicle'] = model, - ['@price'] = modelPrice - }, function(rowsChanged) + MySQL.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {model, modelPrice}, + function(rowsChanged) cb(true) end) else @@ -262,19 +214,17 @@ AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) local xPlayer = ESX.GetPlayerFromId(source) if xPlayer.job.name == 'cardealer' then - MySQL.query('SELECT id, price FROM cardealer_vehicles WHERE vehicle = @vehicle LIMIT 1', { - ['@vehicle'] = vehicleModel - }, function(result) - if result[1] then - local id = result[1].id + MySQL.single('SELECT id, price FROM cardealer_vehicles WHERE vehicle = ?', {vehicleModel}, + function(result) + if result then + local id = result.id - MySQL.update('DELETE FROM cardealer_vehicles WHERE id = @id', { - ['@id'] = id - }, function(rowsChanged) + MySQL.query('DELETE FROM cardealer_vehicles WHERE id = ?', {id}, + function(rowsChanged) if rowsChanged == 1 then TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) - local price = ESX.Math.Round(result[1].price * 0.75) - local vehicleLabel = getVehicleLabelFromModel(vehicleModel) + local price = ESX.Math.Round(result.price * 0.75) + local vehicleLabel = getVehicleFromModel(vehicleModel).label account.addMoney(price) xPlayer.showNotification(_U('vehicle_sold_for', vehicleLabel, ESX.Math.GroupDigits(price))) @@ -292,12 +242,13 @@ ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, MySQL.query('SELECT * FROM rented_vehicles ORDER BY player_name ASC', {}, function(result) local vehicles = {} - for i=1, #result, 1 do - table.insert(vehicles, { - name = result[i].vehicle, - plate = result[i].plate, - playerName = result[i].player_name - }) + for i = 1, #result do + local vehicle = tab[i] + vehicles[#vehicles + 1] = { + name = vehicle.vehicle, + plate = vehicle.plate, + playerName = vehicle.player_name + } end cb(vehicles) @@ -305,20 +256,15 @@ ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, end) ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, cb, plate) - MySQL.query('SELECT base_price, vehicle FROM rented_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - if result[1] then - local vehicle = result[1].vehicle - local basePrice = result[1].base_price + MySQL.single('SELECT base_price, vehicle FROM rented_vehicles WHERE plate = ?', {plate}, + function(result) + if result then + local vehicle = result.vehicle + local basePrice = result.base_price - MySQL.update('DELETE FROM rented_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(rowsChanged) - MySQL.update('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (@vehicle, @price)', { - ['@vehicle'] = vehicle, - ['@price'] = basePrice - }) + MySQL.query('DELETE FROM rented_vehicles WHERE plate = ?', {plate}, + function(rowsChanged) + MySQL.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {result.vehicle, result.base_price}) RemoveOwnedVehicle(plate) cb(true) @@ -335,7 +281,7 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, if xPlayer.job.name == 'cardealer' or not Config.EnablePlayerManagement then -- calculate the resell price for i=1, #vehicles, 1 do - if GetHashKey(vehicles[i].model) == model then + if joaat(vehicles[i].model) == model then resellPrice = ESX.Math.Round(vehicles[i].price / 100 * Config.ResellPercentage) break end @@ -345,18 +291,15 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, print(('[esx_vehicleshop] [^3WARNING^7] %s attempted to sell an unknown vehicle!'):format(xPlayer.identifier)) cb(false) else - MySQL.query('SELECT * FROM rented_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - if result[1] then -- is it a rented vehicle? + MySQL.single('SELECT * FROM rented_vehicles WHERE plate = @plate', {plate}, + function(result) + if result then -- is it a rented vehicle? cb(false) -- it is, don't let the player sell it since he doesn't own it else - MySQL.query('SELECT * FROM owned_vehicles WHERE owner = @owner AND @plate = plate', { - ['@owner'] = xPlayer.identifier, - ['@plate'] = plate - }, function(result) - if result[1] then -- does the owner match? - local vehicle = json.decode(result[1].vehicle) + MySQL.single('SELECT * FROM owned_vehicles WHERE owner = ? AND plate = ?', {xPlayer.identifier, plate}, + function(result) + if result then -- does the owner match? + local vehicle = json.decode(result.vehicle) if vehicle.model == model then if vehicle.plate == plate then @@ -393,21 +336,17 @@ ESX.RegisterServerCallback('esx_vehicleshop:getPlayerInventory', function(source end) ESX.RegisterServerCallback('esx_vehicleshop:isPlateTaken', function(source, cb, plate) - MySQL.query('SELECT 1 FROM owned_vehicles WHERE plate = @plate', { - ['@plate'] = plate - }, function(result) - cb(result[1] ~= nil) + MySQL.scalar('SELECT plate FROM owned_vehicles WHERE plate = ?', {plate}, + function(result) + cb(result ~= nil) end) end) ESX.RegisterServerCallback('esx_vehicleshop:retrieveJobVehicles', function(source, cb, type) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.query('SELECT * FROM owned_vehicles WHERE owner = @owner AND type = @type AND job = @job', { - ['@owner'] = xPlayer.identifier, - ['@type'] = type, - ['@job'] = xPlayer.job.name - }, function(result) + MySQL.query('SELECT * FROM owned_vehicles WHERE owner = ? AND type = ? AND job = ?', {xPlayer.identifier, type, xPlayer.job.name}, + function(result) cb(result) end) end) @@ -416,76 +355,101 @@ RegisterNetEvent('esx_vehicleshop:setJobVehicleState') AddEventHandler('esx_vehicleshop:setJobVehicleState', function(plate, state) local xPlayer = ESX.GetPlayerFromId(source) - MySQL.update('UPDATE owned_vehicles SET `stored` = @stored WHERE plate = @plate AND job = @job', { - ['@stored'] = state, - ['@plate'] = plate, - ['@job'] = xPlayer.job.name - }, function(rowsChanged) + MySQL.update('UPDATE owned_vehicles SET `stored` = ? WHERE plate = ? AND job = ?', {state, plate, xPlayer.job.name}, + function(rowsChanged) if rowsChanged == 0 then print(('[esx_vehicleshop] [^3WARNING^7] %s exploited the garage!'):format(xPlayer.identifier)) end end) end) -function UnrentVehicleAsync(identifier, plate) - MySQL.update('DELETE FROM rented_vehicles WHERE identifier = @identifier AND plate = @plate', { - ['@identifier'] = identifier, - ['@plate'] = plate - }) -end - -function PayRent(d, h, m) - local tasks, timeStart = {}, os.clock() +function PayRent() + local timeStart = os.clock() print('[esx_vehicleshop] [^2INFO^7] Paying rent cron job started') - MySQL.query('SELECT owner, rent_price, plate FROM rented_vehicles', {}, function(result) - for k,v in ipairs(result) do - table.insert(tasks, function(cb) - local xPlayer = ESX.GetPlayerFromIdentifier(v.owner) + MySQL.query('SELECT rented_vehicles.owner, rented_vehicles.rent_price, rented_vehicles.plate, users.accounts FROM rented_vehicles LEFT JOIN users ON rented_vehicles.owner = users.identifier', {}, + function(rentals) + local owners = {} + for i = 1, #rentals do + local rental = rentals[i] + if not owners[rental.owner] then + owners[rental.owner] = {rental} + else + owners[rental.owner][#owners[rental.owner] + 1] = rental + end + end - if xPlayer then - if xPlayer.getAccount('bank').money >= v.rent_price then - xPlayer.removeAccountMoney('bank', v.rent_price) - xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(v.rent_price), v.plate)) - else - xPlayer.showNotification(_U('paid_rental_evicted', ESX.Math.GroupDigits(v.rent_price), v.plate)) - UnrentVehicleAsync(v.owner, v.plate) - end + local total = 0 + local unrentals = {} + local users = {} + for k, v in pairs(owners) do + local sum = 0 + for i = 1, #v do + sum += v[i].rent_price + end + local xPlayer = ESX.GetPlayerFromIdentifier(k) + + if xPlayer then + local bank = xPlayer.getAccount('bank').money + + if bank >= sum and #v > 1 then + total += sum + xPlayer.removeAccountMoney('bank', sum) + xPlayer.showNotification(('You have paid ~g~$%s~s~ for all of your rentals'):format(ESX.Math.GroupDigits(sum))) else - MySQL.scalar('SELECT accounts FROM users WHERE identifier = @identifier', { - ['@identifier'] = v.owner - }, function(accounts) - if accounts then - local playerAccounts = json.decode(accounts) - - if playerAccounts and playerAccounts.bank then - if playerAccounts.bank >= v.price then - playerAccounts.bank = playerAccounts.bank - v.price - - MySQL.update('UPDATE users SET accounts = @accounts WHERE identifier = @identifier', { - ['@identifier'] = v.owner, - ['@accounts'] = json.encode(playerAccounts) - }) - else - UnrentVehicleAsync(v.owner, v.plate) - end - end + for i = 1, #v do + local rental = v[i] + if xPlayer.getAccount('bank').money >= rental.rent_price then + total += rental.rent_price + xPlayer.removeAccountMoney('bank', rental.rent_price) + xPlayer.showNotification(_U('paid_rental', ESX.Math.GroupDigits(rental.rent_price), rental.plate)) + else + xPlayer.showNotification(_U('paid_rental_evicted', ESX.Math.GroupDigits(rental.rent_price), rental.plate)) + unrentals[#unrentals + 1] = {rental.owner, rental.plate} end - end) + end end + else + local accounts = json.decode(v[1].accounts) + if accounts.bank < sum then + sum = 0 + local limit = false + for i = 1, #v do + local rental = v[i] + if not limit then + sum += rental.rent_price + if sum > accounts.bank then + sum -= rental.rent_price + limit = true + end + else + unrentals[#unrentals + 1] = {rental.owner, rental.plate} + end + end + end + if sum > 0 then + total += sum + accounts.bank -= sum + users[#users + 1] = {json.encode(accounts), k} + end + end + end - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) - account.addMoney(result[i].rent_price) - end) - - cb() + if total > 0 then + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + account.addMoney(total) end) end - Async.parallelLimit(tasks, 5, function(results) end) + if next(users) then + MySQL.prepare.await('UPDATE users SET accounts = ? WHERE identifier = ?', users) + end - local elapsedTime = os.clock() - timeStart - print(('[esx_vehicleshop] [^2INFO^7] Paying rent cron job took %s seconds'):format(elapsedTime)) + if next(unrentals) then + MySQL.prepare.await('DELETE FROM rented_vehicles WHERE owner = ? AND plate = ?', unrentals) + end + + print(('[esx_vehicleshop] [^2INFO^7] Paying rent cron job took %s seconds'):format(os.clock() - timeStart)) end) end