diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index db7c127d..58408965 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,9 +3,7 @@ name: Bug report about: Create a report to help us improve title: "[Bug] - esx_script - Issue" labels: bug -assignees: - - TheFantomas - - Gellipapa +assignees: Arctos2win, Kenshiin13 --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bc4eaaba..305b3f1b 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -3,9 +3,7 @@ name: Feature Request about: Help us improve esx with your ideas title: "[Feature Request] - esx_script - Add better configuration" labels: enhancement -assignees: - - TheFantomas - - Gellipapa +assignees: Arctos2win, Kenshiin13 --- diff --git a/[core]/cron/README.md b/[core]/cron/README.md index 8ecd4386..df2e5eeb 100644 --- a/[core]/cron/README.md +++ b/[core]/cron/README.md @@ -1,4 +1,4 @@ -

[ESX] Cron

Discord - Website - Documentation +

[ESX] Cron

Discord - Website - Documentation A simple, but vital, resource that allows resources to Run tasks at specific intervals. diff --git a/[core]/cron/fxmanifest.lua b/[core]/cron/fxmanifest.lua index 200cf33f..db502695 100644 --- a/[core]/cron/fxmanifest.lua +++ b/[core]/cron/fxmanifest.lua @@ -4,6 +4,6 @@ game 'gta5' author 'ESX-Framework' description 'Allows resources to Run tasks at specific intervals.' lua54 'yes' -version '1.12.2' +version '1.12.3' server_script 'server/main.lua' diff --git a/[core]/es_extended/README.md b/[core]/es_extended/README.md index f02b5f71..32ae43b8 100644 --- a/[core]/es_extended/README.md +++ b/[core]/es_extended/README.md @@ -1,13 +1,13 @@ -

es_extended

Discord - Documentation - -## Legal - -es_extended - -Copyright (C) 2015-2024 Jérémie N'gadi - -This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. - -This program Is distributed In the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty Of MERCHANTABILITY Or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License For more details. - -You should have received a copy Of the GNU General Public License along with this program. If Not, see . +

es_extended

Discord - Documentation + +## Legal + +es_extended + +Copyright (C) 2015-2024 Jérémie N'gadi + +This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. + +This program Is distributed In the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty Of MERCHANTABILITY Or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License For more details. + +You should have received a copy Of the GNU General Public License along with this program. If Not, see . diff --git a/[core]/es_extended/fxmanifest.lua b/[core]/es_extended/fxmanifest.lua index c43e9574..a579d4ee 100644 --- a/[core]/es_extended/fxmanifest.lua +++ b/[core]/es_extended/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'cerulean' game 'gta5' description 'The Core resource that provides the functionalities for all other resources.' lua54 'yes' -version '1.12.2' +version '1.12.3' shared_scripts { 'locale.lua', diff --git a/[core]/es_extended/imports.lua b/[core]/es_extended/imports.lua index 6d6a862e..719d0623 100644 --- a/[core]/es_extended/imports.lua +++ b/[core]/es_extended/imports.lua @@ -1,5 +1,5 @@ ESX = exports["es_extended"]:getSharedObject() -_resourceName = GetCurrentResourceName() +ESX.currentResourceName = GetCurrentResourceName() OnPlayerData = function (key, val, last) end @@ -44,67 +44,188 @@ if not IsDuplicityVersion() then -- Only register this event for the client end end -if not lib?.require then - local cachedModules = {} ---@type table - local loadingModules = {} ---@type table +if GetResourceState("ox_lib") == "missing" then + ---@Credits: https://github.com/overextended/ox_lib/blob/master/imports/require/shared.lua - Licensed under the GNU Lesser General Public License v3.0 + local loaded = {} + local _require = require - ---@param modulePath string + package = { + path = './?.lua;./?/init.lua', + preload = {}, + loaded = setmetatable({}, { + __index = loaded, + __newindex = function() end, + __metatable = false, + }) + } + + ---@param modName string ---@return string - local function getResourceNameFromModulePath(modulePath) - local externalResourceName = modulePath:match("^@(.-)%.") - if externalResourceName then - return externalResourceName + ---@return string + local function getModuleInfo(modName) + local resource = modName:match('^@(.-)/.+') --[[@as string?]] + + if resource then + return resource, modName:sub(#resource + 3) end - return _resourceName + local idx = 4 -- call stack depth (kept slightly lower than expected depth "just in case") + + while true do + local dbgInfo = debug.getinfo(idx, 'S') + local src = dbgInfo and dbgInfo.source + + if not src then + return ESX.currentResourceName, modName + end + + resource = src:match('^@@([^/]+)/.+') + + if resource and not src:find('^@@es_extended/imports') then + return resource, modName + end + + idx = idx + 1 + end end - ---@param modulePath string - ---@return string, number - local function getModuleFilePath(modulePath) - if modulePath:sub(1, 1) == "@" then - modulePath = modulePath:sub(modulePath:find("%.") + 1) + local tempData = {} + + ---@param name string + ---@param path string + ---@return string? filename + ---@return string? errmsg + ---@diagnostic disable-next-line: duplicate-set-field + function package.searchpath(name, path) + local resource, modName = getModuleInfo(name:gsub('%.', '/')) + local tried = {} + + for template in path:gmatch('[^;]+') do + local fileName = template:gsub('^%./', ''):gsub('?', modName:gsub('%.', '/') or modName) + local file = LoadResourceFile(resource, fileName) + + if file then + tempData[1] = file + tempData[2] = resource + return fileName + end + + tried[#tried + 1] = ("no file '@%s/%s'"):format(resource, fileName) end - return modulePath:gsub("%.", "/") + return nil, table.concat(tried, "\n\t") end - ---@param modulePath string - ---@return any - function require(modulePath) - assert(type(modulePath) == "string", "Module path must be a string") + ---Attempts to load a module at the given path relative to the resource root directory.\ + ---Returns a function to load the module chunk, or a string containing all tested paths. + ---@param modName string + ---@param env? table + local function loadModule(modName, env) + local fileName, err = package.searchpath(modName, package.path) - if loadingModules[modulePath] then - error(("Circular dependency detected for module '%s'."):format(modulePath)) + if fileName then + local file = tempData[1] + local resource = tempData[2] + + ESX.Table.Wipe(tempData) + return assert(load(file, ('@@%s/%s'):format(resource, fileName), 't', env or _ENV)) end - if cachedModules[modulePath] then - return cachedModules[modulePath] - end - - loadingModules[modulePath] = true - - local resourceName = getResourceNameFromModulePath(modulePath) - local moduleFilePath = getModuleFilePath(modulePath) - local moduleFileContent = LoadResourceFile(resourceName, moduleFilePath .. ".lua") - - if not moduleFileContent then - loadingModules[modulePath] = nil - error(("Module '%s' not found in resource '%s'."):format(moduleFilePath, resourceName)) - end - - local chunk, err = load(moduleFileContent, ("@%s/%s"):format(resourceName, moduleFilePath), "t") - - if not chunk then - loadingModules[modulePath] = nil - error(("Failed to load module '%s': %s"):format(moduleFilePath, err)) - end - - local result = chunk() - - cachedModules[modulePath] = result ~= nil and result or true - loadingModules[modulePath] = nil - - return result + return nil, err or 'unknown error' end + + ---@alias PackageSearcher + ---| fun(modName: string): function loader + ---| fun(modName: string): nil, string errmsg + + ---@type PackageSearcher[] + package.searchers = { + function(modName) + local ok, result = pcall(_require, modName) + + if ok then return result end + + return ok, result + end, + function(modName) + if package.preload[modName] ~= nil then + return package.preload[modName] + end + + return nil, ("no field package.preload['%s']"):format(modName) + end, + function(modName) return loadModule(modName) end, + } + + ---@param filePath string + ---@param env? table + ---@return unknown + ---Loads and runs a Lua file at the given path. Unlike require, the chunk is not cached for future use. + function ESX.load(filePath, env) + if type(filePath) ~= 'string' then + error(("file path must be a string (received '%s')"):format(filePath), 2) + end + + local result, err = loadModule(filePath, env) + + if result then return result() end + + error(("file '%s' not found\n\t%s"):format(filePath, err)) + end + + ---@param filePath string + ---@return table + ---Loads and decodes a json file at the given path. + function ESX.loadJson(filePath) + if type(filePath) ~= 'string' then + error(("file path must be a string (received '%s')"):format(filePath), 2) + end + + local resourceSrc, modPath = getModuleInfo(filePath:gsub('%.', '/')) + local resourceFile = LoadResourceFile(resourceSrc, ('%s.json'):format(modPath)) + + if resourceFile then + return json.decode(resourceFile) + end + + error(("json file '%s' not found\n\tno file '@%s/%s.json'"):format(filePath, resourceSrc, modPath)) + end + + ---Loads the given module, returns any value returned by the seacher (`true` when `nil`).\ + ---Passing `@resourceName.modName` loads a module from a remote resource. + ---@param modName string + ---@return unknown + function ESX.require(modName) + if type(modName) ~= 'string' then + error(("module name must be a string (received '%s')"):format(modName), 3) + end + + local module = loaded[modName] + + if module == '__loading' then + error(("^1circular-dependency occurred when loading module '%s'^0"):format(modName), 2) + end + + if module ~= nil then return module end + + loaded[modName] = '__loading' + + local err = {} + + for i = 1, #package.searchers do + local result, errMsg = package.searchers[i](modName) + if result then + if type(result) == 'function' then result = result() end + loaded[modName] = result or result == nil + + return loaded[modName] + end + + err[#err + 1] = errMsg + end + + error(("%s"):format(table.concat(err, "\n\t"))) + end + + require = ESX.require end diff --git a/[core]/es_extended/server/functions.lua b/[core]/es_extended/server/functions.lua index a7566ffb..12417065 100644 --- a/[core]/es_extended/server/functions.lua +++ b/[core]/es_extended/server/functions.lua @@ -563,7 +563,7 @@ end ---@return table function ESX.GetItems() - return Core.Items + return ESX.Items end ---@return table diff --git a/[core]/es_extended/shared/main.lua b/[core]/es_extended/shared/main.lua index 00f775b4..5d659daa 100644 --- a/[core]/es_extended/shared/main.lua +++ b/[core]/es_extended/shared/main.lua @@ -9,8 +9,8 @@ AddEventHandler("esx:getSharedObject", function(cb) cb(ESX) end local invokingResource = GetInvokingResource() - print(("^3[WARNING]^0 Resource ^5%s^0 used the ^5getSharedObject^0 event. This is not the recommended way to import ESX. Visit https://documentation.esx-framework.org/tutorials/tutorials-esx/sharedevent to find out why."):format(invokingResource)) + print(("^3[WARNING]^0 Resource ^5%s^0 used the ^5getSharedObject^0 event. This is not the recommended way to import ESX. Visit https://docs.esx-legacy.com/tutorials/tutorials-esx/sharedevent to find out why."):format(invokingResource)) end) --- backwards compatibility (DO NOT TOUCH !) -Config.OxInventory = Config.CustomInventory == "ox" \ No newline at end of file +-- backwards compatibility (DO NOT TOUCH !) +Config.OxInventory = Config.CustomInventory == "ox" diff --git a/[core]/es_extended/shared/modules/table.lua b/[core]/es_extended/shared/modules/table.lua index aacb2584..ab4b147d 100644 --- a/[core]/es_extended/shared/modules/table.lua +++ b/[core]/es_extended/shared/modules/table.lua @@ -224,10 +224,18 @@ function ESX.Table.Sort(t, order) end end -function ESX.Table.ToArray(table) +---@param t table +---@return Array +function ESX.Table.ToArray(t) local array = {} - for _, v in pairs(table) do + for _, v in pairs(t) do array[#array + 1] = v end return array end + +---@param t table +---@return table +function ESX.Table.Wipe(t) + return table.wipe(t) +end \ No newline at end of file diff --git a/[core]/esx_chat_theme/README.md b/[core]/esx_chat_theme/README.md index c6c88f0e..1d149d4a 100644 --- a/[core]/esx_chat_theme/README.md +++ b/[core]/esx_chat_theme/README.md @@ -1,4 +1,4 @@ -

[ESX] Chat Theme

Discord - Documentation +

[ESX] Chat Theme

Discord - Documentation A ESX-Based Chat-theme for your server diff --git a/[core]/esx_chat_theme/fxmanifest.lua b/[core]/esx_chat_theme/fxmanifest.lua index e29afa25..704c76b3 100644 --- a/[core]/esx_chat_theme/fxmanifest.lua +++ b/[core]/esx_chat_theme/fxmanifest.lua @@ -1,4 +1,4 @@ -version '1.12.2' +version '1.12.3' author 'ESX-Framework' description 'A ESX Stylised theme for the chat resource.' diff --git a/[core]/esx_context/README.md b/[core]/esx_context/README.md index c4e378a9..6b6a53de 100644 --- a/[core]/esx_context/README.md +++ b/[core]/esx_context/README.md @@ -1,4 +1,4 @@ -

[ESX] Context

Discord - Website - Documentation +

[ESX] Context

Discord - Website - Documentation A elegant, easy to use Context Menu system to make User Interactions clean and hassle free diff --git a/[core]/esx_context/fxmanifest.lua b/[core]/esx_context/fxmanifest.lua index 0db66d92..4be9c618 100644 --- a/[core]/esx_context/fxmanifest.lua +++ b/[core]/esx_context/fxmanifest.lua @@ -4,7 +4,7 @@ game 'gta5' author 'ESX-Framework & Brayden' description 'A simplistic context menu for ESX.' lua54 'yes' -version '1.12.2' +version '1.12.3' ui_page 'index.html' diff --git a/[core]/esx_identity/README.md b/[core]/esx_identity/README.md index 3747c631..c0637081 100644 --- a/[core]/esx_identity/README.md +++ b/[core]/esx_identity/README.md @@ -1,4 +1,4 @@ -

[ESX] Identity

Discord - Documentation +

[ESX] Identity

Discord - Documentation A Core Resource that Allows the player to Pick their characters, Name, Gender, Height and Date-of-birth. diff --git a/[core]/esx_identity/fxmanifest.lua b/[core]/esx_identity/fxmanifest.lua index 027d1168..1ff5e2de 100644 --- a/[core]/esx_identity/fxmanifest.lua +++ b/[core]/esx_identity/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'adamant' game 'gta5' description 'Allows the player to Pick their characters: Name, Gender, Height and Date-of-birth.' lua54 'yes' -version '1.12.2' +version '1.12.3' shared_scripts { '@es_extended/imports.lua', diff --git a/[core]/esx_loadingscreen/README.md b/[core]/esx_loadingscreen/README.md index 1f51ae3e..366c5ada 100644 --- a/[core]/esx_loadingscreen/README.md +++ b/[core]/esx_loadingscreen/README.md @@ -1,4 +1,4 @@ -

[ESX] Loading Screen

Discord - Website - Documentation +

[ESX] Loading Screen

Discord - Website - Documentation A simple but beautiful Loading Screen for your server! diff --git a/[core]/esx_loadingscreen/fxmanifest.lua b/[core]/esx_loadingscreen/fxmanifest.lua index 35acfdb9..9c5eba20 100644 --- a/[core]/esx_loadingscreen/fxmanifest.lua +++ b/[core]/esx_loadingscreen/fxmanifest.lua @@ -3,7 +3,7 @@ game 'common' fx_version 'cerulean' author 'ESX-Framework' description 'Allows resources to Run tasks at specific intervals.' -version '1.12.2' +version '1.12.3' lua54 'yes' loadscreen 'index.html' diff --git a/[core]/esx_menu_default/README.md b/[core]/esx_menu_default/README.md index 05abc038..29e07d1f 100644 --- a/[core]/esx_menu_default/README.md +++ b/[core]/esx_menu_default/README.md @@ -1,4 +1,4 @@ -

[ESX] Menu Defualt

Discord - Website - Documentation +

[ESX] Menu Defualt

Discord - Website - Documentation A default List type menu for ESX. diff --git a/[core]/esx_menu_default/fxmanifest.lua b/[core]/esx_menu_default/fxmanifest.lua index 851fbcd6..fc171998 100644 --- a/[core]/esx_menu_default/fxmanifest.lua +++ b/[core]/esx_menu_default/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'adamant' game 'gta5' description 'A basic menu system for ESX Legacy.' lua54 'yes' -version '1.12.2' +version '1.12.3' client_scripts { '@es_extended/imports.lua', 'client/main.lua' } diff --git a/[core]/esx_menu_dialog/fxmanifest.lua b/[core]/esx_menu_dialog/fxmanifest.lua index a932977a..09350575 100644 --- a/[core]/esx_menu_dialog/fxmanifest.lua +++ b/[core]/esx_menu_dialog/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'adamant' game 'gta5' description 'A basic input dialog for ESX Legacy.' lua54 'yes' -version '1.12.2' +version '1.12.3' client_scripts { '@es_extended/imports.lua', diff --git a/[core]/esx_menu_list/fxmanifest.lua b/[core]/esx_menu_list/fxmanifest.lua index 606c36ad..f0f4b534 100644 --- a/[core]/esx_menu_list/fxmanifest.lua +++ b/[core]/esx_menu_list/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'adamant' game 'gta5' description 'A basic table-based menu system for ESX Legacy.' lua54 'yes' -version '1.12.2' +version '1.12.3' client_scripts { diff --git a/[core]/esx_multicharacter/fxmanifest.lua b/[core]/esx_multicharacter/fxmanifest.lua index 81c76c37..670945b9 100644 --- a/[core]/esx_multicharacter/fxmanifest.lua +++ b/[core]/esx_multicharacter/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'cerulean' game 'gta5' author 'ESX-Framework - Linden - KASH' description 'Allows players to have multiple characters on the same account.' -version '1.12.2' +version '1.12.3' lua54 'yes' dependencies { 'es_extended', 'esx_context', 'esx_identity', 'esx_skin' } diff --git a/[core]/esx_multicharacter/readme.md b/[core]/esx_multicharacter/readme.md index 58b30ff4..2517728e 100644 --- a/[core]/esx_multicharacter/readme.md +++ b/[core]/esx_multicharacter/readme.md @@ -1,4 +1,4 @@ -

[ESX] Multi-Character

Discord - Website - Documentation +

[ESX] Multi-Character

Discord - Website - Documentation A Simplistic system, that allows Players to have multiple Characters, which can be customised for all player with `Config.Slots` or personally set a players character count using `setslots`, `remslots`, `enablechar` and `disablechar` Commands :) diff --git a/[core]/esx_notify/fxmanifest.lua b/[core]/esx_notify/fxmanifest.lua index d019b983..dd554681 100644 --- a/[core]/esx_notify/fxmanifest.lua +++ b/[core]/esx_notify/fxmanifest.lua @@ -2,7 +2,7 @@ fx_version 'adamant' lua54 'yes' game 'gta5' -version '1.12.2' +version '1.12.3' author 'ESX-Framework' description 'A beautiful and simple NUI notification system for ESX' diff --git a/[core]/esx_notify/readme.md b/[core]/esx_notify/readme.md index 666b3498..f6bc4c9d 100644 --- a/[core]/esx_notify/readme.md +++ b/[core]/esx_notify/readme.md @@ -1,4 +1,4 @@ -

[ESX] Notify

Discord - Website - Documentation +

[ESX] Notify

Discord - Website - Documentation A beautiful and simple NUI notification system for ESX diff --git a/[core]/esx_progressbar/fxmanifest.lua b/[core]/esx_progressbar/fxmanifest.lua index 54caeda1..2180b57f 100644 --- a/[core]/esx_progressbar/fxmanifest.lua +++ b/[core]/esx_progressbar/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'adamant' game 'gta5' author 'ESX-Framework' description 'A beautiful and simple NUI progress bar for ESX' -version '1.12.2' +version '1.12.3' lua54 'yes' client_scripts { 'Progress.lua' } diff --git a/[core]/esx_skin/fxmanifest.lua b/[core]/esx_skin/fxmanifest.lua index 0485a171..25569210 100644 --- a/[core]/esx_skin/fxmanifest.lua +++ b/[core]/esx_skin/fxmanifest.lua @@ -2,7 +2,7 @@ fx_version 'adamant' game 'gta5' description 'Allows players to customise their character\'s appearance' -version '1.12.2' +version '1.12.3' lua54 'yes' shared_scripts { diff --git a/[core]/esx_textui/fxmanifest.lua b/[core]/esx_textui/fxmanifest.lua index 4dc027b8..0fdd5605 100644 --- a/[core]/esx_textui/fxmanifest.lua +++ b/[core]/esx_textui/fxmanifest.lua @@ -3,7 +3,7 @@ fx_version 'adamant' game 'gta5' author 'ESX-Framework' description 'A beautiful and simple Persistent Notification system for ESX.' -version '1.12.2' +version '1.12.3' lua54 'yes' client_scripts { 'TextUI.lua' } diff --git a/[core]/esx_textui/readme.md b/[core]/esx_textui/readme.md index 32796da3..922e11a8 100644 --- a/[core]/esx_textui/readme.md +++ b/[core]/esx_textui/readme.md @@ -1,4 +1,4 @@ -

[ESX] TextUI

Discord - Website - Documentation +

[ESX] TextUI

Discord - Website - Documentation A beautiful and simple Persistent Notification. diff --git a/[core]/skinchanger/README.md b/[core]/skinchanger/README.md index cd763d5c..7b1b3dd6 100644 --- a/[core]/skinchanger/README.md +++ b/[core]/skinchanger/README.md @@ -1,4 +1,4 @@ -

[ESX] SkinChanger

Discord - Website - Documentation +

[ESX] SkinChanger

Discord - Website - Documentation skinchanger is a resource used to both Set and Get Players clothing, accessories and Model - It supports the freemode peds `mp_m_freemode_01` and `mp_f_freemode_01` as well as all Ped Features. diff --git a/[core]/skinchanger/fxmanifest.lua b/[core]/skinchanger/fxmanifest.lua index 43cefff9..288bd751 100644 --- a/[core]/skinchanger/fxmanifest.lua +++ b/[core]/skinchanger/fxmanifest.lua @@ -2,7 +2,7 @@ fx_version 'adamant' game 'gta5' description 'Saves/loads character appearances for ESX Legacy.' -version '1.12.2' +version '1.12.3' lua54 'yes' client_scripts { diff --git a/readme.md b/readme.md index ef2abad0..3537e430 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1,19 @@ -

ESX Legacy

-

Discord - Website - Documentation - -

Want more resources? You can browse the Cfx.re Releases board for more! -

ESX is the leading framework, trusted by over 12,000 communities to provide the highest quality roleplay servers on FiveM

- -
- -### 💗 Supporters - -Interested in helping us? [Take a look at our patreon](https://www.patreon.com/esx "Take a look at our patreon") - -| We would like to sincerely thank the following donors who helped fund the development of ESX. | -| ------------ | -| Mohamad Buhamad - Michael Hein - RoadToSix - Montree Narathong | -| Saydoon - Muhannad alyamani - iSentrie - Wecity - Samuel Nicol | -| Kyle McShea - Artin - Mathias Christoffersen - Jaylan Yilmaz - Callum | -| CONGRESS KW - Michael Hein - Smery sitbon - daZepelin - CMF Community | ------- +

ESX Legacy

+

Discord - Website - Documentation + +

Want more resources? You can browse the Cfx.re Releases board for more! +

ESX is the leading framework, trusted by over 12,000 communities to provide the highest quality roleplay servers on FiveM

+ +
+ +### 💗 Supporters + +Interested in helping us? [Take a look at our patreon](https://www.patreon.com/esx "Take a look at our patreon") + +| We would like to sincerely thank the following donors who helped fund the development of ESX. | +| ------------ | +| Mohamad Buhamad - Michael Hein - RoadToSix - Montree Narathong | +| Saydoon - Muhannad alyamani - iSentrie - Wecity - Samuel Nicol | +| Kyle McShea - Artin - Mathias Christoffersen - Jaylan Yilmaz - Callum | +| CONGRESS KW - Michael Hein - Smery sitbon - daZepelin - CMF Community | +------