From 43f44a052f5195b26b2dfc8618cb65390cf1ae76 Mon Sep 17 00:00:00 2001 From: Csoki Date: Fri, 30 Dec 2022 09:43:27 +0100 Subject: [PATCH 1/4] refactor(esx_vehicleshop): GeneratePlate(), IsPlateTaken() --- [esx_addons]/esx_vehicleshop/client/utils.lua | 48 +++++-------------- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/[esx_addons]/esx_vehicleshop/client/utils.lua b/[esx_addons]/esx_vehicleshop/client/utils.lua index ef2a9f51..6d05de30 100644 --- a/[esx_addons]/esx_vehicleshop/client/utils.lua +++ b/[esx_addons]/esx_vehicleshop/client/utils.lua @@ -7,27 +7,13 @@ for i = 65, 90 do table.insert(Charset, string.char(i)) end for i = 97, 122 do table.insert(Charset, string.char(i)) end function GeneratePlate() - local generatedPlate - local doBreak = false + math.randomseed(GetGameTimer()) - while true do - Wait(0) - math.randomseed(GetGameTimer()) - if Config.PlateUseSpace then - generatedPlate = string.upper(GetRandomLetter(Config.PlateLetters) .. ' ' .. GetRandomNumber(Config.PlateNumbers)) - else - generatedPlate = string.upper(GetRandomLetter(Config.PlateLetters) .. GetRandomNumber(Config.PlateNumbers)) - end + local generatedPlate = string.upper(GetRandomLetter(Config.PlateLetters) .. (Config.PlateUseSpace and ' ' or '') .. GetRandomNumber(Config.PlateNumbers)) - ESX.TriggerServerCallback('esx_vehicleshop:isPlateTaken', function(isPlateTaken) - if not isPlateTaken then - doBreak = true - end - end, generatedPlate) - - if doBreak then - break - end + local isTaken = IsPlateTaken(generatedPlate) + if isTaken then + return GeneratePlate() end return generatedPlate @@ -35,33 +21,21 @@ end -- mixing async with sync tasks function IsPlateTaken(plate) - local callback = 'waiting' - + local p = promise.new() + ESX.TriggerServerCallback('esx_vehicleshop:isPlateTaken', function(isPlateTaken) - callback = isPlateTaken + p:resolve(isPlateTaken) end, plate) - while type(callback) == 'string' do - Wait(0) - end - - return callback + return Citizen.Await(p) end function GetRandomNumber(length) Wait(0) - if length > 0 then - return GetRandomNumber(length - 1) .. NumberCharset[math.random(1, #NumberCharset)] - else - return '' - end + return length > 0 and GetRandomNumber(length - 1) .. NumberCharset[math.random(1, #NumberCharset)] or '' end function GetRandomLetter(length) Wait(0) - if length > 0 then - return GetRandomLetter(length - 1) .. Charset[math.random(1, #Charset)] - else - return '' - end + return length > 0 and GetRandomLetter(length - 1) .. Charset[math.random(1, #Charset)] or '' end From fbbd6eb66ab58a337f31adb2f9b8f439a1ece240 Mon Sep 17 00:00:00 2001 From: Csoki Date: Fri, 30 Dec 2022 10:01:51 +0100 Subject: [PATCH 2/4] refactor(esx_vehicleshop): server/main.lua --- [esx_addons]/esx_vehicleshop/server/main.lua | 285 +++++++++---------- 1 file changed, 135 insertions(+), 150 deletions(-) diff --git a/[esx_addons]/esx_vehicleshop/server/main.lua b/[esx_addons]/esx_vehicleshop/server/main.lua index d07bbffc..81d9f0ce 100644 --- a/[esx_addons]/esx_vehicleshop/server/main.lua +++ b/[esx_addons]/esx_vehicleshop/server/main.lua @@ -1,4 +1,5 @@ local categories, vehicles = {}, {} +local vehiclesByModel = {} TriggerEvent('esx_phone:registerNumber', 'cardealer', TranslateCap('dealer_customers'), false, false) TriggerEvent('esx_society:registerSociety', 'cardealer', TranslateCap('car_dealer'), 'society_cardealer', 'society_cardealer', 'society_cardealer', {type = 'private'}) @@ -25,62 +26,50 @@ end) function SQLVehiclesAndCategories() categories = MySQL.query.await('SELECT * FROM vehicle_categories') - vehicles = MySQL.query.await('SELECT * FROM vehicles') + vehicles = MySQL.query.await('SELECT vehicles.*, vehicle_categories.label AS categoryLabel FROM vehicles JOIN vehicle_categories ON vehicles.category = vehicle_categories.name') - GetVehiclesAndCategories(categories, vehicles) -end - -function GetVehiclesAndCategories(categories, vehicles) - for i = 1, #vehicles do - local vehicle = vehicles[i] - for j = 1, #categories do - local category = categories[j] - if category.name == vehicle.category then - vehicle.categoryLabel = category.label - break - end - end + for _, vehicle in pairs(vehicles) do + vehiclesByModel[vehicle.model] = vehicle end - -- send information after db has loaded, making sure everyone gets vehicle information - TriggerClientEvent('esx_vehicleshop:sendCategories', -1, categories) - TriggerClientEvent('esx_vehicleshop:sendVehicles', -1, vehicles) + TriggerClientEvent("esx_vehicleshop:updateVehiclesAndCategories", -1, vehicles, categories, vehiclesByModel) end function getVehicleFromModel(model) - for i = 1, #vehicles do - local vehicle = vehicles[i] - if vehicle.model == model then - return vehicle - end - end - - return + return vehiclesByModel[model] end +RegisterNetEvent("esx_vehicleshop:getVehiclesAndCategories", function() + TriggerClientEvent("esx_vehicleshop:updateVehiclesAndCategories", source, vehicles, categories, vehiclesByModel) +end) + RegisterNetEvent('esx_vehicleshop:setVehicleOwnedPlayerId') AddEventHandler('esx_vehicleshop:setVehicleOwnedPlayerId', function(playerId, vehicleProps, model, label) local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) - if xPlayer.job.name == 'cardealer' and xTarget then - MySQL.scalar('SELECT id FROM cardealer_vehicles WHERE vehicle = ?', {model}, - function(id) - if id then - MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {id}, - function(rowsChanged) - if rowsChanged == 1 then - MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {xTarget.identifier, vehicleProps.plate, json.encode(vehicleProps)}, - function(id) - xPlayer.showNotification(TranslateCap('vehicle_set_owned', vehicleProps.plate, xTarget.getName())) - xTarget.showNotification(TranslateCap('vehicle_belongs', vehicleProps.plate)) - end) + if xPlayer.job.name ~= 'cardealer' or not xTarget then + return + end - 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 + MySQL.scalar('SELECT id FROM cardealer_vehicles WHERE vehicle = ?', {model}, + function(id) + if not id then + return + end + + MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {id}, + function(rowsChanged) + if rowsChanged == 1 then + MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {xTarget.identifier, vehicleProps.plate, json.encode(vehicleProps)}, + function(id) + xPlayer.showNotification(TranslateCap('vehicle_set_owned', vehicleProps.plate, xTarget.getName())) + xTarget.showNotification(TranslateCap('vehicle_belongs', vehicleProps.plate)) end) + + 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 + end) end) ESX.RegisterServerCallback('esx_vehicleshop:getSoldVehicles', function(source, cb) @@ -93,22 +82,28 @@ RegisterNetEvent('esx_vehicleshop:rentVehicle') AddEventHandler('esx_vehicleshop:rentVehicle', function(vehicle, plate, rentPrice, playerId) local xPlayer, xTarget = ESX.GetPlayerFromId(source), ESX.GetPlayerFromId(playerId) - if xPlayer.job.name == 'cardealer' and xTarget then - MySQL.single('SELECT id, price FROM cardealer_vehicles WHERE vehicle = ?', {vehicle}, - function(result) - if result then - MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {result.id}, - function(rowsChanged) - if rowsChanged == 1 then - 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(id) - xPlayer.showNotification(TranslateCap('vehicle_set_rented', plate, xTarget.getName())) - end) - end - end) - end - end) + if xPlayer.job.name ~= 'cardealer' or not xTarget then + return end + + MySQL.single('SELECT id, price FROM cardealer_vehicles WHERE vehicle = ?', {vehicle}, + function(result) + if not result then + return + end + + MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {result.id}, + function(rowsChanged) + if rowsChanged ~= 1 then + return + end + + 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(id) + xPlayer.showNotification(TranslateCap('vehicle_set_rented', plate, xTarget.getName())) + end) + end) + end) end) RegisterNetEvent('esx_vehicleshop:getStockItem') @@ -123,13 +118,12 @@ AddEventHandler('esx_vehicleshop:getStockItem', function(itemName, count) if count > 0 and item.count >= count then -- can the player carry the said amount of x item? - if xPlayer.canCarryItem(itemName, count) then - inventory.removeItem(itemName, count) - xPlayer.addInventoryItem(itemName, count) - xPlayer.showNotification(TranslateCap('have_withdrawn', count, item.label)) - else - xPlayer.showNotification(TranslateCap('player_cannot_hold')) + if not xPlayer.canCarryItem(itemName, count) then + return xPlayer.showNotification(TranslateCap('player_cannot_hold')) end + inventory.removeItem(itemName, count) + xPlayer.addInventoryItem(itemName, count) + xPlayer.showNotification(TranslateCap('have_withdrawn', count, item.label)) else xPlayer.showNotification(TranslateCap('not_enough_in_society')) end @@ -154,14 +148,6 @@ AddEventHandler('esx_vehicleshop:putStockItems', function(itemName, count) end) end) -ESX.RegisterServerCallback('esx_vehicleshop:getCategories', function(source, cb) - cb(categories) -end) - -ESX.RegisterServerCallback('esx_vehicleshop:getVehicles', function(source, cb) - cb(vehicles) -end) - ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, model, plate) local xPlayer = ESX.GetPlayerFromId(source) local modelPrice = getVehicleFromModel(model).price @@ -194,53 +180,57 @@ end) ESX.RegisterServerCallback('esx_vehicleshop:buyCarDealerVehicle', function(source, cb, model) local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.job.name == 'cardealer' then - 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.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {model, modelPrice}, - function(rowsChanged) - cb(true) - end) - else - cb(false) - end - end) - end + if xPlayer.job.name ~= 'cardealer' then + return cb(false) end + local modelPrice = getVehicleFromModel(model).price + + if not modelPrice then + return cb(false) + end + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + if account.money < modelPrice then + return cb(false) + end + + account.removeMoney(modelPrice) + + MySQL.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {model, modelPrice}, + function(rowsChanged) + cb(true) + end) + end) end) RegisterNetEvent('esx_vehicleshop:returnProvider') AddEventHandler('esx_vehicleshop:returnProvider', function(vehicleModel) local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.job.name == 'cardealer' then - 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}, - function(rowsChanged) - if rowsChanged == 1 then - TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) - local price = ESX.Math.Round(result.price * 0.75) - local vehicleLabel = getVehicleFromModel(vehicleModel).label - - account.addMoney(price) - xPlayer.showNotification(TranslateCap('vehicle_sold_for', vehicleLabel, ESX.Math.GroupDigits(price))) - end) - end - end) - else - print(('[^3WARNING^7] Player ^5%s^7 Attempted To Sell Invalid Vehicle - ^5%s^7!'):format(source, vehicleModel)) - end - end) + if xPlayer.job.name ~= 'cardealer' then + return end + MySQL.single('SELECT id, price FROM cardealer_vehicles WHERE vehicle = ?', {vehicleModel}, + function(result) + if not result then + return print(('[^3WARNING^7] Player ^5%s^7 Attempted To Sell Invalid Vehicle - ^5%s^7!'):format(source, vehicleModel)) + end + + local id = result.id + + MySQL.update('DELETE FROM cardealer_vehicles WHERE id = ?', {id}, + function(rowsChanged) + if rowsChanged ~= 1 then + return + end + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_cardealer', function(account) + local price = ESX.Math.Round(result.price * 0.75) + local vehicleLabel = getVehicleFromModel(vehicleModel).label + + account.addMoney(price) + xPlayer.showNotification(TranslateCap('vehicle_sold_for', vehicleLabel, ESX.Math.GroupDigits(price))) + end) + end) + end) end) ESX.RegisterServerCallback('esx_vehicleshop:getRentedVehicles', function(source, cb) @@ -263,20 +253,17 @@ end) ESX.RegisterServerCallback('esx_vehicleshop:giveBackVehicle', function(source, cb, plate) 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}, - function(rowsChanged) - MySQL.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {result.vehicle, result.base_price}) - - RemoveOwnedVehicle(plate) - cb(true) - end) - else - cb(false) + if not result then + return cb(false) end + + MySQL.update('DELETE FROM rented_vehicles WHERE plate = ?', {plate}, + function() + MySQL.insert('INSERT INTO cardealer_vehicles (vehicle, price) VALUES (?, ?)', {result.vehicle, result.base_price}) + + RemoveOwnedVehicle(plate) + cb(true) + end) end) end) @@ -294,36 +281,34 @@ ESX.RegisterServerCallback('esx_vehicleshop:resellVehicle', function(source, cb, if not resellPrice then print(('[^3WARNING^7] Player ^5%s^7 Attempted To Resell Invalid Vehicle - ^5%s^7!'):format(source, model)) - cb(false) - else - MySQL.single('SELECT * FROM rented_vehicles WHERE 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.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 - xPlayer.addMoney(resellPrice, "Sold Vehicle") - RemoveOwnedVehicle(plate) - cb(true) - else - print(('[^3WARNING^7] Player ^5%s^7 Attempted To Resell Vehicle With Invalid Plate - ^5%s^7!'):format(source, plate)) - cb(false) - end - else - print(('[^3WARNING^7] Player ^5%s^7 Attempted To Resell Vehicle With Invalid Model - ^5%s^7!'):format(source, model)) - cb(false) - end - end - end) - end - end) + return cb(false) end + MySQL.single('SELECT * FROM rented_vehicles WHERE plate = ?', {plate}, + function(result) + if result then -- is it a rented vehicle? + return cb(false) -- it is, don't let the player sell it since he doesn't own it + end + MySQL.single('SELECT * FROM owned_vehicles WHERE owner = ? AND plate = ?', {xPlayer.identifier, plate}, + function(result) + if not result then -- does the owner match? + return + end + local vehicle = json.decode(result.vehicle) + + if vehicle.model ~= model then + print(('[^3WARNING^7] Player ^5%s^7 Attempted To Resell Vehicle With Invalid Model - ^5%s^7!'):format(source, model)) + return cb(false) + end + if vehicle.plate ~= plate then + print(('[^3WARNING^7] Player ^5%s^7 Attempted To Resell Vehicle With Invalid Plate - ^5%s^7!'):format(source, plate)) + return cb(false) + end + + xPlayer.addMoney(resellPrice, "Sold Vehicle") + RemoveOwnedVehicle(plate) + cb(true) + end) + end) end end) From 6212076bd439d355aebfc76d715a1d791b92792c Mon Sep 17 00:00:00 2001 From: Csoki Date: Fri, 30 Dec 2022 10:24:19 +0100 Subject: [PATCH 3/4] fix(esx_vehicleshop): 'hu' locales --- [esx_addons]/esx_vehicleshop/locales/hu.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/[esx_addons]/esx_vehicleshop/locales/hu.lua b/[esx_addons]/esx_vehicleshop/locales/hu.lua index b25bfd37..bd681b3a 100644 --- a/[esx_addons]/esx_vehicleshop/locales/hu.lua +++ b/[esx_addons]/esx_vehicleshop/locales/hu.lua @@ -2,13 +2,13 @@ Locales['hu'] = { -- global menus ['not_enough_in_society'] = 'nincs elég ~r~tárgyad a vállalkozásban!', ['player_cannot_hold'] = '~r~nincs elég helyed a leltárban!', - ['vehicle_belongs'] = 'egy jármü engedélyel %s most már hozzád tartozik', + ['vehicle_belongs'] = '%s rendszámú jármű már a tulajdonodban van.', ['broke_company'] = 'nincs elég pénz a vállalati számlán', ['license_missing'] = 'nincs jogosítványod tedd le!', ['purchase_type'] = 'a vásárlás típusa', ['society_type'] = 'vállalkozás', ['staff_type'] = 'személyes használat', - ['buy_vehicle_shop'] = 'meg szeretnéd vásárolni %s ennyiért: %s NP-ért?', + ['buy_vehicle_shop'] = 'meg szeretnéd vásárolni %s ennyiért: %s $-ért?', ['buy_vehicle'] = 'vásárlás', ['car_dealer'] = 'Autókereskedés', ['shop_awaiting_model'] = 'az autó töltése folyamantban kérlek várj', @@ -26,23 +26,23 @@ Locales['hu'] = { ['not_enough_money'] = 'nincs elég pénzed', ['not_rental'] = 'ez nem ~r~bérelhetö autó', ['not_yours'] = 'ez az autó nem tartozik hozzád', - ['paid_rental'] = 'fizettél a kölcsönzönek: %s NP', + ['paid_rental'] = 'fizettél a kölcsönzönek: %s $', ['pop_vehicle'] = 'tedd a jármüvet eladásra', ['rent_vehicle'] = 'Autókereskedö - Jármüvek bérlése', ['return_provider_menu'] = 'Autókereskedö - Jámrü vissza adás a szollgáltatónak', ['rental_amount'] = 'bérlési költség', - ['sell_menu'] = 'nyomj [E] gombot hogy eladd a %s ennyiért %s NP', + ['sell_menu'] = 'nyomj [E] gombot hogy eladd a %s ennyiért %s $', ['set_vehicle_owner_rent'] = 'jármü kijelölése [Location]', ['set_vehicle_owner_sell'] = 'jármü eladása', ['set_vehicle_owner_sell_society'] = 'jármü kijelölése [Sale] [Society]', ['shop_menu'] = 'nyomj [E] gombot a vásárláshoz', - ['generic_shopitem'] = '%s NP', + ['generic_shopitem'] = '%s $', ['vehicle_dealer'] = 'jármü - Autókereskedö', ['vehicle_menu'] = 'nyomj [E] gombot hogy vissza add a bérelt jármüvet', ['vehicle_purchased'] = 'vásároltál egy jármüvet', ['vehicle_set_owned'] = 'jármü %s megvéve ennyiért: %s', ['vehicle_set_rented'] = 'jármü %s kibérelve ennyiért: %s', - ['vehicle_sold_for'] = 'A %s jármü eladva ennyiért %s NP', + ['vehicle_sold_for'] = 'A %s jármü eladva ennyiért %s $', ['vehicle_sold_to'] = 'a jármü rendszámmal %s eladva neki: %s', ['deposit_stock'] = 'beteszek a készletbe', ['take_stock'] = 'kiveszek a készletböl', From 2a659184d6e57a2b7d6d6e2174ed854310d5ed99 Mon Sep 17 00:00:00 2001 From: Csoki Date: Fri, 30 Dec 2022 10:41:57 +0100 Subject: [PATCH 4/4] refactor(esx_vehicleshop): main/client.lua --- [esx_addons]/esx_vehicleshop/client/main.lua | 136 ++++++++----------- 1 file changed, 57 insertions(+), 79 deletions(-) diff --git a/[esx_addons]/esx_vehicleshop/client/main.lua b/[esx_addons]/esx_vehicleshop/client/main.lua index 357869f6..e6065b83 100644 --- a/[esx_addons]/esx_vehicleshop/client/main.lua +++ b/[esx_addons]/esx_vehicleshop/client/main.lua @@ -1,42 +1,28 @@ local HasAlreadyEnteredMarker, IsInShopMenu = false, false local CurrentAction, CurrentActionMsg, LastZone, currentDisplayVehicle, CurrentVehicleData local CurrentActionData, Vehicles, Categories = {}, {}, {} +local VehiclesByModel = {} +local vehiclesByCategory = {} function getVehicleFromModel(model) - for i = 1, #Vehicles do - local vehicle = Vehicles[i] - if vehicle.model == model then - return vehicle - end - end + return VehiclesByModel[model] end -function getVehicles() - ESX.TriggerServerCallback('esx_vehicleshop:getCategories', function(categories) - Categories = categories - end) - - ESX.TriggerServerCallback('esx_vehicleshop:getVehicles', function(vehicles) - Vehicles = vehicles - end) -end - -AddEventHandler("onResourceStart", getVehicles) - function PlayerManagement() - if Config.EnablePlayerManagement then - if ESX.PlayerData.job.name == 'cardealer' then - Config.Zones.ShopEntering.Type = 1 + if not Config.EnablePlayerManagement then + return + end - if ESX.PlayerData.job.grade_name == 'boss' then - Config.Zones.BossActions.Type = 1 - end + if ESX.PlayerData.job.name ~= 'cardealer' then + Config.Zones.ShopEntering.Type = -1 + Config.Zones.BossActions.Type = -1 + Config.Zones.ResellVehicle.Type = -1 + return + end + Config.Zones.ShopEntering.Type = 1 - else - Config.Zones.ShopEntering.Type = -1 - Config.Zones.BossActions.Type = -1 - Config.Zones.ResellVehicle.Type = -1 - end + if ESX.PlayerData.job.grade_name == 'boss' then + Config.Zones.BossActions.Type = 1 end end @@ -45,21 +31,35 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) ESX.PlayerData = xPlayer PlayerManagement() - getVehicles() + TriggerServerEvent("esx_vehicleshop:getVehiclesAndCategories") end) -RegisterNetEvent('esx_vehicleshop:sendCategories') -AddEventHandler('esx_vehicleshop:sendCategories', function(categories) - Categories = categories -end) - -RegisterNetEvent('esx_vehicleshop:sendVehicles') -AddEventHandler('esx_vehicleshop:sendVehicles', function(vehicles) +RegisterNetEvent('esx_vehicleshop:updateVehiclesAndCategories', function(vehicles, categories, vehiclesByModel) Vehicles = vehicles + Categories = categories + + VehiclesByModel = vehiclesByModel + + table.sort(Vehicles, function(a, b) + return a.name < b.name + end) + + for _, vehicle in ipairs(Vehicles) do + if IsModelInCdimage(joaat(vehicle.model)) then + local category = vehicle.category + + if not vehiclesByCategory[category] then + vehiclesByCategory[category] = {} + end + + table.insert(vehiclesByCategory[category], vehicle) + else + print(('[^3WARNING^7] Ignoring vehicle ^5%s^7 due to invalid Model'):format(vehicle.model)) + end + end end) - -RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', PlayerManagement) +RegisterNetEvent('esx:setJob', PlayerManagement) function DeleteDisplayVehicleInsideShop() local attempt = 0 @@ -81,7 +81,7 @@ function ReturnVehicleProvider() ESX.TriggerServerCallback('esx_vehicleshop:getCommercialVehicles', function(vehicles) local elements = {} - for k,v in ipairs(vehicles) do + for k, v in ipairs(vehicles) do local returnPrice = ESX.Math.Round(v.price * 0.75) local vehicleLabel = getVehicleFromModel(v.vehicle).label @@ -135,28 +135,9 @@ function OpenShopMenu() SetEntityVisible(playerPed, false) SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos) - local vehiclesByCategory = {} local elements = {} local firstVehicleData = nil - for i=1, #Categories, 1 do - vehiclesByCategory[Categories[i].name] = {} - end - - for i=1, #Vehicles, 1 do - if IsModelInCdimage(joaat(Vehicles[i].model)) then - table.insert(vehiclesByCategory[Vehicles[i].category], Vehicles[i]) - else - print(('[^3WARNING^7] Ignoring vehicle ^5%s^7 due to invalid Model'):format(Vehicles[i].model)) - end - end - - for k,v in pairs(vehiclesByCategory) do - table.sort(v, function(a, b) - return a.name < b.name - end) - end - for i=1, #Categories, 1 do local category = Categories[i] local categoryVehicles = vehiclesByCategory[category.name] @@ -439,7 +420,7 @@ function OpenPopVehicleMenu() local vehicleLabel = getVehicleFromModel(v.vehicle).label table.insert(elements, { - label = ('%s [MSRP %s]'):format(vehicleLabel, TranslateCap('generic_shopitem', ESX.Math.GroupDigits(v.price))), + label = ('%s [%s]'):format(vehicleLabel, TranslateCap('generic_shopitem', ESX.Math.GroupDigits(v.price))), value = v.vehicle }) end @@ -630,21 +611,18 @@ function OpenPutStocksMenu() end) end -AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) +function hasEnteredMarker(zone) if zone == 'ShopEntering' then - - if Config.EnablePlayerManagement then - if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' then - CurrentAction = 'reseller_menu' - CurrentActionMsg = TranslateCap('shop_menu') - CurrentActionData = {} - end - else + if not Config.EnablePlayerManagement then CurrentAction = 'shop_menu' CurrentActionMsg = TranslateCap('shop_menu') CurrentActionData = {} end - + if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'cardealer' then + CurrentAction = 'reseller_menu' + CurrentActionMsg = TranslateCap('shop_menu') + CurrentActionData = {} + end elseif zone == 'GiveBackVehicle' and Config.EnablePlayerManagement then local playerPed = PlayerPedId() @@ -696,15 +674,15 @@ AddEventHandler('esx_vehicleshop:hasEnteredMarker', function(zone) CurrentActionMsg = TranslateCap('shop_menu') CurrentActionData = {} end -end) +end -AddEventHandler('esx_vehicleshop:hasExitedMarker', function(zone) +function hasExitedMarker(zone) if not IsInShopMenu then ESX.UI.Menu.CloseAll() end ESX.HideUI() CurrentAction = nil -end) +end AddEventHandler('onResourceStop', function(resource) if resource == GetCurrentResourceName() then @@ -736,8 +714,8 @@ if Config.EnablePlayerManagement then end -- Create Blips -CreateThread(function() - if Config.Blip.show then +if Config.Blip.show then + CreateThread(function() local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos) SetBlipSprite (blip, Config.Blip.Sprite) @@ -748,8 +726,8 @@ CreateThread(function() BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(TranslateCap('car_dealer')) EndTextCommandSetBlipName(blip) - end -end) + end) +end -- Enter / Exit marker events & Draw Markers CreateThread(function() @@ -777,12 +755,12 @@ CreateThread(function() if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then HasAlreadyEnteredMarker, LastZone = true, currentZone LastZone = currentZone - TriggerEvent('esx_vehicleshop:hasEnteredMarker', currentZone) + hasEnteredMarker(currentZone) end if not isInMarker and HasAlreadyEnteredMarker then HasAlreadyEnteredMarker = false - TriggerEvent('esx_vehicleshop:hasExitedMarker', LastZone) + hasExitedMarker(LastZone) end if letSleep then