From c12e03210a4567f3a74f86409ffae50aff5b6e29 Mon Sep 17 00:00:00 2001 From: Linden Date: Tue, 6 Jul 2021 00:20:31 +1000 Subject: [PATCH 1/5] improvement(esx): Report the number of saved players and time spent --- [esx]/es_extended/server/functions.lua | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/[esx]/es_extended/server/functions.lua b/[esx]/es_extended/server/functions.lua index 3e61fee7..9ac586f0 100644 --- a/[esx]/es_extended/server/functions.lua +++ b/[esx]/es_extended/server/functions.lua @@ -197,12 +197,12 @@ end ESX.SavePlayers = function(cb) local xPlayers = ESX.GetExtendedPlayers() - print("ESX.GetPlayers executed in es_extended saveplayers") - - local selectListWithNames = "SELECT '%s' AS identifier, '%s' AS new_accounts, '%s' AS new_job, %s AS new_job_grade, '%s' AS new_group, '%s' AS new_loadout, '%s' AS new_position, '%s' AS new_inventory " - local selectListNoNames = "SELECT '%s', '%s', '%s' , %s, '%s', '%s', '%s', '%s' " - if #xPlayers > 0 then + local time = os.time() + + local selectListWithNames = "SELECT '%s' AS identifier, '%s' AS new_accounts, '%s' AS new_job, %s AS new_job_grade, '%s' AS new_group, '%s' AS new_loadout, '%s' AS new_position, '%s' AS new_inventory " + local selectListNoNames = "SELECT '%s', '%s', '%s' , %s, '%s', '%s', '%s', '%s' " + local updateCommand = 'UPDATE users u JOIN (' local selectList = selectListNoNames @@ -230,16 +230,13 @@ ESX.SavePlayers = function(cb) updateCommand = updateCommand .. ' ) vals ON u.identifier = vals.identifier SET accounts = new_accounts, job = new_job, job_grade = new_job_grade, `group` = new_group, loadout = new_loadout, `position` = new_position, inventory = new_inventory' - MySQL.Async.execute(updateCommand) - - print(('[es_extended] [^2INFO^7] Saved %s player(s)'):format(#xPlayers)) - + MySQL.Async.fetchAll(updateCommand, {}, + function(result) + if result then + if cb then cb() else print(('[^2INFO^7] Saved %s of %s player(s) over %s seconds'):format(result.changedRows, #xPlayers, os.time() - time)) end + end + end) end - - if cb then - cb() - end - end ESX.StartDBSync = function() From 5245e1c4af7c9189a24a002b8e809eba9952e1aa Mon Sep 17 00:00:00 2001 From: Linden Date: Tue, 6 Jul 2021 09:01:26 +1000 Subject: [PATCH 2/5] refactor(esx): Reduce the sleep on TimeoutCallbacks --- [esx]/es_extended/client/functions.lua | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/[esx]/es_extended/client/functions.lua b/[esx]/es_extended/client/functions.lua index a4c2248d..2b0bd7b3 100644 --- a/[esx]/es_extended/client/functions.lua +++ b/[esx]/es_extended/client/functions.lua @@ -1015,23 +1015,17 @@ end) -- SetTimeout Citizen.CreateThread(function() while true do - Citizen.Wait(0) - local letSleep = true - local currTime = GetGameTimer() - + local sleep = 100 if #ESX.TimeoutCallbacks > 0 then - letSleep = false + local currTime = GetGameTimer() + sleep = 0 for i=1, #ESX.TimeoutCallbacks, 1 do - if ESX.TimeoutCallbacks[i] then - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil - end + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil end end end - if letSleep then - Citizen.Wait(500) - end + Citizen.Wait(sleep) end end) From 8c642ffebc4f8624fd62878bd137a895f20cc692 Mon Sep 17 00:00:00 2001 From: Linden Date: Tue, 6 Jul 2021 09:03:22 +1000 Subject: [PATCH 3/5] fix(garage): Draw interior markers and correctly enable vehicle engine --- [esx_addons]/esx_garage/client/main.lua | 29 ++++++++++++++----------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/[esx_addons]/esx_garage/client/main.lua b/[esx_addons]/esx_garage/client/main.lua index a168ac59..2ca5c169 100644 --- a/[esx_addons]/esx_garage/client/main.lua +++ b/[esx_addons]/esx_garage/client/main.lua @@ -50,6 +50,7 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) ESX.Game.SpawnLocalVehicle(vehicleProps.model, spawnCoords, garage.InteriorSpawnPoint.Heading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + SetVehicleEngineOn(vehicle, (not GetIsVehicleEngineRunning(vehicle)), true, true) end) ESX.TriggerServerCallback('esx_vehicleshop:getVehiclesInGarage', function(vehicles) @@ -188,7 +189,7 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) ESX.Game.SpawnVehicle(vehicleProps.model, spawnCoords, garage.ExteriorSpawnPoint.Heading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - ESX.Game.SetVehicleEngineOn(vehicle, (not GetIsVehicleEngineRunning(vehicle)), false, true) + SetVehicleEngineOn(vehicle, (not GetIsVehicleEngineRunning(vehicle)), true, true) end) end) @@ -227,10 +228,10 @@ AddEventHandler('esx_garage:hasEnteredMarker', function(name, part, parking) local playerPed = PlayerPedId() local garage = thisGarage local parkingPos = garage.Parkings[parking].Pos + local vehicle = GetVehiclePedIsIn(playerPed, false) - if IsPedInAnyVehicle(playerPed, false) and not IsAnyVehicleNearPoint(parkingPos.x, parkingPos.y, parkingPos.z, 1.0) then + if vehicle > 0 and not IsAnyVehicleNearPoint(parkingPos.x, parkingPos.y, parkingPos.z, 1.0) then - local vehicle = GetVehiclePedIsIn(playerPed, false) local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) TriggerServerEvent('esx_garage:setParking', name, parking, vehicleProps) @@ -290,32 +291,33 @@ Citizen.CreateThread(function() local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) + local inVehicle = IsPedInAnyVehicle(playerPed, false) for k,v in pairs(Config.Garages) do - local garage = vector3(v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z) if v.IsClosed then - if(not v.disabled and #(coords - garage) < Config.DrawDistance) then + if(not v.disabled and #(coords - vector3(v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z)) < Config.DrawDistance) then DrawMarker(Config.MarkerType, v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) sleep = 0 - end - - if(not v.disabled and #(coords - garage) < Config.DrawDistance) then + break + end + + if thisGarage and (not v.disabled and #(coords - vector3(v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z)) < Config.DrawDistance) then DrawMarker(Config.MarkerType, v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) sleep = 0 end end - if IsPedInAnyVehicle(playerPed, false) then + if inVehicle then for i=1, #v.Parkings, 1 do local parking = vector3(v.Parkings[i].Pos.x, v.Parkings[i].Pos.y, v.Parkings[i].Pos.z) if(not v.disabled and #(coords - parking) < Config.DrawDistance) then - DrawMarker(Config.MarkerType, parking.Pos.x, parking.Pos.y, parking.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ParkingMarkerSize.x, Config.ParkingMarkerSize.y, Config.ParkingMarkerSize.z, Config.ParkingMarkerColor.r, Config.ParkingMarkerColor.g, Config.ParkingMarkerColor.b, 100, false, true, 2, false, false, false, false) + DrawMarker(Config.MarkerType, parking.x, parking.y, parking.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ParkingMarkerSize.x, Config.ParkingMarkerSize.y, Config.ParkingMarkerSize.z, Config.ParkingMarkerColor.r, Config.ParkingMarkerColor.g, Config.ParkingMarkerColor.b, 100, false, true, 2, false, false, false, false) sleep = 0 end @@ -343,13 +345,14 @@ Citizen.CreateThread(function() for k,v in pairs(Config.Garages) do if v.IsClosed then - if (not v.disabled and GetDistanceBetweenCoords(coords, v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z, true) < Config.MarkerSize.x) then + if (not v.disabled and #(coords - vector3(v.ExteriorEntryPoint.Pos.x, v.ExteriorEntryPoint.Pos.y, v.ExteriorEntryPoint.Pos.z)) < Config.MarkerSize.x) then isInMarker = true currentGarage = k currentPart = 'ExteriorEntryPoint' + break end - if (not v.disabled and GetDistanceBetweenCoords(coords, v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z, true) < Config.MarkerSize.x) then + if (not v.disabled and #(coords - vector3(v.InteriorExitPoint.Pos.x, v.InteriorExitPoint.Pos.y, v.InteriorExitPoint.Pos.z)) < Config.MarkerSize.x) then isInMarker = true currentGarage = k currentPart = 'InteriorExitPoint' @@ -358,7 +361,7 @@ Citizen.CreateThread(function() for i=1, #v.Parkings, 1 do local parking = v.Parkings[i] - if (not v.disabled and GetDistanceBetweenCoords(coords, parking.Pos.x, parking.Pos.y, parking.Pos.z, true) < Config.ParkingMarkerSize.x) then + if (not v.disabled and #(coords - vector3(parking.Pos.x, parking.Pos.y, parking.Pos.z)) < Config.ParkingMarkerSize.x) then isInMarker = true currentGarage = k currentPart = 'Parking' From 4f5794473eba289b271d38e572cf3194a245c488 Mon Sep 17 00:00:00 2001 From: Linden Date: Tue, 6 Jul 2021 09:57:25 +1000 Subject: [PATCH 4/5] tweak(esx): Print affectedRows instead of changedRows for saved players --- [esx]/es_extended/server/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/[esx]/es_extended/server/functions.lua b/[esx]/es_extended/server/functions.lua index 9ac586f0..f6e1d821 100644 --- a/[esx]/es_extended/server/functions.lua +++ b/[esx]/es_extended/server/functions.lua @@ -233,7 +233,7 @@ ESX.SavePlayers = function(cb) MySQL.Async.fetchAll(updateCommand, {}, function(result) if result then - if cb then cb() else print(('[^2INFO^7] Saved %s of %s player(s) over %s seconds'):format(result.changedRows, #xPlayers, os.time() - time)) end + if cb then cb() else print(('[^2INFO^7] Saved %s of %s player(s) over %s seconds'):format(result.affectedRows, #xPlayers, os.time() - time)) end end end) end From f8d1c69c47b962495ef7aa71c7a465f3ff9e098c Mon Sep 17 00:00:00 2001 From: Linden Date: Thu, 8 Jul 2021 06:07:25 +1000 Subject: [PATCH 5/5] chore(esx): Update readme --- README.md | 2 +- [esx]/es_extended/README.md | 174 +++++++++++++----------------------- 2 files changed, 63 insertions(+), 113 deletions(-) diff --git a/README.md b/README.md index 2270f37f..dafe9148 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Many more resources are included in this repository, or you can browse the [ESX ### Conflicts * The following resources should not be used with ESX Legacy - - essentialsmode + - essentialmode - basic-gamemode - fivem-map-skater - fivem-map-hipster diff --git a/[esx]/es_extended/README.md b/[esx]/es_extended/README.md index d7a5ffcc..dafe9148 100644 --- a/[esx]/es_extended/README.md +++ b/[esx]/es_extended/README.md @@ -1,72 +1,56 @@ -

ESX Legacy

There is no official support for this resource. Create a thread on the ESX Server Development board or find a support Discord.
+

ESX Legacy

Development Discord - Website - Support Discord -ESX is the most popular framework for creating an economy-based roleplay server on FiveM, with many more official and unofficial resources designed to utilise the tools provided by this resource. Here's a taste of what's available: +##### ESX is the most popular framework for creating economy-based roleplay servers on FiveM, with many official and community resources designed to utilise the tools provided here. For a taste of what's available: +> esx_identity: Enables character registration defining a players name, sex, height, and date of birth -###### `esx_identity` enable character registration using a name, sex, and date of birth -###### `esx_society` add employee management, society funds and more -###### `esx_billing` add support for registered societies to fine or bill players -###### `esx_vehicleshop` allow players to purchase vehicles directly or from players -###### `esx_ambulancejob` adds a death and respawn system while allowing players to become EMS to heal or revive others -###### `esx_policejob` allow players to become cops, granting the ability to detain and fine others +> esx_society: Allows job resources to register a society, gaining employee management, society funds, and more +> esx_billing: Allows members of some societies to send fines or bills to other players -Many more resources are available on the [ESX Framework Github](https://github.com/esx-framework) and [ESX Community Github](https://github.com/esx-community/) pages. +> esx_vehicleshop: Allow players to purchase vehicles from a dealership, or setup society support for a player-managed dealership +> esx_ambulancejop: Adds a death and respawn system while allowing players to work as EMS to heal and revive others -## Information +Many more resources are included in this repository, or you can browse the [ESX Community Github](https://github.com/esx-community/) or [Cfx.re Releases board](https://forum.cfx.re/tag/esx) for more. -- [ESX Forum](https://forum.esx-framework.org/) -- [ESX Documentation](https://wiki.esx-framework.org/) -- [ESX Development Discord](https://discord.me/esx) -- [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) +### Information +##### Legacy provides some necessary bug-fixes and improvements to optimise the framework before reaching the end of official support by the development team. +##### Most resources designed for 1.2 will have no issues with Legacy, notable exceptions are those which modify spawning/loading behaviour. There are several minor feature updates which do not impact compatibility with old resources. +##### NOTE: The loadouts system in ESX has always been problematic, and fixing it would require a complete overhaul. Your best option is to use a resource that handles weapons as items. -ESX was initially developed by Gizz back in 2017 for his friend as the were creating an FiveM server and there wasn't any economy roleplaying frameworks available. The original code was written within a week or two and later open sourced, it has ever since been improved and parts been rewritten to further improve on it. - - -## Legacy - -ESX Legacy is mostly intended as a bug-fix and optimisation update to provide a more stable experience for the people using ESX 1.2 or Final, however there are also some new features added in to allow better server performance with other resources and official support for esx_multicharacter. -#### Bug fixes -* ESX.Jobs is no longer set until the full table has been creating, allowing other resources to retrieve it more easily -* Now using spawnmanager to spawn players and prevent weird desync issues - - This may cause problems with some third-party resources that modify player spawns -* /clearloadout now properly removes all weapons instead of needing to be performed multiple times - #### Optimisation -* Support for compile-time hashing instead of calling the native -* Utilise the `MySQL.Store` function to reduce overhead when executing queries -* Allow loops to sleep while not performing any tasks -* The current player ped and death status are now stored in ESX.PlayerData, reducing the need to constantly call the native -* Weapon ammo is no longer synced on every frame, instead triggering a server event once shooting has ceased -* Reduced the number of queries being performed by a single player connecting to the server +- Utilise compile-time jenkins hashing over the GetHashKey native +- Update old MySQL queries to use MySQL.store to improve performance, especially during player saving +- Several loops will now sleep when their tasks are not necessary to perform +- Improved support when using ESX Identity to reduce events and queries during player login +- Support for the latest weapons and components #### Features -* Support for the latest weapons and components -* Additional admin commands from esx_adminplus -* Save all players before the txAdmin scheduled restarts -* When loading a new player, send the isNew argument along with `esx:playerLoaded` -* Added an imports file to load in other resource manifests with `shared_script '@es_extended/imports.lua'` - - Removes the need to define ESX in your resources, as it will perform the task for you - - Ensures ESX.PlayerData will always return current information (exception: loadout and inventory) -* Support for relogging, clearing all player data and cancelling sync loops -* Added the `ESX.GetExtendedPlayers` function to be used with xPlayer loops without causing massive server hitches - -To get an idea for how you can utilise imports and the new functions, you can refer to [this updated boilerplate](https://github.com/thelindat/esx_legacy_boilerplate). -##### Any resources made using the imports will only work for ESX Legacy. - - -## Conflicts -* The following resources should not be used with ESX Legacy and can result in errors - - **essentialsmode** - - basic-gamemode - - fivem-map-skater - - fivem-map-hipster - - default_spawnpoint - - -## 1.2 + Features +- Integrated support for identity data +- Integrated commands from esx_adminplus +- All players will be saved immediately before a txAdmin scheduled restart +- Detect if a player is new and send the result to the playerLoaded event +- Support for players logging out when using multicharacter resources +- Cache the players ped id and death state in ESX.PlayerData +- Added an imports file (similar to locales.lua) for setting up events and functions in other resources + - Before defining all manifest script files, add `shared_script '@es_extended/imports.lua'` + - Automatically retrieve the ESX object, removing the need to send a callback event on both the client and server + - Ensures current information is always returned when using `ESX.PlayerData` (except loadout and inventory) +- Spawnmanager is being utilised to correctly handle player spawns + - Potential conflicts with some third-party resources that do not expect spawnmanager +- Added an improved function when performing xPlayer loops to prevent large server hitches + - Using `ESX.GetExtendedPlayers()` instead of `ESX.GetPlayers()` + - You can use arguments with the new function as well, such as + - ESX.GetExtendedPlayers('job', 'police') + - ESX.GetExtendedPlayers('group', 'admin') + +#### Fixes +- ESX.Jobs table is populated after all jobs are setup, allowing other resources to retrieve it if needed +- All weapons are properly removed when using the clearloadout command +##### For creating or updating resources refer to the [updated boilerplate](/esx_example). +### 1.2 Features - Weight based inventory system - Weapons support, including support for attachments and tints - Supports different money accounts (defaulted with cash, bank and black money) @@ -76,70 +60,36 @@ To get an idea for how you can utilise imports and the new functions, you can re - Easy to use API for developers to easily integrate ESX to their projects - Register your own commands easily, with argument validation, chat suggestion and using FXServer ACL - -## Requirements - -- [mysql-async](https://github.com/brouznouf/fivem-mysql-async) -- [async](https://github.com/esx-framework/async) - - -## Download & Installation - - -### Using Git - -``` -cd resources -git clone https://github.com/esx-framework/es_extended.git --branch legacy -git clone https://github.com/esx-framework/esx_menu_default [esx]/[ui]/esx_menu_default -git clone https://github.com/esx-framework/esx_menu_dialog [esx]/[ui]/esx_menu_dialog -git clone https://github.com/esx-framework/esx_menu_list [esx]/[ui]/esx_menu_list -``` - -### Plume ESX: - -PlumeESX is a full featured (13 jobs) and highly configurable yet lightweight ESX v1.2 base that can be easily extendable. -Forum Thread: https://forum.cfx.re/t/recipe-plumeesx-full-base-2021/1964029 -YouTube Tutorial: https://www.youtube.com/watch?v=iGfwUCO0RZQ - -### Manually - -- Download https://github.com/esx-framework/es_extended/archive/refs/heads/legacy.zip -- Put it in the `resource/[esx]` directory -- Download https://github.com/esx-framework/esx_menu_default/archive/refs/heads/master.zip -- Put it in the `resource/[esx]/[ui]` directory -- Download https://github.com/esx-framework/esx_menu_dialog/archive/refs/heads/master.zip -- Put it in the `resource/[esx]/[ui]` directory -- Download https://github.com/esx-framework/esx_menu_list/archive/refs/heads/master.zip -- Put it in the `resource/[esx]/[ui]` directory +### Requirements +- All resources from the `core` folder +- [spawnmanager](https://github.com/citizenfx/cfx-server-data) +- [mysql-async](https://github.com/brouznouf/fivem-mysql-async/releases/tag/3.3.2) ### Installation - +- Download files to the resources folder and, if desired, prepare directories for organisation (i.e. resources/[core]/es_extended) - Import `es_extended.sql` in your database -- Configure your `server.cfg` to look like this +- Import any other sql files for the resources you are using +- Ensure all resources config files have been adjusted for your preferences +- Use or refer to the included server.cfg for start order and settings -``` -add_principal group.admin group.user -add_ace resource.es_extended command.add_ace allow -add_ace resource.es_extended command.add_principal allow -add_ace resource.es_extended command.remove_principal allow -add_ace resource.es_extended command.stop allow +### Conflicts +* The following resources should not be used with ESX Legacy + - essentialmode + - basic-gamemode + - fivem-map-skater + - fivem-map-hipster + - default_spawnpoint -start mysql-async -start es_extended - -start esx_menu_default -start esx_menu_list -start esx_menu_dialog -``` - -## Reborn - -ESX Reborn is the name for the framework being actively developed by the team, with many existing features being rewritten and improved upon. It is currently possible to create a server using ESX Reborn, however the project is still missing many features and should not be used unless you are a developer looking to contribute in some way. +### Information +ESX was initially developed by Gizz back in 2017 for his friend as the were creating an FiveM server and there wasn't any economy roleplaying frameworks available. The original code was written within a week or two and later open sourced, it has ever since been improved and parts been rewritten to further improve on it. +- [ESX Forum](https://forum.esx-framework.org/) +- [ESX Documentation](https://wiki.esx-framework.org/) +- [ESX Development Discord](https://discord.me/esx) +- [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) -## Legal +### Legal ### License