diff --git a/[esx_addons]/esx_adminmenu/client/actions.lua b/[esx_addons]/esx_adminmenu/client/actions.lua index 08f87bfb..486bae39 100644 --- a/[esx_addons]/esx_adminmenu/client/actions.lua +++ b/[esx_addons]/esx_adminmenu/client/actions.lua @@ -126,7 +126,7 @@ local function getCurrentVehicle() local vehicle = GetVehiclePedIsIn(ped, false) if vehicle == 0 or not DoesEntityExist(vehicle) then - return nil, "You must be in a vehicle." + return nil, TranslateCap("must_be_in_vehicle") end return vehicle @@ -318,7 +318,7 @@ local function applyVehicleCustomizations(vehicle, data) brakeLevel = brakeLevel, transmissionLevel = transmissionLevel, suspensionLevel = suspensionLevel, - armorLevel = armorLevel, + armorLevel = armorLevel } end @@ -330,7 +330,7 @@ local function applyVehiclePerformance(vehicle, engineLevel, brakeLevel, maxPerf suspensionLevel = maxPerformance and 5 or vehicleLevels.suspension, armorLevel = maxPerformance and 5 or vehicleLevels.armor, turbo = maxPerformance and true or nil, - maxPerformance = maxPerformance, + maxPerformance = maxPerformance }) return levels.engineLevel, levels.brakeLevel @@ -394,7 +394,7 @@ local function restoreSpectatePed() SetPlayerInvincible(PlayerId(), false) if lastCoords then - SetEntityCoords(ped, lastCoords) + SetEntityCoords(ped, lastCoords.x, lastCoords.y, lastCoords.z, false, false, false, false) end end @@ -606,7 +606,7 @@ local function nativeRevivePlayer() local coords = GetEntityCoords(ped) local heading = GetEntityHeading(ped) - NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, true, false) + NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, 0, false) ped = PlayerPedId() ClearPedTasksImmediately(ped) ClearPedBloodDamage(ped) @@ -780,7 +780,7 @@ end function ClientActions.RepairVehicle() local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) if vehicle == 0 then - return false, "You must be in a vehicle." + return false, TranslateCap("must_be_in_vehicle") end SetVehicleFixed(vehicle) @@ -794,7 +794,7 @@ end function ClientActions.CleanVehicle() local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) if vehicle == 0 then - return false, "You must be in a vehicle." + return false, TranslateCap("must_be_in_vehicle") end SetVehicleDirtLevel(vehicle, 0.0) @@ -805,7 +805,7 @@ end function ClientActions.FlipVehicle() local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) if vehicle == 0 then - return false, "You must be in a vehicle." + return false, TranslateCap("must_be_in_vehicle") end SetVehicleOnGroundProperly(vehicle) @@ -827,7 +827,7 @@ end function ClientActions.DeleteVehicle() local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) if vehicle == 0 then - return false, "You must be in a vehicle." + return false, TranslateCap("must_be_in_vehicle") end markDeletedVehicleImpounded(vehicle) @@ -848,7 +848,7 @@ function ClientActions.SpawnVehicle(data) local modelHash, err = requestModel(model, { requireVehicle = true }) if not modelHash then - return false, err or "Invalid vehicle model." + return false, err or TranslateCap("invalid_vehicle_model") end local ped = PlayerPedId() @@ -867,7 +867,7 @@ function ClientActions.SpawnVehicle(data) if not vehicle or vehicle == 0 then SetModelAsNoLongerNeeded(modelHash) - return false, "Failed to spawn vehicle." + return false, TranslateCap("failed_spawn_vehicle") end SetEntityAsMissionEntity(vehicle, true, true) @@ -875,6 +875,7 @@ function ClientActions.SpawnVehicle(data) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) SetVehRadioStation(vehicle, "OFF") + SetVehicleFuelLevel(vehicle, 100.0) local fallbackColor = trimString(data.color) if fallbackColor == "" then @@ -917,7 +918,7 @@ function ClientActions.SpawnVehicle(data) SetModelAsNoLongerNeeded(modelHash) local label = Helpers and Helpers.resolveVehicleName and Helpers.resolveVehicleName(modelHash) or model - notifyAction(("Spawned %s%s."):format(label, colorLabel and (" (" .. colorLabel .. ")") or "")) + notifyAction((TranslateCap("vehicle_spawned") .. " %s%s"):format(label, colorLabel and (" (" .. colorLabel .. ")") or "")) return true end @@ -979,7 +980,7 @@ function ClientActions.CycleVehicleColor() local presets = getColorPresets() if #presets == 0 then - return false, "No vehicle color presets configured." + return false, TranslateCap("no_vehicle_color_presets") end vehicleColorIndex = vehicleColorIndex + 1 @@ -1001,7 +1002,7 @@ function ClientActions.CycleVehicleNeonColor() local presets = getNeonPresets() if #presets == 0 then - return false, "No neon color presets configured." + return false, TranslateCap("no_neon_color_presets") end neonColorIndex = neonColorIndex + 1 @@ -1162,7 +1163,7 @@ RegisterNetEvent("esx-adminmenu:client:setModel", function(model) local modelHash, err = requestModel(model) if not modelHash then if ESX and ESX.ShowNotification then - ESX.ShowNotification(err or "Invalid model.", "error") + ESX.ShowNotification(err or TranslateCap("invalid_model"), "error") end return end @@ -1188,7 +1189,7 @@ RegisterNetEvent("esx-adminmenu:client:setRadioChannel", function(channel) end) if not ok and ESX and ESX.ShowNotification then - ESX.ShowNotification("pma-voice radio export was not available.", "error") + ESX.ShowNotification(TranslateCap("pma_voice_radio_export_info"), "error") end end) diff --git a/[esx_addons]/esx_adminmenu/client/nui.lua b/[esx_addons]/esx_adminmenu/client/nui.lua index d2d99eec..b91d3936 100644 --- a/[esx_addons]/esx_adminmenu/client/nui.lua +++ b/[esx_addons]/esx_adminmenu/client/nui.lua @@ -69,7 +69,7 @@ end local function notifyClientError(err) if ESX and ESX.ShowNotification then - ESX.ShowNotification(err or "Action failed.", "error") + ESX.ShowNotification(err or TranslateCap("action_failed"), "error") end end @@ -82,7 +82,7 @@ end local function openDashboard(cb) xLib.callback("esx-adminmenu:server:openDashboard", false, function(res) if not res or not res.success then - local err = getCallbackError(res, "You do not have permission to open the admin dashboard.") + local err = getCallbackError(res, TranslateCap("no_permission_open_dashboard")) notifyClientError(err) if cb then @@ -111,7 +111,7 @@ end local function openAdminMenu(cb) xLib.callback("esx-adminmenu:server:canOpen", false, function(res) if not res or not res.success then - local err = getCallbackError(res, "You do not have permission to open the admin menu.") + local err = getCallbackError(res, TranslateCap("no_permission_open_menu")) notifyClientError(err) if cb then @@ -159,7 +159,7 @@ end local function runProtectedClientAction(cb, label, action, permissionAction) if not permissionAction then - cb({ success = false, err = "Missing admin action permission." }) + cb({ success = false, err = TranslateCap("missing_admin_action_permission") }) return end @@ -176,7 +176,7 @@ local function runProtectedClientAction(cb, label, action, permissionAction) end if not success then - cb({ success = false, err = err or "Action failed." }) + cb({ success = false, err = err or TranslateCap("action_failed") }) return end @@ -205,7 +205,7 @@ end, false) local function runAdminCommandAction(action, handler) checkAdminAction(action, function(res) if not res or not res.success then - notifyClientError(getCallbackError(res, "You do not have permission to use this command.")) + notifyClientError(getCallbackError(res, TranslateCap("no_permission_command"))) return end @@ -218,8 +218,8 @@ local function runAdminCommandAction(action, handler) end) end -RegisterKeyMapping("adminmenu", "Open Admin Menu", "keyboard", Config.Keybinds.AdminMenu) -RegisterKeyMapping("admindashboard", "Open Admin Dashboard", "keyboard", Config.Keybinds.AdminDashboard) +RegisterKeyMapping("adminmenu", TranslateCap("open_admin_menu"), "keyboard", Config.Keybinds.AdminMenu) +RegisterKeyMapping("admindashboard", TranslateCap("open_admin_dashboard"), "keyboard", Config.Keybinds.AdminDashboard) xLib.nui.register("openDashboard", function(data, cb) openDashboard(cb) @@ -269,14 +269,32 @@ end -- reference bare. local directActions = { { name = "heal", permission = "heal", run = ClientActions.Heal }, - { name = "armor", permission = "armor", run = function() return ClientActions.SetArmor(100) end }, + { + name = "armor", + permission = "armor", + run = function() + return ClientActions.SetArmor(100) + end + }, { name = "repairVehicle", permission = "repairVehicle", run = ClientActions.RepairVehicle }, { name = "cleanVehicle", permission = "cleanVehicle", run = ClientActions.CleanVehicle }, { name = "deleteVehicle", permission = "deleteVehicle", run = ClientActions.DeleteVehicle }, { name = "waypoint", permission = "waypoint", run = ClientActions.TeleportToWaypoint }, - { name = "spawnVehicle", permission = "spawnVehicle", run = function(data) return ClientActions.SpawnVehicle(data or {}) end }, + { + name = "spawnVehicle", + permission = "spawnVehicle", + run = function(data) + return ClientActions.SpawnVehicle(data or {}) + end + }, { name = "flipVehicle", permission = "flipVehicle", run = ClientActions.FlipVehicle }, - { name = "customizeVehicle", permission = "customizeVehicle", run = function(data) return ClientActions.CustomizeVehicle(data or {}) end }, + { + name = "customizeVehicle", + permission = "customizeVehicle", + run = function(data) + return ClientActions.CustomizeVehicle(data or {}) + end + }, { name = "copyCoords", permission = "copyCoords", run = ClientActions.CopyCoords }, { name = "cycleVehicleTransmission", permission = "transmissionLevel", run = ClientActions.CycleVehicleTransmission }, { name = "cycleVehicleSuspension", permission = "suspensionLevel", run = ClientActions.CycleVehicleSuspension }, @@ -310,10 +328,8 @@ xLib.nui.register("adminMenu:setVehiclePerformance", function(data, cb) runProtectedClientAction(cb, "[esx-adminmenu:setVehiclePerformance]", function() local success, err, extra = ClientActions.SetVehiclePerformance(data or {}) if success then - sendQuickMenuState("engineLevel", true, - data and data.engineLevel and (tostring(data.engineLevel) .. "/5") or nil) - sendQuickMenuState("brakeLevel", true, - data and data.brakeLevel and (tostring(data.brakeLevel) .. "/5") or nil) + sendQuickMenuState("engineLevel", true, data and data.engineLevel and (tostring(data.engineLevel) .. "/5") or nil) + sendQuickMenuState("brakeLevel", true, data and data.brakeLevel and (tostring(data.brakeLevel) .. "/5") or nil) end return success, err, extra @@ -606,7 +622,7 @@ end) RegisterNetEvent("esx-adminmenu:client:copyToClipboard", function(text) xLib.nui.send({ action = "copyToClipboard", - data = text, + data = text }) end) @@ -616,8 +632,8 @@ RegisterNetEvent("esx-adminmenu:client:open", function(data) xLib.nui.send({ action = "openAdminDashboard", data = { - players = data or {}, - }, + players = data or {} + } }) end) @@ -634,8 +650,8 @@ RegisterNetEvent("esx-adminmenu:client:openInformation", function(data) data = { players = data.players or {}, selectedPlayerId = data.selectedPlayerId, - serverData = data.serverData, - }, + serverData = data.serverData + } }) end) diff --git a/[esx_addons]/esx_adminmenu/locales/de.lua b/[esx_addons]/esx_adminmenu/locales/de.lua new file mode 100644 index 00000000..d7c2db22 --- /dev/null +++ b/[esx_addons]/esx_adminmenu/locales/de.lua @@ -0,0 +1,372 @@ +Locales["de"] = { + -- Allgemeine UI-Texte + ["admin_menu"] = "Admin-Menü", + ["admin_dashboard"] = "Admin-Dashboard", + ["dashboard_home"] = "Startseite des Dashboards", + ["dashboard_snapshot"] = "Aktueller Server-Snapshot und Übersicht der Spielerökonomie", + ["admin_menu_desc"] = "Alles auf deinem Server verwalten", + ["quick_admin_menu"] = "Schnellmenü für Admins", + ["quick_actions"] = "Schnellaktionen", + ["open_admin_dashboard"] = "Admin-Dashboard öffnen", + ["open_admin_menu"] = "Admin-Menü öffnen", + ["admin_menu_self"] = "Selbst", + ["admin_menu_vehicle"] = "Fahrzeug", + ["admin_menu_utility"] = "Hilfsprogramme", + ["search_anything"] = "Alles suchen...", + ["server_online"] = "Server online", + ["server_uptime"] = "Betriebszeit", + ["players"] = "Spieler", + ["search_player"] = "Spieler suchen...", + ["search_vehicle"] = "Fahrzeug suchen...", + ["search_banned_identifier"] = "Bann-ID oder Banngrund suchen...", + ["player_management"] = "Spielerverwaltung", + ["players_list"] = "Spielerliste", + ["vehicles_list"] = "Fahrzeugliste", + ["player_search"] = "Spielersuche", + ["recent_players"] = "Zuletzt verwendete Spieler", + ["no_players_found"] = "Keine Spieler gefunden...", + ["bans_list"] = "Bannliste", + ["population_density"] = "Bevölkerungsdichte", + ["ped_density"] = "Fußgängerdichte", + ["vehicle_density"] = "Fahrzeugdichte", + ["random_vehicle_density"] = "Zufällige Verkehrsdichte", + ["density_override_active"] = "Aktive Überschreibung", + ["density_server_defaults"] = "Verwendung der Standardeinstellungen", + ["density_hint"] = "0 Prozent deaktiviert die Dichte; 100 Prozent verwendet die normale Dichte. Gilt für alle, auch für Spieler, die später beitreten.", + ["apply_density"] = "Dichte anwenden", + ["restore_density"] = "Standardeinstellungen wiederherstellen", + ["no_permission_open_dashboard"] = "Du hast keine Berechtigung, um das Admin-Dashboard zu öffnen.", + ["no_permission_open_menu"] = "Du hast keine Berechtigung, um das Admin-Menü zu öffnen.", + + -- Spielerdaten-Titel + ["id"] = "ID", + ["name"] = "Name", + ["money"] = "Bargeld", + ["total_money"] = "Gesamtgeld", + ["avg_money"] = "Durchschnittliches Geld", + ["avg_money_per_player"] = "Durchschnittliches Geld pro Spieler", + ["active_staff"] = "Aktives Teammitglied", + ["non_staff"] = "Kein-Teammitglied", + ["available_slots"] = "Verfügbare Slots", + ["money_distribution"] = "Geldverteilung", + ["economy_summary"] = "Wirtschaftsübersicht", + ["median_money"] = "Mediangeld", + ["richest_player"] = "Reichster Spieler", + ["avg_money_breakdown"] = "Durchschnittliche Geldaufschlüsselung", + ["health_distribution"] = "Gesundheitszustand Verteilung", + ["avg_health"] = "Durchschnittliche Gesundheit", + ["avg_armor"] = "Durchschnittliche Rüstung", + ["player_counts"] = "Spieleranzahl", + ["player_condition"] = "Spielerzustand", + ["staff_overview"] = "Teamübersicht", + ["active_player_job_distribution"] = "Verteilung der aktiven Spielerberufe", + ["top_jobs"] = "Beliebteste Berufe", + ["wealth_bands"] = "Vermögensstufen", + ["bank_money"] = "Bankguthaben", + ["black_money"] = "Schwarzgeld", + ["health"] = "Gesundheit", + ["armor"] = "Rüstung", + ["last_visited"] = "Zuletzt besucht", + ["gender"] = "Geschlecht", + ["male"] = "Männlich", + ["female"] = "Weiblich", + ["job"] = "Beruf", + ["job_grade"] = "Berufsbezeichnung", + ["identifier"] = "Kennung", + ["ip_address"] = "IP-Adresse", + ["char_identifier"] = "Zeichenkennung", + ["play_time"] = "Spielzeit", + ["position"] = "Position", + ["identifiers"] = "Kennungen", + ["routing_bucket"] = "Dimension", + ["radio_channel"] = "Funkkanal", + ["thirst"] = "Durst", + ["hunger"] = "Hunger", + + -- Aktionen & Sonstiges + ["player_information"] = "Spielerinformationen", + ["information"] = "Informationen", + ["teleport"] = "Teleportieren", + ["bring"] = "Bringen", + ["spectate"] = "Zuschauen", + ["notify_player"] = "Spieler benachrichtigen", + ["notification_message"] = "Nachricht", + ["give_money"] = "Geld geben", + ["take_money"] = "Geld nehmen", + ["set_health"] = "Gesundheit festlegen", + ["set_armor"] = "Rüstung festlegen", + ["clean_inventory"] = "Inventar leeren", + ["player_tools"] = "Spielerwerkzeuge", + ["kill_player"] = "Spieler töten", + ["revive_player"] = "Spieler wiederbeleben", + ["freeze_player"] = "Spieler einfrieren", + ["unfreeze_player"] = "Spieler auftauen", + ["set_model"] = "Modell festlegen", + ["open_clothing"] = "Kleidung öffnen", + ["give_all_weapons"] = "Alle Waffen geben", + ["set_bucket"] = "Dimension festlegen", + ["set_radio"] = "Funkkanal festlegen", + ["set_job"] = "Beruf festlegen", + ["set_name"] = "Name festlegen", + ["set_thirst"] = "Durst festlegen", + ["set_hunger"] = "Hunger festlegen", + ["ace_add"] = "ACE-Gruppe hinzufügen", + ["ace_remove"] = "ACE-Gruppe entfernen", + ["model_name"] = "Modellname", + ["ace_group"] = "ACE-Gruppe", + ["first_name"] = "Vorname", + ["last_name"] = "Nachname", + ["delete_character"] = "Charakter löschen", + ["troll_options"] = "Troll-Optionen", + ["troll_burn"] = "Verbrennen", + ["troll_explode"] = "Explodieren", + ["troll_sky"] = "Zum Himmel teleportieren", + ["troll_random"] = "Zufällige Teleportation", + ["troll_nausea"] = "Übelkeit", + ["noclip"] = "NoClip", + ["show_names"] = "Namen anzeigen", + ["show_blips"] = "Blips anzeigen", + ["godmode"] = "Unbesiegbar", + ["invisible"] = "Unsichtbar", + ["infinite_ammo"] = "Unendlich Munition", + ["revive"] = "Wiederbeleben", + ["heal"] = "Heilen", + ["spawn_vehicle"] = "Fahrzeug spawnen", + ["vehicle_spawner"] = "Fahrzeug-Spawner", + ["vehicle_model"] = "Fahrzeugmodell", + ["vehicle_color"] = "Fahrzeugfarbe", + ["primary_color"] = "Primärfarbe", + ["secondary_color"] = "Sekundärfarbe", + ["customize_vehicle"] = "Fahrzeug anpassen", + ["customize_vehicle_hint"] = "Verwende die Pfeiltasten links und rechts, um die Fahrzeugstufen zu ändern.", + ["spawn_tuned"] = "Getuntes Fahrzeug spawnen", + ["engine_level"] = "Motor", + ["brake_level"] = "Bremsen", + ["transmission_level"] = "Getriebe", + ["suspension_level"] = "Federung", + ["vehicle_armor"] = "Fahrzeugpanzerung", + ["turbo"] = "Turbo", + ["xenon_lights"] = "Xenon", + ["neon_lights"] = "Neon", + ["neon_color"] = "Neonfarbe", + ["window_tint"] = "Scheibentönung", + ["wheel_category"] = "Felgenkategorie", + ["wheel_design"] = "Felgendesign", + ["bulletproof_tires"] = "Kugelsichere Reifen", + ["apply_performance"] = "Leistungssteigerung anwenden", + ["apply_customization"] = "Anpassung anwenden", + ["max_performance"] = "Maximale Leistung", + ["repair_vehicle"] = "Fahrzeug reparieren", + ["clean_vehicle"] = "Fahrzeug reinigen", + ["flip_vehicle"] = "Fahrzeug umdrehen", + ["teleport_waypoint"] = "Zum Wegpunkt teleportieren", + ["copy_coords"] = "Koordinaten kopieren", + ["delete_current_vehicle"] = "Fahrzeug löschen", + ["quick_menu_hint"] = "Pfeiltasten bewegen, Enter rennen, Rücktaste schließen.", + ["quick_menu_edit_hint"] = "Hoch/Runter bewegen, Links/Rechts Werte ändern, Enter auswählen.", + ["back"] = "Zurück", + ["kick"] = "Kick", + ["ban"] = "Bann", + ["never"] = "Nie", + ["copied_to_clipboard"] = "In die Zwischenablage kopiert", + ["online"] = "Online", + ["offline"] = "Offline", + ["on"] = "An", + ["off"] = "Aus", + ["player"] = "Spieler:", + ["reason"] = "Grund", + ["kick_reason_placeholder"] = "Kick-Grund eingeben.", + ["ban_reason_placeholder"] = "Bann-Grund eingeben", + ["duration"] = "Dauer", + ["minutes"] = "Minuten", + ["hours"] = "Stunden", + ["days"] = "Tage", + ["months"] = "Monate", + ["years"] = "Jahre", + ["permanent"] = "Permanent", + ["duration_desc"] = "Wenn keine Dauer angegeben wird, wird der Benutzer dauerhaft gebannt.", + ["cancel"] = "Abbrechen", + ["confirm"] = "Bestätigen", + ["escape_spectate"] = "Drücke [ESC], um das Zuschauen zu beenden", + ["default_ban"] = "Du wurdest von diesem Server gebannt!", + ["finalizing_connection"] = "Verbinde...", + ["action_failed"] = "Aktion fehlgeschlagen.", + ["invalid_model"] = "Ungültiges Modell.", + ["invalid_vehicle_model"] = "Ungültiges Fahrzeugmodell.", + ["failed_spawn_vehicle"] = "Fahrzeug konnte nicht gespawnt werden.", + ["vehicle_spawned"] = "Fahrzeug gespawnt:", + ["no_vehicle_color_presets"] = "Es sind keine Fahrzeugfarben-Voreinstellungen konfiguriert.", + ["no_neon_color_presets"] = "Es sind keine Neonfarben-Voreinstellungen konfiguriert.", + ["pma_voice_radio_export_info"] = "Der Funk-Export von pma-voice ist nicht verfügbar.", + ["missing_admin_action_permission"] = "Fehlende Adminaktion-Berechtigung.", + + -- Bannverwaltung + ["banned_by"] = "Gebannt von", + ["banned_at"] = "Gebannt am", + ["expires_at"] = "Gültig bis", + ["change_expiry"] = "Ablaufdatum ändern", + ["revoke"] = "Bann aufheben", + ["new_expiry_date"] = "Neues Ablaufdatum", + + -- Fahrzeuge + ["plate"] = "Kennzeichen", + ["owner"] = "Besitzer", + ["vehicle_name"] = "Fahrzeugname", + ["vehicle_type"] = "Fahrzeugtyp", + ["mileage"] = "Kilometerstand", + ["impounded"] = "Beschlagnahmt", + ["copy_plate"] = "Kennzeichen kopieren", + ["copy_owner"] = "Besitzer kopieren", + ["impound"] = "Beschlagnahmen", + ["unimpound"] = "Beschlagnahmung aufheben", + ["delete_vehicle"] = "Fahrzeug löschen", + ["select_impound"] = "Beschlagnahmtes Fahrzeug auswählen", + + -- Admin-Aktionsprotokoll + ["admin_logs"] = "Admin-Protokolle", + ["all_categories"] = "Alle Kategorien", + ["player_actions"] = "Spieleraktionen", + ["server_management"] = "Serververwaltung", + ["moderation"] = "Moderation", + ["last_24h"] = "Letzte 24 Stunden", + ["last_7_days"] = "Letzte 7 Tage", + ["last_30_days"] = "Letzte 30 Tage", + ["search_logs"] = "Suche Protokolle...", + ["date"] = "Datum", + ["admin"] = "Admin", + ["action"] = "Aktion", + ["target"] = "Ziel", + ["result"] = "Ergebnis", + ["details"] = "Details", + ["success"] = "Erfolgreich", + ["failed"] = "Fehlgeschlagen", + ["loading"] = "Wird geladen...", + ["load_more"] = "Mehr laden", + ["more_info"] = "Weitere Informationen", + ["hide_details"] = "Details ausblenden", + ["no_logs_found"] = "Keine Protokolle gefunden", + + -- Serverseitige Fehlermeldungen + ["insufficient_permissions"] = "Unzureichende Berechtigungen.", + ["player_not_online"] = "Spieler ist nicht online", + ["invalid_action"] = "Ungültige Admin-Aktion.", + ["amount_must_be_positive"] = "Betrag muss größer als 0 sein.", + ["must_be_in_vehicle"] = "Du musst in einem Fahrzeug sein.", + ["no_permission_command"] = "Du hast keine Berechtigung, für diesen Befehl.", + ["database_unavailable"] = "Datenbank nicht verfügbar.", + ["cannot_spectate_yourself"] = "Du kannst dir nicht selbst zusehen!", + ["cannot_kick_yourself"] = "Du kannst dich nicht selbst kicken!", + ["cannot_ban_yourself"] = "Du kannst dich nicht selbst bannen!", + ["kicked_by_admin"] = "Von einem Admin gekickt", + ["banned_by_admin"] = "Von einem Admin gebannt", + ["missing_player_license_id"] = "Fehlende Spielerlizenzkennung.", + ["failed_persist_ban"] = "Permanenter-Bann fehlgeschlagen", + ["invalid_identifier"] = "Ungültige Kennung", + ["invalid_expiry_date"] = "Ungültiges Ablaufdatum.", + ["failed_update_ban_expiry"] = "Ändern des Bann-Ablaufdatums fehlgeschlagen.", + ["failed_revoke_ban"] = "Bann-Aufhebung fehlgeschlagen.", + ["missing_plate"] = "Fehlendes Kennzeichen", + ["invalid_impound"] = "Ungültige Beschlagnahmung", + ["failed_impound_vehicle"] = "Fahrzeug-Beschlagnahmung fehlgeschlagen.", + ["vehicle_not_found"] = "Fahrzeug nicht gefunden.", + ["notification_by_admin"] = "Benachrichtigung von einem Admin", + ["unknown_self_action"] = "Unbekannte Selbstaktion.", + ["invalid_population_density"] = "Ungültige Bevölkerungsdichte.", + ["admin_not_found"] = "Admin nicht gefunden.", + ["unknown_server_action"] = "Unbekannte Serveraktion.", + ["action_permission_not_configured"] = "Aktionsberechtigung nicht konfiguriert.", + ["version_not_expose"] = "Diese ESX-Version stellt nicht bereit:", + ["failed_update_balance"] = "Kontostand konnte nicht aktualisiert werden.", + ["missing_character_identifier"] = "Fehlendes Kennungszeichen.", + ["identifier_not_match"] = "Die Charakterkennung stimmt nicht mit dem ausgewählten Spieler überein.", + ["character_deleted_by_admin"] = "Charakter wurde von einem Admin gelöscht.", + ["failed_read_inventory"] = "Fehler beim Lesen des Inventars.", + ["missing_model"] = "Fehlendes Modell.", + ["missing_job_name"] = "Fehlender Jobname.", + ["invalid_job_or_grade"] = "Ungültiger Job oder Rang.", + ["failed_set_job"] = "Fehler beim Ändern des Jobs.", + ["missing_first_or_last_name"] = "Fehlender Vor- oder Nachname.", + ["invalid_ace_group"] = "Ungültige ACE-Gruppe", + ["ace_group_not_allowed"] = "ACE-Gruppe nicht erlaubt.", + ["missing_player_identifier"] = "Fehlende Spielerkennung.", + ["invalid_troll_action"] = "Ungültige Trollaktion.", + ["unknown_player_action"] = "Unbekannte Spieleraktion.", + ["invalid_admin_action"] = "Ungültige Adminaktion.", + ["enter_valid_radio_channel"] = "Gebe einen gültigen Funkkanal ein.", + ["search_rate_limited"] = "Suchrate ist begrenzt.", + + -- Serverseitige Befehle + ["invalid_player"] = "Ungültiger Spieler.", + ["failed_get_player_ped"] = "Spieler-Ped konnte nicht abgerufen werden.", + ["no_permission_open_player_info"] = "Du hast keine Berechtigung, um Spielerinformationen zu öffnen.", + ["open_admin_dashboard_player_info"] = "Öffne das Admin-Dashboard und gelange direkt zu den Spielerinformationen.", + ["target_player_id"] = "Zielspieler-ID", + ["no_permission_refresh_ban_cache"] = "Du hast keine Berechtigung, um den Bann-Cache zu aktualisieren.", + ["refreshes_ban_cache"] = "Aktualisiert den Bann-Cache, falls manuelle Änderungen an der Datenbank vorgenommen wurden.", + ["no_permission_save_admin_vehicles"] = "Du hast keine Berechtigung, um Adminfahrzeuge zu speichern.", + ["must_be_driver"] = "Du musst der Fahrer sein.", + ["failed_get_vehicle_properties"] = "Fahrzeugeigenschaften konnten nicht abgerufen werden.", + ["generated_plate_already_taken"] = "Das generierte Kennzeichen ist bereits vergeben. Bitte versuche es erneut.", + ["failed_validate_vehicle_model"] = "Fahrzeugmodell konnte nicht validiert werden.", + ["vehicle_properties_too_large"] = "Fahrzeugeigenschaften sind zu groß.", + ["vehicle_registered_to_you"] = "Das Fahrzeug ist auf dich zugelassen.", + ["spawn_and_own_or_register_vehicle"] = "Spawne und besitze ein Fahrzeug oder registriere das Fahrzeug, das du fährst.", + ["vehicle_model_to_spawn"] = "Fahrzeugmodell zum Spawnen (optional)", + ["change_player_model"] = "Das Spielermodell ändern.", + ["teleport_to_player"] = "Teleportiere dich zu einem Spieler.", + ["bring_player_to_you"] = "Teleportiere einen Spieler zu dir.", + ["spectate_player"] = "Einen Spieler beobachten.", + ["stop_spectating"] = "Beobachten beenden", + + ["kick_player"] = "Einen Spieler kicken.", + ["kick_reason"] = "Grund für den Kick", + + ["ban_player"] = "Einen Spieler bannen.", + ["duration_in_minutes"] = "Dauer in Minuten", + ["ban_reason"] = "Grund für den Bann", + + ["send_notification_to_player"] = "Sende eine Benachrichtigung an einen Spieler.", + ["notification_type"] = "Benachrichtigungs-Typ (info, error, success)", + ["duration_in_ms"] = "Dauer in ms", + ["notification_title"] = "Benachrichtigungs-Title", + + ["copy_position_as_vec2"] = "Kopiere deine aktuelle Position als vec2(x, y).", + ["copy_position_as_vec3"] = "Kopiere deine aktuelle Position als vec3(x, y, z).", + ["copy_position_as_vec4"] = "Kopiere deine aktuelle Position als vec4(x, y, z, heading).", + ["copy_heading"] = "Kopiere deinen aktuellen Blickwinkel.", + ["copy_coords_and_heading"] = "Kopiere deine aktuellen Koordinaten und den Blickwinkel.", + ["copy_rotation"] = "Kopiere deine aktuelle Rotation als vec3(x, y, z).", + ["copy_ped_or_vehicle_model"] = "Kopiere den Hash deines aktuellen Peds- oder Fahrzeugmodells.", + ["copy_vehicle_plate"] = "Kopiere das aktuelle Fahrzeug-Kennzeichen.", + + -- Fahrzeugspawner Farben + ["black"] = "Schwarz", + ["white"] = "Weiß", + ["silver"] = "Silber", + ["red"] = "Rot", + ["orange"] = "Orange", + ["yellow"] = "Gelb", + ["green"] = "Grün", + ["blue"] = "Blau", + ["purple"] = "Lila", + + -- Fahrzeugspawner Fenstertönung + ["none"] = "Keine", + ["pure_black"] = "Reines Schwarz", + ["dark_smoke"] = "Dunkles Rauchglas", + ["light_smoke"] = "Helles Rauchglas", + ["stock"] = "Standard", + ["limo"] = "Limousine", + + -- Fahrzeugspawner Rad Kategorien + ["sport"] = "Sport", + ["muscle"] = "Muscle", + ["lowrider"] = "Lowrider", + ["suv"] = "SUV", + ["offroad"] = "Gelände", + ["tuner"] = "Tuning", + ["bike"] = "Motorrad", + ["highend"] = "Luxus", + ["street"] = "Straße", + ["track"] = "Rennen", +} diff --git a/[esx_addons]/esx_adminmenu/locales/en.lua b/[esx_addons]/esx_adminmenu/locales/en.lua index 7263b7cd..d2f9cdbc 100644 --- a/[esx_addons]/esx_adminmenu/locales/en.lua +++ b/[esx_addons]/esx_adminmenu/locales/en.lua @@ -35,9 +35,11 @@ Locales["en"] = { ["random_vehicle_density"] = "Random Traffic Density", ["density_override_active"] = "Override active", ["density_server_defaults"] = "Using server defaults", - ["density_hint"] = "0% disables new population; 100% uses normal density. Applies to everyone, including players joining later.", + ["density_hint"] = "0 percent disables new population; 100 percent uses normal density. Applies to everyone, including players joining later.", ["apply_density"] = "Apply Density", ["restore_density"] = "Restore Server Defaults", + ["no_permission_open_dashboard"] = "You do not have permission to open the admin dashboard.", + ["no_permission_open_menu"] = "You do not have permission to open the admin menu.", -- Player Data Titles ["id"] = "ID", @@ -191,6 +193,15 @@ Locales["en"] = { ["escape_spectate"] = "Press [ESC] to stop spectating", ["default_ban"] = "You are banned from this server!", ["finalizing_connection"] = "Finalizing connection...", + ["action_failed"] = "Action failed.", + ["invalid_model"] = "Invalid model.", + ["invalid_vehicle_model"] = "Invalid vehicle model.", + ["failed_spawn_vehicle"] = "Failed to spawn vehicle.", + ["vehicle_spawned"] = "Vehicle spawned:", + ["no_vehicle_color_presets"] = "No vehicle color presets configured.", + ["no_neon_color_presets"] = "No neon color presets configured.", + ["pma_voice_radio_export_info"] = "pma-voice radio export was not available.", + ["missing_admin_action_permission"] = "Missing admin action permission.", -- Ban Management ["banned_by"] = "Banned By", @@ -246,4 +257,119 @@ Locales["en"] = { ["must_be_in_vehicle"] = "You must be in a vehicle.", ["no_permission_command"] = "You do not have permission to use this command.", ["database_unavailable"] = "Database unavailable.", + ["cannot_spectate_yourself"] = "You cannot spectate yourself!", + ["cannot_kick_yourself"] = "You cannot kick yourself!", + ["cannot_ban_yourself"] = "You cannot ban yourself!", + ["kicked_by_admin"] = "Kicked by admin", + ["banned_by_admin"] = "Banned by admin", + ["missing_player_license_id"] = "Missing player license identifier.", + ["failed_persist_ban"] = "Failed to persist ban", + ["invalid_identifier"] = "Invalid identifier", + ["invalid_expiry_date"] = "Invalid expiry date.", + ["failed_update_ban_expiry"] = "Failed to update ban expiry.", + ["failed_revoke_ban"] = "Failed to revoke ban.", + ["missing_plate"] = "Missing plate", + ["invalid_impound"] = "Invalid impound.", + ["failed_impound_vehicle"] = "Failed to impound vehicle.", + ["vehicle_not_found"] = "Vehicle not found.", + ["notification_by_admin"] = "Notification by admin", + ["unknown_self_action"] = "Unknown self action.", + ["invalid_population_density"] = "Invalid population density.", + ["admin_not_found"] = "Admin not found.", + ["unknown_server_action"] = "Unknown server action.", + ["action_permission_not_configured"] = "Action permission not configured.", + ["version_not_expose"] = "This ESX version does not expose", + ["failed_update_balance"] = "Failed to update balance.", + ["missing_character_identifier"] = "Missing character identifier.", + ["identifier_not_match"] = "Character identifier does not match the selected player.", + ["character_deleted_by_admin"] = "Character deleted by an admin.", + ["failed_read_inventory"] = "Failed to read inventory.", + ["missing_model"] = "Missing model.", + ["missing_job_name"] = "Missing job name.", + ["invalid_job_or_grade"] = "Invalid job or grade.", + ["failed_set_job"] = "Failed to set job.", + ["missing_first_or_last_name"] = "Missing first or last name.", + ["invalid_ace_group"] = "Invalid ACE group.", + ["ace_group_not_allowed"] = "ACE group not allowed.", + ["missing_player_identifier"] = "Missing player identifier.", + ["invalid_troll_action"] = "Invalid troll action.", + ["unknown_player_action"] = "Unknown player action.", + ["invalid_admin_action"] = "Invalid admin action.", + ["enter_valid_radio_channel"] = "Enter a valid radio channel.", + ["search_rate_limited"] = "Search rate limited.", + + -- Server-facing commands + ["invalid_player"] = "Invalid player.", + ["failed_get_player_ped"] = "Failed to get player ped.", + ["no_permission_open_player_info"] = "You do not have permission to open player information.", + ["open_admin_dashboard_player_info"] = "Open the admin dashboard directly to a player's information panel.", + ["target_player_id"] = "Target player ID", + ["no_permission_refresh_ban_cache"] = "You do not have permission to refresh the ban cache.", + ["refreshes_ban_cache"] = "Refreshes the ban cache if manual changes were made to the database.", + ["no_permission_save_admin_vehicles"] = "You do not have permission to save admin vehicles.", + ["must_be_driver"] = "You must be the driver.", + ["failed_get_vehicle_properties"] = "Failed to get vehicle properties.", + ["generated_plate_already_taken"] = "Generated plate was already taken. Try again.", + ["failed_validate_vehicle_model"] = "Failed to validate vehicle model.", + ["vehicle_properties_too_large"] = "Vehicle properties are too large.", + ["vehicle_registered_to_you"] = "Vehicle registered to you.", + ["spawn_and_own_or_register_vehicle"] = "Spawn and own a vehicle, or register the vehicle you are driving.", + ["vehicle_model_to_spawn"] = "Vehicle model to spawn (optional)", + ["change_player_model"] = "Change a player's model.", + ["teleport_to_player"] = "Teleport to a player.", + ["bring_player_to_you"] = "Bring a player to you.", + ["spectate_player"] = "Spectate a player.", + ["stop_spectating"] = "Stop spectating.", + + ["kick_player"] = "Kick a player.", + ["kick_reason"] = "Reason for kick", + + ["ban_player"] = "Ban a player.", + ["duration_in_minutes"] = "Duration in minutes", + ["ban_reason"] = "Reason for Ban", + + ["send_notification_to_player"] = "Send a notification to a player.", + ["notification_type"] = "Notification type (info, error, success)", + ["duration_in_ms"] = "Duration in ms", + ["notification_title"] = "Notification title", + + ["copy_position_as_vec2"] = "Copy your current position as vec2(x, y).", + ["copy_position_as_vec3"] = "Copy your current position as vec3(x, y, z).", + ["copy_position_as_vec4"] = "Copy your current position as vec4(x, y, z, heading).", + ["copy_heading"] = "Copy your current heading.", + ["copy_coords_and_heading"] = "Copy your current coordinates and heading as fields.", + ["copy_rotation"] = "Copy your current rotation as vec3(x, y, z).", + ["copy_ped_or_vehicle_model"] = "Copy your current ped or vehicle model hash.", + ["copy_vehicle_plate"] = "Copy the current vehicle plate.", + + -- Vehice spawner colors + ["black"] = "Black", + ["white"] = "White", + ["silver"] = "Silver", + ["red"] = "Red", + ["orange"] = "Orange", + ["yellow"] = "Yellow", + ["green"] = "Green", + ["blue"] = "Blue", + ["purple"] = "Purple", + + -- Vehicle spawner window tints + ["none"] = "None", + ["pure_black"] = "Pure Black", + ["dark_smoke"] = "Dark Smoke", + ["light_smoke"] = "Light Smoke", + ["stock"] = "Stock", + ["limo"] = "Limo", + + -- Vehicle spawner wheel categorys + ["sport"] = "Sport", + ["muscle"] = "Muscle", + ["lowrider"] = "Lowrider", + ["suv"] = "SUV", + ["offroad"] = "Offroad", + ["tuner"] = "Tuner", + ["bike"] = "Bike", + ["highend"] = "High End", + ["street"] = "Street", + ["track"] = "Track", } diff --git a/[esx_addons]/esx_adminmenu/server/actions.lua b/[esx_addons]/esx_adminmenu/server/actions.lua index 39d4865d..df630888 100644 --- a/[esx_addons]/esx_adminmenu/server/actions.lua +++ b/[esx_addons]/esx_adminmenu/server/actions.lua @@ -351,7 +351,7 @@ function Actions.Goto(src, data) data = data or {} if not Helpers.hasFeaturePermission(src, 'playerTeleport') then - return { success = false, err = 'Insufficient Permissions', playerOnline = true } + return { success = false, err = TranslateCap('insufficient_permissions'), playerOnline = true } end local targetId = getTargetId(data) @@ -409,17 +409,17 @@ function Actions.Spectate(src, data) data = data or {} if not Helpers.hasFeaturePermission(src, 'spectate') then - return { success = false, err = 'Insufficient Permissions', playerOnline = true, isAdmin = false } + return { success = false, err = TranslateCap('insufficient_permissions'), playerOnline = true, isAdmin = false } end local targetId = getTargetId(data) if not Helpers.isOnline(targetId) then - return { success = false, err = 'Player Not Online', playerOnline = false, isAdmin = true } + return { success = false, err = TranslateCap('player_not_online'), playerOnline = false, isAdmin = true } end if targetId == src then - return { success = false, err = 'You cannot spectate yourself.', playerOnline = true, isAdmin = true } + return { success = false, err = TranslateCap('cannot_spectate_yourself'), playerOnline = true, isAdmin = true } end local targetPed = GetPlayerPed(targetId) @@ -437,7 +437,7 @@ end) function Actions.StopSpectate(src) if not Helpers.hasFeaturePermission(src, 'spectate') then - return { success = false, err = 'Insufficient Permissions' } + return { success = false, err = TranslateCap('insufficient_permissions') } end Helpers.stopSpectate(src) @@ -454,20 +454,20 @@ function Actions.Kick(src, data) data = data or {} if not Helpers.hasFeaturePermission(src, 'playerModeration') then - return { success = false, err = 'Insufficient Permissions', playerOnline = true, isAdmin = false } + return { success = false, err = TranslateCap('insufficient_permissions'), playerOnline = true, isAdmin = false } end local targetId = getTargetId(data) if not Helpers.isOnline(targetId) then - return { success = false, err = 'Player Not Online', playerOnline = false, isAdmin = true } + return { success = false, err = TranslateCap('player_not_online'), playerOnline = false, isAdmin = true } end if targetId == src then - return { success = false, err = 'You cannot kick yourself.', playerOnline = true, isAdmin = true } + return { success = false, err = TranslateCap('cannot_kick_yourself'), playerOnline = true, isAdmin = true } end - local reason = limitString(data.reason, getLimits().MaxReasonLength, 'Kicked by admin') + local reason = limitString(data.reason, getLimits().MaxReasonLength, TranslateCap('kicked_by_admin')) -- Queued, not written inline: the drop must not wait on the database. -- Recorded before DropPlayer so the target is still resolvable. @@ -493,23 +493,23 @@ function Actions.Ban(src, data) data = data or {} if not Helpers.hasFeaturePermission(src, 'banManagement') then - return { success = false, err = 'Insufficient Permissions', playerOnline = true, isAdmin = false } + return { success = false, err = TranslateCap('insufficient_permissions'), playerOnline = true, isAdmin = false } end local targetId = getTargetId(data) if not Helpers.isOnline(targetId) then - return { success = false, err = 'Player Not Online', playerOnline = false, isAdmin = true } + return { success = false, err = TranslateCap('player_not_online'), playerOnline = false, isAdmin = true } end if targetId == src then - return { success = false, err = 'You cannot ban yourself.', playerOnline = true, isAdmin = true } + return { success = false, err = TranslateCap('cannot_ban_yourself'), playerOnline = true, isAdmin = true } end local identifier = Helpers.getPlayerLicenseIdentifier(targetId) if not identifier then - return { success = false, err = 'Missing player license identifier.', playerOnline = true, isAdmin = true } + return { success = false, err = TranslateCap('missing_player_license_id'), playerOnline = true, isAdmin = true } end -- Capture every enabled identifier so the ban matches on reconnect even if @@ -520,13 +520,13 @@ function Actions.Ban(src, data) local seconds = duration and (os.time() + duration * 60) or nil local bannedAt = os.time() local adminName = GetPlayerName(src) - local reason = limitString(data.reason, getLimits().MaxReasonLength, 'Banned by admin') + local reason = limitString(data.reason, getLimits().MaxReasonLength, TranslateCap('banned_by_admin')) local ok, banId = pcall(insertBan, identifier, reason, adminName, seconds, bannedAt, banIdentifiers) if not ok or not banId then print(('[esx-adminmenu] Failed to persist ban for %s: %s'):format(tostring(identifier), tostring(banId))) - return { success = false, err = 'Failed to persist ban.', playerOnline = true, isAdmin = true } + return { success = false, err = TranslateCap('failed_persist_ban'), playerOnline = true, isAdmin = true } end BanCache.add({ @@ -560,7 +560,7 @@ end) Helpers.registerCallback('esx-adminmenu:server:ban:offline', function(source, data) if not Helpers.hasFeaturePermission(source, 'banManagement') then - return { success = false, err = 'Insufficient Permissions', isAdmin = false } + return { success = false, err = TranslateCap('insufficient_permissions'), isAdmin = false } end data = data or {} @@ -568,14 +568,14 @@ Helpers.registerCallback('esx-adminmenu:server:ban:offline', function(source, da local normalizedIdentifier = Helpers.normalizeLicenseIdentifier(data.identifier) if not normalizedIdentifier then - return { success = false, err = 'Invalid Identifier', isAdmin = true } + return { success = false, err = TranslateCap('invalid_identifier'), isAdmin = true } end local duration = normalizeBanDuration(data.duration) local seconds = duration and (os.time() + duration * 60) or nil local bannedAt = os.time() local adminName = GetPlayerName(source) - local reason = limitString(data.reason, getLimits().MaxReasonLength, 'Banned by admin') + local reason = limitString(data.reason, getLimits().MaxReasonLength, TranslateCap('banned_by_admin')) -- Offline bans are single-identifier by design: the player is not connected, -- so their other identifiers (discord, steam, ...) cannot be read, and ESX @@ -584,7 +584,7 @@ Helpers.registerCallback('esx-adminmenu:server:ban:offline', function(source, da if not ok or not banId then print(('[esx-adminmenu] Failed to persist offline ban for %s: %s'):format(tostring(normalizedIdentifier), tostring(banId))) - return { success = false, err = 'Failed to persist ban.', isAdmin = true } + return { success = false, err = TranslateCap('failed_persist_ban'), isAdmin = true } end BanCache.add({ @@ -611,7 +611,7 @@ end) Helpers.registerCallback('esx-adminmenu:server:ban:changeExpiry', function(source, data) if not Helpers.hasFeaturePermission(source, 'banManagement') then - return { success = false, err = 'Insufficient Permissions', isAdmin = false } + return { success = false, err = TranslateCap('insufficient_permissions'), isAdmin = false } end data = data or {} @@ -619,7 +619,7 @@ Helpers.registerCallback('esx-adminmenu:server:ban:changeExpiry', function(sourc local normalizedIdentifier = Helpers.normalizeLicenseIdentifier(data.identifier) if not normalizedIdentifier then - return { success = false, err = 'Invalid Identifier', isAdmin = true } + return { success = false, err = TranslateCap('invalid_identifier'), isAdmin = true } end local seconds = nil @@ -628,7 +628,7 @@ Helpers.registerCallback('esx-adminmenu:server:ban:changeExpiry', function(sourc local newDate = tonumber(data.newDate) if not newDate then - return { success = false, err = 'Invalid expiry date.', isAdmin = true } + return { success = false, err = TranslateCap('invalid_expiry_date'), isAdmin = true } end local now = os.time() @@ -652,7 +652,7 @@ Helpers.registerCallback('esx-adminmenu:server:ban:changeExpiry', function(sourc end) if not ok then - return { success = false, err = 'Failed to update ban expiry.', isAdmin = true } + return { success = false, err = TranslateCap('failed_update_ban_expiry'), isAdmin = true } end Logs.record({ @@ -670,7 +670,7 @@ end) Helpers.registerCallback('esx-adminmenu:server:ban:revoke', function(source, data) if not Helpers.hasFeaturePermission(source, 'banManagement') then - return { success = false, err = 'Insufficient Permissions', isAdmin = false } + return { success = false, err = TranslateCap('insufficient_permissions'), isAdmin = false } end data = data or {} @@ -678,7 +678,7 @@ Helpers.registerCallback('esx-adminmenu:server:ban:revoke', function(source, dat local normalizedIdentifier = Helpers.normalizeLicenseIdentifier(data.identifier) if not normalizedIdentifier then - return { success = false, err = 'Invalid Identifier', isAdmin = true } + return { success = false, err = TranslateCap('invalid_identifier'), isAdmin = true } end local ok = pcall(function() @@ -687,7 +687,7 @@ Helpers.registerCallback('esx-adminmenu:server:ban:revoke', function(source, dat end) if not ok then - return { success = false, err = 'Failed to revoke ban.', isAdmin = true } + return { success = false, err = TranslateCap('failed_revoke_ban'), isAdmin = true } end Logs.record({ @@ -704,7 +704,7 @@ end) local function vehicleUpdate(source, data, queryTemplate, params, feature) if not Helpers.hasFeaturePermission(source, feature or 'vehicleManagement') then - return { success = false, err = 'Insufficient Permissions' } + return { success = false, err = TranslateCap('insufficient_permissions') } end data = data or {} @@ -713,7 +713,7 @@ local function vehicleUpdate(source, data, queryTemplate, params, feature) local plate = normalizePlate(data.plate) if not plate then - return { success = false, err = 'Missing plate' } + return { success = false, err = TranslateCap('missing_plate') } end local condition, plateParams = plateCondition(plate) @@ -751,7 +751,7 @@ local function setVehicleImpounded(plate, impoundName) end if not impoundName then - return { success = false, err = 'Invalid impound.' } + return { success = false, err = TranslateCap('invalid_impound') } end local condition, plateParams = plateCondition(plate) @@ -762,11 +762,11 @@ local function setVehicleImpounded(plate, impoundName) local affected = Helpers.safeUpdate(('UPDATE owned_vehicles SET stored = 1, parking = NULL, pound = ? WHERE %s'):format(condition), params) if affected == nil then - return { success = false, err = 'Failed to impound vehicle.' } + return { success = false, err = TranslateCap('failed_impound_vehicle') } end if affected < 1 then - return { success = false, err = 'Vehicle not found.' } + return { success = false, err = TranslateCap('vehicle_not_found') } end return { success = true } @@ -774,7 +774,7 @@ end Helpers.registerCallback('esx-adminmenu:server:vehicleImpound', function(source, data) if not Helpers.hasFeaturePermission(source, 'vehicleManagement') then - return { success = false, err = 'Insufficient Permissions' } + return { success = false, err = TranslateCap('insufficient_permissions') } end data = data or {} @@ -782,7 +782,7 @@ Helpers.registerCallback('esx-adminmenu:server:vehicleImpound', function(source, local plate = normalizePlate(data.plate) if not plate then - return { success = false, err = 'Missing plate' } + return { success = false, err = TranslateCap('missing_plate') } end local impoundName = trimString(data.impoundName) @@ -794,7 +794,7 @@ Helpers.registerCallback('esx-adminmenu:server:vehicleImpound', function(source, local impounds = Helpers.getImpounds() or {} if next(impounds) and not impounds[impoundName] then - return { success = false, err = 'Invalid impound.' } + return { success = false, err = TranslateCap('invalid_impound') } end return setVehicleImpounded(plate, impoundName) @@ -831,16 +831,16 @@ function Actions.Notify(src, data) data = data or {} if not Helpers.hasFeaturePermission(src, 'playerNotify') then - return { success = false, err = 'Insufficient Permissions', playerOnline = true, isAdmin = false } + return { success = false, err = TranslateCap('insufficient_permissions'), playerOnline = true, isAdmin = false } end local targetId = getTargetId(data) if not Helpers.isOnline(targetId) then - return { success = false, err = 'Player Not Online', playerOnline = false, isAdmin = true } + return { success = false, err = TranslateCap('player_not_online'), playerOnline = false, isAdmin = true } end - local message = limitString(data.notificationContent, getLimits().MaxNotificationLength, 'Notification by Admin') + local message = limitString(data.notificationContent, getLimits().MaxNotificationLength, TranslateCap('notification_by_admin')) local notificationType = normalizeNotificationType(data.notificationType) local duration = math.floor(clampNumber(data.duration, 1000, getLimits().MaxNotificationDuration or 30000, 5000)) local title = limitString(data.notificationTitle, 80, '') @@ -860,14 +860,14 @@ function Actions.SelfAction(src, data) data = data or {} if not Helpers.hasPermission(src) then - return { success = false, err = 'Insufficient Permissions' } + return { success = false, err = TranslateCap('insufficient_permissions') } end local action = data.action local feature = Helpers.getActionPermission('adminMenu', action) if not feature or not Helpers.hasFeaturePermission(src, feature) then - return { success = false, err = 'Insufficient Permissions' } + return { success = false, err = TranslateCap('insufficient_permissions') } end if action == 'revive' then @@ -875,7 +875,7 @@ function Actions.SelfAction(src, data) return { success = true } end - return { success = false, err = 'Unknown self action.' } + return { success = false, err = TranslateCap('unknown_self_action') } end Helpers.registerCallback('esx-adminmenu:server:selfAction', function(source, data) @@ -937,7 +937,7 @@ end) regServer('density', function(_, payload) if type(payload) ~= 'table' then - return { success = false, err = 'Invalid population density.' } + return { success = false, err = TranslateCap('invalid_population_density') } end local ok, err = Helpers.setPopulationDensity(payload.enabled, payload) @@ -961,7 +961,7 @@ regServer('bringAll', function(src) local admin = ESX.GetPlayerFromId(src) if not admin then - return { success = false, err = 'Admin player not found.' } + return { success = false, err = TranslateCap('admin_not_found') } end local coords = admin.getCoords(true) @@ -988,7 +988,7 @@ end) regServer('kickAll', function(src, payload) local reason = - limitString(payload.reason, getLimits().MaxReasonLength, (Config.ServerManagement and Config.ServerManagement.DefaultKickReason) or 'Kicked by admin') + limitString(payload.reason, getLimits().MaxReasonLength, (Config.ServerManagement and Config.ServerManagement.DefaultKickReason) or TranslateCap('kicked_by_admin')) for _, playerSource in ipairs(GetPlayers()) do local targetId = tonumber(playerSource) @@ -1014,7 +1014,7 @@ regServer('deleteObjects', function() end) regServer('notifyAll', function(_, payload) - local message = limitString(payload.message, getLimits().MaxNotificationLength, 'Notification by Admin') + local message = limitString(payload.message, getLimits().MaxNotificationLength, TranslateCap('notification_by_admin')) local notificationType = normalizeNotificationType(payload.notificationType) local duration = math.floor(clampNumber(payload.duration, 1000, getLimits().MaxNotificationDuration or 30000, 5000)) local title = limitString(payload.title, 80, '') @@ -1028,16 +1028,16 @@ regServer('giveMoneyAll', function(_, payload) local account = normalizeMoneyAccount(payload.account) if amount <= 0 then - return { success = false, err = 'Amount must be greater than 0.' } + return { success = false, err = TranslateCap('amount_must_be_positive') } end local players = ESX.ExtendedPlayers() for i = 1, #players do if account == 'money' then - players[i].addMoney(amount, 'Admin menu') + players[i].addMoney(amount, TranslateCap('admin_menu')) else - players[i].addAccountMoney(account, amount, 'Admin menu') + players[i].addAccountMoney(account, amount, TranslateCap('admin_menu')) end end @@ -1055,38 +1055,31 @@ function Actions.ServerManagement(src, data) -- Any client can invoke a server callback, so a denial here is a genuine -- abuse signal and is worth recording. if not Helpers.hasFeaturePermission(src, 'serverManagement') then - Logs.record({ namespace = 'serverManagement', action = action, actor = src, success = false, err = 'Insufficient Permissions' }) - return { success = false, err = 'Insufficient Permissions' } + Logs.record({namespace = 'serverManagement', action = action, actor = src, success = false, err = TranslateCap('insufficient_permissions')}) + return { success = false, err = TranslateCap('insufficient_permissions') } end local handler = ServerHandlers[action] if not handler then - return { success = false, err = 'Unknown server action.' } + return { success = false, err = TranslateCap('unknown_server_action') } end local permission = getServerActionPermission(action) if not permission then - Logs.record({ namespace = 'serverManagement', action = action, actor = src, success = false, err = 'Action permission not configured' }) - return { success = false, err = 'Action permission not configured.' } + Logs.record({namespace = 'serverManagement', action = action, actor = src, success = false, err = TranslateCap('action_permission_not_configured')}) + return { success = false, err = TranslateCap('action_permission_not_configured') } end if not Helpers.hasFeaturePermission(src, permission) then - Logs.record({ namespace = 'serverManagement', action = action, actor = src, success = false, err = 'Insufficient Permissions' }) - return { success = false, err = 'Insufficient Permissions' } + Logs.record({namespace = 'serverManagement', action = action, actor = src, success = false, err = TranslateCap('insufficient_permissions')}) + return { success = false, err = TranslateCap('insufficient_permissions') } end local result = handler(src, data.payload or {}) - Logs.record({ - namespace = 'serverManagement', - action = action, - actor = src, - success = type(result) ~= 'table' or result.success ~= false, - err = type(result) == 'table' and result.err or nil, - payload = data.payload, - }) + Logs.record({namespace = 'serverManagement', action = action, actor = src, success = type(result) ~= 'table' or result.success ~= false, err = type(result) == 'table' and result.err or nil, payload = data.payload}) return result end @@ -1112,7 +1105,7 @@ local function moneyHandler(ctx, isGive) local account = normalizeMoneyAccount(ctx.payload.account) if amount <= 0 then - return { success = false, err = 'Amount must be greater than 0.', playerOnline = true } + return { success = false, err = TranslateCap('amount_must_be_positive'), playerOnline = true } end local method @@ -1126,19 +1119,19 @@ local function moneyHandler(ctx, isGive) -- Callable, not type()=="function": xPlayer methods reach us as function -- references across the es_extended resource boundary. if not Helpers.isCallable(ctx.target[method]) then - return { success = false, err = 'This ESX version does not expose ' .. method .. '.', playerOnline = true } + return { success = false, err = TranslateCap('version_not_expose') .. ' ' .. method, playerOnline = true } end local ok = pcall(function() if account == 'money' then - ctx.target[method](amount, 'Admin menu') + ctx.target[method](amount, TranslateCap('admin_menu')) else - ctx.target[method](account, amount, 'Admin menu') + ctx.target[method](account, amount, TranslateCap('admin_menu')) end end) if not ok then - return { success = false, err = 'Failed to update balance.', playerOnline = true } + return { success = false, err = TranslateCap('failed_update_balance'), playerOnline = true } end return { success = true, playerOnline = true } @@ -1150,14 +1143,14 @@ regPlayer('deleteCharacter', { local identifier = trimString(ctx.payload.identifier) if not isValidCharacterIdentifier(identifier) then - return { success = false, err = 'Missing character identifier.' } + return { success = false, err = TranslateCap('missing_character_identifier') } end if ctx.target then local targetIdentifier = getOnlineCharacterIdentifier(ctx.target, ctx.targetId) if targetIdentifier ~= identifier then - return { success = false, err = 'Character identifier does not match the selected player.', playerOnline = true } + return { success = false, err = TranslateCap('identifier_not_match'), playerOnline = true } end end @@ -1167,7 +1160,7 @@ regPlayer('deleteCharacter', { end) if ctx.targetId and Helpers.isOnline(ctx.targetId) then - DropPlayer(ctx.targetId, 'Character deleted by an admin.') + DropPlayer(ctx.targetId, TranslateCap('character_deleted_by_admin')) end return { success = true, playerOnline = ctx.targetId and Helpers.isOnline(ctx.targetId) or false } @@ -1203,13 +1196,13 @@ regPlayer('setArmor', { regPlayer('cleanInventory', { handler = function(ctx) if not Helpers.isCallable(ctx.target.getInventory) then - return { success = false, err = 'This ESX version does not expose getInventory.', playerOnline = true } + return { success = false, err = TranslateCap('version_not_expose') .. ' ' .. 'getInventory', playerOnline = true } end local inventory = ctx.target.getInventory() if type(inventory) ~= 'table' then - return { success = false, err = 'Failed to read inventory.', playerOnline = true } + return { success = false, err = TranslateCap('failed_read_inventory'), playerOnline = true } end for i = 1, #inventory do @@ -1252,7 +1245,7 @@ regPlayer('setModel', { local model = limitString(ctx.payload.model, 64) if model == '' then - return { success = false, err = 'Missing model.', playerOnline = true } + return { success = false, err = TranslateCap('missing_model'), playerOnline = true } end TriggerClientEvent('esx-adminmenu:client:setModel', ctx.targetId, model) @@ -1316,15 +1309,15 @@ regPlayer('setJob', { local grade = math.floor(clampNumber(ctx.payload.grade, 0, 100, 0)) if job == '' or not job:match('^[%w_%-]+$') then - return { success = false, err = 'Missing job name.', playerOnline = true } + return { success = false, err = TranslateCap('missing_job_name'), playerOnline = true } end if ESX.DoesJobExist and not ESX.DoesJobExist(job, grade) then - return { success = false, err = 'Invalid job or grade.', playerOnline = true } + return { success = false, err = TranslateCap('invalid_job_or_grade'), playerOnline = true } end if not ctx.target.setJob then - return { success = false, err = 'This ESX version does not expose setJob.', playerOnline = true } + return { success = false, err = TranslateCap('version_not_expose') .. ' ' .. 'setJob', playerOnline = true } end local ok, err = pcall(function() @@ -1332,7 +1325,7 @@ regPlayer('setJob', { end) if not ok then - return { success = false, err = err or 'Failed to set job.', playerOnline = true } + return { success = false, err = err or TranslateCap('failed_set_job'), playerOnline = true } end return { success = true, playerOnline = true } @@ -1345,13 +1338,13 @@ regPlayer('setName', { local lastName = limitString(trimString(ctx.payload.lastName), 32) if firstName == '' or lastName == '' then - return { success = false, err = 'Missing first or last name.', playerOnline = true } + return { success = false, err = TranslateCap('missing_first_or_last_name'), playerOnline = true } end local identifier = getPlayerIdentifier(ctx.target) if not identifier then - return { success = false, err = 'Missing character identifier.', playerOnline = true } + return { success = false, err = TranslateCap('missing_character_identifier'), playerOnline = true } end Helpers.safeUpdate('UPDATE users SET firstname = ?, lastname = ? WHERE identifier = ?', { @@ -1391,17 +1384,17 @@ local function aceHandler(ctx, isAdd) local group = normalizeAceGroup(ctx.payload.group or ctx.payload.permission) if not group then - return { success = false, err = 'Invalid ACE group.', playerOnline = true } + return { success = false, err = TranslateCap('invalid_ace_group'), playerOnline = true } end if not isAllowedAceGroup(group) then - return { success = false, err = 'ACE group not allowed.', playerOnline = true } + return { success = false, err = TranslateCap('ace_group_not_allowed'), playerOnline = true } end local identifier = Helpers.getPlayerLicenseIdentifier(ctx.targetId) if not isValidIdentifier(identifier) then - return { success = false, err = 'Missing player identifier.', playerOnline = true } + return { success = false, err = TranslateCap('missing_player_identifier'), playerOnline = true } end local command = isAdd and 'add_principal' or 'remove_principal' @@ -1429,7 +1422,7 @@ regPlayer('troll', { local allowedTrollActions = Config.TrollActions or {} if not allowedTrollActions[trollAction] then - return { success = false, err = 'Invalid troll action.', playerOnline = true } + return { success = false, err = TranslateCap('invalid_troll_action'), playerOnline = true } end TriggerClientEvent('esx-adminmenu:client:troll', ctx.targetId, trollAction) @@ -1446,14 +1439,14 @@ function Actions.PlayerAction(src, data) local action = type(data.action) == 'string' and data.action or 'unknown' if not Helpers.hasPermission(src) then - Logs.record({ namespace = 'playerActions', action = action, actor = src, success = false, err = 'Insufficient Permissions' }) - return { success = false, err = 'Insufficient Permissions' } + Logs.record({namespace = 'playerActions', action = action, actor = src, success = false, err = TranslateCap('insufficient_permissions')}) + return { success = false, err = TranslateCap('insufficient_permissions') } end local spec = PlayerHandlers[action] if not spec then - return { success = false, err = 'Unknown player action.', playerOnline = true } + return { success = false, err = TranslateCap('unknown_player_action'), playerOnline = true } end local targetId = getTargetId(data) @@ -1462,24 +1455,17 @@ function Actions.PlayerAction(src, data) local permission = Helpers.getActionPermission('playerActions', action) if not permission then - Logs.record({ - namespace = 'playerActions', - action = action, - actor = src, - target = targetId, - success = false, - err = 'Action permission not configured', - }) - return { success = false, err = 'Action permission not configured.', playerOnline = target ~= nil } + Logs.record({namespace = 'playerActions', action = action, actor = src, target = targetId, success = false, err = TranslateCap('action_permission_not_configured')}) + return { success = false, err = TranslateCap('action_permission_not_configured'), playerOnline = target ~= nil } end if not Helpers.hasFeaturePermission(src, permission) then - Logs.record({ namespace = 'playerActions', action = action, actor = src, target = targetId, success = false, err = 'Insufficient Permissions' }) - return { success = false, err = 'Insufficient Permissions', playerOnline = target ~= nil } + Logs.record({namespace = 'playerActions', action = action, actor = src, target = targetId, success = false, err = TranslateCap('insufficient_permissions')}) + return { success = false, err = TranslateCap('insufficient_permissions'), playerOnline = target ~= nil } end if not spec.offline and not target then - return { success = false, err = 'Player Not Online', playerOnline = false } + return { success = false, err = TranslateCap('player_not_online'), playerOnline = false } end -- Resolved before the handler runs: deleteCharacter and friends drop the @@ -1496,16 +1482,7 @@ function Actions.PlayerAction(src, data) Helpers.addRecentPlayer(targetId, 'online') end - Logs.record({ - namespace = 'playerActions', - action = action, - actor = src, - target = targetIdentifier, - targetName = targetName, - success = type(result) ~= 'table' or result.success ~= false, - err = type(result) == 'table' and result.err or nil, - payload = data.payload, - }) + Logs.record({namespace = 'playerActions', action = action, actor = src, target = targetIdentifier, targetName = targetName, success = type(result) ~= 'table' or result.success ~= false, err = type(result) == 'table' and result.err or nil, payload = data.payload}) return result end diff --git a/[esx_addons]/esx_adminmenu/server/commands.lua b/[esx_addons]/esx_adminmenu/server/commands.lua index 5f284409..7482391a 100644 --- a/[esx_addons]/esx_adminmenu/server/commands.lua +++ b/[esx_addons]/esx_adminmenu/server/commands.lua @@ -9,7 +9,7 @@ local function showActionError(result, showError) return end - showError((result and result.err) or "Action failed.") + showError((result and result.err) or TranslateCap("action_failed")) end -- Helper commands that copy a computed string to the clipboard all share the @@ -17,24 +17,24 @@ end local function registerCopyCommand(names, help, computeText) ESX.RegisterCommand(names, allowedPermissions, function(xPlayer, args, showError) if not xPlayer or xPlayer.source == 0 then - showError("Invalid player.") + showError(TranslateCap("invalid_player")) return end if not Helpers.hasFeaturePermission(xPlayer.source, "helperCommands") then - showError("You do not have permission to use this command.") + showError(TranslateCap("no_permission_command")) return end local ped = GetPlayerPed(xPlayer.source) if ped == 0 then - showError("Failed to get player ped.") + showError(TranslateCap("failed_get_player_ped")) return end local text, err = computeText(xPlayer, ped) if not text then - showError(err or "Action failed.") + showError(err or TranslateCap("action_failed")) return end @@ -42,46 +42,46 @@ local function registerCopyCommand(names, help, computeText) end, false, { help = help }) end -registerCopyCommand("vec2", "Copy your current position as vec2(x, y)", function(_, ped) +registerCopyCommand("vec2", TranslateCap("copy_position_as_vec2"), function(_, ped) local coords = GetEntityCoords(ped) return string.format("vec2(%.2f, %.2f)", coords.x, coords.y) end) -registerCopyCommand("vec3", "Copy your current position as vec3(x, y, z)", function(_, ped) +registerCopyCommand("vec3", TranslateCap("copy_position_as_vec3"), function(_, ped) local coords = GetEntityCoords(ped) return string.format("vec3(%.2f, %.2f, %.2f)", coords.x, coords.y, coords.z) end) -registerCopyCommand("vec4", "Copy your current position as vec4(x, y, z, heading)", function(_, ped) +registerCopyCommand("vec4", TranslateCap("copy_position_as_vec4"), function(_, ped) local coords = GetEntityCoords(ped) return string.format("vec4(%.2f, %.2f, %.2f, %.2f)", coords.x, coords.y, coords.z, GetEntityHeading(ped)) end) -registerCopyCommand("heading", "Copy your current heading.", function(_, ped) +registerCopyCommand("heading", TranslateCap("copy_heading"), function(_, ped) return string.format("%.2f", GetEntityHeading(ped)) end) -registerCopyCommand({ "copycoords" }, "Copy your current coordinates and heading as fields.", function(_, ped) +registerCopyCommand({ "copycoords" }, TranslateCap("copy_coords_and_heading"), function(_, ped) local coords = GetEntityCoords(ped) local heading = GetEntityHeading(ped) return string.format("x = %.2f, y = %.2f, z = %.2f, heading = %.2f", coords.x, coords.y, coords.z, heading) end) -registerCopyCommand({ "rot", "rotation" }, "Copy your current rotation as vec3(x, y, z).", function(_, ped) +registerCopyCommand({ "rot", "rotation" }, TranslateCap("copy_rotation"), function(_, ped) local rotation = GetEntityRotation(ped, 2) return string.format("vec3(%.2f, %.2f, %.2f)", rotation.x, rotation.y, rotation.z) end) -registerCopyCommand({ "model", "entitymodel" }, "Copy your current ped or vehicle model hash.", function(_, ped) +registerCopyCommand({ "model", "entitymodel" }, TranslateCap("copy_ped_or_vehicle_model"), function(_, ped) local vehicle = GetVehiclePedIsIn(ped, false) local entity = vehicle ~= 0 and vehicle or ped return tostring(GetEntityModel(entity)) end) -registerCopyCommand({ "vehplate", "copyplate" }, "Copy the current vehicle plate.", function(_, ped) +registerCopyCommand({ "vehplate", "copyplate" }, TranslateCap("copy_vehicle_plate"), function(_, ped) local vehicle = GetVehiclePedIsIn(ped, false) if vehicle == 0 then - return nil, "You must be in a vehicle." + return nil, TranslateCap("must_be_in_vehicle") end return ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) end) @@ -91,12 +91,12 @@ ESX.RegisterCommand( allowedPermissions, function(xPlayer, args, showError) if not xPlayer or xPlayer.source == 0 then - showError("Invalid player.") + showError(TranslateCap("invalid_player")) return end if not Helpers.hasPermission(xPlayer.source) then - showError("You do not have permission to open the admin menu.") + showError(TranslateCap("no_permission_open_menu")) return end @@ -104,7 +104,7 @@ ESX.RegisterCommand( end, true, { - help = "Opens the ESX Admin Menu", + help = TranslateCap("open_admin_menu"), } ) @@ -113,17 +113,17 @@ ESX.RegisterCommand( allowedPermissions, function(xPlayer, args, showError) if not xPlayer or xPlayer.source == 0 then - showError("Invalid player.") + showError(TranslateCap("invalid_player")) return end if not Helpers.hasPermission(xPlayer.source) then - showError("You do not have permission to open player information.") + showError(TranslateCap("no_permission_open_player_info")) return end if not Helpers.isOnline(args.playerId) then - showError("Player is not online.") + showError(TranslateCap("player_not_online")) return end @@ -135,9 +135,9 @@ ESX.RegisterCommand( end, true, { - help = "Open the admin dashboard directly to a player's information panel.", + help = TranslateCap("open_admin_dashboard_player_info"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, }, } ) @@ -147,19 +147,19 @@ ESX.RegisterCommand( allowedPermissions, function(xPlayer, args, showError) if not xPlayer or xPlayer.source == 0 then - showError("Invalid player.") + showError(TranslateCap("invalid_player")) return end if not Helpers.hasFeaturePermission(xPlayer.source, "banManagement") then - showError("You do not have permission to refresh the ban cache.") + showError(TranslateCap("no_permission_refresh_ban_cache")) return end BanCache.load() end, true, { - help = "Refreshes the ban cache if manual changes were made to the database.", + help = TranslateCap("refreshes_ban_cache"), } ) @@ -168,17 +168,17 @@ ESX.RegisterCommand( allowedPermissions, function(xPlayer, args, showError) if not xPlayer or xPlayer.source == 0 then - showError("Invalid player.") + showError(TranslateCap("invalid_player")) return end if not Helpers.hasPermission(xPlayer.source) then - showError("No permission.") + showError(TranslateCap("insufficient_permissions")) return end if not Helpers.hasFeaturePermission(xPlayer.source, "vehicleOwnership") then - showError("You do not have permission to save admin vehicles.") + showError(TranslateCap("no_permission_save_admin_vehicles")) return end @@ -191,12 +191,12 @@ ESX.RegisterCommand( local vehicle = GetVehiclePedIsIn(ped, false) if (not model or model == "") and (not vehicle or vehicle == 0) then - showError("You must be in a vehicle.") + showError(TranslateCap("must_be_in_vehicle")) return end if (not model or model == "") and GetPedInVehicleSeat(vehicle, -1) ~= ped then - showError("You must be the driver.") + showError(TranslateCap("must_be_driver")) return end @@ -208,12 +208,12 @@ ESX.RegisterCommand( xLib.callback("esx-adminmenu:client:adminCarVehicleProps", xPlayer.source, function(props) if not props or type(props) ~= "table" then - showError("Failed to get vehicle properties.") + showError(TranslateCap("failed_get_vehicle_properties")) return end if Helpers.isPlateTaken(plate) then - showError("Generated plate was already taken. Try again.") + showError(TranslateCap("generated_plate_already_taken")) return end @@ -223,7 +223,7 @@ ESX.RegisterCommand( end if not props.model then - showError("Failed to validate vehicle model.") + showError(TranslateCap("failed_validate_vehicle_model")) return end @@ -232,7 +232,7 @@ ESX.RegisterCommand( local maxBytes = tonumber(Config.AdminLimits and Config.AdminLimits.MaxVehiclePropsBytes) or 16384 local encoded = json.encode(props) if type(encoded) ~= "string" or #encoded > maxBytes then - showError("Vehicle properties are too large.") + showError(TranslateCap("vehicle_properties_too_large")) return end @@ -241,7 +241,7 @@ ESX.RegisterCommand( plate, encoded, }, function() - xPlayer.showNotification("Vehicle registered to you.") + xPlayer.showNotification(TranslateCap("vehicle_registered_to_you")) end) end, { model = model, @@ -250,16 +250,16 @@ ESX.RegisterCommand( end, false, { - help = "Spawn and own a vehicle, or register the vehicle you are driving.", + help = TranslateCap("spawn_and_own_or_register_vehicle"), arguments = { - { name = "model", help = "Vehicle model to spawn (optional)", type = "string" }, + { name = "model", help = TranslateCap("vehicle_model_to_spawn"), type = "string" }, }, } ) ESX.RegisterCommand({ "setmodel" }, allowedPermissions, function(xPlayer, args, showError) if not xPlayer or xPlayer.source == 0 then - showError("Invalid player.") + showError(TranslateCap("invalid_player")) return end @@ -273,10 +273,10 @@ ESX.RegisterCommand({ "setmodel" }, allowedPermissions, function(xPlayer, args, showActionError(result, showError) end, true, { - help = "Change a player's model.", + help = TranslateCap("change_player_model"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, - { name = "model", help = "Model name", type = "string" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, + { name = "model", help = TranslateCap("model_name"), type = "string" }, }, }) @@ -287,9 +287,9 @@ ESX.RegisterCommand({ "goto" }, allowedPermissions, function(xPlayer, args, show showActionError(result, showError) end, true, { - help = "Teleport to a player.", + help = TranslateCap("teleport_to_player"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, }, }) @@ -298,9 +298,9 @@ ESX.RegisterCommand({ "bring" }, allowedPermissions, function(xPlayer, args, sho showActionError(result, showError) end, true, { - help = "Bring a player to you.", + help = TranslateCap("bring_player_to_you"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, }, }) @@ -309,9 +309,9 @@ ESX.RegisterCommand({ "spectate" }, allowedPermissions, function(xPlayer, args, showActionError(result, showError) end, true, { - help = "Spectate a player.", + help = TranslateCap("spectate_player"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, }, }) @@ -320,7 +320,7 @@ ESX.RegisterCommand({ "stopspectate" }, allowedPermissions, function(xPlayer, ar showActionError(result, showError) end, true, { - help = "Stop spectating.", + help = TranslateCap("stop_spectating"), }) ESX.RegisterCommand({ "kick" }, allowedPermissions, function(xPlayer, args, showError) @@ -331,10 +331,10 @@ ESX.RegisterCommand({ "kick" }, allowedPermissions, function(xPlayer, args, show showActionError(result, showError) end, true, { - help = "Kick a player.", + help = TranslateCap("kick_player"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, - { name = "reason", help = "Reason for kick", type = "string" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, + { name = "reason", help = TranslateCap("kick_reason"), type = "string" }, }, }) @@ -347,11 +347,11 @@ ESX.RegisterCommand({ "ban" }, allowedPermissions, function(xPlayer, args, showE showActionError(result, showError) end, true, { - help = "Ban a player.", + help = TranslateCap("ban_player"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, - { name = "duration", help = "Duration in minutes", type = "number" }, - { name = "reason", help = "Reason for ban", type = "string" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, + { name = "duration", help = TranslateCap("duration_in_minutes"), type = "number" }, + { name = "reason", help = TranslateCap("ban_reason"), type = "string" }, }, }) @@ -366,12 +366,12 @@ ESX.RegisterCommand({ "notify" }, allowedPermissions, function(xPlayer, args, sh showActionError(result, showError) end, true, { - help = "Send a notification to a player.", + help = TranslateCap("send_notification_to_player"), arguments = { - { name = "playerId", help = "Target player ID", type = "number" }, - { name = "message", help = "Notification message", type = "string" }, - { name = "type", help = "Notification type (info, error, success)", type = "string" }, - { name = "duration", help = "Duration in ms", type = "number" }, - { name = "title", help = "Notification title", type = "string" }, + { name = "playerId", help = TranslateCap("target_player_id"), type = "number" }, + { name = "message", help = TranslateCap("notification_message"), type = "string" }, + { name = "type", help = TranslateCap("notification_type"), type = "string" }, + { name = "duration", help = TranslateCap("duration_in_ms"), type = "number" }, + { name = "title", help = TranslateCap("notification_title"), type = "string" }, }, }) diff --git a/[esx_addons]/esx_adminmenu/server/main.lua b/[esx_addons]/esx_adminmenu/server/main.lua index 39a5c788..d25074f5 100644 --- a/[esx_addons]/esx_adminmenu/server/main.lua +++ b/[esx_addons]/esx_adminmenu/server/main.lua @@ -3,7 +3,7 @@ Helpers.registerCallback("esx-adminmenu:server:getInitData", function(source) if not Helpers.hasPermission(source) then - return { err = "Insufficient Permissions." } + return { err = TranslateCap("insufficient_permissions") } end local impounds = Helpers.getImpounds() @@ -26,7 +26,7 @@ end) Helpers.registerCallback("esx-adminmenu:server:canOpen", function(source) if not Helpers.hasPermission(source) then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end return { @@ -38,21 +38,21 @@ end) Helpers.registerCallback("esx-adminmenu:server:canUseAdminAction", function(source, data) if not Helpers.hasPermission(source) then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end local action = type(data) == "table" and data.action or data if type(action) ~= "string" or action == "" then - return { success = false, err = "Invalid admin action." } + return { success = false, err = TranslateCap("invalid_admin_action") } end local feature = Helpers.getActionPermission("adminMenu", action) if not feature then - return { success = false, err = "Invalid admin action." } + return { success = false, err = TranslateCap("invalid_admin_action") } end if not Helpers.hasFeaturePermission(source, feature) then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end return { @@ -63,7 +63,7 @@ end) Helpers.registerCallback("esx-adminmenu:server:openDashboard", function(source) if not Helpers.hasPermission(source) then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end return { @@ -76,7 +76,7 @@ end) Helpers.registerCallback("esx-adminmenu:server:getVehicles", function(source, data) if not Helpers.hasPermission(source) then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end local canSeeSensitive = Helpers.hasFeaturePermission(source, "sensitiveInfo") @@ -88,7 +88,7 @@ end) Helpers.registerCallback("esx-adminmenu:server:getBans", function(source, data) if not Helpers.hasFeaturePermission(source, "banManagement") then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end local result = Helpers.getActiveBansPage(data) @@ -99,7 +99,7 @@ end) Helpers.registerCallback("esx-adminmenu:server:getRecentPlayers", function(source) if not Helpers.hasPermission(source) then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end return { @@ -110,12 +110,12 @@ end) Helpers.registerCallback("esx-adminmenu:server:getRadioChannelPlayers", function(source, data) if not Helpers.hasFeaturePermission(source, "radioLookup") then - return { success = false, err = "Insufficient Permissions." } + return { success = false, err = TranslateCap("insufficient_permissions") } end local channel = tonumber(data and data.channel) or 0 if channel <= 0 then - return { success = false, err = "Enter a valid radio channel." } + return { success = false, err = TranslateCap("enter_valid_radio_channel") } end local players = {} @@ -142,7 +142,7 @@ end) -- which is more sensitive than most actions it records. Helpers.registerCallback("esx-adminmenu:server:getAdminLogs", function(source, data) if not Helpers.hasFeaturePermission(source, "logViewer") then - return { success = false, err = "Insufficient Permissions", logs = {} } + return { success = false, err = TranslateCap("insufficient_permissions"), logs = {} } end local result = Logs.query(data) @@ -292,7 +292,7 @@ local function buildOfflineEntry(row, canSeeSensitive) } end ---[[ +--[[ We only need this to prevent currently-online characters from also appearing as OFFLINE results. ]]-- @@ -449,7 +449,7 @@ Helpers.registerCallback( if not Helpers.hasPermission(src) then return { success = false, - err = "Insufficient Permissions", + err = TranslateCap("insufficient_permissions"), players = {}, } end @@ -481,7 +481,7 @@ Helpers.registerCallback( if isOfflineSearchRateLimited(src) then return { success = false, - err = "Search rate limited.", + err = TranslateCap("search_rate_limited"), players = {}, } end @@ -510,7 +510,7 @@ Helpers.registerCallback( if rows == nil then return { success = false, - err = "Database unavailable.", + err = TranslateCap("database_unavailable"), players = {}, } end diff --git a/[esx_addons]/esx_adminmenu/shared/config.lua b/[esx_addons]/esx_adminmenu/shared/config.lua index d18adafb..fb5e5c8b 100644 --- a/[esx_addons]/esx_adminmenu/shared/config.lua +++ b/[esx_addons]/esx_adminmenu/shared/config.lua @@ -182,47 +182,47 @@ Config.VehicleSpawner = { WarpIntoVehicle = true, DefaultColor = "black", ColorPresets = { - { id = "black", label = "Black", primary = 0, secondary = 0 }, - { id = "white", label = "White", primary = 111, secondary = 111 }, - { id = "silver", label = "Silver", primary = 4, secondary = 4 }, - { id = "red", label = "Red", primary = 27, secondary = 27 }, - { id = "orange", label = "Orange", primary = 38, secondary = 38 }, - { id = "yellow", label = "Yellow", primary = 88, secondary = 88 }, - { id = "green", label = "Green", primary = 55, secondary = 55 }, - { id = "blue", label = "Blue", primary = 64, secondary = 64 }, - { id = "purple", label = "Purple", primary = 145, secondary = 145 }, + { id = "black", label = TranslateCap("black"), primary = 0, secondary = 0 }, + { id = "white", label = TranslateCap("white"), primary = 111, secondary = 111 }, + { id = "silver", label = TranslateCap("silver"), primary = 4, secondary = 4 }, + { id = "red", label = TranslateCap("red"), primary = 27, secondary = 27 }, + { id = "orange", label = TranslateCap("orange"), primary = 38, secondary = 38 }, + { id = "yellow", label = TranslateCap("yellow"), primary = 88, secondary = 88 }, + { id = "green", label = TranslateCap("green"), primary = 55, secondary = 55 }, + { id = "blue", label = TranslateCap("blue"), primary = 64, secondary = 64 }, + { id = "purple", label = TranslateCap("purple"), primary = 145, secondary = 145 } }, NeonPresets = { - { id = "white", label = "White", r = 255, g = 255, b = 255 }, - { id = "orange", label = "Orange", r = 251, g = 155, b = 4 }, - { id = "red", label = "Red", r = 255, g = 32, b = 32 }, - { id = "green", label = "Green", r = 32, g = 255, b = 96 }, - { id = "blue", label = "Blue", r = 32, g = 128, b = 255 }, - { id = "purple", label = "Purple", r = 180, g = 72, b = 255 }, + { id = "white", label = TranslateCap("white"), r = 255, g = 255, b = 255 }, + { id = "orange", label = TranslateCap("orange"), r = 251, g = 155, b = 4 }, + { id = "red", label = TranslateCap("red"), r = 255, g = 32, b = 32 }, + { id = "green", label = TranslateCap("green"), r = 32, g = 255, b = 96 }, + { id = "blue", label = TranslateCap("blue"), r = 32, g = 128, b = 255 }, + { id = "purple", label = TranslateCap("purple"), r = 180, g = 72, b = 255 } }, WindowTints = { - { id = 0, label = "None" }, - { id = 1, label = "Pure Black" }, - { id = 2, label = "Dark Smoke" }, - { id = 3, label = "Light Smoke" }, - { id = 4, label = "Stock" }, - { id = 5, label = "Limo" }, - { id = 6, label = "Green" }, + { id = 0, label = TranslateCap("none") }, + { id = 1, label = TranslateCap("pure_black") }, + { id = 2, label = TranslateCap("dark_smoke") }, + { id = 3, label = TranslateCap("light_smoke") }, + { id = 4, label = TranslateCap("stock") }, + { id = 5, label = TranslateCap("limo") }, + { id = 6, label = TranslateCap("green") } }, WheelCategories = { - { id = "sport", label = "Sport", type = 0 }, - { id = "muscle", label = "Muscle", type = 1 }, - { id = "lowrider", label = "Lowrider", type = 2 }, - { id = "suv", label = "SUV", type = 3 }, - { id = "offroad", label = "Offroad", type = 4 }, - { id = "tuner", label = "Tuner", type = 5 }, - { id = "bike", label = "Bike", type = 6 }, - { id = "highend", label = "High End", type = 7 }, - { id = "street", label = "Street", type = 11 }, - { id = "track", label = "Track", type = 12 }, + { id = "sport", label = TranslateCap("sport"), type = 0 }, + { id = "muscle", label = TranslateCap("muscle"), type = 1 }, + { id = "lowrider", label = TranslateCap("lowrider"), type = 2 }, + { id = "suv", label = TranslateCap("suv"), type = 3 }, + { id = "offroad", label = TranslateCap("offroad"), type = 4 }, + { id = "tuner", label = TranslateCap("tuner"), type = 5 }, + { id = "bike", label = TranslateCap("bike"), type = 6 }, + { id = "highend", label = TranslateCap("highend"), type = 7 }, + { id = "street", label = TranslateCap("street"), type = 11 }, + { id = "track", label = TranslateCap("track"), type = 12 } }, WheelDesigns = { - { id = -1, label = "Stock" }, + { id = -1, label = TranslateCap("stock") }, { id = 0, label = "1" }, { id = 1, label = "2" }, { id = 2, label = "3" }, @@ -242,12 +242,12 @@ Config.VehicleSpawner = { { id = 16, label = "17" }, { id = 17, label = "18" }, { id = 18, label = "19" }, - { id = 19, label = "20" }, + { id = 19, label = "20" } }, } Config.ServerManagement = { - DefaultKickReason = "Kicked by admin", + DefaultKickReason = TranslateCap("kicked_by_admin"), DefaultWeather = "CLEAR", DefaultHour = 12, DefaultMinute = 0,