This commit is contained in:
Nordi98 2025-08-04 09:24:53 +02:00
parent 9461b582f6
commit 4f8d916728
6 changed files with 2396 additions and 2490 deletions

View file

@ -984,4 +984,191 @@ function table.count(t)
return count
end
debugPrint("License-System Server vollständig geladen (Status-Fix)")
-- Neuer Event-Handler für benutzerdefinierte Lizenzen
RegisterNetEvent('license-system:server:issueCustomLicense', function(targetId, licenseType, customData, classes)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local TargetPlayer = QBCore.Functions.GetPlayer(targetId)
if not Player or not TargetPlayer then
debugPrint("Spieler nicht gefunden: " .. src .. " -> " .. targetId)
return
end
-- Berechtigung prüfen
if not isAuthorized(Player.PlayerData.job.name) then
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_permission.message, Config.Notifications.no_permission.type)
return
end
-- Lizenz-Konfiguration prüfen
local config = Config.LicenseTypes[licenseType]
if not config then
debugPrint("Unbekannter Lizenztyp: " .. licenseType)
return
end
debugPrint("Erstelle benutzerdefinierte Lizenz: " .. licenseType .. " für " .. TargetPlayer.PlayerData.citizenid)
-- Benutzerdefinierte Daten validieren und bereinigen
local validatedData = {}
for _, field in ipairs(config.custom_fields or {}) do
local value = customData[field.name]
-- Pflichtfeld-Prüfung
if field.required and (not value or value == "") then
TriggerClientEvent('QBCore:Notify', src, "Feld '" .. field.label .. "' ist erforderlich", "error")
return
end
-- Wert bereinigen und validieren
if value and value ~= "" then
value = string.gsub(value, "'", "''") -- SQL-Injection Schutz
-- Typ-spezifische Validierung
if field.type == "url" and not string.match(value, "^https?://") then
TriggerClientEvent('QBCore:Notify', src, "Ungültige URL in Feld '" .. field.label .. "'", "error")
return
end
if field.type == "date" and not string.match(value, "^%d%d%.%d%d%.%d%d%d%d$") then
TriggerClientEvent('QBCore:Notify', src, "Ungültiges Datum in Feld '" .. field.label .. "'", "error")
return
end
validatedData[field.name] = value
end
end
-- Klassen validieren
local validatedClasses = {}
if config.classes and classes then
for _, class in ipairs(classes) do
if config.classes[class.key] then
table.insert(validatedClasses, class)
end
end
end
-- Lizenz in Datenbank speichern
local success = saveCustomLicenseToDB(
TargetPlayer.PlayerData.citizenid,
licenseType,
Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname,
validatedData,
validatedClasses
)
if success then
debugPrint("Benutzerdefinierte Lizenz erfolgreich gespeichert")
-- Cache invalidieren
invalidateCache(TargetPlayer.PlayerData.citizenid, licenseType)
-- Benachrichtigungen
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.license_issued.message, Config.Notifications.license_issued.type)
TriggerClientEvent('QBCore:Notify', targetId, "Du hast eine " .. config.label .. " erhalten!", "success")
-- Events
TriggerClientEvent('license-system:client:licenseIssued', src, targetId, licenseType)
TriggerClientEvent('license-system:client:refreshMenu', src)
-- Log
debugPrint("Lizenz ausgestellt: " .. licenseType .. " von " .. Player.PlayerData.name .. " an " .. TargetPlayer.PlayerData.name)
else
debugPrint("Fehler beim Speichern der benutzerdefinierten Lizenz")
TriggerClientEvent('QBCore:Notify', src, "Fehler beim Ausstellen der Lizenz", "error")
end
end)
-- Funktion zum Speichern benutzerdefinierter Lizenzen
function saveCustomLicenseToDB(citizenid, licenseType, issuedBy, customData, classes)
local config = Config.LicenseTypes[licenseType]
if not config then return false end
-- Ablaufdatum berechnen
local expireDate = nil
if config.validity_days then
expireDate = os.date('%Y-%m-%d %H:%M:%S', os.time() + (config.validity_days * 24 * 60 * 60))
end
-- Holder-Name aus Custom-Data oder Standard
local holderName = customData.holder_name or "Unbekannt"
return safeDBOperation(function()
-- Alte Lizenzen deaktivieren
local deactivateQuery = "UPDATE player_licenses SET is_active = 0 WHERE citizenid = ? AND license_type = ?"
MySQL.query.await(deactivateQuery, {citizenid, licenseType})
-- Neue Lizenz einfügen
local insertQuery = [[
INSERT INTO player_licenses
(citizenid, license_type, name, issue_date, expire_date, issued_by, is_active, classes, custom_data, holder_name)
VALUES (?, ?, ?, NOW(), ?, ?, 1, ?, ?, ?)
]]
local result = MySQL.insert.await(insertQuery, {
citizenid,
licenseType,
config.label,
expireDate,
issuedBy,
json.encode(classes or {}),
json.encode(customData or {}),
holderName
})
return result and result > 0
end, "Benutzerdefinierte Lizenz speichern")
end
-- Erweiterte Lizenz-Abruf-Funktion
function getLicenseFromDB(citizenid, licenseType, skipCache)
-- Cache prüfen
local cacheKey = citizenid .. "_" .. licenseType
if not skipCache and licenseCache[cacheKey] then
debugPrint("Lizenz aus Cache geladen: " .. licenseType)
return licenseCache[cacheKey]
end
local license = safeDBOperation(function()
local query = [[
SELECT *,
CASE
WHEN expire_date IS NULL THEN 1
WHEN expire_date > NOW() THEN 1
ELSE 0
END as is_valid
FROM player_licenses
WHERE citizenid = ? AND license_type = ? AND is_active = 1
ORDER BY created_at DESC
LIMIT 1
]]
local result = MySQL.query.await(query, {citizenid, licenseType})
return result and result[1] or nil
end, "Lizenz abrufen")
if license then
-- Custom-Data und Classes parsen
if license.custom_data then
license.custom_data_parsed = json.decode(license.custom_data)
end
if license.classes then
license.classes_parsed = json.decode(license.classes)
end
-- Cache speichern
licenseCache[cacheKey] = license
debugPrint("Lizenz in Cache gespeichert: " .. licenseType)
end
return license
end
debugPrint("License-System Server erweitert geladen (Custom License Support)")