Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
dd60b20
feat: add auto-migrations on startup
Kenshiin13 Aug 24, 2025
5cb6f35
feat: add "restart required" print
Kenshiin13 Aug 24, 2025
22ab3dc
refactor: store migrations in core table
Kenshiin13 Aug 24, 2025
45308f5
refactor: only store migrations if not ran
Kenshiin13 Aug 24, 2025
ff8798a
Revert "refactor: only store migrations if not ran"
Kenshiin13 Aug 24, 2025
8fad1f9
refactor: only store migrations if not already ran
Kenshiin13 Aug 24, 2025
15d9c07
New ESX MENU DEFAULT DESIGN
Kr3mu Aug 26, 2025
0b8637b
Added auto scroll and maximum height, logo to right corner of title
Kr3mu Aug 26, 2025
7b36d7a
Adds options to the slider component
Kr3mu Aug 27, 2025
8aca701
Adds usable, unselectable, disableRightArrow
Kr3mu Aug 30, 2025
bbd0a57
fix(es_extended/client/functions): add export default values
Kenshiin13 Aug 31, 2025
f78beaf
fix(es_extended/server/migration): only require restart if actually n…
Kenshiin13 Aug 31, 2025
6d73946
Merge pull request #1711 from esx-framework/migration
Kenshiin13 Aug 31, 2025
8dc6f8d
Fixes the issue with less forgiving Typescript
Kr3mu Aug 31, 2025
63b76ad
fix(esx_identity/server/main): fix error when creating char
Kenshiin13 Aug 31, 2025
5382f50
refactor(esx_identity): fix formatting
Kenshiin13 Aug 31, 2025
12c0c9a
refactor(esx_identity): use static player methods
Kenshiin13 Aug 31, 2025
6ef25f1
Merge branch 'dev' into feature/argument-isValid-on-register-command
Kenshiin13 Aug 31, 2025
52eab10
refactor(es_extended/server/functions): Refactor command argument val…
Kenshiin13 Aug 31, 2025
bc1a7e2
Merge pull request #1715 from esx-framework/feature/argument-isValid-…
Kenshiin13 Aug 31, 2025
7a3a1e1
Merge pull request #1712 from Kr3mu/esx_default_menu
Kenshiin13 Aug 31, 2025
b8d0fa6
Deletes console.log from openMenu
Kr3mu Aug 31, 2025
faf1b40
fix(esx_inventory): fix return arrow
Kenshiin13 Aug 31, 2025
5e5b559
fix(es_extended/locales): add missing locales for inv
Kenshiin13 Aug 31, 2025
7c3b3c8
Merge pull request #1716 from Kr3mu/esx_default_menu
Kenshiin13 Aug 31, 2025
78ed0c6
Merge branch 'dev' of https://github.com/esx-framework/esx_core into dev
Kenshiin13 Aug 31, 2025
d95daf1
chore: bump manifest version to 1.13.4
github-actions[bot] Aug 31, 2025
54f4a2a
Updates the UI of esx_menu_dialog to match esx_menu_default, replace …
Kr3mu Aug 31, 2025
e214dd5
Merge pull request #1717 from Kr3mu/esx_menu_dialog
Kr3mu Aug 31, 2025
01805bf
fix(cron): resolve task execution conflicts and timing precision issues
DyroS3 Sep 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion [core]/cron/fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ game 'gta5'
author 'ESX-Framework'
description 'Allows resources to Run tasks at specific intervals.'
lua54 'yes'
version '1.13.3'
version '1.13.4'

server_script 'server/main.lua'
63 changes: 43 additions & 20 deletions [core]/cron/server/main.lua
Original file line number Diff line number Diff line change
@@ -1,75 +1,98 @@
---@class CronJob
---@field h number
---@field m number
---@field cb function|table
---@field h number Hour (0-23)
---@field m number Minute (0-59)
---@field cb function|table Callback function to execute
---@field lastRun number|nil Timestamp of last execution (prevents duplicates)

---@type CronJob[]
local cronJobs = {}

---@type number|false
local lastTimestamp = false

---@param h number
---@param m number
---@param cb function|table
---Registers a new cron job to run at specified time daily
---@param h number Hour (0-23)
---@param m number Minute (0-59)
---@param cb function|table Callback function to execute
function RunAt(h, m, cb)
cronJobs[#cronJobs + 1] = {
h = h,
m = m,
cb = cb,
lastRun = nil
}
end

---@return number
---Gets current Unix timestamp
---@return number Current timestamp
function GetUnixTimestamp()
return os.time()
end

---@param timestamp number
---Checks and executes due cron jobs for the current timestamp
---@param timestamp number Current Unix timestamp
function OnTime(timestamp)
for i = 1, #cronJobs, 1 do
-- Calculate today's scheduled timestamp for this job
local scheduledTimestamp = os.time({
hour = cronJobs[i].h,
min = cronJobs[i].m,
sec = 0, -- Assuming tasks run at the start of the minute
sec = 0
day = os.date("%d", timestamp),
month = os.date("%m", timestamp),
year = os.date("%Y", timestamp),
})

if timestamp >= scheduledTimestamp and (not lastTimestamp or lastTimestamp < scheduledTimestamp) then
local d = os.date('*t', scheduledTimestamp).wday
cronJobs[i].cb(d, cronJobs[i].h, cronJobs[i].m)
-- Execute if current time >= scheduled time and hasn't run today
if timestamp >= scheduledTimestamp and (not cronJobs[i].lastRun or cronJobs[i].lastRun < scheduledTimestamp) then
local dayOfWeek = os.date('*t', scheduledTimestamp).wday

-- Execute the callback with day, hour, minute parameters
cronJobs[i].cb(dayOfWeek, cronJobs[i].h, cronJobs[i].m)

-- Mark this job as executed for today
cronJobs[i].lastRun = scheduledTimestamp
end
end
end

---@return nil
---Main tick function that checks for minute changes and processes jobs
---Automatically reschedules itself for precise minute-boundary timing
function Tick()
local timestamp = GetUnixTimestamp()

-- Only process jobs when minute changes to avoid duplicate checks
if not lastTimestamp or os.date("%M", timestamp) ~= os.date("%M", lastTimestamp) then
OnTime(timestamp)
lastTimestamp = timestamp
end

SetTimeout(60000, Tick)
-- Schedule next check at the start of the next minute for precision
local currentSeconds = tonumber(os.date("%S", timestamp))
local msToNextMinute = (60 - currentSeconds) * 1000
SetTimeout(msToNextMinute, Tick)
end

lastTimestamp = GetUnixTimestamp()
Tick()

---@param h number
---@param m number
---@param cb function|table
---Event handler for external resources to register cron jobs
---Usage: TriggerEvent('cron:runAt', hour, minute, callback)
AddEventHandler("cron:runAt", function(h, m, cb)
local invokingResource = GetInvokingResource() or "Unknown"

-- Validate parameters with detailed error messages
local typeH = type(h)
local typeM = type(m)
local typeCb = type(cb)

assert(typeH == "number", ("Expected number for h, got %s. Invoking Resource: '%s'"):format(typeH, invokingResource))
assert(typeM == "number", ("Expected number for m, got %s. Invoking Resource: '%s'"):format(typeM, invokingResource))
assert(typeCb == "function" or (typeCb == "table" and type(getmetatable(cb)?.__call) == "function"), ("Expected function for cb, got %s. Invoking Resource: '%s'"):format(typeCb, invokingResource))
assert(typeH == "number", ("Expected number for hour, got %s. Invoking Resource: '%s'"):format(typeH, invokingResource))
assert(typeM == "number", ("Expected number for minute, got %s. Invoking Resource: '%s'"):format(typeM, invokingResource))
assert(typeCb == "function" or (typeCb == "table" and type(getmetatable(cb)?.__call) == "function"), ("Expected function for callback, got %s. Invoking Resource: '%s'"):format(typeCb, invokingResource))

-- Validate time ranges
assert(h >= 0 and h <= 23, ("Hour must be between 0-23, got %d. Invoking Resource: '%s'"):format(h, invokingResource))
assert(m >= 0 and m <= 59, ("Minute must be between 0-59, got %d. Invoking Resource: '%s'"):format(m, invokingResource))

RunAt(h, m, cb)
end)
2 changes: 1 addition & 1 deletion [core]/es_extended/client/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ end
---@param position? string The position of the notification
---@return nil
function ESX.ShowNotification(message, notifyType, length, title, position)
return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType, length, message, title, position)
return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType or "info", length or 5000, message, title, position)
end

function ESX.TextUI(...)
Expand Down
6 changes: 4 additions & 2 deletions [core]/es_extended/fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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.13.3'
version '1.13.4'

shared_scripts {
'locale.lua',
Expand Down Expand Up @@ -35,7 +35,9 @@ server_scripts {

'server/bridge/**/*.lua',
'server/modules/npwd.lua',
'server/modules/createJob.lua'
'server/modules/createJob.lua',
'server/migration/**/main.lua',
'server/migration/main.lua',
}

client_scripts {
Expand Down
41 changes: 41 additions & 0 deletions [core]/es_extended/locales/cs.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
return {
-- Inventory
["inventory"] = "Inventář ( Váha %s / %s )",
["use"] = "Použít",
["give"] = "Darovat",
["remove"] = "Odhodit",
["return"] = "Vrátit",
["give_to"] = "Darováno",
["amount"] = "Počet",
["giveammo"] = "Podat náboje",
["amountammo"] = "Počet nábojů",
["noammo"] = "Nedostatek!",
["gave_item"] = "Daroval %sx %s pro %s",
["received_item"] = "Získáno %sx %s od %s",
["gave_weapon"] = "Předání %s pro %s",
["gave_weapon_ammo"] = "Darování ~o~%sx %s do %s pro %s",
["gave_weapon_withammo"] = "Darování %s s ~o~%sx %s pro %s",
["gave_weapon_hasalready"] = "%s již vlastní %s",
["gave_weapon_noweapon"] = "%s nemá tuto zbraň",
["received_weapon"] = "Obdrženo %s od %s",
["received_weapon_ammo"] = "Obdrženo ~o~%sx %s pro zbraň %s od %s",
["received_weapon_withammo"] = "Obdrženo %s s ~o~%sx %s od %s",
["received_weapon_hasalready"] = "%s se snažil darovat %s, ale již tuto zbraň máš",
["received_weapon_noweapon"] = "%s se snažil ti dát náboje %s, ale nemáš potřebnou zbrań",
["gave_account_money"] = "Darováno $%s (%s) pro %s",
["received_account_money"] = "Získáno $%s (%s) od %s",
["amount_invalid"] = "Špatné množství",
["players_nearby"] = "Žádný hráč není poblíž",
["ex_inv_lim"] = "Nelze sebrat,protože máš plné kapsy %s",
["imp_invalid_quantity"] = "Neplatné množství",
["imp_invalid_amount"] = "Nelze provést, neplatné množství",
["threw_standard"] = "Zahozeno %sx %s",
["threw_account"] = "Zahozeno $%s %s",
["threw_weapon"] = "Zahozeno %s",
["threw_weapon_ammo"] = "Zahozeno %s s ~o~%sx %s",
["threw_weapon_already"] = "Již vlastníš tuto zbraň",
["threw_cannot_pickup"] = "Kapsy máš plné, nemůžeš sebrat!",
["threw_pickup_prompt"] = "Zmáčkni E pro sebrání!",

-- Key mapping
["keymap_showinventory"] = "Otevřít inventář",

-- Salary related
["received_salary"] = "Obdržel jsi: $%s",
["received_help"] = "Obdržel jsi svůj podíl: $%s",
Expand Down
41 changes: 41 additions & 0 deletions [core]/es_extended/locales/de.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
return {
-- Inventory
["inventory"] = "Inventar ( Gewicht %s / %s )",
["use"] = "Benutzen",
["give"] = "Geben",
["remove"] = "Entsorgen",
["return"] = "Zurück",
["give_to"] = "Geben an",
["amount"] = "Anzahl",
["giveammo"] = "Munition geben",
["amountammo"] = "Munitions Anzahl",
["noammo"] = "Nicht Genug!",
["gave_item"] = "Du gibst %sx %s an %s",
["received_item"] = "Du bekommst %sx %s von %s",
["gave_weapon"] = "Du gibst %s an %s",
["gave_weapon_ammo"] = "Du gibst ~o~%sx %s für %s an %s",
["gave_weapon_withammo"] = "Du gibst %s mit ~o~%sx %s an %s",
["gave_weapon_hasalready"] = "%s hat bereits %s",
["gave_weapon_noweapon"] = "%s hat diese Waffe nicht",
["received_weapon"] = "Du bekommst %s von %s",
["received_weapon_ammo"] = "Du bekommst ~o~%sx %s für deine %s von %s",
["received_weapon_withammo"] = "Du bekommst %s mit ~o~%sx %s von %s",
["received_weapon_hasalready"] = "%s hat versucht dir eine %s zu geben, jedoch hast du diese Waffe bereits!",
["received_weapon_noweapon"] = "%s hat versucht dir Munition für eine %s zu geben, jedoch hast du diese Waffe nicht!",
["gave_account_money"] = "Du gibst %s€ (%s) an %s",
["received_account_money"] = "Du bekommst %s€ (%s) von %s",
["amount_invalid"] = "Ungültige Anzahl",
["players_nearby"] = "Keine Personen in der Nähe!",
["ex_inv_lim"] = "Du kannst diese Aktion nicht ausführen!, Inventarlimit für %s überschritten.",
["imp_invalid_quantity"] = "Du kannst diese Aktion nicht ausführen!, Ungültige Anzahl!",
["imp_invalid_amount"] = "Du kannst diese Aktion nicht ausführen!, Ungültige Anzahl",
["threw_standard"] = "Du entsorgst %sx %s",
["threw_account"] = "Du Entsorgst %s€ %s",
["threw_weapon"] = "Du entsorgst %s",
["threw_weapon_ammo"] = "Du entsorgst %s mit ~o~%sx %s",
["threw_weapon_already"] = "Du hast diese Waffe bereits!",
["threw_cannot_pickup"] = "Inventar ist voll! Du kannst dies nicht aufheben",
["threw_pickup_prompt"] = "Drücke [E] zum aufheben",

-- Key mapping
["keymap_showinventory"] = "Inventar Anzeigen",

-- Salary related
["received_salary"] = "Dein Gehaltscheck ist angekommen!: %s€",
["received_help"] = "Deine Sozialhilfe ist angekommen: %s€",
Expand Down
41 changes: 41 additions & 0 deletions [core]/es_extended/locales/el.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
return {
-- Inventory
["inventory"] = "Αποθήκη ( Βάρος %s / %s )",
["use"] = "Χρήση",
["give"] = "Δώσε",
["remove"] = "Πέτα",
["return"] = "Επιστροφή",
["give_to"] = "Δώσε σε",
["amount"] = "Ποσότητα",
["giveammo"] = "Δώσε σφαίρες",
["amountammo"] = "Ποσότητα σφαιρών",
["noammo"] = "Δεν υπάρχουν αρκετές σφαίρες!",
["gave_item"] = "Δώσατε %sx %s στον/στην %s",
["received_item"] = "Λάβατε %sx %s από τον/την %s",
["gave_weapon"] = "Δίνετε %s στον/στην %s",
["gave_weapon_ammo"] = "Δίνετε ~o~%sx %s για %s στον/στην %s",
["gave_weapon_withammo"] = "Δίνετε %s με ~o~%sx %s στον/στην %s",
["gave_weapon_hasalready"] = "Ο/Η %s έχει ήδη ένα %s",
["gave_weapon_noweapon"] = "Ο/Η %s δεν έχει αυτό το όπλο",
["received_weapon"] = "Λάβατε %s από τον/την %s",
["received_weapon_ammo"] = "Λάβατε ~o~%sx %s για το %s από τον/την %s",
["received_weapon_withammo"] = "Λάβατε %s για ~o~%sx %s από τον/την %s",
["received_weapon_hasalready"] = "Ο/Η %s προσπάθησε να σας δώσει ένα %s, αλλά το έχετε ήδη",
["received_weapon_noweapon"] = "Ο/Η %s προσπάθησε να σας δώσει σφαίρες για το %s, αλλά δεν έχετε αυτό το όπλο",
["gave_account_money"] = "Δίνετε $%s (%s) στον/στην %s",
["received_account_money"] = "Λάβατε $%s (%s) από τον/την %s",
["amount_invalid"] = "Μη έγκυρη ποσότητα",
["players_nearby"] = "Δεν υπάρχουν κοντινοί παίκτες",
["ex_inv_lim"] = "Δεν είναι δυνατή η ενέργεια, υπέρβαση του μέγιστου βάρους των %s",
["imp_invalid_quantity"] = "Δεν είναι δυνατή η ενέργεια, η ποσότητα δεν είναι έγκυρη",
["imp_invalid_amount"] = "Δεν είναι δυνατή η ενέργεια, το ποσό δεν είναι έγκυρο",
["threw_standard"] = "Ρίχνοντας %sx %s",
["threw_account"] = "Ρίχνοντας $%s %s",
["threw_weapon"] = "Ρίχνοντας %s",
["threw_weapon_ammo"] = "Ρίχνοντας %s με ~o~%sx %s",
["threw_weapon_already"] = "Ήδη έχετε αυτό το όπλο",
["threw_cannot_pickup"] = "Η αποθήκη είναι γεμάτη, δεν μπορείτε να σηκώσετε!",
["threw_pickup_prompt"] = "Πατήστε E για να σηκώσετε",

-- Key mapping
["keymap_showinventory"] = "Εμφάνιση Αποθήκης",

-- Salary related
["received_salary"] = "Έχετε λάβει μισθό: $%s",
["received_help"] = "Έχετε λάβει το βοήθημά σας: $%s",
Expand Down
41 changes: 41 additions & 0 deletions [core]/es_extended/locales/en.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
return {
-- Inventory
["inventory"] = "Inventory ( Weight %s / %s )",
["use"] = "Use",
["give"] = "Give",
["remove"] = "Throw",
["return"] = "Return",
["give_to"] = "Give to",
["amount"] = "Amount",
["giveammo"] = "Give ammo",
["amountammo"] = "Ammo Amount",
["noammo"] = "Not Enough!",
["gave_item"] = "Giving %sx %s to %s",
["received_item"] = "Received %sx %s from %s",
["gave_weapon"] = "Giving %s to %s",
["gave_weapon_ammo"] = "Giving ~o~%sx %s for %s to %s",
["gave_weapon_withammo"] = "Giving %s with ~o~%sx %s to %s",
["gave_weapon_hasalready"] = "%s already has a %s",
["gave_weapon_noweapon"] = "%s does not have that weapon",
["received_weapon"] = "Received %s from %s",
["received_weapon_ammo"] = "Received ~o~%sx %s for your %s from %s",
["received_weapon_withammo"] = "Received %s with ~o~%sx %s from %s",
["received_weapon_hasalready"] = "%s has attempted to give you a %s, but you already this weapon",
["received_weapon_noweapon"] = "%s has attempted to give you ammo for a %s, but you do not have this weapon",
["gave_account_money"] = "Giving $%s (%s) to %s",
["received_account_money"] = "Received $%s (%s) from %s",
["amount_invalid"] = "Invalid quantity",
["players_nearby"] = "No nearby Players",
["ex_inv_lim"] = "Cannot perfom action,exceeding max weight of %s",
["imp_invalid_quantity"] = "Cannot perfom action, the quantity is invalid",
["imp_invalid_amount"] = "Cannot perfom action, the amount is invalid",
["threw_standard"] = "Throwing %sx %s",
["threw_account"] = "Throwing $%s %s",
["threw_weapon"] = "Throwing %s",
["threw_weapon_ammo"] = "Throwing %s with ~o~%sx %s",
["threw_weapon_already"] = "You already have this weapon",
["threw_cannot_pickup"] = "Inventory is full, Cannot Pickup!",
["threw_pickup_prompt"] = "Press E to Pickup",

-- Key mapping
["keymap_showinventory"] = "Show Inventory",

-- Salary related
["received_salary"] = "You have been paid: $%s",
["received_help"] = "You have been paid your welfare check: $%s",
Expand Down
41 changes: 41 additions & 0 deletions [core]/es_extended/locales/es.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
return {
-- Inventory
["inventory"] = "Inventario (Peso %s / %s)",
["use"] = "Usar",
["give"] = "Dar",
["remove"] = "Tirar",
["return"] = "Devolver",
["give_to"] = "Dar a",
["amount"] = "Cantidad",
["giveammo"] = "Dar munición",
["amountammo"] = "Cantidad de munición",
["noammo"] = "¡Insuficiente!",
["gave_item"] = "Dando %sx %s a %s",
["received_item"] = "Recibido %sx %s de %s",
["gave_weapon"] = "Dando %s a %s",
["gave_weapon_ammo"] = "Dando ~o~%sx %s para %s a %s",
["gave_weapon_withammo"] = "Dando %s con ~o~%sx %s a %s",
["gave_weapon_hasalready"] = "%s ya tiene un %s",
["gave_weapon_noweapon"] = "%s no tiene esa arma",
["received_weapon"] = "Recibido %s de %s",
["received_weapon_ammo"] = "Recibido ~o~%sx %s para tu %s de %s",
["received_weapon_withammo"] = "Recibido %s con ~o~%sx %s de %s",
["received_weapon_hasalready"] = "%s ha intentado darte un %s, pero ya tienes esta arma",
["received_weapon_noweapon"] = "%s ha intentado darte munición para un %s, pero no tienes esta arma",
["gave_account_money"] = "Dando $%s (%s) a %s",
["received_account_money"] = "Recibido $%s (%s) de %s",
["amount_invalid"] = "Cantidad inválida",
["players_nearby"] = "No hay jugadores cerca",
["ex_inv_lim"] = "No se puede realizar la acción, se excede el peso máximo de %s",
["imp_invalid_quantity"] = "No se puede realizar la acción, la cantidad es inválida",
["imp_invalid_amount"] = "No se puede realizar la acción, la cantidad es inválida",
["threw_standard"] = "Tirando %sx %s",
["threw_account"] = "Tirando $%s %s",
["threw_weapon"] = "Tirando %s",
["threw_weapon_ammo"] = "Tirando %s con ~o~%sx %s",
["threw_weapon_already"] = "Ya tienes esta arma",
["threw_cannot_pickup"] = "¡Inventario lleno, no se puede recoger!",
["threw_pickup_prompt"] = "Pulsa E para recoger",

-- Key mapping
["keymap_showinventory"] = "Mostrar inventario",

-- Salary related
["received_salary"] = "Has cobrado: $%s",
["received_help"] = "Has cobrado tu subsidio: $%s",
Expand Down
Loading
Loading