From 32734919a10493b5716201ed18a7a9b928f7c22f Mon Sep 17 00:00:00 2001
From: Rafael Antunes <147253092+Fellow1990@users.noreply.github.com>
Date: Fri, 3 Oct 2025 23:24:12 +0100
Subject: [PATCH 1/6] refactor(esx_dmvschool): code structure
---
[esx_addons]/esx_dmvschool/client/main.lua | 50 ++++++++++------------
1 file changed, 23 insertions(+), 27 deletions(-)
diff --git a/[esx_addons]/esx_dmvschool/client/main.lua b/[esx_addons]/esx_dmvschool/client/main.lua
index 719cce1c..420a24b8 100644
--- a/[esx_addons]/esx_dmvschool/client/main.lua
+++ b/[esx_addons]/esx_dmvschool/client/main.lua
@@ -1,6 +1,5 @@
local CurrentAction = nil
local CurrentActionMsg = nil
-local CurrentActionData = nil
local Licenses = {}
local CurrentTest = nil
local CurrentTestType = nil
@@ -30,7 +29,7 @@ function StartTheoryTest()
SetNuiFocus(true, true)
end)
-
+ ESX.HideUI()
end
function StopTheoryTest(success)
@@ -48,6 +47,8 @@ function StopTheoryTest(success)
else
ESX.ShowNotification(TranslateCap('failed_test'))
end
+
+ ESX.TextUI(TranslateCap('press_open_menu'))
end
function StartDriveTest(type)
@@ -84,10 +85,11 @@ function StopDriveTest(success)
end
function SetCurrentZoneType(type)
-CurrentZoneType = type
+ CurrentZoneType = type
end
function OpenDMVSchoolMenu()
+ ESX.HideUI()
local ownedLicenses = {}
for i=1, #Licenses, 1 do
@@ -100,9 +102,10 @@ function OpenDMVSchoolMenu()
if not ownedLicenses['dmv'] then
elements[#elements+1] = {
- icon = "fas fa-car",
+ icon = "fas fa-id-card",
title = (('%s: %s'):format(TranslateCap('theory_test'), TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices['dmv'])))),
- value = "theory_test"
+ value = "theory_test",
+ type = "dmv"
}
end
@@ -118,7 +121,7 @@ function OpenDMVSchoolMenu()
if not ownedLicenses['drive_bike'] then
elements[#elements+1] = {
- icon = "fas fa-car",
+ icon = "fas fa-motorcycle",
title = (('%s: %s'):format(TranslateCap('road_test_bike'), TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices['drive_bike'])))),
value = "drive_test",
type = "drive_bike"
@@ -127,7 +130,7 @@ function OpenDMVSchoolMenu()
if not ownedLicenses['drive_truck'] then
elements[#elements+1] = {
- icon = "fas fa-car",
+ icon = "fas fa-truck",
title = (('%s: %s'):format(TranslateCap('road_test_truck'), TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices['drive_truck'])))),
value = "drive_test",
type = "drive_truck"
@@ -136,29 +139,22 @@ function OpenDMVSchoolMenu()
end
ESX.OpenContext("right", elements, function(menu,element)
- if element.value == "theory_test" then
- ESX.TriggerServerCallback('esx_dmvschool:canYouPay', function(haveMoney)
- if haveMoney then
- ESX.CloseContext()
+ ESX.TriggerServerCallback('esx_dmvschool:canYouPay', function(haveMoney)
+ if haveMoney then
+ ESX.CloseContext()
+ if element.value == "theory_test" then
StartTheoryTest()
else
- ESX.ShowNotification(TranslateCap('not_enough_money'))
- end
- end, 'dmv')
- elseif element.value == "drive_test" then
- ESX.TriggerServerCallback('esx_dmvschool:canYouPay', function(haveMoney)
- if haveMoney then
- ESX.CloseContext()
StartDriveTest(element.type)
- else
- ESX.ShowNotification(TranslateCap('not_enough_money'))
end
- end, element.type)
- end
+ else
+ ESX.ShowNotification(TranslateCap('not_enough_money'))
+ end
+ end, element.type)
end, function(menu)
CurrentAction = 'dmvschool_menu'
CurrentActionMsg = TranslateCap('press_open_menu')
- CurrentActionData = {}
+ ESX.TextUI(CurrentActionMsg)
end)
end
@@ -184,13 +180,14 @@ AddEventHandler('esx_dmvschool:hasEnteredMarker', function(zone)
if zone == 'DMVSchool' then
CurrentAction = 'dmvschool_menu'
CurrentActionMsg = TranslateCap('press_open_menu')
- CurrentActionData = {}
end
+ ESX.TextUI(CurrentActionMsg)
end)
AddEventHandler('esx_dmvschool:hasExitedMarker', function(zone)
CurrentAction = nil
ESX.CloseContext()
+ ESX.HideUI()
end)
RegisterNetEvent('esx_dmvschool:loadLicenses')
@@ -277,10 +274,10 @@ CreateThread(function()
if CurrentAction then
sleep = 0
- ESX.ShowHelpNotification(CurrentActionMsg)
if (IsControlJustReleased(0, 38)) and (CurrentAction == 'dmvschool_menu') then
OpenDMVSchoolMenu()
+ ESX.HideUI()
CurrentAction = nil
end
end
@@ -368,5 +365,4 @@ CreateThread(function()
end
Wait(sleep)
end
-end)
-
+end)
\ No newline at end of file
From 88613e2c1f785324a20c2d908d8b4272188472df Mon Sep 17 00:00:00 2001
From: Rafael Antunes <147253092+Fellow1990@users.noreply.github.com>
Date: Fri, 3 Oct 2025 23:59:11 +0100
Subject: [PATCH 2/6] Add updater.lua
---
[esx_addons]/esx_dmvschool/fxmanifest.lua | 2 +-
[esx_addons]/esx_dmvschool/locales/de.lua | 3 +
[esx_addons]/esx_dmvschool/locales/en.lua | 4 +
[esx_addons]/esx_dmvschool/locales/es.lua | 60 ++++++------
[esx_addons]/esx_dmvschool/locales/fi.lua | 6 +-
[esx_addons]/esx_dmvschool/locales/fr.lua | 6 +-
[esx_addons]/esx_dmvschool/locales/hu.lua | 4 +
[esx_addons]/esx_dmvschool/locales/it.lua | 4 +
[esx_addons]/esx_dmvschool/locales/nl.lua | 4 +
[esx_addons]/esx_dmvschool/locales/pl.lua | 6 +-
[esx_addons]/esx_dmvschool/locales/sr.lua | 4 +
[esx_addons]/esx_dmvschool/locales/sv.lua | 4 +
[esx_addons]/esx_dmvschool/locales/tr.lua | 4 +
[esx_addons]/esx_dmvschool/locales/zh-cn.lua | 4 +
[esx_addons]/esx_dmvschool/server/updater.lua | 95 +++++++++++++++++++
15 files changed, 178 insertions(+), 32 deletions(-)
create mode 100644 [esx_addons]/esx_dmvschool/server/updater.lua
diff --git a/[esx_addons]/esx_dmvschool/fxmanifest.lua b/[esx_addons]/esx_dmvschool/fxmanifest.lua
index 9bd93c57..83e149f5 100644
--- a/[esx_addons]/esx_dmvschool/fxmanifest.lua
+++ b/[esx_addons]/esx_dmvschool/fxmanifest.lua
@@ -15,7 +15,7 @@ server_scripts {
'@es_extended/locale.lua',
'locales/*.lua',
'config.lua',
- 'server/main.lua'
+ 'server/*.lua'
}
client_scripts {
diff --git a/[esx_addons]/esx_dmvschool/locales/de.lua b/[esx_addons]/esx_dmvschool/locales/de.lua
index ad705cc9..9bfb4456 100644
--- a/[esx_addons]/esx_dmvschool/locales/de.lua
+++ b/[esx_addons]/esx_dmvschool/locales/de.lua
@@ -27,4 +27,7 @@ Locales['de'] = {
['errors'] = 'Fehler: ~r~%s/%s',
['you_damaged_veh'] = 'Du hast das Fahrzeug beschädigt!',
['not_enough_money'] = 'Du hast nicht genug Geld!',
+ ['latestVersion'] = "Du bruger den seneste version!",
+ ['needUpdateResource'] = "Du skal downloade den nyeste version! Du bruger en gammel version i øjeblikket!",
+ ['errorGetCurrentVersion'] = "Der opstod en fejl under forsøget på at hente den nuværende version!",
}
diff --git a/[esx_addons]/esx_dmvschool/locales/en.lua b/[esx_addons]/esx_dmvschool/locales/en.lua
index 935fa835..3e6e0289 100644
--- a/[esx_addons]/esx_dmvschool/locales/en.lua
+++ b/[esx_addons]/esx_dmvschool/locales/en.lua
@@ -27,4 +27,8 @@ Locales['en'] = {
['errors'] = 'mistakes: ~r~%s/%s',
['you_damaged_veh'] = 'you damaged the vehicle',
['not_enough_money'] = 'You don\'t have enough money',
+ ['yourVersion'] = "Your version: ",
+ ['latestVersion'] = "You are using the latest version!",
+ ['needUpdateResource'] = "You need download latest version! You are using an old version at the moment!",
+ ['errorGetCurrentVersion'] = "An error occurred while trying to get the current version!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/es.lua b/[esx_addons]/esx_dmvschool/locales/es.lua
index 999b6741..3e6e0289 100644
--- a/[esx_addons]/esx_dmvschool/locales/es.lua
+++ b/[esx_addons]/esx_dmvschool/locales/es.lua
@@ -1,30 +1,34 @@
-Locales['es'] = {
- ['you_paid'] = 'Pagaste %s$ a la autoescuela',
- ['go_next_point'] = '¡Vete al siguiente punto!',
- ['in_town_speed'] = '¡Entraste a la ciudad, presta atención a tu velocidad! Límite de velocidad: %s km/h',
- ['next_point_speed'] = '¡Vete al siguiente punto! Límite de velocidad: %s km/h',
- ['stop_for_ped'] = '~r~Para en el paso de peatones',
- ['good_lets_cont'] = 'Bien, continua',
- ['stop_look_left'] = '~r~Para y mira a la izquierda. Límite de velocidad: %s km/h',
- ['good_turn_right'] = 'Bien, gira a la derecha y sigue la línea',
- ['watch_traffic_lightson'] = '¡Mira el tráfico y enciende las luces!',
- ['stop_for_passing'] = '¡~r~Para para que pasen los vehículos!',
- ['hway_time'] = '¡Es hora de conducir por la autopista! Límite de velocidad: %s km/h',
- ['gratz_stay_alert'] = '¡Estoy impresionado pero no dejes de estar ~r~alerta mientras conduces!',
- ['passed_test'] = 'Has aprobado el examen, ¡Enorabuena!',
- ['failed_test'] = 'Has ~r~suspendido el examen, ¡Más suerte la próxima vez!',
- ['theory_test'] = 'Examen teórico de conducir',
- ['road_test_car'] = 'Examen práctico de conducir',
- ['road_test_bike'] = 'Examen práctico de moto',
- ['road_test_truck'] = 'Examen práctico de camiones',
- ['school_item'] = '%s$',
- ['driving_school'] = 'Escuela de conducción',
- ['press_open_menu'] = 'Pulsa [E] para abrir el menú',
- ['driving_school_blip'] = 'Autoescuela',
- ['driving_test_complete'] = 'Examen de conducir finalizado',
- ['driving_too_fast'] = '¡~r~Estás conduciendo muy rápido, el límite de velocidad actual es: %s km/h!',
+Locales['en'] = {
+ ['you_paid'] = 'you paid $%s to the DMV school',
+ ['go_next_point'] = 'go to the next point!',
+ ['in_town_speed'] = 'entered town, pay attention to your speed! Speed Limit: %s km/h',
+ ['next_point_speed'] = 'go to the next point! Speed Limit: %s km/h',
+ ['stop_for_ped'] = '~r~Stop for the pedestrian crossing',
+ ['good_lets_cont'] = 'Good, continue.',
+ ['stop_look_left'] = '~r~Stop and look left. Speed Limit: %s km/h',
+ ['good_turn_right'] = 'Good, turn right and follow the line',
+ ['watch_traffic_lightson'] = 'watch the traffic and turn on your lights!',
+ ['stop_for_passing'] = '~r~Stop for passing vehicles!',
+ ['hway_time'] = 'it\'s time to drive on the highway! Speed Limit: %s km/h',
+ ['gratz_stay_alert'] = 'i\'m impressed, but don\'t forget to stay ~r~alert whilst driving!',
+ ['passed_test'] = 'you passed the test, congratulations!',
+ ['failed_test'] = 'you ~r~failed the test, better luck next time!',
+ ['theory_test'] = 'theoretical Driving Test',
+ ['road_test_car'] = 'driving Test',
+ ['road_test_bike'] = 'motorcycle Skills Test',
+ ['road_test_truck'] = 'truck Skills Test',
+ ['school_item'] = '$%s',
+ ['driving_school'] = 'driving School',
+ ['press_open_menu'] = 'press [E] to open the menu',
+ ['driving_school_blip'] = 'driving School',
+ ['driving_test_complete'] = 'driving test completed',
+ ['driving_too_fast'] = '~r~You\'re driving too fast, the current speed limit is: %s km/h!',
['test_failed_go_to_start_point'] = '~r~Go to the starting point, because you failed the test!',
- ['errors'] = 'Fallos: ~r~%s / %s',
- ['you_damaged_veh'] = '¡Has dañado el vehículo!',
- ['not_enough_money'] = 'No tienes suficiente dinero'
+ ['errors'] = 'mistakes: ~r~%s/%s',
+ ['you_damaged_veh'] = 'you damaged the vehicle',
+ ['not_enough_money'] = 'You don\'t have enough money',
+ ['yourVersion'] = "Your version: ",
+ ['latestVersion'] = "You are using the latest version!",
+ ['needUpdateResource'] = "You need download latest version! You are using an old version at the moment!",
+ ['errorGetCurrentVersion'] = "An error occurred while trying to get the current version!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/fi.lua b/[esx_addons]/esx_dmvschool/locales/fi.lua
index eea7d747..80a2f58c 100644
--- a/[esx_addons]/esx_dmvschool/locales/fi.lua
+++ b/[esx_addons]/esx_dmvschool/locales/fi.lua
@@ -26,5 +26,9 @@ Locales['fi'] = {
['test_failed_go_to_start_point'] = '~r~Go to the starting point, because you failed the test!',
['errors'] = 'mistakes: ~r~%s/%s',
['you_damaged_veh'] = 'Vahingoitit ajoneuvoa. Aja varovaisemmin...',
- ['not_enough_money'] = 'Sinulla ei ole tarpeeksi rahaa'
+ ['not_enough_money'] = 'Sinulla ei ole tarpeeksi rahaa',
+ ['yourVersion'] = "Versiosi: ",
+ ['latestVersion'] = "Käytät uusinta versiota!",
+ ['needUpdateResource'] = "Sinun täytyy ladata uusin versio! Käytät tällä hetkellä vanhaa versiota!",
+ ['errorGetCurrentVersion'] = "Virhe tapahtui haettaessa nykyistä versiota!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/fr.lua b/[esx_addons]/esx_dmvschool/locales/fr.lua
index 17598071..01e5f21f 100644
--- a/[esx_addons]/esx_dmvschool/locales/fr.lua
+++ b/[esx_addons]/esx_dmvschool/locales/fr.lua
@@ -26,5 +26,9 @@ Locales['fr'] = {
['test_failed_go_to_start_point'] = '~r~Go to the starting point, because you failed the test!',
['errors'] = 'erreurs: ~r~%s/%s',
['you_damaged_veh'] = 'Vous avez endommagé votre véhicule',
- ['not_enough_money'] = 'Tu n\'as pas assez d\'argent'
+ ['not_enough_money'] = 'Tu n\'as pas assez d\'argent',
+ ['yourVersion'] = "Votre version : ",
+ ['latestVersion'] = "Vous utilisez la dernière version !",
+ ['needUpdateResource'] = "Vous devez télécharger la dernière version ! Vous utilisez actuellement une ancienne version !",
+ ['errorGetCurrentVersion'] = "Une erreur s'est produite lors de la récupération de la version actuelle !"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/hu.lua b/[esx_addons]/esx_dmvschool/locales/hu.lua
index 560b362f..e1c7bd1a 100644
--- a/[esx_addons]/esx_dmvschool/locales/hu.lua
+++ b/[esx_addons]/esx_dmvschool/locales/hu.lua
@@ -27,4 +27,8 @@ Locales['hu'] = {
['errors'] = 'Hibapontok: ~r~%s/%s',
['you_damaged_veh'] = 'Összetörted az autót, ez drága lesz.',
['not_enough_money'] = 'Nincs elég pénzed!',
+ ['yourVersion'] = "A verziód: ",
+ ['latestVersion'] = "A legújabb verziót használod!",
+ ['needUpdateResource'] = "Le kell töltened a legújabb verziót! Jelenleg egy régi verziót használsz!",
+ ['errorGetCurrentVersion'] = "Hiba történt az aktuális verzió lekérése közben!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/it.lua b/[esx_addons]/esx_dmvschool/locales/it.lua
index 11dcbd0d..887ae33d 100644
--- a/[esx_addons]/esx_dmvschool/locales/it.lua
+++ b/[esx_addons]/esx_dmvschool/locales/it.lua
@@ -27,4 +27,8 @@ Locales['it'] = {
['errors'] = 'errori: ~r~%s/%s',
['you_damaged_veh'] = 'hai danneggiato il veicolo',
['not_enough_money'] = 'non hai abbastanza soldi',
+ ['yourVersion'] = "La tua versione: ",
+ ['latestVersion'] = "Stai usando l'ultima versione!",
+ ['needUpdateResource'] = "Devi scaricare l'ultima versione! Stai usando una versione vecchia!",
+ ['errorGetCurrentVersion'] = "Si è verificato un errore durante il recupero della versione corrente!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/nl.lua b/[esx_addons]/esx_dmvschool/locales/nl.lua
index 0ab60295..8009e21e 100644
--- a/[esx_addons]/esx_dmvschool/locales/nl.lua
+++ b/[esx_addons]/esx_dmvschool/locales/nl.lua
@@ -27,4 +27,8 @@ Locales['nl'] = {
['errors'] = 'Fouten: ~r~%s/%s',
['you_damaged_veh'] = 'Je hebt het voertuig beschadigd',
['not_enough_money'] = 'Je hebt niet genoeg geld',
+ ['yourVersion'] = "Jouw versie: ",
+ ['latestVersion'] = "Je gebruikt de nieuwste versie!",
+ ['needUpdateResource'] = "Je moet de nieuwste versie downloaden! Je gebruikt momenteel een oude versie!",
+ ['errorGetCurrentVersion'] = "Er is een fout opgetreden bij het ophalen van de huidige versie!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/pl.lua b/[esx_addons]/esx_dmvschool/locales/pl.lua
index f5ea6bce..2e0d44fe 100644
--- a/[esx_addons]/esx_dmvschool/locales/pl.lua
+++ b/[esx_addons]/esx_dmvschool/locales/pl.lua
@@ -26,5 +26,9 @@ Locales['pl'] = {
['test_failed_go_to_start_point'] = '~r~Go to the starting point, because you failed the test!',
['errors'] = 'błędy: ~r~%s/%s',
['you_damaged_veh'] = 'uszkodziłeś auto',
- ['not_enough_money'] = 'Nie masz wystarczająco dużo pieniędzy'
+ ['not_enough_money'] = 'Nie masz wystarczająco dużo pieniędzy',
+ ['yourVersion'] = "Twoja wersja: ",
+ ['latestVersion'] = "Używasz najnowszej wersji!",
+ ['needUpdateResource'] = "Musisz pobrać najnowszą wersję! Obecnie używasz starej wersji!",
+ ['errorGetCurrentVersion'] = "Wystąpił błąd podczas pobierania aktualnej wersji!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/sr.lua b/[esx_addons]/esx_dmvschool/locales/sr.lua
index e3507a50..3ef42819 100644
--- a/[esx_addons]/esx_dmvschool/locales/sr.lua
+++ b/[esx_addons]/esx_dmvschool/locales/sr.lua
@@ -27,4 +27,8 @@ Locales['sr'] = {
['errors'] = 'Greške: ~r~%s/%s',
['you_damaged_veh'] = 'Oštetili ste vozilo',
['not_enough_money'] = 'Nemate dovoljno novca',
+ ['yourVersion'] = "Vaša verzija: ",
+ ['latestVersion'] = "Koristite najnoviju verziju!",
+ ['needUpdateResource'] = "Morate preuzeti najnoviju verziju! Trenutno koristite staru verziju!",
+ ['errorGetCurrentVersion'] = "Došlo je do greške prilikom pokušaja dobavljanja trenutne verzije!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/sv.lua b/[esx_addons]/esx_dmvschool/locales/sv.lua
index 9a72f05b..cb1f2aab 100644
--- a/[esx_addons]/esx_dmvschool/locales/sv.lua
+++ b/[esx_addons]/esx_dmvschool/locales/sv.lua
@@ -27,4 +27,8 @@ Locales['sv'] = {
['errors'] = 'Misstag: ~r~%s/%s',
['you_damaged_veh'] = 'Du skadade fordonet',
['not_enough_money'] = 'Du har inte tillräckligt med pengar',
+ ['yourVersion'] = "Din version: ",
+ ['latestVersion'] = "Du använder den senaste versionen!",
+ ['needUpdateResource'] = "Du måste ladda ner den senaste versionen! Du använder för närvarande en gammal version!",
+ ['errorGetCurrentVersion'] = "Ett fel uppstod när den aktuella versionen försöktes hämtas!"
}
diff --git a/[esx_addons]/esx_dmvschool/locales/tr.lua b/[esx_addons]/esx_dmvschool/locales/tr.lua
index 924f7fb4..62cf86d9 100644
--- a/[esx_addons]/esx_dmvschool/locales/tr.lua
+++ b/[esx_addons]/esx_dmvschool/locales/tr.lua
@@ -27,5 +27,9 @@ Locales['tr'] = {
['errors'] = 'Hatalar: ~r~%s/%s',
['you_damaged_veh'] = 'Araç hasar gördü',
['not_enough_money'] = 'Yeterli paranız yok',
+ ['yourVersion'] = "Sürümünüz: ",
+ ['latestVersion'] = "En son sürümü kullanıyorsunuz!",
+ ['needUpdateResource'] = "En son sürümü indirmeniz gerekiyor! Şu anda eski bir sürüm kullanıyorsunuz!",
+ ['errorGetCurrentVersion'] = "Mevcut sürüm alınmaya çalışılırken bir hata oluştu!"
}
\ No newline at end of file
diff --git a/[esx_addons]/esx_dmvschool/locales/zh-cn.lua b/[esx_addons]/esx_dmvschool/locales/zh-cn.lua
index 549077be..7a45c4e5 100644
--- a/[esx_addons]/esx_dmvschool/locales/zh-cn.lua
+++ b/[esx_addons]/esx_dmvschool/locales/zh-cn.lua
@@ -27,4 +27,8 @@ Locales['zh-cn'] = {
['errors'] = '失误: ~r~%s~s~/~g~%s~s~',
['you_damaged_veh'] = '载具出现受损!',
['not_enough_money'] = '您暂无足够现金',
+ ['yourVersion'] = "你的版本:",
+ ['latestVersion'] = "你正在使用最新版本!",
+ ['needUpdateResource'] = "你需要下载最新版本!你当前使用的是旧版本!",
+ ['errorGetCurrentVersion'] = "尝试获取当前版本时发生错误!"
}
diff --git a/[esx_addons]/esx_dmvschool/server/updater.lua b/[esx_addons]/esx_dmvschool/server/updater.lua
new file mode 100644
index 00000000..6390522f
--- /dev/null
+++ b/[esx_addons]/esx_dmvschool/server/updater.lua
@@ -0,0 +1,95 @@
+DMV = DMV or {}
+
+DMV.VersionCheckBaseURL = "https://raw.githubusercontent.com/esx-framework/ESX-Legacy-Addons/main/%5Besx_addons%5D/"
+
+function DMV:ErrorHandle(msg)
+ local resourceName = GetCurrentResourceName()
+ print(("[^1ERROR^7] ^3%s^7: %s"):format(resourceName, msg))
+end
+
+function DMV:InfoHandle(msg, color)
+ local resourceName = GetCurrentResourceName()
+ local c = ({green=2, red=1, blue=4})[color] or 3
+ print(("[^9INFO^7] ^3%s^7: ^" .. c .. "%s^7"):format(resourceName, msg))
+end
+
+local function normalizeSemver(v)
+ if type(v) ~= "string" then return nil end
+ local three = v:match("%d+%.%d+%.%d+")
+ if three then return three end
+ local two = v:match("^%d+%.%d+$")
+ if two then return (two .. ".0") end
+ local one = v:match("^%d+$")
+ if one then return (one .. ".0.0") end
+ return nil
+end
+
+VERSION = {
+ Check = function(err, response, headers)
+ local resourceName = GetCurrentResourceName()
+ local currentVersion = GetResourceMetadata(resourceName, "version", 0)
+ if not currentVersion then return end
+
+ local manifestURL = DMV.VersionCheckBaseURL .. resourceName .. "/fxmanifest.lua"
+ DMV:InfoHandle(("Checking manifest from %s"):format(manifestURL), "blue")
+
+ if err ~= 200 or not response then
+ DMV:ErrorHandle(Translate("errorGetCurrentVersion"))
+ return
+ end
+
+ local remoteVersion = response:match("version%s+'([%d%.]+)'")
+ if not remoteVersion then
+ DMV:ErrorHandle(Translate("errorGetRemoteVersion"))
+ return
+ end
+
+ local latestVersion = normalizeSemver(remoteVersion)
+ currentVersion = normalizeSemver(currentVersion)
+
+ if not latestVersion or not currentVersion then
+ DMV:ErrorHandle(Translate("invalidVersion"))
+ return
+ end
+
+ if currentVersion == latestVersion then
+ DMV:InfoHandle(Translate("latestVersion"), "green")
+ DMV:InfoHandle(("Up to date version (%s)"):format(currentVersion), "green")
+ return
+ end
+
+ local currentVersionSplitted = { string.strsplit(".", currentVersion) }
+ local latestVersionSplitted = { string.strsplit(".", latestVersion) }
+
+ DMV:InfoHandle(Translate("currentVersion") .. latestVersion, "green")
+ DMV:InfoHandle(Translate("yourVersion") .. currentVersion, "blue")
+ DMV:InfoHandle(("Update available: remote %s > local %s"):format(latestVersion, currentVersion), "red")
+
+ for i = 1, #currentVersionSplitted do
+ local current, latest = tonumber(currentVersionSplitted[i]), tonumber(latestVersionSplitted[i])
+ if current ~= latest then
+ if not current or not latest then return end
+ if current < latest then
+ DMV:InfoHandle(Translate("needUpdateResource"), "red")
+ end
+ break
+ end
+ end
+ end,
+
+ RunVersionChecker = function()
+ CreateThread(function()
+ local resourceName = GetCurrentResourceName()
+ local manifestURL = DMV.VersionCheckBaseURL .. resourceName .. "/fxmanifest.lua"
+ PerformHttpRequest(manifestURL, VERSION.Check, "GET")
+ end)
+ end,
+}
+
+AddEventHandler("onResourceStart", function(resourceName)
+ local currentName = GetCurrentResourceName()
+ if resourceName ~= currentName then return end
+
+ Wait(100)
+ VERSION:RunVersionChecker()
+end)
\ No newline at end of file
From b9035d58bb68b9eb7bdadf3e26d1969b2e82c2f2 Mon Sep 17 00:00:00 2001
From: Rafael Antunes <147253092+Fellow1990@users.noreply.github.com>
Date: Sat, 4 Oct 2025 19:47:22 +0100
Subject: [PATCH 3/6] Update de.lua
---
[esx_addons]/esx_dmvschool/locales/de.lua | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/[esx_addons]/esx_dmvschool/locales/de.lua b/[esx_addons]/esx_dmvschool/locales/de.lua
index 9bfb4456..72e2d9f8 100644
--- a/[esx_addons]/esx_dmvschool/locales/de.lua
+++ b/[esx_addons]/esx_dmvschool/locales/de.lua
@@ -27,7 +27,7 @@ Locales['de'] = {
['errors'] = 'Fehler: ~r~%s/%s',
['you_damaged_veh'] = 'Du hast das Fahrzeug beschädigt!',
['not_enough_money'] = 'Du hast nicht genug Geld!',
- ['latestVersion'] = "Du bruger den seneste version!",
- ['needUpdateResource'] = "Du skal downloade den nyeste version! Du bruger en gammel version i øjeblikket!",
- ['errorGetCurrentVersion'] = "Der opstod en fejl under forsøget på at hente den nuværende version!",
+ ['latestVersion'] = "Du verwendest die neueste Version!",
+ ['needUpdateResource'] = "Du musst die neueste Version herunterladen! Du verwendest derzeit eine veraltete Version!",
+ ['errorGetCurrentVersion'] = "Beim Versuch, die aktuelle Version abzurufen, ist ein Fehler aufgetreten!",
}
From 72e8d4ae69b0900b62337359c520e7aedea58193 Mon Sep 17 00:00:00 2001
From: Rafael Antunes <147253092+Fellow1990@users.noreply.github.com>
Date: Sun, 5 Oct 2025 22:52:14 +0100
Subject: [PATCH 4/6] refactor(esx_dmvschool): code structure
---
[esx_addons]/esx_dmvschool/client/main.lua | 223 ++++++++-------------
[esx_addons]/esx_dmvschool/server/main.lua | 16 +-
2 files changed, 87 insertions(+), 152 deletions(-)
diff --git a/[esx_addons]/esx_dmvschool/client/main.lua b/[esx_addons]/esx_dmvschool/client/main.lua
index 420a24b8..caf78965 100644
--- a/[esx_addons]/esx_dmvschool/client/main.lua
+++ b/[esx_addons]/esx_dmvschool/client/main.lua
@@ -1,5 +1,3 @@
-local CurrentAction = nil
-local CurrentActionMsg = nil
local Licenses = {}
local CurrentTest = nil
local CurrentTestType = nil
@@ -20,34 +18,27 @@ end
function StartTheoryTest()
CurrentTest = 'theory'
-
SendNUIMessage({
openQuestion = true
})
-
ESX.SetTimeout(200, function()
SetNuiFocus(true, true)
end)
-
ESX.HideUI()
end
function StopTheoryTest(success)
CurrentTest = nil
-
SendNUIMessage({
openQuestion = false
})
-
SetNuiFocus(false)
-
if success then
TriggerServerEvent('esx_dmvschool:addLicense', 'dmv')
ESX.ShowNotification(TranslateCap('passed_test'))
else
ESX.ShowNotification(TranslateCap('failed_test'))
end
-
ESX.TextUI(TranslateCap('press_open_menu'))
end
@@ -63,7 +54,6 @@ function StartDriveTest(type)
CurrentVehicle = vehicle
LastVehicleHealth = GetEntityHealth(vehicle)
failedTest = false
-
local playerPed = PlayerPedId()
TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
SetVehicleFuelLevel(vehicle, 100.0)
@@ -79,7 +69,6 @@ function StopDriveTest(success)
else
ESX.ShowNotification(TranslateCap('failed_test'))
end
-
CurrentTest = nil
CurrentTestType = nil
end
@@ -89,80 +78,65 @@ function SetCurrentZoneType(type)
end
function OpenDMVSchoolMenu()
- ESX.HideUI()
- local ownedLicenses = {}
-
- for i=1, #Licenses, 1 do
- ownedLicenses[Licenses[i].type] = true
- end
-
- local elements = {
- {unselectable = true, icon = "fas fa-car", title = TranslateCap("driving_school")}
- }
-
- if not ownedLicenses['dmv'] then
- elements[#elements+1] = {
- icon = "fas fa-id-card",
- title = (('%s: %s'):format(TranslateCap('theory_test'), TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices['dmv'])))),
- value = "theory_test",
- type = "dmv"
- }
- end
-
- if ownedLicenses['dmv'] then
- if not ownedLicenses['drive'] then
- elements[#elements+1] = {
- icon = "fas fa-car",
- title = (('%s: %s'):format(TranslateCap('road_test_car'), TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices['drive'])))),
- value = "drive_test",
- type = "drive"
- }
- end
-
- if not ownedLicenses['drive_bike'] then
- elements[#elements+1] = {
- icon = "fas fa-motorcycle",
- title = (('%s: %s'):format(TranslateCap('road_test_bike'), TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices['drive_bike'])))),
- value = "drive_test",
- type = "drive_bike"
- }
- end
-
- if not ownedLicenses['drive_truck'] then
- elements[#elements+1] = {
- icon = "fas fa-truck",
- title = (('%s: %s'):format(TranslateCap('road_test_truck'), TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices['drive_truck'])))),
- value = "drive_test",
- type = "drive_truck"
- }
- end
- end
-
- ESX.OpenContext("right", elements, function(menu,element)
- ESX.TriggerServerCallback('esx_dmvschool:canYouPay', function(haveMoney)
- if haveMoney then
- ESX.CloseContext()
- if element.value == "theory_test" then
- StartTheoryTest()
- else
- StartDriveTest(element.type)
- end
- else
- ESX.ShowNotification(TranslateCap('not_enough_money'))
- end
- end, element.type)
- end, function(menu)
- CurrentAction = 'dmvschool_menu'
- CurrentActionMsg = TranslateCap('press_open_menu')
- ESX.TextUI(CurrentActionMsg)
- end)
+ ESX.TriggerServerCallback('esx_license:getLicenses', function(licenses)
+ ESX.HideUI()
+
+ local ownedLicenses = {}
+ for i=1, #licenses do
+ ownedLicenses[licenses[i].type] = true
+ end
+
+ local elements = {
+ { unselectable = true, icon = "fas fa-car", title = TranslateCap("driving_school") }
+ }
+
+ local function addLicenseOption(icon, titleKey, priceKey, value, licType)
+ elements[#elements+1] = {
+ icon = icon,
+ title = (('%s: %s'):format(
+ TranslateCap(titleKey),
+ TranslateCap('school_item', ESX.Math.GroupDigits(Config.Prices[priceKey]))
+ )),
+ value = value,
+ type = licType
+ }
+ end
+
+ if not ownedLicenses['dmv'] then
+ addLicenseOption("fas fa-id-card", "theory", "dmv", "theory", "dmv")
+ else
+ local driveTests = {
+ { icon = "fas fa-car", key = "drive", label = "road_test_car" },
+ { icon = "fas fa-motorcycle", key = "drive_bike", label = "road_test_bike" },
+ { icon = "fas fa-truck", key = "drive_truck", label = "road_test_truck" }
+ }
+ for _, test in ipairs(driveTests) do
+ if not ownedLicenses[test.key] then
+ addLicenseOption(test.icon, test.label, test.key, "drive_test", test.key)
+ end
+ end
+ end
+
+ ESX.OpenContext("right", elements, function(menu, element)
+ ESX.TriggerServerCallback('esx_dmvschool:canYouPay', function(haveMoney)
+ if not haveMoney then
+ return ESX.ShowNotification(TranslateCap('not_enough_money'))
+ end
+ ESX.CloseContext()
+ if element.value == "theory" then
+ StartTheoryTest()
+ else
+ StartDriveTest(element.type)
+ end
+ end, element.type)
+ end, function(menu)
+ ESX.TextUI(TranslateCap('press_open_menu'))
+ end)
+ end, GetPlayerServerId(PlayerId()))
end
RegisterNUICallback('question', function(data, cb)
- SendNUIMessage({
- openSection = 'question'
- })
-
+ SendNUIMessage({openSection = 'question'})
cb()
end)
@@ -177,25 +151,14 @@ RegisterNUICallback('kick', function(data, cb)
end)
AddEventHandler('esx_dmvschool:hasEnteredMarker', function(zone)
- if zone == 'DMVSchool' then
- CurrentAction = 'dmvschool_menu'
- CurrentActionMsg = TranslateCap('press_open_menu')
- end
- ESX.TextUI(CurrentActionMsg)
+ ESX.TextUI(TranslateCap('press_open_menu'))
end)
AddEventHandler('esx_dmvschool:hasExitedMarker', function(zone)
- CurrentAction = nil
ESX.CloseContext()
ESX.HideUI()
end)
-RegisterNetEvent('esx_dmvschool:loadLicenses')
-AddEventHandler('esx_dmvschool:loadLicenses', function(licenses)
- Licenses = licenses
-end)
-
--- Create Blips
CreateThread(function()
local blip = AddBlipForCoord(Config.Zones.DMVSchool.Pos.x, Config.Zones.DMVSchool.Pos.y, Config.Zones.DMVSchool.Pos.z)
@@ -210,29 +173,38 @@ CreateThread(function()
EndTextCommandSetBlipName(blip)
end)
--- Display markers
CreateThread(function()
while true do
local sleep = 1500
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
- for k,v in pairs(Config.Zones) do
+ local isInMarker = false
+ local currentZone = nil
+
+ for k, v in pairs(Config.Zones) do
local Pos = vector3(v.Pos.x, v.Pos.y, v.Pos.z)
- if(v.Type ~= -1 and #(coords - Pos) < Config.DrawDistance) then
+ local distance = #(coords - Pos)
+
+ if v.Type ~= -1 and distance < Config.DrawDistance then
sleep = 0
- DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false)
+ DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z,0.0, 0.0, 0.0, 0, 0.0, 0.0,v.Size.x, v.Size.y, v.Size.z,v.Color.r, v.Color.g, v.Color.b, 100,false, true, 2, false, false, false, false)
+ end
+
+ if distance < v.Size.x then
+ sleep = 0
+ isInMarker = true
+ currentZone = k
end
end
if CurrentTest == 'theory' then
-
sleep = 0
- DisableControlAction(0, 1, true) -- LookLeftRight
- DisableControlAction(0, 2, true) -- LookUpDown
- DisablePlayerFiring(playerPed, true) -- Disable weapon firing
- DisableControlAction(0, 142, true) -- MeleeAttackAlternate
- DisableControlAction(0, 106, true) -- VehicleMouseControlOverride
+ DisableControlAction(0, 1, true)
+ DisableControlAction(0, 2, true)
+ DisablePlayerFiring(playerPed, true)
+ DisableControlAction(0, 142, true)
+ DisableControlAction(0, 106, true)
end
if CurrentTest == 'drive' then
@@ -243,7 +215,6 @@ CreateThread(function()
if DoesBlipExist(CurrentBlip) then
RemoveBlip(CurrentBlip)
end
-
CurrentTest = nil
StopDriveTest(DriveErrors < Config.MaxErrors)
else
@@ -251,18 +222,16 @@ CreateThread(function()
if DoesBlipExist(CurrentBlip) then
RemoveBlip(CurrentBlip)
end
-
CurrentBlip = AddBlipForCoord(Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z)
- SetBlipRoute(CurrentBlip, 1)
-
+ SetBlipRoute(CurrentBlip, true)
LastCheckPoint = CurrentCheckPoint
end
-
- local Pos = vector3(Config.CheckPoints[nextCheckPoint].Pos.x,Config.CheckPoints[nextCheckPoint].Pos.y,Config.CheckPoints[nextCheckPoint].Pos.z)
+
+ local Pos = vector3(Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z)
local distance = #(coords - Pos)
-
+
if distance <= Config.DrawDistance then
- DrawMarker(1, Config.CheckPoints[nextCheckPoint].Pos.x, Config.CheckPoints[nextCheckPoint].Pos.y, Config.CheckPoints[nextCheckPoint].Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.5, 1.5, 1.5, 102, 204, 102, 100, false, true, 2, false, false, false, false)
+ DrawMarker(1, Pos.x, Pos.y, Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.5, 1.5, 1.5, 102, 204, 102, 100, false, true, 2, false, false, false, false)
end
if distance <= 3.0 then
@@ -270,33 +239,17 @@ CreateThread(function()
CurrentCheckPoint = CurrentCheckPoint + 1
end
end
- end
-
- if CurrentAction then
+ else
sleep = 0
-
- if (IsControlJustReleased(0, 38)) and (CurrentAction == 'dmvschool_menu') then
+ if IsControlJustReleased(0, 38) then
OpenDMVSchoolMenu()
ESX.HideUI()
- CurrentAction = nil
- end
- end
-
- local isInMarker = false
- local currentZone = nil
-
- for k,v in pairs(Config.Zones) do
- local Pos = vector3(v.Pos.x, v.Pos.y, v.Pos.z)
- if(#(coords - Pos) < v.Size.x) then
- sleep = 0
- isInMarker = true
- currentZone = k
end
end
if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then
HasAlreadyEnteredMarker = true
- LastZone = currentZone
+ LastZone = currentZone
TriggerEvent('esx_dmvschool:hasEnteredMarker', currentZone)
end
@@ -304,17 +257,16 @@ CreateThread(function()
HasAlreadyEnteredMarker = false
TriggerEvent('esx_dmvschool:hasExitedMarker', LastZone)
end
+
Wait(sleep)
end
end)
-
function TestFailedGoToLastCheckPoint()
CurrentCheckPoint = #Config.CheckPoints - 1
failedTest = true
end
--- Speed / Damage control
CreateThread(function()
while true do
local sleep = 1500
@@ -327,12 +279,9 @@ CreateThread(function()
local speed = GetEntitySpeed(vehicle) * Config.SpeedMultiplier
local health = GetEntityHealth(vehicle)
- -- Speed check
for k, v in pairs(Config.SpeedLimits) do
-
if CurrentZoneType == k and speed > v then
DriveErrors += 1
-
if DriveErrors <= Config.MaxErrors then
ESX.ShowNotification(TranslateCap('driving_too_fast', v))
ESX.ShowNotification(TranslateCap('errors', DriveErrors, Config.MaxErrors))
@@ -342,14 +291,12 @@ CreateThread(function()
end
end
- -- Vehicle damage check
if health < LastVehicleHealth then
DriveErrors += 1
if DriveErrors <= Config.MaxErrors then
ESX.ShowNotification(TranslateCap('you_damaged_veh'))
ESX.ShowNotification(TranslateCap('errors', DriveErrors, Config.MaxErrors))
end
-
LastVehicleHealth = health
sleep = 1500
end
diff --git a/[esx_addons]/esx_dmvschool/server/main.lua b/[esx_addons]/esx_dmvschool/server/main.lua
index d9aade16..f2b5e5df 100644
--- a/[esx_addons]/esx_dmvschool/server/main.lua
+++ b/[esx_addons]/esx_dmvschool/server/main.lua
@@ -10,20 +10,8 @@ ESX.RegisterServerCallback('esx_dmvschool:canYouPay', function(source, cb, type)
end
end)
-AddEventHandler('esx:playerLoaded', function(source)
- TriggerEvent('esx_license:getLicenses', source, function(licenses)
- TriggerClientEvent('esx_dmvschool:loadLicenses', source, licenses)
- end)
-end)
-
RegisterNetEvent('esx_dmvschool:addLicense')
AddEventHandler('esx_dmvschool:addLicense', function(type)
local source = source
-
- TriggerEvent('esx_license:addLicense', source, type, function()
- TriggerEvent('esx_license:getLicenses', source, function(licenses)
- TriggerClientEvent('esx_dmvschool:loadLicenses', source, licenses)
- end)
- end)
-end)
-
+ TriggerEvent('esx_license:addLicense', source, type)
+end)
\ No newline at end of file
From 80dc1bd84b7581be403db064afb54e6843ce1870 Mon Sep 17 00:00:00 2001
From: Rafael Antunes <147253092+Fellow1990@users.noreply.github.com>
Date: Tue, 7 Oct 2025 17:17:28 +0100
Subject: [PATCH 5/6] Update updater.lua
---
[esx_addons]/esx_dmvschool/server/updater.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/[esx_addons]/esx_dmvschool/server/updater.lua b/[esx_addons]/esx_dmvschool/server/updater.lua
index 6390522f..2a8af32d 100644
--- a/[esx_addons]/esx_dmvschool/server/updater.lua
+++ b/[esx_addons]/esx_dmvschool/server/updater.lua
@@ -38,7 +38,7 @@ VERSION = {
return
end
- local remoteVersion = response:match("version%s+'([%d%.]+)'")
+ local remoteVersion = response:match('version%s+["\']([%d%.]+)["\']')
if not remoteVersion then
DMV:ErrorHandle(Translate("errorGetRemoteVersion"))
return
From cf36fa0e18e6cb77b6c820b74ae17aca5ca84fcf Mon Sep 17 00:00:00 2001
From: Rafael Antunes <147253092+Fellow1990@users.noreply.github.com>
Date: Sat, 11 Oct 2025 18:32:50 +0100
Subject: [PATCH 6/6] Update main.lua
---
[esx_addons]/esx_dmvschool/client/main.lua | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/[esx_addons]/esx_dmvschool/client/main.lua b/[esx_addons]/esx_dmvschool/client/main.lua
index caf78965..51264d78 100644
--- a/[esx_addons]/esx_dmvschool/client/main.lua
+++ b/[esx_addons]/esx_dmvschool/client/main.lua
@@ -1,4 +1,3 @@
-local Licenses = {}
local CurrentTest = nil
local CurrentTestType = nil
local CurrentVehicle = nil
@@ -241,7 +240,7 @@ CreateThread(function()
end
else
sleep = 0
- if IsControlJustReleased(0, 38) then
+ if isInMarker and IsControlJustReleased(0, 38) then
OpenDMVSchoolMenu()
ESX.HideUI()
end