forked from Simnation/Main
Update main.lua
This commit is contained in:
parent
4a1367fb44
commit
b7d3d90e28
1 changed files with 558 additions and 102 deletions
|
@ -109,62 +109,87 @@ local function showMyLicense(licenseType)
|
|||
TriggerServerEvent('license-system:server:requestMyLicense', licenseType)
|
||||
end
|
||||
|
||||
-- Spieler-Lizenz-Menü
|
||||
local function openPlayerLicenseMenu(targetId, targetName)
|
||||
debugPrint("=== openPlayerLicenseMenu START ===")
|
||||
debugPrint("Sende Event: requestPlayerLicenses für: " .. targetName .. " (ID: " .. targetId .. ")")
|
||||
-- FORWARD DECLARATIONS (Funktionen die später definiert werden)
|
||||
local confirmIssueLicense
|
||||
local openIssueLicenseMenu
|
||||
local openDriversLicenseClassMenu
|
||||
local openRevokeLicenseMenu
|
||||
local openPlayerLicenseMenu
|
||||
local openLicenseMenu
|
||||
|
||||
TriggerServerEvent('license-system:server:requestPlayerLicenses', targetId)
|
||||
end
|
||||
-- Lizenz-Ausstellung bestätigen (FRÜH DEFINIERT)
|
||||
confirmIssueLicense = function(targetId, targetName, licenseType, classes)
|
||||
local config = Config.LicenseTypes[licenseType]
|
||||
if not config then
|
||||
showNotification('Unbekannter Lizenztyp!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Lizenz ausstellen Menü
|
||||
local function openIssueLicenseMenu(targetId, targetName)
|
||||
debugPrint("Öffne Lizenz-Ausstellungs-Menü für: " .. targetName)
|
||||
|
||||
local menuOptions = {}
|
||||
|
||||
for licenseType, config in pairs(Config.LicenseTypes) do
|
||||
local classText = classes and table.concat(classes, ', ') or 'Keine'
|
||||
local priceText = config.price and (config.price .. ' $') or 'Kostenlos'
|
||||
local validityText = config.validity_days and (config.validity_days .. ' Tage') or 'Unbegrenzt'
|
||||
|
||||
table.insert(menuOptions, {
|
||||
title = config.label,
|
||||
description = config.description or 'Keine Beschreibung verfügbar',
|
||||
icon = config.icon,
|
||||
onSelect = function()
|
||||
if licenseType == 'drivers_license' and config.classes then
|
||||
openDriversLicenseClassMenu(targetId, targetName, licenseType)
|
||||
else
|
||||
confirmIssueLicense(targetId, targetName, licenseType, nil)
|
||||
end
|
||||
end,
|
||||
metadata = {
|
||||
{label = 'Preis', value = priceText},
|
||||
{label = 'Gültigkeitsdauer', value = validityText}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
table.insert(menuOptions, {
|
||||
title = '← Zurück',
|
||||
icon = 'fas fa-arrow-left',
|
||||
onSelect = function()
|
||||
openPlayerLicenseMenu(targetId, targetName)
|
||||
end
|
||||
})
|
||||
debugPrint("Bestätige Lizenz-Ausstellung: " .. licenseType .. " für " .. targetName)
|
||||
|
||||
lib.registerContext({
|
||||
id = 'issue_license',
|
||||
title = 'Lizenz ausstellen: ' .. targetName,
|
||||
options = menuOptions
|
||||
id = 'confirm_issue_license',
|
||||
title = 'Lizenz ausstellen bestätigen',
|
||||
options = {
|
||||
{
|
||||
title = 'Spieler: ' .. targetName,
|
||||
disabled = true,
|
||||
icon = 'fas fa-user'
|
||||
},
|
||||
{
|
||||
title = 'Lizenztyp: ' .. config.label,
|
||||
disabled = true,
|
||||
icon = config.icon
|
||||
},
|
||||
{
|
||||
title = 'Klassen: ' .. classText,
|
||||
disabled = true,
|
||||
icon = 'fas fa-list'
|
||||
},
|
||||
{
|
||||
title = 'Kosten: ' .. priceText,
|
||||
disabled = true,
|
||||
icon = 'fas fa-dollar-sign'
|
||||
},
|
||||
{
|
||||
title = '─────────────────',
|
||||
disabled = true
|
||||
},
|
||||
{
|
||||
title = '✅ Bestätigen',
|
||||
description = 'Lizenz jetzt ausstellen',
|
||||
icon = 'fas fa-check',
|
||||
onSelect = function()
|
||||
debugPrint("Sende Lizenz-Ausstellung an Server...")
|
||||
TriggerServerEvent('license-system:server:issueLicense', targetId, licenseType, classes)
|
||||
lib.hideContext()
|
||||
end
|
||||
},
|
||||
{
|
||||
title = '❌ Abbrechen',
|
||||
description = 'Vorgang abbrechen',
|
||||
icon = 'fas fa-times',
|
||||
onSelect = function()
|
||||
openIssueLicenseMenu(targetId, targetName)
|
||||
end
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
lib.showContext('issue_license')
|
||||
lib.showContext('confirm_issue_license')
|
||||
end
|
||||
|
||||
-- Führerschein-Klassen Menü
|
||||
local function openDriversLicenseClassMenu(targetId, targetName, licenseType)
|
||||
openDriversLicenseClassMenu = function(targetId, targetName, licenseType)
|
||||
local config = Config.LicenseTypes[licenseType]
|
||||
if not config then
|
||||
showNotification('Lizenz-Konfiguration nicht gefunden!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
local selectedClasses = {}
|
||||
|
||||
local function updateMenu()
|
||||
|
@ -250,68 +275,53 @@ local function openDriversLicenseClassMenu(targetId, targetName, licenseType)
|
|||
updateMenu()
|
||||
end
|
||||
|
||||
-- Lizenz-Ausstellung bestätigen
|
||||
local function confirmIssueLicense(targetId, targetName, licenseType, classes)
|
||||
local config = Config.LicenseTypes[licenseType]
|
||||
local classText = classes and table.concat(classes, ', ') or 'Keine'
|
||||
-- Lizenz ausstellen Menü
|
||||
openIssueLicenseMenu = function(targetId, targetName)
|
||||
debugPrint("Öffne Lizenz-Ausstellungs-Menü für: " .. targetName)
|
||||
|
||||
local menuOptions = {}
|
||||
|
||||
for licenseType, config in pairs(Config.LicenseTypes) do
|
||||
local priceText = config.price and (config.price .. ' $') or 'Kostenlos'
|
||||
local validityText = config.validity_days and (config.validity_days .. ' Tage') or 'Unbegrenzt'
|
||||
|
||||
debugPrint("Bestätige Lizenz-Ausstellung: " .. licenseType .. " für " .. targetName)
|
||||
|
||||
lib.registerContext({
|
||||
id = 'confirm_issue_license',
|
||||
title = 'Lizenz ausstellen bestätigen',
|
||||
options = {
|
||||
{
|
||||
title = 'Spieler: ' .. targetName,
|
||||
disabled = true,
|
||||
icon = 'fas fa-user'
|
||||
},
|
||||
{
|
||||
title = 'Lizenztyp: ' .. config.label,
|
||||
disabled = true,
|
||||
icon = config.icon
|
||||
},
|
||||
{
|
||||
title = 'Klassen: ' .. classText,
|
||||
disabled = true,
|
||||
icon = 'fas fa-list'
|
||||
},
|
||||
{
|
||||
title = 'Kosten: ' .. priceText,
|
||||
disabled = true,
|
||||
icon = 'fas fa-dollar-sign'
|
||||
},
|
||||
{
|
||||
title = '─────────────────',
|
||||
disabled = true
|
||||
},
|
||||
{
|
||||
title = '✅ Bestätigen',
|
||||
description = 'Lizenz jetzt ausstellen',
|
||||
icon = 'fas fa-check',
|
||||
table.insert(menuOptions, {
|
||||
title = config.label,
|
||||
description = config.description or 'Keine Beschreibung verfügbar',
|
||||
icon = config.icon,
|
||||
onSelect = function()
|
||||
debugPrint("Sende Lizenz-Ausstellung an Server...")
|
||||
TriggerServerEvent('license-system:server:issueLicense', targetId, licenseType, classes)
|
||||
lib.hideContext()
|
||||
if licenseType == 'drivers_license' and config.classes then
|
||||
openDriversLicenseClassMenu(targetId, targetName, licenseType)
|
||||
else
|
||||
confirmIssueLicense(targetId, targetName, licenseType, nil)
|
||||
end
|
||||
},
|
||||
{
|
||||
title = '❌ Abbrechen',
|
||||
description = 'Vorgang abbrechen',
|
||||
icon = 'fas fa-times',
|
||||
onSelect = function()
|
||||
openIssueLicenseMenu(targetId, targetName)
|
||||
end
|
||||
}
|
||||
end,
|
||||
metadata = {
|
||||
{label = 'Preis', value = priceText},
|
||||
{label = 'Gültigkeitsdauer', value = validityText}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
lib.showContext('confirm_issue_license')
|
||||
table.insert(menuOptions, {
|
||||
title = '← Zurück',
|
||||
icon = 'fas fa-arrow-left',
|
||||
onSelect = function()
|
||||
openPlayerLicenseMenu(targetId, targetName)
|
||||
end
|
||||
})
|
||||
|
||||
lib.registerContext({
|
||||
id = 'issue_license',
|
||||
title = 'Lizenz ausstellen: ' .. targetName,
|
||||
options = menuOptions
|
||||
})
|
||||
|
||||
lib.showContext('issue_license')
|
||||
end
|
||||
|
||||
-- Lizenz entziehen Menü
|
||||
local function openRevokeLicenseMenu(targetId, targetName, licenses)
|
||||
openRevokeLicenseMenu = function(targetId, targetName, licenses)
|
||||
debugPrint("Öffne Lizenz-Entziehungs-Menü für: " .. targetName)
|
||||
|
||||
local menuOptions = {}
|
||||
|
@ -399,8 +409,16 @@ local function openRevokeLicenseMenu(targetId, targetName, licenses)
|
|||
lib.showContext('revoke_license')
|
||||
end
|
||||
|
||||
-- Spieler-Lizenz-Menü
|
||||
openPlayerLicenseMenu = function(targetId, targetName)
|
||||
debugPrint("=== openPlayerLicenseMenu START ===")
|
||||
debugPrint("Sende Event: requestPlayerLicenses für: " .. targetName .. " (ID: " .. targetId .. ")")
|
||||
|
||||
TriggerServerEvent('license-system:server:requestPlayerLicenses', targetId)
|
||||
end
|
||||
|
||||
-- Hauptmenü für Lizenz-System
|
||||
local function openLicenseMenu()
|
||||
openLicenseMenu = function()
|
||||
debugPrint("Öffne Hauptmenü für Lizenz-System")
|
||||
|
||||
if not hasPermission() then
|
||||
|
@ -721,11 +739,11 @@ RegisterCommand('pass', function()
|
|||
end, false)
|
||||
|
||||
-- KEYBINDS
|
||||
if Config.Keybinds.open_license_menu then
|
||||
if Config.Keybinds and Config.Keybinds.open_license_menu then
|
||||
RegisterKeyMapping(Config.Commands.license.name, Config.Keybinds.open_license_menu.description, 'keyboard', Config.Keybinds.open_license_menu.key)
|
||||
end
|
||||
|
||||
if Config.Keybinds.show_my_licenses then
|
||||
if Config.Keybinds and Config.Keybinds.show_my_licenses then
|
||||
RegisterKeyMapping(Config.Commands.mylicense.name, Config.Keybinds.show_my_licenses.description, 'keyboard', Config.Keybinds.show_my_licenses.key)
|
||||
end
|
||||
|
||||
|
@ -864,3 +882,441 @@ showLicense = function(licenseData)
|
|||
return originalShowLicense(licenseData)
|
||||
end
|
||||
|
||||
-- Erweiterte Fehlerbehandlung für Events
|
||||
local function safeEventHandler(eventName, handler)
|
||||
RegisterNetEvent(eventName, function(...)
|
||||
local success, error = pcall(handler, ...)
|
||||
if not success then
|
||||
debugPrint("^1Fehler in Event " .. eventName .. ": " .. tostring(error) .. "^7")
|
||||
performanceStats.errors = performanceStats.errors + 1
|
||||
showNotification('Ein Fehler ist aufgetreten!', 'error')
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Zusätzliche Validierungen
|
||||
local function validateLicenseData(licenseData)
|
||||
if not licenseData then
|
||||
debugPrint("^1Validierung fehlgeschlagen: licenseData ist nil^7")
|
||||
return false
|
||||
end
|
||||
|
||||
if not licenseData.license then
|
||||
debugPrint("^1Validierung fehlgeschlagen: license-Objekt fehlt^7")
|
||||
return false
|
||||
end
|
||||
|
||||
if not licenseData.license.license_type then
|
||||
debugPrint("^1Validierung fehlgeschlagen: license_type fehlt^7")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Erweiterte showLicense Funktion mit Validierung
|
||||
local function showLicenseWithValidation(licenseData)
|
||||
if not validateLicenseData(licenseData) then
|
||||
showNotification('Ungültige Lizenz-Daten!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
debugPrint("Zeige Lizenz: " .. licenseData.license.license_type)
|
||||
|
||||
-- Zusätzliche Daten für NUI vorbereiten
|
||||
local nuitData = {
|
||||
license = licenseData.license,
|
||||
config = licenseData.config or Config.LicenseTypes[licenseData.license.license_type],
|
||||
timestamp = GetGameTimer(),
|
||||
playerData = QBCore.Functions.GetPlayerData()
|
||||
}
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'showLicense',
|
||||
data = nuitData
|
||||
})
|
||||
|
||||
SetNuiFocus(true, true)
|
||||
isLicenseShowing = true
|
||||
performanceStats.licenseShows = performanceStats.licenseShows + 1
|
||||
end
|
||||
|
||||
-- Überschreibe die ursprüngliche showLicense Funktion
|
||||
showLicense = showLicenseWithValidation
|
||||
|
||||
-- Erweiterte Menü-Funktionen mit Error-Handling
|
||||
local function safeMenuAction(action, errorMessage)
|
||||
return function(...)
|
||||
local success, error = pcall(action, ...)
|
||||
if not success then
|
||||
debugPrint("^1Menü-Fehler: " .. (errorMessage or "Unbekannt") .. "^7")
|
||||
debugPrint("^1Details: " .. tostring(error) .. "^7")
|
||||
performanceStats.errors = performanceStats.errors + 1
|
||||
showNotification('Menü-Fehler aufgetreten!', 'error')
|
||||
|
||||
-- Menü schließen bei Fehler
|
||||
if lib.getOpenContextMenu() then
|
||||
lib.hideContext()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Cache für Spieler-Daten
|
||||
local playerCache = {}
|
||||
local cacheTimeout = 30000 -- 30 Sekunden
|
||||
|
||||
local function getCachedPlayerData(playerId)
|
||||
local now = GetGameTimer()
|
||||
local cached = playerCache[playerId]
|
||||
|
||||
if cached and (now - cached.timestamp) < cacheTimeout then
|
||||
debugPrint("Verwende gecachte Spieler-Daten für ID: " .. playerId)
|
||||
return cached.data
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function setCachedPlayerData(playerId, data)
|
||||
playerCache[playerId] = {
|
||||
data = data,
|
||||
timestamp = GetGameTimer()
|
||||
}
|
||||
debugPrint("Spieler-Daten gecacht für ID: " .. playerId)
|
||||
end
|
||||
|
||||
-- Cache-Cleanup
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(60000) -- Jede Minute
|
||||
|
||||
local now = GetGameTimer()
|
||||
local cleaned = 0
|
||||
|
||||
for playerId, cached in pairs(playerCache) do
|
||||
if (now - cached.timestamp) > cacheTimeout then
|
||||
playerCache[playerId] = nil
|
||||
cleaned = cleaned + 1
|
||||
end
|
||||
end
|
||||
|
||||
if cleaned > 0 then
|
||||
debugPrint("Cache bereinigt: " .. cleaned .. " Einträge entfernt")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Erweiterte Nearby-Players Funktion mit Cache
|
||||
local function getNearbyPlayersWithCache(radius)
|
||||
radius = radius or 5.0
|
||||
local players = {}
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
for _, playerId in ipairs(GetActivePlayers()) do
|
||||
local targetPed = GetPlayerPed(playerId)
|
||||
if targetPed ~= playerPed then
|
||||
local targetCoords = GetEntityCoords(targetPed)
|
||||
local distance = #(playerCoords - targetCoords)
|
||||
|
||||
if distance <= radius then
|
||||
local serverId = GetPlayerServerId(playerId)
|
||||
local playerName = GetPlayerName(playerId)
|
||||
|
||||
-- Cache-Daten verwenden wenn verfügbar
|
||||
local cachedData = getCachedPlayerData(serverId)
|
||||
local playerData = cachedData or {
|
||||
id = serverId,
|
||||
name = playerName,
|
||||
ped = targetPed
|
||||
}
|
||||
|
||||
playerData.distance = math.floor(distance * 100) / 100
|
||||
|
||||
-- Daten cachen wenn nicht bereits gecacht
|
||||
if not cachedData then
|
||||
setCachedPlayerData(serverId, playerData)
|
||||
end
|
||||
|
||||
table.insert(players, playerData)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Nach Entfernung sortieren
|
||||
table.sort(players, function(a, b)
|
||||
return a.distance < b.distance
|
||||
end)
|
||||
|
||||
debugPrint("Gefundene Spieler in der Nähe: " .. #players)
|
||||
return players
|
||||
end
|
||||
|
||||
-- Überschreibe die ursprüngliche getNearbyPlayers Funktion
|
||||
getNearbyPlayers = getNearbyPlayersWithCache
|
||||
|
||||
-- Erweiterte Notification-Funktion
|
||||
local function showNotificationWithSound(message, type, sound)
|
||||
QBCore.Functions.Notify(message, type or 'primary')
|
||||
|
||||
if sound and Config.Sounds and Config.Sounds[sound] then
|
||||
PlaySoundFrontend(-1, Config.Sounds[sound].name, Config.Sounds[sound].set, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Erweiterte Event-Handler mit besserer Fehlerbehandlung
|
||||
RegisterNetEvent('license-system:client:receiveLicenseWithValidation', function(licenseData)
|
||||
debugPrint("=== Event: receiveLicenseWithValidation ===")
|
||||
|
||||
if not validateLicenseData(licenseData) then
|
||||
showNotificationWithSound('Ungültige Lizenz-Daten erhalten!', 'error', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
debugPrint("Gültige Lizenz-Daten erhalten: " .. licenseData.license.license_type)
|
||||
showLicense(licenseData)
|
||||
end)
|
||||
|
||||
-- Erweiterte Lizenz-Anzeige mit Animationen
|
||||
local function showLicenseWithAnimation(licenseData)
|
||||
if not validateLicenseData(licenseData) then
|
||||
showNotification('Ungültige Lizenz-Daten!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Animation starten
|
||||
local playerPed = PlayerPedId()
|
||||
|
||||
-- Lizenz-Animation (falls gewünscht)
|
||||
if Config.Animations and Config.Animations.show_license then
|
||||
local anim = Config.Animations.show_license
|
||||
RequestAnimDict(anim.dict)
|
||||
|
||||
while not HasAnimDictLoaded(anim.dict) do
|
||||
Wait(10)
|
||||
end
|
||||
|
||||
TaskPlayAnim(playerPed, anim.dict, anim.name, 8.0, -8.0, -1, anim.flag or 49, 0, false, false, false)
|
||||
end
|
||||
|
||||
-- Lizenz anzeigen
|
||||
showLicense(licenseData)
|
||||
|
||||
-- Animation nach kurzer Zeit stoppen
|
||||
if Config.Animations and Config.Animations.show_license then
|
||||
CreateThread(function()
|
||||
Wait(2000)
|
||||
ClearPedTasks(playerPed)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Erweiterte Menü-Navigation
|
||||
local menuHistory = {}
|
||||
|
||||
local function pushMenuHistory(menuId)
|
||||
table.insert(menuHistory, menuId)
|
||||
debugPrint("Menü-Historie: " .. menuId .. " hinzugefügt")
|
||||
end
|
||||
|
||||
local function popMenuHistory()
|
||||
if #menuHistory > 0 then
|
||||
local lastMenu = table.remove(menuHistory)
|
||||
debugPrint("Menü-Historie: " .. lastMenu .. " entfernt")
|
||||
return lastMenu
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function clearMenuHistory()
|
||||
menuHistory = {}
|
||||
debugPrint("Menü-Historie geleert")
|
||||
end
|
||||
|
||||
-- Erweiterte Cleanup-Funktion
|
||||
local function cleanup()
|
||||
debugPrint("Führe erweiterte Cleanup-Routine aus...")
|
||||
|
||||
-- NUI schließen
|
||||
if isLicenseShowing then
|
||||
closeLicense()
|
||||
end
|
||||
|
||||
-- Menüs schließen
|
||||
if lib.getOpenContextMenu() then
|
||||
lib.hideContext()
|
||||
end
|
||||
|
||||
-- Cache leeren
|
||||
playerCache = {}
|
||||
|
||||
-- Historie leeren
|
||||
clearMenuHistory()
|
||||
|
||||
-- Pending Requests leeren
|
||||
pendingRequests = {}
|
||||
|
||||
-- Animationen stoppen
|
||||
local playerPed = PlayerPedId()
|
||||
if DoesEntityExist(playerPed) then
|
||||
ClearPedTasks(playerPed)
|
||||
end
|
||||
|
||||
debugPrint("Cleanup abgeschlossen")
|
||||
end
|
||||
|
||||
-- Erweiterte Resource-Stop Handler
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if GetCurrentResourceName() == resourceName then
|
||||
cleanup()
|
||||
debugPrint("License-System Client gestoppt (erweitert)")
|
||||
end
|
||||
end)
|
||||
|
||||
-- Erweiterte Resource-Start Handler
|
||||
AddEventHandler('onResourceStart', function(resourceName)
|
||||
if GetCurrentResourceName() == resourceName then
|
||||
debugPrint("License-System Client gestartet (erweitert)")
|
||||
|
||||
-- Initialisierung
|
||||
CreateThread(function()
|
||||
-- Warten bis QBCore geladen ist
|
||||
while not QBCore do
|
||||
Wait(100)
|
||||
end
|
||||
|
||||
debugPrint("QBCore erfolgreich geladen (erweitert)")
|
||||
|
||||
-- Zusätzliche Initialisierung
|
||||
Wait(1000)
|
||||
|
||||
-- Performance-Stats zurücksetzen
|
||||
performanceStats = {
|
||||
menuOpens = 0,
|
||||
licenseShows = 0,
|
||||
errors = 0
|
||||
}
|
||||
|
||||
debugPrint("Erweiterte Initialisierung abgeschlossen")
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Erweiterte Debug-Funktionen
|
||||
local function debugPlayerInfo()
|
||||
if not Config.Debug then return end
|
||||
|
||||
local PlayerData = QBCore.Functions.GetPlayerData()
|
||||
debugPrint("=== PLAYER DEBUG INFO ===")
|
||||
debugPrint("Name: " .. (PlayerData.charinfo and PlayerData.charinfo.firstname .. " " .. PlayerData.charinfo.lastname or "Unbekannt"))
|
||||
debugPrint("Job: " .. (PlayerData.job and PlayerData.job.name or "Unbekannt"))
|
||||
debugPrint("CitizenID: " .. (PlayerData.citizenid or "Unbekannt"))
|
||||
debugPrint("Server ID: " .. GetPlayerServerId(PlayerId()))
|
||||
debugPrint("========================")
|
||||
end
|
||||
|
||||
-- Debug-Command
|
||||
RegisterCommand('licensedebug', function()
|
||||
if not Config.Debug then
|
||||
showNotification('Debug-Modus ist deaktiviert!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
debugPlayerInfo()
|
||||
|
||||
debugPrint("=== SYSTEM DEBUG INFO ===")
|
||||
debugPrint("Nearby Players: " .. #nearbyPlayers)
|
||||
debugPrint("License Showing: " .. tostring(isLicenseShowing))
|
||||
debugPrint("Menu Open: " .. tostring(lib.getOpenContextMenu() ~= nil))
|
||||
debugPrint("Cached Players: " .. #playerCache)
|
||||
debugPrint("Menu History: " .. #menuHistory)
|
||||
debugPrint("Pending Requests: " .. #pendingRequests)
|
||||
debugPrint("========================")
|
||||
|
||||
showNotification('Debug-Informationen in der Konsole ausgegeben!', 'success')
|
||||
end, false)
|
||||
|
||||
-- Erweiterte Keybind-Behandlung
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(0)
|
||||
|
||||
-- ESC-Taste für Lizenz schließen
|
||||
if isLicenseShowing then
|
||||
if IsControlJustPressed(0, 322) then -- ESC
|
||||
closeLicense()
|
||||
end
|
||||
end
|
||||
|
||||
-- Zusätzliche Hotkeys (falls konfiguriert)
|
||||
if Config.Keybinds and Config.Keybinds.emergency_close then
|
||||
if IsControlJustPressed(0, Config.Keybinds.emergency_close.control) then
|
||||
cleanup()
|
||||
showNotification('Notfall-Schließung aktiviert!', 'info')
|
||||
end
|
||||
end
|
||||
|
||||
-- Performance-Optimierung
|
||||
if not isLicenseShowing and not lib.getOpenContextMenu() then
|
||||
Wait(500)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Erweiterte Netzwerk-Events mit Retry-Mechanismus
|
||||
local function sendEventWithRetry(eventName, data, maxRetries)
|
||||
maxRetries = maxRetries or 3
|
||||
local retries = 0
|
||||
|
||||
local function attemptSend()
|
||||
retries = retries + 1
|
||||
debugPrint("Sende Event: " .. eventName .. " (Versuch " .. retries .. "/" .. maxRetries .. ")")
|
||||
|
||||
TriggerServerEvent(eventName, table.unpack(data or {}))
|
||||
|
||||
-- Timeout für Response
|
||||
CreateThread(function()
|
||||
Wait(5000) -- 5 Sekunden Timeout
|
||||
|
||||
if retries < maxRetries then
|
||||
debugPrint("^3Timeout für Event " .. eventName .. " - Wiederhole...^7")
|
||||
attemptSend()
|
||||
else
|
||||
debugPrint("^1Maximale Wiederholungen für Event " .. eventName .. " erreicht^7")
|
||||
showNotification('Netzwerk-Fehler! Bitte versuche es später erneut.', 'error')
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
attemptSend()
|
||||
end
|
||||
|
||||
-- Erweiterte Export-Funktionen für andere Resources
|
||||
exports('hasLicense', function(licenseType)
|
||||
-- Diese Funktion kann von anderen Resources verwendet werden
|
||||
local PlayerData = QBCore.Functions.GetPlayerData()
|
||||
if not PlayerData or not PlayerData.citizenid then return false end
|
||||
|
||||
-- Hier würde normalerweise eine Server-Anfrage gemacht werden
|
||||
-- Für jetzt geben wir false zurück
|
||||
return false
|
||||
end)
|
||||
|
||||
exports('showPlayerLicense', function(targetId, licenseType)
|
||||
-- Export für andere Resources um Lizenzen anzuzeigen
|
||||
if licenseType then
|
||||
TriggerServerEvent('license-system:server:requestSpecificLicense', targetId, licenseType)
|
||||
else
|
||||
showPlayerLicense(targetId)
|
||||
end
|
||||
end)
|
||||
|
||||
exports('openLicenseMenu', function()
|
||||
-- Export für andere Resources um das Lizenz-Menü zu öffnen
|
||||
openLicenseMenu()
|
||||
end)
|
||||
|
||||
-- Finaler Debug-Output
|
||||
debugPrint("License-System Client vollständig geladen - Alle Funktionen verfügbar")
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue