From 7fd278affbeb5b46297322ead744e3d4641e9b27 Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Mon, 4 Aug 2025 10:19:24 +0200 Subject: [PATCH] ed --- .../inventory_images/images/greencard.png | Bin 0 -> 95009 bytes .../configs/configMetadata.lua | 9 + .../tgiann-inventory/items/items.lua | 13 + .../[tools]/nordi_license/client/main.lua | 1471 ----------------- resources/[tools]/nordi_license/config.lua | 317 ---- .../[tools]/nordi_license/fxmanifest.lua | 35 - .../html/images/drivers_license.png | Bin 9207 -> 0 bytes .../html/images/government_seal.png | Bin 20463 -> 0 bytes .../nordi_license/html/images/id_card.png | Bin 10623 -> 0 bytes .../nordi_license/html/images/watermark.png | Bin 7415 -> 0 bytes .../html/images/weapon_license.png | Bin 10324 -> 0 bytes .../[tools]/nordi_license/html/index.html | 274 --- .../[tools]/nordi_license/html/script.js | 341 ---- .../[tools]/nordi_license/html/style.css | 368 ----- .../[tools]/nordi_license/server/main.lua | 1249 -------------- 15 files changed, 22 insertions(+), 4055 deletions(-) create mode 100644 resources/[inventory]/inventory_images/images/greencard.png delete mode 100644 resources/[tools]/nordi_license/client/main.lua delete mode 100644 resources/[tools]/nordi_license/config.lua delete mode 100644 resources/[tools]/nordi_license/fxmanifest.lua delete mode 100644 resources/[tools]/nordi_license/html/images/drivers_license.png delete mode 100644 resources/[tools]/nordi_license/html/images/government_seal.png delete mode 100644 resources/[tools]/nordi_license/html/images/id_card.png delete mode 100644 resources/[tools]/nordi_license/html/images/watermark.png delete mode 100644 resources/[tools]/nordi_license/html/images/weapon_license.png delete mode 100644 resources/[tools]/nordi_license/html/index.html delete mode 100644 resources/[tools]/nordi_license/html/script.js delete mode 100644 resources/[tools]/nordi_license/html/style.css delete mode 100644 resources/[tools]/nordi_license/server/main.lua diff --git a/resources/[inventory]/inventory_images/images/greencard.png b/resources/[inventory]/inventory_images/images/greencard.png new file mode 100644 index 0000000000000000000000000000000000000000..820d25bf0692171aa60e4967dd595a90b2f97025 GIT binary patch literal 95009 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 literal 0 HcmV?d00001 diff --git a/resources/[inventory]/tgiann-inventory/configs/configMetadata.lua b/resources/[inventory]/tgiann-inventory/configs/configMetadata.lua index 2471c9687..644ea4082 100644 --- a/resources/[inventory]/tgiann-inventory/configs/configMetadata.lua +++ b/resources/[inventory]/tgiann-inventory/configs/configMetadata.lua @@ -8,6 +8,15 @@ config.metadata = { { metadata = "nationality", value = "Nationality:" }, { metadata = "quality", value = "Quality:" }, }, + greencard = { + { metadata = "citizenid", value = "CSN:" }, + { metadata = "firstname", value = "First Name:" }, + { metadata = "lastname", value = "Last Name:" }, + { metadata = "birthdate", value = "Birth Date:" }, + { metadata = "gender", value = "Gender:" }, + { metadata = "nationality", value = "Nationality:" }, + { metadata = "quality", value = "Quality:" }, + }, driver_license = { { metadata = "firstname", value = "First Name:" }, { metadata = "lastname", value = "Last Name:" }, diff --git a/resources/[inventory]/tgiann-inventory/items/items.lua b/resources/[inventory]/tgiann-inventory/items/items.lua index 22f07c456..c30ee9d33 100644 --- a/resources/[inventory]/tgiann-inventory/items/items.lua +++ b/resources/[inventory]/tgiann-inventory/items/items.lua @@ -10915,5 +10915,18 @@ itemsData = { image = 'weaponlicense.png', name = 'weaponlicense', }, + greencard= { + shouldClose = true, + type = 'item', + description = 'Deine Zeitlich begrenzte Genehmigung für deine LS aufenthalt.', + weight = 10, + label = 'Greencard', + unique = true, + useable = true, + image = 'greencard.png', + name = 'greencard', + }, + + } diff --git a/resources/[tools]/nordi_license/client/main.lua b/resources/[tools]/nordi_license/client/main.lua deleted file mode 100644 index 1d649e49f..000000000 --- a/resources/[tools]/nordi_license/client/main.lua +++ /dev/null @@ -1,1471 +0,0 @@ -local QBCore = exports['qb-core']:GetCoreObject() - --- Lokale Variablen -local isMenuOpen = false -local currentTarget = nil -local nearbyPlayers = {} -local isLicenseShowing = false -local pendingRequests = {} -local currentLicenseData = nil -local currentTargetId = nil - --- Hilfsfunktionen -local function debugPrint(message) - if Config.Debug then - print("^3[License-System Client] " .. message .. "^7") - end -end - -local function showNotification(message, type) - QBCore.Functions.Notify(message, type or 'primary') -end - --- Nearby Players abrufen -local function getNearbyPlayers(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) - - table.insert(players, { - id = serverId, - name = playerName, - distance = math.floor(distance * 100) / 100, - ped = targetPed - }) - 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 - --- Berechtigung prüfen -local function hasPermission() - local PlayerData = QBCore.Functions.GetPlayerData() - if not PlayerData or not PlayerData.job then return false end - - local hasAuth = Config.AuthorizedJobs[PlayerData.job.name] or false - debugPrint("Berechtigung für Job " .. PlayerData.job.name .. ": " .. tostring(hasAuth)) - return hasAuth -end - --- Lizenz anzeigen -local function showLicense(licenseData) - if not licenseData then - showNotification(Config.Notifications.license_not_found.message, Config.Notifications.license_not_found.type) - return - end - - debugPrint("Zeige Lizenz: " .. licenseData.license.license_type) - - SendNUIMessage({ - action = 'showLicense', - data = licenseData - }) - - SetNuiFocus(true, true) - isLicenseShowing = true -end - --- Lizenz schließen -local function closeLicense() - SendNUIMessage({ - action = 'hideLicense' - }) - - SetNuiFocus(false, false) - isLicenseShowing = false - debugPrint("Lizenz geschlossen") -end - --- Spieler-Lizenz anzeigen -local function showPlayerLicense(targetId) - debugPrint("=== showPlayerLicense START ===") - debugPrint("Sende Event: requestLicense für Spieler: " .. tostring(targetId)) - - TriggerServerEvent('license-system:server:requestLicense', targetId) -end - --- Eigene Lizenz anzeigen -local function showMyLicense(licenseType) - debugPrint("=== showMyLicense START ===") - debugPrint("Sende Event: requestMyLicense für Typ: " .. tostring(licenseType)) - - TriggerServerEvent('license-system:server:requestMyLicense', licenseType) -end - --- FORWARD DECLARATIONS (Funktionen die später definiert werden) -local confirmIssueLicense -local openIssueLicenseMenu -local openDriversLicenseClassMenu -local openRevokeLicenseMenu -local openPlayerLicenseMenu -local openLicenseMenu -local openManualLicenseEntry -local openReactivateLicenseMenu - --- Helper function to get license type options -local function getLicenseTypeOptions() - local options = {} - for licenseType, config in pairs(Config.LicenseTypes) do - table.insert(options, { - value = licenseType, - label = config.label - }) - end - return options -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 - - local classText = classes and table.concat(classes, ', ') or 'Keine' - local priceText = config.price and (config.price .. ' $') or 'Kostenlos' - - 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', - 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('confirm_issue_license') -end - --- Führerschein-Klassen Menü -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() - local menuOptions = {} - - if config.classes then - for _, class in ipairs(config.classes) do - local isSelected = false - for _, selected in ipairs(selectedClasses) do - if selected == class then - isSelected = true - break - end - end - - local classDescriptions = { - ['A'] = 'Motorräder', - ['A1'] = 'Leichte Motorräder (bis 125ccm)', - ['A2'] = 'Mittlere Motorräder (bis 35kW)', - ['B'] = 'PKW (bis 3,5t)', - ['BE'] = 'PKW mit Anhänger', - ['C'] = 'LKW (über 3,5t)', - ['CE'] = 'LKW mit Anhänger', - ['D'] = 'Bus (über 8 Personen)', - ['DE'] = 'Bus mit Anhänger' - } - - table.insert(menuOptions, { - title = 'Klasse ' .. class .. (isSelected and ' ✅' or ''), - description = classDescriptions[class] or 'Keine Beschreibung', - icon = isSelected and 'fas fa-check-square' or 'far fa-square', - onSelect = function() - if isSelected then - -- Klasse entfernen - for i, selected in ipairs(selectedClasses) do - if selected == class then - table.remove(selectedClasses, i) - break - end - end - else - -- Klasse hinzufügen - table.insert(selectedClasses, class) - end - updateMenu() - end - }) - end - end - - table.insert(menuOptions, { - title = '─────────────────', - disabled = true - }) - - table.insert(menuOptions, { - title = 'Bestätigen (' .. #selectedClasses .. ' Klassen)', - description = 'Führerschein mit ausgewählten Klassen ausstellen', - icon = 'fas fa-check', - disabled = #selectedClasses == 0, - onSelect = function() - confirmIssueLicense(targetId, targetName, licenseType, selectedClasses) - end - }) - - table.insert(menuOptions, { - title = '← Zurück', - icon = 'fas fa-arrow-left', - onSelect = function() - openIssueLicenseMenu(targetId, targetName) - end - }) - - lib.registerContext({ - id = 'drivers_license_classes', - title = 'Führerschein-Klassen: ' .. targetName, - options = menuOptions - }) - - lib.showContext('drivers_license_classes') - end - - updateMenu() -end - --- 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' - - 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 - }) - - lib.registerContext({ - id = 'issue_license', - title = 'Lizenz ausstellen: ' .. targetName, - options = menuOptions - }) - - lib.showContext('issue_license') -end - --- Lizenz entziehen Menü -openRevokeLicenseMenu = function(targetId, targetName, licenses) - debugPrint("Öffne Lizenz-Entziehungs-Menü für: " .. targetName) - - local menuOptions = {} - - for _, license in ipairs(licenses) do - if license.is_active == 1 then - local config = Config.LicenseTypes[license.license_type] or { - label = license.license_type, - icon = 'fas fa-id-card' - } - - table.insert(menuOptions, { - title = config.label, - description = 'Diese Lizenz entziehen', - icon = config.icon, - onSelect = function() - lib.registerContext({ - id = 'confirm_revoke_license', - title = 'Lizenz entziehen bestätigen', - options = { - { - title = 'Spieler: ' .. targetName, - disabled = true, - icon = 'fas fa-user' - }, - { - title = 'Lizenztyp: ' .. config.label, - disabled = true, - icon = config.icon - }, - { - title = '─────────────────', - disabled = true - }, - { - title = '✅ Bestätigen', - description = 'Lizenz jetzt entziehen', - icon = 'fas fa-check', - onSelect = function() - debugPrint("Sende Lizenz-Entziehung an Server...") - TriggerServerEvent('license-system:server:revokeLicense', targetId, license.license_type) - lib.hideContext() - end - }, - { - title = '❌ Abbrechen', - description = 'Vorgang abbrechen', - icon = 'fas fa-times', - onSelect = function() - openRevokeLicenseMenu(targetId, targetName, licenses) - end - } - } - }) - - lib.showContext('confirm_revoke_license') - end - }) - end - end - - if #menuOptions == 0 then - table.insert(menuOptions, { - title = 'Keine aktiven Lizenzen', - description = 'Dieser Spieler hat keine aktiven Lizenzen', - icon = 'fas fa-exclamation-triangle', - disabled = true - }) - end - - table.insert(menuOptions, { - title = '← Zurück', - icon = 'fas fa-arrow-left', - onSelect = function() - openPlayerLicenseMenu(targetId, targetName) - end - }) - - lib.registerContext({ - id = 'revoke_license', - title = 'Lizenz entziehen: ' .. targetName, - options = menuOptions - }) - - lib.showContext('revoke_license') -end - --- Manual License Entry Menu (Vollständig manuell) -openManualLicenseEntry = function(targetId, targetName) - debugPrint("Öffne manuelle Lizenz-Eingabe für: " .. targetName) - - -- Aktuelles Datum für Standardwerte - local currentDate = os.date("%d.%m.%Y") - - -- Berechne Standardablaufdatum (1 Jahr später) - local day, month, year = currentDate:match("(%d+)%.(%d+)%.(%d+)") - local defaultExpireDate = day .. "." .. month .. "." .. (tonumber(year) + 1) - - local input = lib.inputDialog('Lizenz manuell ausstellen', { - {type = 'select', label = 'Lizenztyp', options = getLicenseTypeOptions()}, - {type = 'input', label = 'Name', default = targetName}, - {type = 'input', label = 'Geburtsdatum', description = 'Format: DD.MM.YYYY'}, - {type = 'select', label = 'Geschlecht', options = { - {value = 'male', label = 'Männlich'}, - {value = 'female', label = 'Weiblich'}, - {value = 'other', label = 'Divers'} - }}, - {type = 'input', label = 'Ausstellungsdatum', description = 'Format: DD.MM.YYYY', default = currentDate}, - {type = 'input', label = 'Ablaufdatum', description = 'Format: DD.MM.YYYY', default = defaultExpireDate}, - {type = 'input', label = 'Klassen (kommagetrennt)', description = 'z.B. A,B,C', default = ''}, - {type = 'input', label = 'Bemerkungen', default = ''}, - {type = 'checkbox', label = 'Foto aufnehmen?'} - }) - - if not input then return end - - local licenseType = input[1] - - -- Klassen verarbeiten - local classes = {} - if input[7] and input[7] ~= "" then - for class in string.gmatch(input[7], '([^,]+)') do - table.insert(classes, class:match("^%s*(.-)%s*$")) -- Leerzeichen entfernen - end - end - - local licenseData = { - name = input[2], - birthday = input[3], - gender = input[4], - issue_date = input[5], - expire_date = input[6], - classes = classes, - notes = input[8], - license_type = licenseType - } - - if input[9] then -- Foto aufnehmen - TriggerEvent('license-system:client:openCamera', targetId, licenseData) - else - TriggerServerEvent('license-system:server:issueManualLicense', targetId, licenseData) - end -end - - --- License Reactivation Menu -openReactivateLicenseMenu = function(targetId, targetName) - debugPrint("Öffne Lizenz-Reaktivierungs-Menü für: " .. targetName) - - -- Request all licenses including inactive ones - TriggerServerEvent('license-system:server:requestAllPlayerLicenses', targetId, true) -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 -openLicenseMenu = function() - debugPrint("Öffne Hauptmenü für Lizenz-System") - - if not hasPermission() then - showNotification(Config.Notifications.no_permission.message, Config.Notifications.no_permission.type) - return - end - - nearbyPlayers = getNearbyPlayers(5.0) - - if #nearbyPlayers == 0 then - showNotification(Config.Notifications.no_players_nearby.message, Config.Notifications.no_players_nearby.type) - return - end - - local menuOptions = {} - - for _, player in ipairs(nearbyPlayers) do - table.insert(menuOptions, { - title = player.name, - description = 'Entfernung: ' .. player.distance .. 'm', - icon = 'fas fa-user', - onSelect = function() - openPlayerLicenseMenu(player.id, player.name) - end - }) - end - - lib.registerContext({ - id = 'license_nearby_players', - title = 'Spieler in der Nähe (' .. #nearbyPlayers .. ')', - options = menuOptions - }) - - lib.showContext('license_nearby_players') -end - --- Eigene Lizenzen anzeigen -local function showMyLicenses() - debugPrint("Öffne Menü für eigene Lizenzen") - - local menuOptions = {} - - for licenseType, config in pairs(Config.LicenseTypes) do - table.insert(menuOptions, { - title = config.label, - description = 'Deine ' .. config.label .. ' anzeigen', - icon = config.icon, - onSelect = function() - showMyLicense(licenseType) - end - }) - end - - lib.registerContext({ - id = 'my_licenses', - title = 'Meine Lizenzen', - options = menuOptions - }) - - lib.showContext('my_licenses') -end - --- EVENT HANDLER: Einzelne Lizenz erhalten -RegisterNetEvent('license-system:client:receiveLicense', function(licenseData) - debugPrint("=== Event: receiveLicense ===") - debugPrint("LicenseData-Typ: " .. type(licenseData)) - - if licenseData then - debugPrint("Lizenz-Daten erhalten: " .. licenseData.license.license_type) - showLicense(licenseData) - else - debugPrint("Keine Lizenz-Daten erhalten") - showNotification(Config.Notifications.license_not_found.message, Config.Notifications.license_not_found.type) - end -end) - --- EVENT HANDLER: Eigene Lizenz erhalten -RegisterNetEvent('license-system:client:receiveMyLicense', function(licenseData, licenseType) - debugPrint("=== Event: receiveMyLicense ===") - debugPrint("LicenseType: " .. tostring(licenseType)) - debugPrint("LicenseData-Typ: " .. type(licenseData)) - - if licenseData then - debugPrint("Eigene Lizenz-Daten erhalten: " .. licenseData.license.license_type) - showLicense(licenseData) - else - debugPrint("Keine eigene Lizenz gefunden") - local config = Config.LicenseTypes[licenseType] - local licenseName = config and config.label or licenseType - showNotification('Du hast keine ' .. licenseName .. '!', 'error') - end -end) - --- EVENT HANDLER: Alle Spieler-Lizenzen erhalten -RegisterNetEvent('license-system:client:receivePlayerLicenses', function(licenses, targetId, targetName) - debugPrint("=== Event: receivePlayerLicenses ===") - debugPrint("Erhaltene Lizenzen: " .. #licenses) - debugPrint("TargetName: " .. tostring(targetName)) - - local menuOptions = {} - - if licenses and #licenses > 0 then - for _, license in ipairs(licenses) do - local licenseConfig = Config.LicenseTypes[license.license_type] or { - label = license.license_type, - icon = 'fas fa-id-card', - color = '#667eea' - } - - local statusIcon = (license.is_active == 1) and '✅' or '❌' - local statusText = (license.is_active == 1) and 'Gültig' or 'Ungültig' - local expireText = license.expire_date or 'Unbegrenzt' - - table.insert(menuOptions, { - title = licenseConfig.label .. ' ' .. statusIcon, - description = 'Status: ' .. statusText .. ' | Gültig bis: ' .. expireText, - icon = licenseConfig.icon, - onSelect = function() - local licenseData = { - license = license, - config = licenseConfig - } - showLicense(licenseData) - end, - metadata = { - {label = 'Status', value = statusText}, - {label = 'Ausgestellt', value = license.issue_date or 'Unbekannt'}, - {label = 'Gültig bis', value = expireText}, - {label = 'Aussteller', value = license.issued_by_name or 'System'} - } - }) - end - else - table.insert(menuOptions, { - title = 'Keine Lizenzen gefunden', - description = 'Dieser Spieler hat keine Lizenzen', - icon = 'fas fa-exclamation-triangle', - disabled = true - }) - end - - -- Aktionen hinzufügen - table.insert(menuOptions, { - title = '─────────────────', - disabled = true - }) - - table.insert(menuOptions, { - title = 'Neue Lizenz ausstellen', - description = 'Eine neue Lizenz für diesen Spieler ausstellen', - icon = 'fas fa-plus', - onSelect = function() - openIssueLicenseMenu(targetId, targetName) - end - }) - - table.insert(menuOptions, { - title = 'Lizenz manuell ausstellen', - description = 'Lizenz mit benutzerdefinierten Daten ausstellen', - icon = 'fas fa-edit', - onSelect = function() - openManualLicenseEntry(targetId, targetName) - end - }) - - if licenses and #licenses > 0 then - table.insert(menuOptions, { - title = 'Lizenz entziehen', - description = 'Eine bestehende Lizenz entziehen', - icon = 'fas fa-minus', - onSelect = function() - openRevokeLicenseMenu(targetId, targetName, licenses) - end - }) - end - - table.insert(menuOptions, { - title = 'Lizenz reaktivieren', - description = 'Eine inaktive Lizenz wieder aktivieren', - icon = 'fas fa-redo', - onSelect = function() - openReactivateLicenseMenu(targetId, targetName) - end - }) - - table.insert(menuOptions, { - title = '← Zurück', - icon = 'fas fa-arrow-left', - onSelect = function() - openLicenseMenu() - end - }) - - lib.registerContext({ - id = 'player_licenses', - title = 'Lizenzen: ' .. targetName, - options = menuOptions - }) - - lib.showContext('player_licenses') -end) - --- EVENT HANDLER: Alle Spieler-Lizenzen (inkl. inaktive) erhalten -RegisterNetEvent('license-system:client:receiveAllPlayerLicenses', function(licenses, targetId, targetName) - debugPrint("=== Event: receiveAllPlayerLicenses ===") - debugPrint("Erhaltene Lizenzen: " .. #licenses) - - local menuOptions = {} - - if licenses and #licenses > 0 then - for _, license in ipairs(licenses) do - if license.is_active == 0 then -- Only show inactive licenses - local licenseConfig = Config.LicenseTypes[license.license_type] or { - label = license.license_type, - icon = 'fas fa-id-card', - color = '#667eea' - } - - table.insert(menuOptions, { - title = licenseConfig.label .. ' ❌', - description = 'Status: Ungültig | Ausgestellt: ' .. (license.issue_date or 'Unbekannt'), - icon = licenseConfig.icon, - onSelect = function() - -- Confirmation dialog - lib.registerContext({ - id = 'confirm_reactivate_license', - title = 'Lizenz reaktivieren bestätigen', - options = { - { - title = 'Spieler: ' .. targetName, - disabled = true, - icon = 'fas fa-user' - }, - { - title = 'Lizenztyp: ' .. licenseConfig.label, - disabled = true, - icon = licenseConfig.icon - }, - { - title = '─────────────────', - disabled = true - }, - { - title = '✅ Bestätigen', - description = 'Lizenz jetzt reaktivieren', - icon = 'fas fa-check', - onSelect = function() - debugPrint("Sende Lizenz-Reaktivierung an Server...") - TriggerServerEvent('license-system:server:reactivateLicense', targetId, license.license_type) - lib.hideContext() - end - }, - { - title = '❌ Abbrechen', - description = 'Vorgang abbrechen', - icon = 'fas fa-times', - onSelect = function() - openReactivateLicenseMenu(targetId, targetName) - end - } - } - }) - - lib.showContext('confirm_reactivate_license') - end - }) - end - end - end - - if #menuOptions == 0 then - table.insert(menuOptions, { - title = 'Keine inaktiven Lizenzen', - description = 'Dieser Spieler hat keine inaktiven Lizenzen', - icon = 'fas fa-exclamation-triangle', - disabled = true - }) - end - - table.insert(menuOptions, { - title = '← Zurück', - icon = 'fas fa-arrow-left', - onSelect = function() - openPlayerLicenseMenu(targetId, targetName) - end - }) - - lib.registerContext({ - id = 'reactivate_license', - title = 'Lizenz reaktivieren: ' .. targetName, - options = menuOptions - }) - - lib.showContext('reactivate_license') -end) - --- EVENT HANDLER: Berechtigung erhalten -RegisterNetEvent('license-system:client:receivePermission', function(hasAuth, licenseType) - debugPrint("=== Event: receivePermission ===") - debugPrint("Berechtigung für " .. licenseType .. ": " .. tostring(hasAuth)) - - if not hasAuth then - showNotification(Config.Notifications.no_permission.message, Config.Notifications.no_permission.type) - end -end) - --- EVENT HANDLER: Lizenz erfolgreich ausgestellt -RegisterNetEvent('license-system:client:licenseIssued', function(targetId, licenseType) - debugPrint("=== Event: licenseIssued ===") - debugPrint("Lizenz " .. licenseType .. " für Spieler " .. targetId .. " ausgestellt") - - -- Menü aktualisieren - if lib.getOpenContextMenu() then - lib.hideContext() - Wait(100) - openLicenseMenu() - end -end) - --- EVENT HANDLER: Lizenz erfolgreich entzogen -RegisterNetEvent('license-system:client:licenseRevoked', function(targetId, licenseType) - debugPrint("=== Event: licenseRevoked ===") - debugPrint("Lizenz " .. licenseType .. " für Spieler " .. targetId .. " entzogen") - - -- Menü aktualisieren - if lib.getOpenContextMenu() then - lib.hideContext() - Wait(100) - openLicenseMenu() - end -end) - --- EVENT HANDLER: Lizenz erfolgreich reaktiviert -RegisterNetEvent('license-system:client:licenseReactivated', function(targetId, licenseType) - debugPrint("=== Event: licenseReactivated ===") - debugPrint("Lizenz " .. licenseType .. " für Spieler " .. targetId .. " reaktiviert") - - -- Menü aktualisieren - if lib.getOpenContextMenu() then - lib.hideContext() - Wait(100) - openLicenseMenu() - end -end) - --- EVENT HANDLER: Lizenz anzeigen (von anderen Spielern) -RegisterNetEvent('license-system:client:showLicense', function(targetId) - debugPrint("Event erhalten: showLicense für ID " .. tostring(targetId)) - showPlayerLicense(targetId) -end) - --- EVENT HANDLER: Eigene Lizenz anzeigen -RegisterNetEvent('license-system:client:showMyLicense', function(licenseType) - debugPrint("Event erhalten: showMyLicense für Typ " .. tostring(licenseType)) - showMyLicense(licenseType) -end) - --- EVENT HANDLER: Kamera öffnen -RegisterNetEvent('license-system:client:openCamera', function(targetId, licenseData) - debugPrint("Event erhalten: openCamera für Spieler " .. tostring(targetId)) - - -- Store the data temporarily - currentLicenseData = licenseData - currentTargetId = targetId - - SendNUIMessage({ - action = 'openCamera', - citizenid = QBCore.Functions.GetPlayerData().citizenid - }) -end) - --- EVENT HANDLER: Menü aktualisieren -RegisterNetEvent('license-system:client:refreshMenu', function() - debugPrint("Event erhalten: refreshMenu") - if lib.getOpenContextMenu() then - lib.hideContext() - Wait(100) - openLicenseMenu() - end -end) - --- NUI CALLBACKS -RegisterNUICallback('closeLicense', function(data, cb) - debugPrint("NUI Callback: closeLicense") - closeLicense() - - if cb and type(cb) == "function" then - cb('ok') - end -end) - -RegisterNUICallback('savePhoto', function(data, cb) - debugPrint("NUI Callback: savePhoto") - - if data.photo and currentLicenseData and currentTargetId then - -- Add photo to license data - currentLicenseData.photo_url = data.photo - - -- Issue the license with the photo - TriggerServerEvent('license-system:server:issueManualLicense', currentTargetId, currentLicenseData) - - -- Reset temporary data - currentLicenseData = nil - currentTargetId = nil - - if cb and type(cb) == "function" then - cb('ok') - end - else - debugPrint("^1Fehler: Foto-Daten unvollständig oder keine aktuelle Lizenz-Ausstellung^7") - - if cb and type(cb) == "function" then - cb('error') - end - end -end) - -RegisterNUICallback('takePicture', function(data, cb) - debugPrint("NUI Callback: takePicture") - - -- Hier könnte eine Kamera-Funktion implementiert werden - if cb and type(cb) == "function" then - cb('ok') - end -end) - --- COMMANDS -RegisterCommand(Config.Commands.license.name, function() - debugPrint("Command ausgeführt: " .. Config.Commands.license.name) - openLicenseMenu() -end, Config.Commands.license.restricted) - -RegisterCommand(Config.Commands.mylicense.name, function() - debugPrint("Command ausgeführt: " .. Config.Commands.mylicense.name) - showMyLicenses() -end, Config.Commands.mylicense.restricted) - --- Zusätzliche Commands für schnellen Zugriff -RegisterCommand('ausweis', function() - debugPrint("Command ausgeführt: ausweis") - showMyLicense('id_card') -end, false) - -RegisterCommand('führerschein', function() - debugPrint("Command ausgeführt: führerschein") - showMyLicense('drivers_license') -end, false) - -RegisterCommand('waffenschein', function() - debugPrint("Command ausgeführt: waffenschein") - showMyLicense('weapon_license') -end, false) - -RegisterCommand('pass', function() - debugPrint("Command ausgeführt: pass") - showMyLicense('passport') -end, false) - --- KEYBINDS -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 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 - --- ESC-Taste zum Schließen der Lizenz -CreateThread(function() - while true do - Wait(0) - - if isLicenseShowing then - if IsControlJustPressed(0, 322) then -- ESC-Taste - closeLicense() - end - else - Wait(500) - end - end -end) - --- CLEANUP UND INITIALISIERUNG -AddEventHandler('onResourceStop', function(resourceName) - if GetCurrentResourceName() == resourceName then - if isLicenseShowing then - closeLicense() - end - - if lib.getOpenContextMenu() then - lib.hideContext() - end - - -- Reset temporary data - currentLicenseData = nil - currentTargetId = nil - - debugPrint("License-System Client gestoppt") - end -end) - -AddEventHandler('onResourceStart', function(resourceName) - if GetCurrentResourceName() == resourceName then - debugPrint("License-System Client gestartet (Event-basiert)") - - -- Warten bis QBCore geladen ist - while not QBCore do - Wait(100) - end - - debugPrint("QBCore erfolgreich geladen") - end -end) - --- Player laden Event -RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() - debugPrint("Spieler geladen - License-System bereit") -end) - --- Job Update Event -RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo) - debugPrint("Job aktualisiert: " .. JobInfo.name) -end) - --- Initialisierung -CreateThread(function() - debugPrint("License-System Client Thread gestartet") - - -- Warten bis Spieler gespawnt ist - while not NetworkIsPlayerActive(PlayerId()) do - Wait(100) - end - - debugPrint("Spieler ist aktiv - System bereit") -end) - --- Zusätzliche Utility-Funktionen -local function requestLicenseWithTimeout(eventName, targetId, timeout) - timeout = timeout or 5000 - local requestId = math.random(1000, 9999) - - pendingRequests[requestId] = { - timestamp = GetGameTimer(), - timeout = timeout - } - - debugPrint("Sende Request mit Timeout: " .. eventName .. " (ID: " .. requestId .. ")") - TriggerServerEvent(eventName, targetId, requestId) - - -- Timeout-Handler - CreateThread(function() - Wait(timeout) - if pendingRequests[requestId] then - pendingRequests[requestId] = nil - debugPrint("^1Request Timeout: " .. eventName .. " (ID: " .. requestId .. ")^7") - showNotification('Anfrage-Timeout! Versuche es erneut.', 'error') - end - end) - - return requestId -end - --- Erweiterte Error-Handling -local function safeExecute(func, errorMessage) - local success, error = pcall(func) - if not success then - debugPrint("^1Fehler: " .. (errorMessage or "Unbekannter Fehler") .. "^7") - debugPrint("^1Details: " .. tostring(error) .. "^7") - showNotification('Ein Fehler ist aufgetreten!', 'error') - end - return success -end - --- Performance-Monitoring -local performanceStats = { - menuOpens = 0, - licenseShows = 0, - errors = 0 -} - -CreateThread(function() - while true do - Wait(60000) -- Jede Minute - - if Config.Debug then - debugPrint("=== Performance Stats ===") - debugPrint("Menü-Öffnungen: " .. performanceStats.menuOpens) - debugPrint("Lizenz-Anzeigen: " .. performanceStats.licenseShows) - debugPrint("Fehler: " .. performanceStats.errors) - end - end -end) - --- Stats aktualisieren -local originalOpenLicenseMenu = openLicenseMenu -openLicenseMenu = function() - performanceStats.menuOpens = performanceStats.menuOpens + 1 - return originalOpenLicenseMenu() -end - -local originalShowLicense = showLicense -showLicense = function(licenseData) - performanceStats.licenseShows = performanceStats.licenseShows + 1 - 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 = {} - - -- Temporary data leeren - currentLicenseData = nil - currentTargetId = nil - - -- 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) - --- Finaler Debug-Output -debugPrint("License-System Client vollständig geladen - Alle Funktionen verfügbar") - diff --git a/resources/[tools]/nordi_license/config.lua b/resources/[tools]/nordi_license/config.lua deleted file mode 100644 index d9a05f41f..000000000 --- a/resources/[tools]/nordi_license/config.lua +++ /dev/null @@ -1,317 +0,0 @@ -Config = {} - --- Allgemeine Einstellungen -Config.Debug = true -Config.UseBackgroundImages = true -Config.MaxLicenseAge = 365 -- Tage bis Ablauf -Config.RenewalDays = 30 -- Tage vor Ablauf für Verlängerung - --- Berechtigte Jobs -Config.AuthorizedJobs = { - ['police'] = true, - ['sheriff'] = true, - ['government'] = true, - ['judge'] = true, - ['lawyer'] = true, - ['ambulance'] = true, -- Für medizinische Lizenzen - ['mechanic'] = true -- Für Fahrzeug-Lizenzen -} - --- Jobs that can reactivate specific license types -Config.ReactivationPermissions = { - ['police'] = {'weapon_license', 'drivers_license'}, - ['admin'] = {'id_card', 'passport', 'business_license'}, - ['ambulance'] = {'medical_license'}, - ['driving_school'] = {'drivers_license'}, - ['harbor'] = {'boat_license'}, - ['airport'] = {'pilot_license'} -} - - --- Lizenz-Typen -Config.LicenseTypes = { - ['id_card'] = { - label = 'Personalausweis', - icon = 'fas fa-id-card', - color = '#667eea', - price = 50, - required_items = {}, - can_expire = true, - validity_days = 3650, -- 10 Jahre - required_job = nil, - description = 'Offizieller Personalausweis' - }, - ['drivers_license'] = { - label = 'Führerschein', - icon = 'fas fa-car', - color = '#f093fb', - price = 500, - required_items = {'driving_test_certificate'}, - can_expire = true, - validity_days = 5475, -- 15 Jahre - required_job = 'driving_school', - description = 'Berechtigung zum Führen von Kraftfahrzeugen', - classes = { - 'A', 'A1', 'A2', 'B', 'BE', 'C', 'CE', 'D', 'DE' - } - }, - ['weapon_license'] = { - label = 'Waffenschein', - icon = 'fas fa-crosshairs', - color = '#4facfe', - price = 2500, - required_items = {'weapon_course_certificate', 'psychological_evaluation'}, - can_expire = true, - validity_days = 1095, -- 3 Jahre - required_job = 'police', - description = 'Berechtigung zum Führen von Schusswaffen', - restrictions = { - 'Nur für registrierte Waffen', - 'Regelmäßige Überprüfung erforderlich', - 'Nicht übertragbar' - } - }, - ['passport'] = { - label = 'Reisepass', - icon = 'fas fa-passport', - color = '#43e97b', - price = 150, - required_items = {'birth_certificate', 'id_card'}, - can_expire = true, - validity_days = 3650, -- 10 Jahre - required_job = 'government', - description = 'Internationales Reisedokument' - }, - ['business_license'] = { - label = 'Gewerbeschein', - icon = 'fas fa-briefcase', - color = '#fa709a', - price = 1000, - required_items = {'business_plan', 'tax_certificate'}, - can_expire = true, - validity_days = 1825, -- 5 Jahre - required_job = 'government', - description = 'Berechtigung zur Ausübung eines Gewerbes' - }, - ['pilot_license'] = { - label = 'Pilotenlizenz', - icon = 'fas fa-plane', - color = '#667eea', - price = 5000, - required_items = {'flight_hours_log', 'medical_certificate'}, - can_expire = true, - validity_days = 730, -- 2 Jahre - required_job = 'airport', - description = 'Berechtigung zum Führen von Luftfahrzeugen' - }, - ['boat_license'] = { - label = 'Bootsführerschein', - icon = 'fas fa-ship', - color = '#00f2fe', - price = 800, - required_items = {'boat_course_certificate'}, - can_expire = true, - validity_days = 1825, -- 5 Jahre - required_job = 'harbor', - description = 'Berechtigung zum Führen von Wasserfahrzeugen' - }, - ['medical_license'] = { - label = 'Approbation', - icon = 'fas fa-user-md', - color = '#ff6b6b', - price = 0, -- Kostenlos für Ärzte - required_items = {'medical_degree', 'medical_exam'}, - can_expire = false, - validity_days = nil, - required_job = 'ambulance', - description = 'Berechtigung zur Ausübung der Heilkunde' - }, - ['hunting_license'] = { - label = 'Jagdschein', - icon = 'fas fa-crosshairs', - color = '#8b5a3c', - price = 300, - required_items = {'hunting_course_certificate'}, - can_expire = true, - validity_days = 1095, -- 3 Jahre - required_job = 'police', - description = 'Berechtigung zur Ausübung der Jagd' - }, - ['fishing_license'] = { - label = 'Angelschein', - icon = 'fas fa-fish', - color = '#4ecdc4', - price = 50, - required_items = {}, - can_expire = true, - validity_days = 365, -- 1 Jahr - required_job = 'police', - description = 'Berechtigung zum Angeln in öffentlichen Gewässern' - } -} - --- Standorte für Lizenz-Ausgabe -Config.LicenseLocations = { - ['city_hall'] = { - label = 'Rathaus', - coords = vector3(-544.85, -204.13, 38.22), - blip = { - sprite = 419, - color = 2, - scale = 0.8 - }, - available_licenses = { - 'id_card', 'passport', 'business_license' - }, - ped = { - model = 'a_m_m_business_01', - coords = vector4(-544.9543, -204.8450, 37.2151, 219.1676) - } - }, - ['driving_school'] = { - label = 'Fahrschule', - coords = vector3(-829.22, -1209.58, 7.33), - blip = { - sprite = 225, - color = 46, - scale = 0.8 - }, - available_licenses = { - 'drivers_license' - }, - ped = { - model = 'a_m_y_business_02', - coords = vector4(-829.22, -1209.58, 6.33, 90.0) - } - }, - ['police_station'] = { - label = 'Polizeiwache', - coords = vector3(441.07, -979.76, 30.69), - blip = { - sprite = 60, - color = 29, - scale = 0.8 - }, - available_licenses = { - 'weapon_license' - }, - ped = { - model = 's_m_y_cop_01', - coords = vector4(441.07, -979.76, 29.69, 270.0) - } - }, - ['hospital'] = { - label = 'Krankenhaus', - coords = vector3(307.7, -1433.4, 29.9), - blip = { - sprite = 61, - color = 1, - scale = 0.8 - }, - available_licenses = { - 'medical_license' - }, - ped = { - model = 's_m_m_doctor_01', - coords = vector4(307.7, -1433.4, 28.9, 180.0) - } - } -} - --- Kommandos -Config.Commands = { - ['license'] = { - name = 'lizenz', - help = 'Lizenz-System öffnen', - restricted = true -- Nur für berechtigte Jobs - }, - ['mylicense'] = { - name = 'meinelizenz', - help = 'Eigene Lizenzen anzeigen', - restricted = false -- Für alle Spieler - }, - ['givelicense'] = { - name = 'givelicense', - help = 'Lizenz an Spieler vergeben', - restricted = true, - admin_only = true - }, - ['revokelicense'] = { - name = 'revokelicense', - help = 'Lizenz entziehen', - restricted = true, - admin_only = false - } -} - --- Keybinds -Config.Keybinds = { - ['open_license_menu'] = { - key = 'F6', - command = 'lizenz', - description = 'Lizenz-System öffnen' - }, - ['show_my_licenses'] = { - key = 'F7', - command = 'meinelizenz', - description = 'Meine Lizenzen anzeigen' - } -} - --- Benachrichtigungen -Config.Notifications = { - ['no_permission'] = { - message = 'Du hast keine Berechtigung!', - type = 'error' - }, - ['no_players_nearby'] = { - message = 'Keine Spieler in der Nähe!', - type = 'error' - }, - ['license_not_found'] = { - message = 'Keine Lizenz gefunden!', - type = 'error' - }, - ['license_expired'] = { - message = 'Diese Lizenz ist abgelaufen!', - type = 'warning' - }, - ['license_expires_soon'] = { - message = 'Diese Lizenz läuft bald ab!', - type = 'warning' - }, - ['license_granted'] = { - message = 'Lizenz erfolgreich ausgestellt!', - type = 'success' - }, - ['license_revoked'] = { - message = 'Lizenz wurde entzogen!', - type = 'info' - }, - ['photo_saved'] = { - message = 'Foto gespeichert!', - type = 'success' - }, - ['insufficient_funds'] = { - message = 'Nicht genügend Geld!', - type = 'error' - }, - ['missing_items'] = { - message = 'Benötigte Gegenstände fehlen!', - type = 'error' - } -} - --- Sounds -Config.Sounds = { - ['card_flip'] = 'sounds/card_flip.mp3', - ['camera_shutter'] = 'sounds/camera_shutter.mp3', - ['notification'] = 'sounds/notification.mp3' -} - --- Datenbank-Einstellungen -Config.Database = { - ['table_name'] = 'player_licenses', - ['auto_cleanup'] = true, -- Alte Lizenzen automatisch löschen - ['cleanup_days'] = 365 -- Nach wie vielen Tagen löschen -} diff --git a/resources/[tools]/nordi_license/fxmanifest.lua b/resources/[tools]/nordi_license/fxmanifest.lua deleted file mode 100644 index 2ddcd9f06..000000000 --- a/resources/[tools]/nordi_license/fxmanifest.lua +++ /dev/null @@ -1,35 +0,0 @@ -fx_version 'cerulean' -game 'gta5' - -author 'YourName' -description 'License System for QBCore' -version '1.0.0' - -shared_scripts { - '@ox_lib/init.lua', - 'config.lua' -} - -client_scripts { - 'client/main.lua' -} - -server_scripts { - '@oxmysql/lib/MySQL.lua', - 'server/main.lua' -} - -ui_page 'html/index.html' - -files { - 'html/index.html', - 'html/style.css', - 'html/script.js', - 'html/images/*.png' -} - -dependencies { - 'qb-core', - 'ox_lib', - 'oxmysql' -} diff --git a/resources/[tools]/nordi_license/html/images/drivers_license.png b/resources/[tools]/nordi_license/html/images/drivers_license.png deleted file mode 100644 index 77dff3b18b2e5cf81b05af41b93c5c9ff27f765a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9207 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 BJXHVy diff --git a/resources/[tools]/nordi_license/html/images/government_seal.png b/resources/[tools]/nordi_license/html/images/government_seal.png deleted file mode 100644 index 993072d3e011125d6be3f8840f426ed13061f893..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20463 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 TIv$Q9Dlt@*G!-l4ErS0KQRY9C diff --git a/resources/[tools]/nordi_license/html/images/watermark.png b/resources/[tools]/nordi_license/html/images/watermark.png deleted file mode 100644 index d304a430e2501ab0fe9ea41b0add4c6062cb407a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7415 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%0ArjrL`eT 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 - - - - - License System - - - - - - - - -

- - - - - - - - -
- -
- - - - - - - - - - diff --git a/resources/[tools]/nordi_license/html/script.js b/resources/[tools]/nordi_license/html/script.js deleted file mode 100644 index 67a71241b..000000000 --- a/resources/[tools]/nordi_license/html/script.js +++ /dev/null @@ -1,341 +0,0 @@ -let currentLicense = null; -let isCardFlipped = false; -let cameraStream = null; - -// Event Listener für Nachrichten von FiveM -window.addEventListener('message', function(event) { - const data = event.data; - - switch(data.action) { - case 'showLicense': - showLicense(data.data); - break; - case 'hideLicense': - closeLicense(); - break; - case 'openCamera': - openCamera(); - break; - } -}); - -// In der showLicense Funktion in script.js -function showLicense(data) { - currentLicense = data; - const container = document.getElementById('license-container'); - const card = document.getElementById('license-card'); - - // Loading anzeigen - showLoading(); - - setTimeout(() => { - // Lizenztyp-spezifische Klasse hinzufügen - card.className = 'license-card ' + data.license.license_type; - - // Header befüllen - document.getElementById('license-title').textContent = data.config.label; - document.getElementById('license-icon').className = 'license-icon ' + data.config.icon; - - // Persönliche Daten - document.getElementById('license-name').textContent = data.license.name || 'N/A'; - document.getElementById('license-birthday').textContent = formatDate(data.license.birthday) || 'N/A'; - document.getElementById('license-gender').textContent = formatGender(data.license.gender) || 'N/A'; - - // Dokument-Informationen - document.getElementById('license-issue').textContent = formatDate(data.license.issue_date) || 'N/A'; - document.getElementById('license-expire').textContent = formatDate(data.license.expire_date) || 'N/A'; - document.getElementById('license-id').textContent = '#' + (data.license.id || '000000').toString().padStart(6, '0'); - document.getElementById('license-issuer').textContent = data.license.issued_by_name || 'Behörde'; - - // Foto anzeigen - displayPlayerPhoto(data.license); - - // Klassen anzeigen (nur bei Führerschein) - displayLicenseClasses(data.license); - - // Status und Gültigkeit - displayLicenseStatus(data.license); - displayValidityIndicator(data.license); - - // Rückseite vorbereiten - prepareBackSide(data.license); - - // Container anzeigen - hideLoading(); - container.classList.remove('hidden'); - - // Sound-Effekt - playSound('card-flip-sound'); - - // Notification - showNotification('Lizenz geladen', 'success'); - }, 500); -} - -// Erweitere die prepareBackSide Funktion um Bemerkungen anzuzeigen -function prepareBackSide(license) { - const classesGrid = document.getElementById('classes-grid'); - const restrictionsList = document.getElementById('restrictions-list'); - const notesText = document.getElementById('notes-text'); - - // Klassen-Grid für Führerschein - if (license.license_type === 'drivers_license' && license.classes) { - try { - const classes = Array.isArray(license.classes) ? license.classes : JSON.parse(license.classes); - classesGrid.innerHTML = ''; - - const classDescriptions = { - 'A': 'Motorräder', - 'A1': 'Leichte Motorräder', - 'A2': 'Mittlere Motorräder', - 'B': 'PKW', - 'BE': 'PKW mit Anhänger', - 'C': 'LKW', - 'CE': 'LKW mit Anhänger', - 'D': 'Bus', - 'DE': 'Bus mit Anhänger' - }; - - if (classes && classes.length > 0) { - classes.forEach(cls => { - const classItem = document.createElement('div'); - classItem.className = 'class-item'; - classItem.innerHTML = ` -
${cls}
-
${classDescriptions[cls] || 'Unbekannt'}
- `; - classesGrid.appendChild(classItem); - }); - } else { - classesGrid.innerHTML = '

Keine Klassen verfügbar

'; - } - } catch (e) { - classesGrid.innerHTML = '

Keine Klassen verfügbar

'; - } - } else { - classesGrid.innerHTML = '

Nicht zutreffend

'; - } - - // Beschränkungen (Beispiel) - restrictionsList.innerHTML = '
  • Keine besonderen Beschränkungen
  • '; - - // Bemerkungen - notesText.textContent = license.notes || 'Keine besonderen Bemerkungen'; -} - - -// Karte drehen -function flipCard() { - const frontSide = document.querySelector('.license-content, .license-footer'); - const backSide = document.getElementById('license-back'); - - isCardFlipped = !isCardFlipped; - - if (isCardFlipped) { - // Zur Rückseite - document.querySelector('.license-content').classList.add('hidden'); - document.querySelector('.license-footer').classList.add('hidden'); - backSide.classList.remove('hidden'); - } else { - // Zur Vorderseite - document.querySelector('.license-content').classList.remove('hidden'); - document.querySelector('.license-footer').classList.remove('hidden'); - backSide.classList.add('hidden'); - } - - playSound('card-flip-sound'); -} - -// Kamera öffnen -async function openCamera() { - const container = document.getElementById('camera-container'); - const video = document.getElementById('camera-video'); - - try { - cameraStream = await navigator.mediaDevices.getUserMedia({ - video: { - width: 640, - height: 480, - facingMode: 'user' - } - }); - - video.srcObject = cameraStream; - container.classList.remove('hidden'); - - showNotification('Kamera geöffnet', 'info'); - } catch (err) { - console.error('Kamera-Zugriff fehlgeschlagen:', err); - showNotification('Kamera-Zugriff fehlgeschlagen', 'error'); - } -} - -// Foto aufnehmen -function takePhoto() { - const video = document.getElementById('camera-video'); - const canvas = document.getElementById('camera-canvas'); - const ctx = canvas.getContext('2d'); - - canvas.width = video.videoWidth; - canvas.height = video.videoHeight; - ctx.drawImage(video, 0, 0); - - const photoData = canvas.toDataURL('image/jpeg', 0.8); - - // Sound-Effekt - playSound('camera-shutter-sound'); - - // An FiveM senden - fetch(`https://${GetParentResourceName()}/savePhoto`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - photo: photoData, - citizenid: currentLicense?.license?.citizenid - }) - }).then(() => { - showNotification('Foto gespeichert', 'success'); - closeCamera(); - }).catch(err => { - console.error('Fehler beim Speichern:', err); - showNotification('Fehler beim Speichern', 'error'); - }); -} - -// Kamera schließen -function closeCamera() { - const container = document.getElementById('camera-container'); - - if (cameraStream) { - cameraStream.getTracks().forEach(track => track.stop()); - cameraStream = null; - } - - container.classList.add('hidden'); -} - -// Lizenz schließen -function closeLicense() { - const container = document.getElementById('license-container'); - container.classList.add('hidden'); - - // Karte zurücksetzen - isCardFlipped = false; - document.querySelector('.license-content').classList.remove('hidden'); - document.querySelector('.license-footer').classList.remove('hidden'); - document.getElementById('license-back').classList.add('hidden'); - - // Callback an FiveM - fetch(`https://${GetParentResourceName()}/closeLicense`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({}) - }).catch(() => {}); // Fehler ignorieren -} - -// Hilfsfunktionen -function formatGender(gender) { - const genderMap = { - 'male': 'Männlich', - 'female': 'Weiblich', - 'other': 'Divers', - 'm': 'Männlich', - 'f': 'Weiblich' - }; - return genderMap[gender?.toLowerCase()] || gender || 'Unbekannt'; -} - -function formatDate(dateString) { - if (!dateString) return null; - - try { - const date = new Date(dateString); - return date.toLocaleDateString('de-DE'); - } catch (e) { - return dateString; - } -} - -function showLoading() { - document.getElementById('loading-overlay').classList.remove('hidden'); -} - -function hideLoading() { - document.getElementById('loading-overlay').classList.add('hidden'); -} - -function playSound(soundId) { - const audio = document.getElementById(soundId); - if (audio) { - audio.volume = 0.3; - audio.play().catch(() => {}); // Fehler ignorieren - } -} - -function showNotification(message, type = 'info') { - const container = document.getElementById('notification-container'); - const notification = document.createElement('div'); - - notification.className = `notification ${type}`; - notification.innerHTML = ` -
    - - ${message} -
    - - `; - - container.appendChild(notification); - - // Auto-remove nach 5 Sekunden - setTimeout(() => { - if (notification.parentElement) { - notification.remove(); - } - }, 5000); -} - -function getNotificationIcon(type) { - const icons = { - 'success': 'fa-check-circle', - 'error': 'fa-exclamation-circle', - 'warning': 'fa-exclamation-triangle', - 'info': 'fa-info-circle' - }; - return icons[type] || icons.info; -} - -// Event Listeners -document.addEventListener('keydown', function(event) { - if (event.key === 'Escape') { - if (!document.getElementById('camera-container').classList.contains('hidden')) { - closeCamera(); - } else if (!document.getElementById('license-container').classList.contains('hidden')) { - closeLicense(); - } - } - - if (event.key === 'f' || event.key === 'F') { - if (!document.getElementById('license-container').classList.contains('hidden')) { - flipCard(); - } - } -}); - -// Klick außerhalb zum Schließen -document.getElementById('license-container').addEventListener('click', function(event) { - if (event.target.classList.contains('license-overlay')) { - closeLicense(); - } -}); - -// Initialisierung -document.addEventListener('DOMContentLoaded', function() { - console.log('License System UI geladen'); -}); diff --git a/resources/[tools]/nordi_license/html/style.css b/resources/[tools]/nordi_license/html/style.css deleted file mode 100644 index f631638fb..000000000 --- a/resources/[tools]/nordi_license/html/style.css +++ /dev/null @@ -1,368 +0,0 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Arial', sans-serif; - background: transparent; - overflow: hidden; -} - -.hidden { - display: none !important; -} - -#license-container { - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - background: rgba(0, 0, 0, 0.8); - display: flex; - justify-content: center; - align-items: center; - z-index: 1000; -} - -.license-card { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - border-radius: 15px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); - width: 450px; - min-height: 300px; - color: white; - position: relative; - overflow: hidden; -} - -.license-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: url('data:image/svg+xml,'); - opacity: 0.3; - pointer-events: none; -} - -.license-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 20px; - border-bottom: 2px solid rgba(255, 255, 255, 0.2); -} - -.license-title { - font-size: 24px; - font-weight: bold; - text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); -} - -.license-logo { - font-size: 32px; - opacity: 0.8; -} - -.license-content { - display: flex; - padding: 20px; - gap: 20px; -} - -.license-photo { - width: 100px; - height: 120px; - background: rgba(255, 255, 255, 0.2); - border-radius: 8px; - display: flex; - align-items: center; - justify-content: center; - border: 2px solid rgba(255, 255, 255, 0.3); - overflow: hidden; - position: relative; -} - -#player-photo { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 6px; -} - -#photo-placeholder { - font-size: 48px; - color: rgba(255, 255, 255, 0.7); -} - -.hidden { - display: none !important; -} - - -.license-info { - flex: 1; -} - -.info-row { - display: flex; - justify-content: space-between; - margin-bottom: 12px; - padding: 8px 0; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); -} - -.info-row:last-child { - border-bottom: none; - margin-bottom: 0; -} - -.label { - font-weight: bold; - opacity: 0.9; - min-width: 100px; -} - -.value { - text-align: right; - opacity: 0.8; -} - -.license-footer { - padding: 20px; - border-top: 2px solid rgba(255, 255, 255, 0.2); - display: flex; - justify-content: space-between; - align-items: center; -} - -.license-status { - font-weight: bold; - padding: 5px 15px; - border-radius: 20px; - font-size: 14px; -} - -.license-status.active { - background: rgba(76, 175, 80, 0.3); - color: #4CAF50; - border: 1px solid #4CAF50; -} - -.license-status.inactive { - background: rgba(244, 67, 54, 0.3); - color: #F44336; - border: 1px solid #F44336; -} - -.close-btn { - background: rgba(255, 255, 255, 0.2); - border: 1px solid rgba(255, 255, 255, 0.3); - color: white; - padding: 10px 20px; - border-radius: 25px; - cursor: pointer; - transition: all 0.3s ease; - font-size: 14px; - display: flex; - align-items: center; - gap: 8px; -} - -.close-btn:hover { - background: rgba(255, 255, 255, 0.3); - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); -} - -/* Spezielle Styles für verschiedene Lizenztypen */ -.license-card.id_card { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -} - -.license-card.drivers_license { - background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); -} - -.license-card.weapon_license { - background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); -} - -.license-card.passport { - background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); -} - -.license-card.business_license { - background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); -} - -/* Responsive Design */ -@media (max-width: 500px) { - .license-card { - width: 90vw; - margin: 20px; - } - - .license-content { - flex-direction: column; - align-items: center; - } - - .license-photo { - width: 80px; - height: 100px; - font-size: 36px; - } -} - -/* Animation für das Erscheinen */ -@keyframes slideIn { - from { - opacity: 0; - transform: translateY(-50px) scale(0.9); - } - to { - opacity: 1; - transform: translateY(0) scale(1); - } -} - -.license-card { - animation: slideIn 0.3s ease-out; -} - -/* Notification System */ -#notification-container { - position: fixed; - top: 20px; - right: 20px; - z-index: 10000; - display: flex; - flex-direction: column; - gap: 10px; -} - -.notification { - background: rgba(0, 0, 0, 0.9); - color: white; - padding: 15px; - border-radius: 8px; - display: flex; - align-items: center; - justify-content: space-between; - min-width: 300px; - animation: slideInRight 0.3s ease; -} - -.notification.success { border-left: 4px solid #4CAF50; } -.notification.error { border-left: 4px solid #f44336; } -.notification.warning { border-left: 4px solid #ff9800; } -.notification.info { border-left: 4px solid #2196F3; } - -.notification-content { - display: flex; - align-items: center; - gap: 10px; -} - -.notification-close { - background: none; - border: none; - color: white; - cursor: pointer; - padding: 5px; -} - -/* Loading Overlay */ -#loading-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.8); - display: flex; - align-items: center; - justify-content: center; - z-index: 9999; -} - -.loading-spinner { - text-align: center; - color: white; -} - -.spinner { - width: 50px; - height: 50px; - border: 3px solid rgba(255, 255, 255, 0.3); - border-top: 3px solid white; - border-radius: 50%; - animation: spin 1s linear infinite; - margin: 0 auto 20px; -} - -/* Kamera Interface */ -#camera-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.9); - display: flex; - align-items: center; - justify-content: center; - z-index: 9998; -} - -.camera-interface { - background: white; - border-radius: 15px; - padding: 20px; - max-width: 600px; - width: 90%; -} - -.camera-preview { - position: relative; - margin: 20px 0; -} - -#camera-video { - width: 100%; - border-radius: 10px; -} - -.face-guide { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - color: white; -} - -.guide-circle { - width: 200px; - height: 200px; - border: 3px solid rgba(255, 255, 255, 0.8); - border-radius: 50%; - margin: 0 auto 10px; -} - -/* Animationen */ -@keyframes slideInRight { - from { transform: translateX(100%); opacity: 0; } - to { transform: translateX(0); opacity: 1; } -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} diff --git a/resources/[tools]/nordi_license/server/main.lua b/resources/[tools]/nordi_license/server/main.lua deleted file mode 100644 index 2a7925a33..000000000 --- a/resources/[tools]/nordi_license/server/main.lua +++ /dev/null @@ -1,1249 +0,0 @@ -local QBCore = exports['qb-core']:GetCoreObject() - --- Lokale Variablen -local licenseCache = {} -local cacheTimeout = 300000 -- 5 Minuten - --- Debug-Funktion -local function debugPrint(message) - if Config.Debug then - print("^3[License-System Server] " .. message .. "^7") - end -end - --- Spieler-Name abrufen -local function getPlayerName(src) - local Player = QBCore.Functions.GetPlayer(src) - if not Player then return "Unbekannt" end - - local charinfo = Player.PlayerData.charinfo - if charinfo and charinfo.firstname and charinfo.lastname then - return charinfo.firstname .. " " .. charinfo.lastname - end - - return "Unbekannt" -end - --- Berechtigung prüfen -local function hasPermission(src) - local Player = QBCore.Functions.GetPlayer(src) - if not Player then return false end - - local job = Player.PlayerData.job - if not job then return false end - - return Config.AuthorizedJobs[job.name] or false -end - --- Cache-Funktionen (KORRIGIERT - Aggressive Cache-Invalidierung) -local function getCachedLicense(citizenid, licenseType) - local cacheKey = citizenid .. "_" .. licenseType - local cached = licenseCache[cacheKey] - - if cached and (os.time() * 1000 - cached.timestamp) < cacheTimeout then - debugPrint("Cache-Hit für: " .. cacheKey) - return cached.data - end - - return nil -end - -local function setCachedLicense(citizenid, licenseType, data) - local cacheKey = citizenid .. "_" .. licenseType - licenseCache[cacheKey] = { - data = data, - timestamp = os.time() * 1000 - } - debugPrint("Lizenz gecacht: " .. cacheKey) -end - --- Cache invalidieren (ERWEITERT) -local function invalidateCache(citizenid, licenseType) - if licenseType then - -- Spezifische Lizenz invalidieren - local cacheKey = citizenid .. "_" .. licenseType - licenseCache[cacheKey] = nil - debugPrint("Cache invalidiert für: " .. cacheKey) - else - -- Alle Lizenzen des Spielers invalidieren - for key, _ in pairs(licenseCache) do - if string.find(key, citizenid .. "_") then - licenseCache[key] = nil - debugPrint("Cache invalidiert für: " .. key) - end - end - end -end - --- Spieler-Name aus JSON extrahieren -local function extractPlayerName(charinfo_json) - if not charinfo_json then return "Unbekannt" end - - local success, charinfo = pcall(json.decode, charinfo_json) - if success and charinfo and charinfo.firstname and charinfo.lastname then - return charinfo.firstname .. " " .. charinfo.lastname - end - - return "Unbekannt" -end - --- Sichere DB-Operation -local function safeDBOperation(operation, errorMessage, maxRetries) - maxRetries = maxRetries or 3 - local retries = 0 - - while retries < maxRetries do - retries = retries + 1 - local success, result = pcall(operation) - - if success then - return result - else - debugPrint("^3DB-Retry " .. retries .. "/" .. maxRetries .. ": " .. tostring(result) .. "^7") - if retries >= maxRetries then - debugPrint("^1DB-Fehler: " .. (errorMessage or "Unbekannt") .. "^7") - debugPrint("^1Details: " .. tostring(result) .. "^7") - return nil - end - Wait(1000) - end - end - - return nil -end - --- Lizenz-Status prüfen (NEUE FUNKTION) -local function isLicenseActive(license) - if not license then return false end - - -- is_active prüfen (1 = aktiv, 0 = inaktiv, nil = aktiv per default) - local isActive = license.is_active - if isActive == nil then - isActive = 1 -- Default: aktiv - end - - if isActive ~= 1 then - debugPrint("Lizenz inaktiv (is_active = " .. tostring(isActive) .. ")") - return false - end - - -- Ablaufdatum prüfen (falls vorhanden) - if license.expire_date and license.expire_date ~= "" then - local expireDate = license.expire_date - local currentDate = os.date("%d.%m.%Y") - - -- Einfache Datumsvergleich (DD.MM.YYYY) - local function parseDate(dateStr) - local day, month, year = dateStr:match("(%d+)%.(%d+)%.(%d+)") - if day and month and year then - return os.time({year = tonumber(year), month = tonumber(month), day = tonumber(day)}) - end - return nil - end - - local expireTimestamp = parseDate(expireDate) - local currentTimestamp = parseDate(currentDate) - - if expireTimestamp and currentTimestamp and expireTimestamp < currentTimestamp then - debugPrint("Lizenz abgelaufen: " .. expireDate .. " < " .. currentDate) - return false - end - end - - debugPrint("Lizenz ist aktiv und gültig") - return true -end - --- KORRIGIERTE Lizenz-Abfrage (Ohne Cache für frische Daten) -local function getLicenseFromDB(citizenid, licenseType, skipCache) - debugPrint("=== getLicenseFromDB START ===") - debugPrint("CitizenID: " .. tostring(citizenid)) - debugPrint("LicenseType: " .. tostring(licenseType)) - debugPrint("SkipCache: " .. tostring(skipCache)) - - -- Cache prüfen (nur wenn nicht übersprungen) - if not skipCache then - local cached = getCachedLicense(citizenid, licenseType) - if cached then - debugPrint("Lizenz aus Cache geladen") - return cached - end - end - - -- Direkte DB-Abfrage (VEREINFACHT - nur aktive Lizenzen) - local query = [[ - SELECT * FROM player_licenses - WHERE citizenid = ? AND license_type = ? - ORDER BY created_at DESC - LIMIT 1 - ]] - - local result = safeDBOperation(function() - return MySQL.query.await(query, {citizenid, licenseType}) - end, "Fehler beim Abrufen der Lizenz") - - if not result or #result == 0 then - debugPrint("^1Keine Lizenz in DB gefunden für " .. citizenid .. " / " .. licenseType .. "^7") - return nil - end - - local license = result[1] - debugPrint("Rohe Lizenz-Daten aus DB:") - debugPrint("ID: " .. tostring(license.id)) - debugPrint("is_active: " .. tostring(license.is_active)) - debugPrint("created_at: " .. tostring(license.created_at)) - - -- Spieler-Namen abrufen - local holderQuery = "SELECT charinfo FROM players WHERE citizenid = ?" - local holderResult = safeDBOperation(function() - return MySQL.query.await(holderQuery, {citizenid}) - end, "Fehler beim Abrufen des Spieler-Namens") - - if holderResult and #holderResult > 0 then - license.holder_name = extractPlayerName(holderResult[1].charinfo) - else - license.holder_name = "Unbekannt" - end - - -- Aussteller-Namen abrufen - if license.issued_by then - local issuerQuery = "SELECT charinfo FROM players WHERE citizenid = ?" - local issuerResult = safeDBOperation(function() - return MySQL.query.await(issuerQuery, {license.issued_by}) - end, "Fehler beim Abrufen des Aussteller-Namens") - - if issuerResult and #issuerResult > 0 then - license.issued_by_name = extractPlayerName(issuerResult[1].charinfo) - else - license.issued_by_name = "System" - end - else - license.issued_by_name = "System" - end - - -- Classes parsen - if license.classes then - local success, classes = pcall(json.decode, license.classes) - if success and type(classes) == "table" then - license.classes = classes - else - license.classes = {} - end - else - license.classes = {} - end - - -- is_active normalisieren (WICHTIG!) - if license.is_active == nil then - license.is_active = 1 - debugPrint("is_active war nil, auf 1 gesetzt") - end - - -- Status prüfen - local isActive = isLicenseActive(license) - debugPrint("Lizenz-Status-Prüfung: " .. tostring(isActive)) - - if not isActive then - debugPrint("Lizenz ist nicht aktiv/gültig") - return nil - end - - debugPrint("Lizenz erfolgreich geladen: " .. license.license_type .. " (Active: " .. tostring(license.is_active) .. ")") - - -- In Cache speichern (nur wenn aktiv) - if not skipCache then - setCachedLicense(citizenid, licenseType, license) - end - - return license -end - --- Alle Lizenzen eines Spielers abrufen (KORRIGIERT) -local function getAllPlayerLicenses(citizenid) - debugPrint("=== getAllPlayerLicenses START ===") - debugPrint("CitizenID: " .. tostring(citizenid)) - - -- Alle Lizenzen abrufen (ohne is_active Filter) - local query = "SELECT * FROM player_licenses WHERE citizenid = ? ORDER BY license_type, created_at DESC" - - local result = safeDBOperation(function() - return MySQL.query.await(query, {citizenid}) - end, "Fehler beim Abrufen aller Lizenzen") - - if not result or #result == 0 then - debugPrint("Keine Lizenzen gefunden für: " .. citizenid) - return {} - end - - local licenses = {} - local seenTypes = {} - - -- Spieler-Namen einmal abrufen - local holderQuery = "SELECT charinfo FROM players WHERE citizenid = ?" - local holderResult = safeDBOperation(function() - return MySQL.query.await(holderQuery, {citizenid}) - end, "Fehler beim Abrufen des Spieler-Namens") - - local holderName = "Unbekannt" - if holderResult and #holderResult > 0 then - holderName = extractPlayerName(holderResult[1].charinfo) - end - - for _, license in ipairs(result) do - -- Nur die neueste Lizenz pro Typ nehmen - if not seenTypes[license.license_type] then - seenTypes[license.license_type] = true - - license.holder_name = holderName - - -- Aussteller-Namen abrufen - if license.issued_by then - local issuerQuery = "SELECT charinfo FROM players WHERE citizenid = ?" - local issuerResult = safeDBOperation(function() - return MySQL.query.await(issuerQuery, {license.issued_by}) - end, "Fehler beim Abrufen des Aussteller-Namens") - - if issuerResult and #issuerResult > 0 then - license.issued_by_name = extractPlayerName(issuerResult[1].charinfo) - else - license.issued_by_name = "System" - end - else - license.issued_by_name = "System" - end - - -- Classes parsen - if license.classes then - local success, classes = pcall(json.decode, license.classes) - if success and type(classes) == "table" then - license.classes = classes - else - license.classes = {} - end - else - license.classes = {} - end - - -- is_active normalisieren - if license.is_active == nil then - license.is_active = 1 - end - - -- Status prüfen und nur aktive Lizenzen hinzufügen - if isLicenseActive(license) then - table.insert(licenses, license) - debugPrint("Aktive Lizenz hinzugefügt: " .. license.license_type) - else - debugPrint("Inaktive Lizenz übersprungen: " .. license.license_type) - end - end - end - - debugPrint("Verarbeitete aktive Lizenzen: " .. #licenses) - return licenses -end - --- Lizenz in Datenbank speichern (KORRIGIERT - Explizite is_active Setzung) -local function saveLicenseToDB(citizenid, licenseType, issuedBy, classes) - debugPrint("=== saveLicenseToDB START ===") - debugPrint("CitizenID: " .. tostring(citizenid)) - debugPrint("LicenseType: " .. tostring(licenseType)) - debugPrint("IssuedBy: " .. tostring(issuedBy)) - - local config = Config.LicenseTypes[licenseType] - if not config then - debugPrint("^1Fehler: Unbekannter Lizenztyp: " .. licenseType .. "^7") - return false - end - - -- Cache für diesen Spieler komplett invalidieren - invalidateCache(citizenid) - - -- Spieler-Name abrufen - local holderQuery = "SELECT charinfo FROM players WHERE citizenid = ?" - local holderResult = safeDBOperation(function() - return MySQL.query.await(holderQuery, {citizenid}) - end, "Fehler beim Abrufen des Spieler-Namens") - - local holderName = "Unbekannt" - if holderResult and #holderResult > 0 and holderResult[1].charinfo then - holderName = extractPlayerName(holderResult[1].charinfo) - end - - -- Datum berechnen - local issueDate = os.date("%d.%m.%Y") - local expireDate = nil - - if config.validity_days then - local expireTimestamp = os.time() + (config.validity_days * 24 * 60 * 60) - expireDate = os.date("%d.%m.%Y", expireTimestamp) - end - - -- Classes zu JSON konvertieren - local classesJson = json.encode(classes or {}) - - -- WICHTIG: Alte Lizenz explizit deaktivieren - local deactivateQuery = "UPDATE player_licenses SET is_active = 0 WHERE citizenid = ? AND license_type = ?" - local deactivateResult = safeDBOperation(function() - return MySQL.query.await(deactivateQuery, {citizenid, licenseType}) - end, "Fehler beim Deaktivieren alter Lizenz") - - debugPrint("Alte Lizenzen deaktiviert: " .. tostring(deactivateResult ~= nil)) - - -- Neue Lizenz einfügen (EXPLIZIT is_active = 1) - local insertQuery = [[ - INSERT INTO player_licenses - (citizenid, license_type, name, issue_date, expire_date, issued_by, is_active, classes, created_at) - VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?) - ]] - - local createdAt = os.time() -- Unix Timestamp - - local insertData = { - citizenid, - licenseType, - holderName, - issueDate, - expireDate, - issuedBy, - -- is_active = 1 ist direkt in der Query - classesJson, - createdAt - } - - debugPrint("Führe INSERT-Query aus...") - debugPrint("Daten: " .. json.encode(insertData)) - - local result = safeDBOperation(function() - return MySQL.insert.await(insertQuery, insertData) - end, "Fehler beim Speichern der Lizenz") - - if result then - debugPrint("Lizenz erfolgreich gespeichert. ID: " .. result) - - -- Cache komplett invalidieren (sicherstellen dass neue Daten geladen werden) - invalidateCache(citizenid) - - -- Sofort neue Lizenz aus DB laden um zu verifizieren - Wait(100) -- Kurz warten - local newLicense = getLicenseFromDB(citizenid, licenseType, true) -- Skip Cache - - if newLicense then - debugPrint("Neue Lizenz erfolgreich verifiziert: is_active = " .. tostring(newLicense.is_active)) - else - debugPrint("^3Warnung: Neue Lizenz konnte nicht verifiziert werden^7") - end - - return true - else - debugPrint("^1Fehler beim Speichern der Lizenz^7") - return false - end -end - --- Lizenz entziehen (KORRIGIERT) -local function revokeLicenseInDB(citizenid, licenseType) - debugPrint("=== revokeLicenseInDB START ===") - debugPrint("CitizenID: " .. tostring(citizenid)) - debugPrint("LicenseType: " .. tostring(licenseType)) - - local query = "UPDATE player_licenses SET is_active = 0 WHERE citizenid = ? AND license_type = ? AND is_active = 1" - - local result = safeDBOperation(function() - return MySQL.query.await(query, {citizenid, licenseType}) - end, "Fehler beim Entziehen der Lizenz") - - if result then - debugPrint("Lizenz erfolgreich entzogen") - - -- Cache invalidieren - invalidateCache(citizenid, licenseType) - - return true - else - debugPrint("^1Fehler beim Entziehen der Lizenz^7") - return false - end -end - --- Cache bereinigen -local function cleanupCache() - local now = os.time() * 1000 - local cleaned = 0 - - for key, cached in pairs(licenseCache) do - if (now - cached.timestamp) > cacheTimeout then - licenseCache[key] = nil - cleaned = cleaned + 1 - end - end - - if cleaned > 0 then - debugPrint("Cache bereinigt: " .. cleaned .. " Einträge") - end -end - --- Cache-Cleanup Thread -CreateThread(function() - while true do - Wait(300000) -- 5 Minuten - cleanupCache() - end -end) - --- EVENT HANDLER: Lizenz anfordern -RegisterNetEvent('license-system:server:requestLicense', function(targetId) - local src = source - debugPrint("=== Event: requestLicense ===") - debugPrint("Source: " .. src .. ", Target: " .. targetId) - - if not hasPermission(src) then - debugPrint("Keine Berechtigung für Spieler: " .. src) - TriggerClientEvent('license-system:client:receiveLicense', src, nil) - return - end - - local targetPlayer = QBCore.Functions.GetPlayer(targetId) - if not targetPlayer then - debugPrint("Ziel-Spieler nicht gefunden: " .. targetId) - TriggerClientEvent('license-system:client:receiveLicense', src, nil) - return - end - - local citizenid = targetPlayer.PlayerData.citizenid - - -- PRIORITÄT: Erst nach Ausweis suchen, dann andere Lizenzen - local licenseTypes = {"id_card", "driver_license", "weapon_license", "pilot_license"} - local foundLicense = nil - - for _, licenseType in ipairs(licenseTypes) do - if Config.LicenseTypes[licenseType] then - local license = getLicenseFromDB(citizenid, licenseType, true) -- Skip Cache für frische Daten - - if license then - foundLicense = { - license = license, - config = Config.LicenseTypes[licenseType] - } - debugPrint("Lizenz gefunden: " .. licenseType) - break - end - end - end - - if foundLicense then - debugPrint("Sende Lizenz an Client: " .. foundLicense.license.license_type) - TriggerClientEvent('license-system:client:receiveLicense', src, foundLicense) - else - debugPrint("Keine Lizenz gefunden") - TriggerClientEvent('license-system:client:receiveLicense', src, nil) - end -end) - --- EVENT HANDLER: Eigene Lizenz anfordern (KORRIGIERT) -RegisterNetEvent('license-system:server:requestMyLicense', function(licenseType) - local src = source - debugPrint("=== Event: requestMyLicense ===") - debugPrint("Source: " .. src .. ", LicenseType: " .. tostring(licenseType)) - - local Player = QBCore.Functions.GetPlayer(src) - if not Player then - debugPrint("Spieler nicht gefunden: " .. src) - TriggerClientEvent('license-system:client:receiveMyLicense', src, nil, licenseType) - return - end - - local citizenid = Player.PlayerData.citizenid - - -- Falls kein spezifischer Typ angegeben, suche nach Ausweis - if not licenseType or licenseType == "" then - licenseType = "id_card" - debugPrint("Kein Lizenztyp angegeben, verwende: " .. licenseType) - end - - local license = getLicenseFromDB(citizenid, licenseType, true) -- Skip Cache für frische Daten - - if license then - local licenseData = { - license = license, - config = Config.LicenseTypes[licenseType] - } - debugPrint("Sende eigene Lizenz an Client: " .. licenseType) - TriggerClientEvent('license-system:client:receiveMyLicense', src, licenseData, licenseType) - else - debugPrint("Keine aktive eigene Lizenz gefunden: " .. licenseType) - TriggerClientEvent('license-system:client:receiveMyLicense', src, nil, licenseType) - end -end) - --- EVENT HANDLER: Alle Spieler-Lizenzen anfordern -RegisterNetEvent('license-system:server:requestPlayerLicenses', function(targetId) - local src = source - debugPrint("=== Event: requestPlayerLicenses ===") - debugPrint("Source: " .. src .. ", Target: " .. targetId) - - if not hasPermission(src) then - debugPrint("Keine Berechtigung für Spieler: " .. src) - TriggerClientEvent('license-system:client:receivePlayerLicenses', src, {}, targetId, "Unbekannt") - return - end - - local targetPlayer = QBCore.Functions.GetPlayer(targetId) - if not targetPlayer then - debugPrint("Ziel-Spieler nicht gefunden: " .. targetId) - TriggerClientEvent('license-system:client:receivePlayerLicenses', src, {}, targetId, "Unbekannt") - return - end - - local citizenid = targetPlayer.PlayerData.citizenid - local targetName = getPlayerName(targetId) - local licenses = getAllPlayerLicenses(citizenid) - - debugPrint("Sende " .. #licenses .. " Lizenzen für " .. targetName) - TriggerClientEvent('license-system:client:receivePlayerLicenses', src, licenses, targetId, targetName) -end) - --- EVENT HANDLER: Lizenz ausstellen (KORRIGIERT) -RegisterNetEvent('license-system:server:issueLicense', function(targetId, licenseType, classes) - local src = source - debugPrint("=== Event: issueLicense ===") - debugPrint("Source: " .. src .. ", Target: " .. targetId .. ", Type: " .. licenseType) - - if not hasPermission(src) then - debugPrint("Keine Berechtigung für Spieler: " .. src) - TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_permission.message, Config.Notifications.no_permission.type) - return - end - - local targetPlayer = QBCore.Functions.GetPlayer(targetId) - if not targetPlayer then - debugPrint("Ziel-Spieler nicht gefunden: " .. targetId) - TriggerClientEvent('QBCore:Notify', src, 'Spieler nicht gefunden!', 'error') - return - end - - local issuerPlayer = QBCore.Functions.GetPlayer(src) - if not issuerPlayer then - debugPrint("Aussteller nicht gefunden: " .. src) - return - end - - local targetCitizenId = targetPlayer.PlayerData.citizenid - local issuerCitizenId = issuerPlayer.PlayerData.citizenid - - -- Prüfen ob aktive Lizenz bereits existiert (Skip Cache) - local existingLicense = getLicenseFromDB(targetCitizenId, licenseType, true) - - if existingLicense then - debugPrint("Lizenz bereits vorhanden und aktiv") - TriggerClientEvent('QBCore:Notify', src, 'Spieler hat bereits eine aktive ' .. (Config.LicenseTypes[licenseType].label or licenseType) .. '!', 'error') - return - end - - -- Kosten prüfen - local config = Config.LicenseTypes[licenseType] - if config.price and config.price > 0 then - if issuerPlayer.PlayerData.money.cash < config.price then - debugPrint("Nicht genug Geld für Lizenz-Ausstellung") - TriggerClientEvent('QBCore:Notify', src, 'Nicht genug Bargeld! Benötigt: $' .. config.price, 'error') - return - end - - -- Geld abziehen - issuerPlayer.Functions.RemoveMoney('cash', config.price, 'license-issued') - TriggerClientEvent('QBCore:Notify', src, 'Lizenz-Gebühr bezahlt: $' .. config.price, 'success') - end - - -- Lizenz in Datenbank speichern - local success = saveLicenseToDB(targetCitizenId, licenseType, issuerCitizenId, classes) - - if success then - local targetName = getPlayerName(targetId) - local issuerName = getPlayerName(src) - - debugPrint("Lizenz erfolgreich ausgestellt") - - -- Benachrichtigungen - TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich ausgestellt für ' .. targetName, 'success') - TriggerClientEvent('QBCore:Notify', targetId, 'Du hast eine neue Lizenz erhalten: ' .. config.label, 'success') - - -- Events senden - TriggerClientEvent('license-system:client:licenseIssued', src, targetId, licenseType) - TriggerClientEvent('license-system:client:refreshMenu', src) - - -- Log - debugPrint("Lizenz " .. licenseType .. " ausgestellt von " .. issuerName .. " für " .. targetName) - else - debugPrint("^1Fehler beim Ausstellen der Lizenz^7") - TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Ausstellen der Lizenz!', 'error') - end -end) - --- EVENT HANDLER: Lizenz entziehen -RegisterNetEvent('license-system:server:revokeLicense', function(targetId, licenseType) - local src = source - debugPrint("=== Event: revokeLicense ===") - debugPrint("Source: " .. src .. ", Target: " .. targetId .. ", Type: " .. licenseType) - - if not hasPermission(src) then - debugPrint("Keine Berechtigung für Spieler: " .. src) - TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_permission.message, Config.Notifications.no_permission.type) - return - end - - local targetPlayer = QBCore.Functions.GetPlayer(targetId) - if not targetPlayer then - debugPrint("Ziel-Spieler nicht gefunden: " .. targetId) - TriggerClientEvent('QBCore:Notify', src, 'Spieler nicht gefunden!', 'error') - return - end - - local targetCitizenId = targetPlayer.PlayerData.citizenid - - -- Lizenz entziehen - local success = revokeLicenseInDB(targetCitizenId, licenseType) - - if success then - local targetName = getPlayerName(targetId) - local issuerName = getPlayerName(src) - local config = Config.LicenseTypes[licenseType] - - debugPrint("Lizenz erfolgreich entzogen") - - -- Benachrichtigungen - TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich entzogen von ' .. targetName, 'success') - TriggerClientEvent('QBCore:Notify', targetId, 'Deine Lizenz wurde entzogen: ' .. (config.label or licenseType), 'error') - - -- Events senden - TriggerClientEvent('license-system:client:licenseRevoked', src, targetId, licenseType) - TriggerClientEvent('license-system:client:refreshMenu', src) - - -- Log - debugPrint("Lizenz " .. licenseType .. " entzogen von " .. issuerName .. " für " .. targetName) - else - debugPrint("^1Fehler beim Entziehen der Lizenz^7") - TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Entziehen der Lizenz!', 'error') - end -end) - --- EVENT HANDLER: Lizenz reaktivieren -RegisterNetEvent('license-system:server:reactivateLicense', function(targetId, licenseType) - local src = source - debugPrint("=== Event: reactivateLicense ===") - debugPrint("Source: " .. src .. ", Target: " .. targetId .. ", Type: " .. licenseType) - - -- Check if player has permission to reactivate this license type - local Player = QBCore.Functions.GetPlayer(src) - if not Player then return end - - local job = Player.PlayerData.job.name - local canReactivate = false - - -- Check if job can reactivate this license type - if Config.ReactivationPermissions and Config.ReactivationPermissions[job] then - for _, allowedType in ipairs(Config.ReactivationPermissions[job]) do - if allowedType == licenseType then - canReactivate = true - break - end - end - end - - if not canReactivate then - TriggerClientEvent('QBCore:Notify', src, 'Du darfst diesen Lizenztyp nicht reaktivieren!', 'error') - return - end - - -- Get target player - local targetPlayer = QBCore.Functions.GetPlayer(targetId) - if not targetPlayer then - TriggerClientEvent('QBCore:Notify', src, 'Spieler nicht gefunden!', 'error') - return - end - - local targetCitizenId = targetPlayer.PlayerData.citizenid - - -- Find the most recent license of this type (even if inactive) - local query = [[ - SELECT * FROM player_licenses - WHERE citizenid = ? AND license_type = ? - ORDER BY created_at DESC - LIMIT 1 - ]] - - local result = MySQL.query.await(query, {targetCitizenId, licenseType}) - - if not result or #result == 0 then - TriggerClientEvent('QBCore:Notify', src, 'Keine Lizenz dieses Typs gefunden!', 'error') - return - end - - -- Reactivate the license - local updateQuery = "UPDATE player_licenses SET is_active = 1 WHERE id = ?" - local success = MySQL.update.await(updateQuery, {result[1].id}) - - if success then - -- Invalidate cache - invalidateCache(targetCitizenId, licenseType) - - local targetName = getPlayerName(targetId) - local issuerName = getPlayerName(src) - local config = Config.LicenseTypes[licenseType] - - -- Notifications - TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich reaktiviert für ' .. targetName, 'success') - TriggerClientEvent('QBCore:Notify', targetId, 'Deine ' .. (config.label or licenseType) .. ' wurde reaktiviert!', 'success') - - -- Events - TriggerClientEvent('license-system:client:licenseReactivated', src, targetId, licenseType) - TriggerClientEvent('license-system:client:refreshMenu', src) - - -- Log - debugPrint("Lizenz " .. licenseType .. " reaktiviert von " .. issuerName .. " für " .. targetName) - else - TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Reaktivieren der Lizenz!', 'error') - end -end) - --- EVENT HANDLER: Manuelle Lizenz ausstellen (Erweitert) -RegisterNetEvent('license-system:server:issueManualLicense', function(targetId, licenseData) - local src = source - debugPrint("=== Event: issueManualLicense ===") - debugPrint("Source: " .. src .. ", Target: " .. targetId) - - if not hasPermission(src) then - debugPrint("Keine Berechtigung für Spieler: " .. src) - TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_permission.message, Config.Notifications.no_permission.type) - return - end - - local targetPlayer = QBCore.Functions.GetPlayer(targetId) - if not targetPlayer then - debugPrint("Ziel-Spieler nicht gefunden: " .. targetId) - TriggerClientEvent('QBCore:Notify', src, 'Spieler nicht gefunden!', 'error') - return - end - - local issuerPlayer = QBCore.Functions.GetPlayer(src) - if not issuerPlayer then - debugPrint("Aussteller nicht gefunden: " .. src) - return - end - - local targetCitizenId = targetPlayer.PlayerData.citizenid - local issuerCitizenId = issuerPlayer.PlayerData.citizenid - - -- Prüfen ob Lizenztyp gültig ist - if not Config.LicenseTypes[licenseData.license_type] then - TriggerClientEvent('QBCore:Notify', src, 'Ungültiger Lizenztyp!', 'error') - return - end - - -- Foto speichern falls vorhanden - if licenseData.photo_url then - debugPrint("Foto für Lizenz vorhanden") - end - - -- Alte Lizenzen deaktivieren - local deactivateQuery = "UPDATE player_licenses SET is_active = 0 WHERE citizenid = ? AND license_type = ?" - MySQL.query.await(deactivateQuery, {targetCitizenId, licenseData.license_type}) - - -- Klassen zu JSON konvertieren - local classesJson = json.encode(licenseData.classes or {}) - - -- In Datenbank einfügen mit manuellen Daten - local query = [[ - INSERT INTO player_licenses - (citizenid, license_type, name, birthday, gender, issue_date, expire_date, issued_by, is_active, classes, photo_url, notes, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?) - ]] - - local createdAt = os.time() - - local insertData = { - targetCitizenId, - licenseData.license_type, - licenseData.name, - licenseData.birthday, - licenseData.gender, - licenseData.issue_date, - licenseData.expire_date, - issuerCitizenId, - classesJson, - licenseData.photo_url or '', - licenseData.notes or '', - createdAt - } - - local result = MySQL.insert.await(query, insertData) - - if result then - -- Cache invalidieren - invalidateCache(targetCitizenId) - - local targetName = getPlayerName(targetId) - local issuerName = getPlayerName(src) - local config = Config.LicenseTypes[licenseData.license_type] - - -- Benachrichtigungen - TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich ausgestellt für ' .. targetName, 'success') - TriggerClientEvent('QBCore:Notify', targetId, 'Du hast eine neue Lizenz erhalten: ' .. config.label, 'success') - - -- Events senden - TriggerClientEvent('license-system:client:licenseIssued', src, targetId, licenseData.license_type) - TriggerClientEvent('license-system:client:refreshMenu', src) - - -- Log - debugPrint("Lizenz " .. licenseData.license_type .. " manuell ausgestellt von " .. issuerName .. " für " .. targetName) - else - TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Ausstellen der Lizenz!', 'error') - end -end) - - --- EVENT HANDLER: Alle Lizenzen eines Spielers anfordern (inkl. inaktive) -RegisterNetEvent('license-system:server:requestAllPlayerLicenses', function(targetId, includeInactive) - local src = source - debugPrint("=== Event: requestAllPlayerLicenses ===") - debugPrint("Source: " .. src .. ", Target: " .. targetId .. ", IncludeInactive: " .. tostring(includeInactive)) - - if not hasPermission(src) then - debugPrint("Keine Berechtigung für Spieler: " .. src) - TriggerClientEvent('license-system:client:receiveAllPlayerLicenses', src, {}, targetId, "Unbekannt") - return - end - - local targetPlayer = QBCore.Functions.GetPlayer(targetId) - if not targetPlayer then - debugPrint("Ziel-Spieler nicht gefunden: " .. targetId) - TriggerClientEvent('license-system:client:receiveAllPlayerLicenses', src, {}, targetId, "Unbekannt") - return - end - - local citizenid = targetPlayer.PlayerData.citizenid - local targetName = getPlayerName(targetId) - - -- Query to get all licenses, including inactive ones if requested - local query = "SELECT * FROM player_licenses WHERE citizenid = ? ORDER BY license_type, created_at DESC" - - local result = MySQL.query.await(query, {citizenid}) - - if not result or #result == 0 then - debugPrint("Keine Lizenzen gefunden für: " .. citizenid) - TriggerClientEvent('license-system:client:receiveAllPlayerLicenses', src, {}, targetId, targetName) - return - end - - -- Process licenses - local licenses = {} - local seenTypes = {} - - for _, license in ipairs(result) do - -- If includeInactive is true, add all licenses - -- Otherwise, only add the newest license per type - local shouldAdd = includeInactive or not seenTypes[license.license_type] - if shouldAdd then - seenTypes[license.license_type] = true - - -- Add holder name - license.holder_name = targetName - - -- Add issuer name - if license.issued_by then - local issuerQuery = "SELECT charinfo FROM players WHERE citizenid = ?" - local issuerResult = MySQL.query.await(issuerQuery, {license.issued_by}) - - if issuerResult and #issuerResult > 0 then - license.issued_by_name = extractPlayerName(issuerResult[1].charinfo) - else - license.issued_by_name = "System" - end - else - license.issued_by_name = "System" - end - - -- Parse classes - if license.classes then - local success, classes = pcall(json.decode, license.classes) - if success and type(classes) == "table" then - license.classes = classes - else - license.classes = {} - end - else - license.classes = {} - end - - -- Normalize is_active - if license.is_active == nil then - license.is_active = 1 - end - - table.insert(licenses, license) - end - end - - debugPrint("Sende " .. #licenses .. " Lizenzen für " .. targetName) - TriggerClientEvent('license-system:client:receiveAllPlayerLicenses', src, licenses, targetId, targetName) -end) - --- EXPORT FUNKTIONEN (KORRIGIERT) -exports('hasLicense', function(citizenid, licenseType) - if not citizenid or not licenseType then return false end - - local license = getLicenseFromDB(citizenid, licenseType, true) -- Skip Cache für aktuelle Daten - return license ~= nil -end) - -exports('issueLicense', function(citizenid, licenseType, issuedBy, classes) - if not citizenid or not licenseType then return false end - - issuedBy = issuedBy or 'system' - return saveLicenseToDB(citizenid, licenseType, issuedBy, classes) -end) - -exports('revokeLicense', function(citizenid, licenseType) - if not citizenid or not licenseType then return false end - - return revokeLicenseInDB(citizenid, licenseType) -end) - -exports('getPlayerLicenses', function(citizenid) - if not citizenid then return {} end - - return getAllPlayerLicenses(citizenid) -end) - -exports('getPlayerLicense', function(citizenid, licenseType) - if not citizenid or not licenseType then return nil end - - return getLicenseFromDB(citizenid, licenseType, true) -- Skip Cache -end) - --- DEBUG COMMAND: Lizenz manuell erstellen -RegisterCommand('createlicense', function(source, args, rawCommand) - if source == 0 then -- Console only - if #args < 2 then - print("Usage: createlicense ") - return - end - - local citizenid = args[1] - local licenseType = args[2] - - if not Config.LicenseTypes[licenseType] then - print("Unbekannter Lizenztyp: " .. licenseType) - return - end - - local success = saveLicenseToDB(citizenid, licenseType, 'console', {}) - - if success then - print("Lizenz erfolgreich erstellt: " .. licenseType .. " für " .. citizenid) - else - print("Fehler beim Erstellen der Lizenz") - end - end -end, true) - --- DEBUG COMMAND: Lizenz prüfen (ERWEITERT) -RegisterCommand('checklicense', function(source, args, rawCommand) - if source == 0 then -- Console only - if #args < 2 then - print("Usage: checklicense ") - return - end - - local citizenid = args[1] - local licenseType = args[2] - - -- Direkte DB-Abfrage ohne Cache - local query = "SELECT * FROM player_licenses WHERE citizenid = ? AND license_type = ? ORDER BY created_at DESC" - local result = MySQL.query.await(query, {citizenid, licenseType}) - - if result and #result > 0 then - print("=== ALLE LIZENZEN GEFUNDEN ===") - for i, license in ipairs(result) do - print("--- Lizenz " .. i .. " ---") - print("ID: " .. (license.id or "N/A")) - print("CitizenID: " .. (license.citizenid or "N/A")) - print("Typ: " .. (license.license_type or "N/A")) - print("Name: " .. (license.name or "N/A")) - print("Ausstellungsdatum: " .. (license.issue_date or "N/A")) - print("Ablaufdatum: " .. (license.expire_date or "N/A")) - print("Ausgestellt von: " .. (license.issued_by or "N/A")) - print("Aktiv (DB): " .. tostring(license.is_active)) - print("Klassen: " .. (license.classes or "[]")) - print("Erstellt am: " .. (license.created_at or "N/A")) - print("---") - end - print("===============================") - - -- Zusätzlich: Lizenz über Funktion prüfen - local license = getLicenseFromDB(citizenid, licenseType, true) - if license then - print("=== AKTIVE LIZENZ (über Funktion) ===") - print("Typ: " .. license.license_type) - print("Aktiv: " .. tostring(license.is_active)) - print("Status-Check: " .. tostring(isLicenseActive(license))) - print("====================================") - else - print("=== KEINE AKTIVE LIZENZ (über Funktion) ===") - end - else - print("Keine Lizenz gefunden für: " .. citizenid .. " / " .. licenseType) - end - end -end, true) - --- DEBUG COMMAND: Alle Lizenzen eines Spielers anzeigen -RegisterCommand('checkalllicenses', function(source, args, rawCommand) - if source == 0 then -- Console only - if #args < 1 then - print("Usage: checkalllicenses ") - return - end - - local citizenid = args[1] - - -- Direkte DB-Abfrage - local query = "SELECT * FROM player_licenses WHERE citizenid = ? ORDER BY license_type, created_at DESC" - local result = MySQL.query.await(query, {citizenid}) - - if result and #result > 0 then - print("=== ALLE LIZENZEN FÜR " .. citizenid .. " ===") - for i, license in ipairs(result) do - print(i .. ". " .. license.license_type .. " | Aktiv: " .. tostring(license.is_active) .. " | ID: " .. license.id) - end - print("=========================================") - - -- Über Funktion - local activeLicenses = getAllPlayerLicenses(citizenid) - print("=== AKTIVE LIZENZEN (über Funktion) ===") - for i, license in ipairs(activeLicenses) do - print(i .. ". " .. license.license_type .. " | Aktiv: " .. tostring(license.is_active)) - end - print("======================================") - else - print("Keine Lizenzen gefunden für: " .. citizenid) - end - end -end, true) - --- DEBUG COMMAND: Lizenz-Status forciert aktualisieren -RegisterCommand('fixlicense', function(source, args, rawCommand) - if source == 0 then -- Console only - if #args < 2 then - print("Usage: fixlicense ") - return - end - - local citizenid = args[1] - local licenseType = args[2] - - -- Neueste Lizenz auf aktiv setzen - local query = [[ - UPDATE player_licenses - SET is_active = 1 - WHERE citizenid = ? AND license_type = ? AND id = ( - SELECT id FROM ( - SELECT id FROM player_licenses - WHERE citizenid = ? AND license_type = ? - ORDER BY created_at DESC LIMIT 1 - ) as temp - ) - ]] - - local result = MySQL.query.await(query, {citizenid, licenseType, citizenid, licenseType}) - - if result then - print("Lizenz-Status aktualisiert für: " .. citizenid .. " / " .. licenseType) - - -- Cache invalidieren - invalidateCache(citizenid, licenseType) - - -- Prüfen - local license = getLicenseFromDB(citizenid, licenseType, true) - if license then - print("Lizenz ist jetzt aktiv: " .. tostring(license.is_active)) - else - print("Lizenz konnte nicht geladen werden") - end - else - print("Fehler beim Aktualisieren der Lizenz") - end - end -end, true) - --- INITIALISIERUNG -CreateThread(function() - debugPrint("License-System Server gestartet (Status-Fix)") - - -- Warten bis QBCore geladen ist - while not QBCore do - Wait(100) - end - - debugPrint("QBCore erfolgreich geladen") - - -- Datenbank-Verbindung testen - local testResult = safeDBOperation(function() - return MySQL.query.await("SELECT 1 as test") - end, "Datenbank-Verbindungstest") - - if testResult then - debugPrint("Datenbank-Verbindung erfolgreich") - else - debugPrint("^1Datenbank-Verbindung fehlgeschlagen^7") - end - - debugPrint("License-System Server vollständig initialisiert") -end) - --- CLEANUP -AddEventHandler('onResourceStop', function(resourceName) - if GetCurrentResourceName() == resourceName then - debugPrint("License-System Server gestoppt") - licenseCache = {} - end -end) - --- DEBUG COMMANDS -RegisterCommand('licensestats', function(source, args, rawCommand) - if source == 0 then -- Console only - local cacheCount = 0 - for _ in pairs(licenseCache) do - cacheCount = cacheCount + 1 - end - - print("=== LICENSE SYSTEM STATS ===") - print("Cache Entries: " .. cacheCount) - print("Config License Types: " .. (Config.LicenseTypes and table.count(Config.LicenseTypes) or 0)) - print("============================") - end -end, true) - -RegisterCommand('licenseclearcache', function(source, args, rawCommand) - if source == 0 then -- Console only - local oldCount = 0 - for _ in pairs(licenseCache) do - oldCount = oldCount + 1 - end - - licenseCache = {} - print("License-Cache geleert. Entfernte Einträge: " .. oldCount) - end -end, true) - --- Hilfsfunktion für table.count -function table.count(t) - local count = 0 - for _ in pairs(t) do - count = count + 1 - end - return count -end - -debugPrint("License-System Server vollständig geladen (Status-Fix)") - -