1
0
Fork 0
forked from Simnation/Main
Main/resources/[tools]/nordi_license/server/main.lua

723 lines
25 KiB
Lua
Raw Normal View History

2025-08-04 06:14:47 +02:00
local QBCore = exports['qb-core']:GetCoreObject()
2025-08-04 08:12:36 +02:00
-- Lokale Variablen
local licenseCache = {}
2025-08-04 08:45:50 +02:00
local cacheTimeout = 300000 -- 5 Minuten
2025-08-04 08:12:36 +02:00
2025-08-04 07:40:06 +02:00
-- Hilfsfunktionen
local function debugPrint(message)
if Config.Debug then
2025-08-04 08:45:50 +02:00
print("^3[License-System Server] " .. message .. "^7")
2025-08-04 07:40:06 +02:00
end
end
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
-- 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"
2025-08-04 07:40:06 +02:00
end
2025-08-04 06:14:47 +02:00
2025-08-04 07:40:06 +02:00
-- Spieler-Daten abrufen
2025-08-04 08:45:50 +02:00
local function getPlayerData(src)
local Player = QBCore.Functions.GetPlayer(src)
2025-08-04 07:40:06 +02:00
if not Player then return nil end
return {
citizenid = Player.PlayerData.citizenid,
2025-08-04 08:45:50 +02:00
name = getPlayerName(src),
charinfo = Player.PlayerData.charinfo,
job = Player.PlayerData.job
2025-08-04 07:40:06 +02:00
}
end
2025-08-04 06:14:47 +02:00
2025-08-04 07:40:06 +02:00
-- Berechtigung prüfen
2025-08-04 08:45:50 +02:00
local function hasPermission(src)
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return false end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
local job = Player.PlayerData.job
if not job then return false end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
local hasAuth = Config.AuthorizedJobs[job.name] or false
debugPrint("Berechtigung für " .. job.name .. ": " .. tostring(hasAuth))
return hasAuth
end
-- Cache-Funktionen
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
2025-08-04 07:40:06 +02:00
end
2025-08-04 08:45:50 +02:00
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 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
2025-08-04 07:40:06 +02:00
end
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
if cleaned > 0 then
debugPrint("Cache bereinigt: " .. cleaned .. " Einträge")
end
2025-08-04 07:40:06 +02:00
end
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
-- Cache-Cleanup Thread
CreateThread(function()
while true do
Wait(300000) -- 5 Minuten
cleanupCache()
end
end)
2025-08-04 08:51:13 +02:00
-- Spieler-Name aus JSON extrahieren (MariaDB-kompatibel)
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
-- Lizenz aus Datenbank abrufen (KORRIGIERT für MariaDB)
2025-08-04 08:45:50 +02:00
local function getLicenseFromDB(citizenid, licenseType)
debugPrint("=== getLicenseFromDB START ===")
debugPrint("CitizenID: " .. tostring(citizenid))
debugPrint("LicenseType: " .. tostring(licenseType))
-- Cache prüfen
local cached = getCachedLicense(citizenid, licenseType)
if cached then
return cached
end
2025-08-04 07:40:06 +02:00
2025-08-04 08:51:13 +02:00
-- MariaDB-kompatible Query ohne JSON-Operatoren
2025-08-04 08:45:50 +02:00
local query = [[
SELECT pl.*,
2025-08-04 08:51:13 +02:00
p.charinfo as holder_charinfo,
pi.charinfo as issued_by_charinfo
2025-08-04 08:45:50 +02:00
FROM player_licenses pl
LEFT JOIN players p ON p.citizenid = pl.citizenid
LEFT JOIN players pi ON pi.citizenid = pl.issued_by
WHERE pl.citizenid = ? AND pl.license_type = ?
ORDER BY pl.created_at DESC
LIMIT 1
]]
local result = MySQL.query.await(query, {citizenid, licenseType})
if result and #result > 0 then
local license = result[1]
2025-08-04 08:51:13 +02:00
-- Namen aus JSON extrahieren
license.holder_name = extractPlayerName(license.holder_charinfo)
license.issued_by_name = extractPlayerName(license.issued_by_charinfo)
-- Fallback für issued_by_name
if license.issued_by_name == "Unbekannt" then
2025-08-04 08:45:50 +02:00
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
2025-08-04 08:51:13 +02:00
-- Cleanup - charinfo nicht mehr benötigt
license.holder_charinfo = nil
license.issued_by_charinfo = nil
2025-08-04 08:45:50 +02:00
debugPrint("Lizenz aus DB geladen: " .. license.license_type)
-- In Cache speichern
setCachedLicense(citizenid, licenseType, license)
return license
end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
debugPrint("Keine Lizenz in DB gefunden")
return nil
end
2025-08-04 08:51:13 +02:00
-- Alle Lizenzen eines Spielers abrufen (KORRIGIERT für MariaDB)
2025-08-04 08:45:50 +02:00
local function getAllPlayerLicenses(citizenid)
debugPrint("=== getAllPlayerLicenses START ===")
debugPrint("CitizenID: " .. tostring(citizenid))
2025-08-04 08:51:13 +02:00
-- MariaDB-kompatible Query
2025-08-04 08:45:50 +02:00
local query = [[
SELECT pl.*,
2025-08-04 08:51:13 +02:00
p.charinfo as holder_charinfo,
pi.charinfo as issued_by_charinfo
2025-08-04 08:45:50 +02:00
FROM player_licenses pl
LEFT JOIN players p ON p.citizenid = pl.citizenid
LEFT JOIN players pi ON pi.citizenid = pl.issued_by
WHERE pl.citizenid = ?
ORDER BY pl.license_type, pl.created_at DESC
]]
local result = MySQL.query.await(query, {citizenid})
if result and #result > 0 then
local licenses = {}
local seenTypes = {}
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
2025-08-04 08:51:13 +02:00
-- Namen aus JSON extrahieren
license.holder_name = extractPlayerName(license.holder_charinfo)
license.issued_by_name = extractPlayerName(license.issued_by_charinfo)
-- Fallback für issued_by_name
if license.issued_by_name == "Unbekannt" then
2025-08-04 08:45:50 +02:00
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
2025-08-04 08:51:13 +02:00
-- Cleanup
license.holder_charinfo = nil
license.issued_by_charinfo = nil
2025-08-04 08:45:50 +02:00
table.insert(licenses, license)
end
2025-08-04 07:40:06 +02:00
end
2025-08-04 08:45:50 +02:00
debugPrint("Gefundene Lizenzen: " .. #licenses)
return licenses
2025-08-04 06:14:47 +02:00
end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
debugPrint("Keine Lizenzen gefunden")
return {}
2025-08-04 07:40:06 +02:00
end
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
-- Lizenz in Datenbank speichern (KORRIGIERT)
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
2025-08-04 08:51:13 +02:00
-- Spieler-Name für das name-Feld abrufen (MariaDB-kompatibel)
local holderQuery = "SELECT charinfo FROM players WHERE citizenid = ?"
2025-08-04 08:45:50 +02:00
local holderResult = MySQL.query.await(holderQuery, {citizenid})
local holderName = "Unbekannt"
2025-08-04 08:51:13 +02:00
if holderResult and #holderResult > 0 and holderResult[1].charinfo then
holderName = extractPlayerName(holderResult[1].charinfo)
2025-08-04 08:12:36 +02:00
end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
-- Datum berechnen
local issueDate = os.date("%d.%m.%Y")
2025-08-04 07:40:06 +02:00
local expireDate = nil
2025-08-04 08:45:50 +02:00
if config.validity_days then
local expireTimestamp = os.time() + (config.validity_days * 24 * 60 * 60)
expireDate = os.date("%d.%m.%Y", expireTimestamp)
2025-08-04 07:40:06 +02:00
end
2025-08-04 08:45:50 +02:00
-- Classes zu JSON konvertieren
local classesJson = json.encode(classes or {})
-- Alte Lizenz deaktivieren
local deactivateQuery = "UPDATE player_licenses SET is_active = 0 WHERE citizenid = ? AND license_type = ?"
MySQL.query.await(deactivateQuery, {citizenid, licenseType})
2025-08-04 08:51:13 +02:00
-- Neue Lizenz einfügen
2025-08-04 08:45:50 +02:00
local insertQuery = [[
INSERT INTO player_licenses
(citizenid, license_type, name, issue_date, expire_date, issued_by, is_active, classes, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
]]
local insertData = {
citizenid,
licenseType,
2025-08-04 08:51:13 +02:00
holderName,
2025-08-04 08:45:50 +02:00
issueDate,
expireDate,
issuedBy,
1,
classesJson,
os.time()
2025-08-04 07:40:06 +02:00
}
2025-08-04 08:45:50 +02:00
debugPrint("Führe INSERT-Query aus...")
debugPrint("Daten: " .. json.encode(insertData))
2025-08-04 06:14:47 +02:00
2025-08-04 08:51:13 +02:00
local success, result = pcall(MySQL.insert.await, insertQuery, insertData)
2025-08-04 08:45:50 +02:00
2025-08-04 08:51:13 +02:00
if success and result then
2025-08-04 08:45:50 +02:00
debugPrint("Lizenz erfolgreich gespeichert. ID: " .. result)
-- Cache invalidieren
local cacheKey = citizenid .. "_" .. licenseType
licenseCache[cacheKey] = nil
return true
else
2025-08-04 08:51:13 +02:00
debugPrint("^1Fehler beim Speichern der Lizenz: " .. tostring(result) .. "^7")
2025-08-04 08:45:50 +02:00
return false
end
2025-08-04 07:40:06 +02:00
end
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
-- Lizenz entziehen
local function revokeLicenseInDB(citizenid, licenseType)
debugPrint("=== revokeLicenseInDB START ===")
debugPrint("CitizenID: " .. tostring(citizenid))
debugPrint("LicenseType: " .. tostring(licenseType))
2025-08-04 08:12:36 +02:00
2025-08-04 08:45:50 +02:00
local query = "UPDATE player_licenses SET is_active = 0 WHERE citizenid = ? AND license_type = ? AND is_active = 1"
2025-08-04 08:51:13 +02:00
local success, result = pcall(MySQL.query.await, query, {citizenid, licenseType})
2025-08-04 08:45:50 +02:00
2025-08-04 08:51:13 +02:00
if success and result then
2025-08-04 08:45:50 +02:00
debugPrint("Lizenz erfolgreich entzogen")
-- Cache invalidieren
local cacheKey = citizenid .. "_" .. licenseType
licenseCache[cacheKey] = nil
return true
else
2025-08-04 08:51:13 +02:00
debugPrint("^1Fehler beim Entziehen der Lizenz: " .. tostring(result) .. "^7")
2025-08-04 08:45:50 +02:00
return false
end
2025-08-04 08:12:36 +02:00
end
2025-08-04 08:51:13 +02:00
-- Erweiterte Fehlerbehandlung für Datenbankoperationen
local function safeDBOperation(operation, errorMessage)
local success, result = pcall(operation)
if not success then
debugPrint("^1DB-Fehler: " .. (errorMessage or "Unbekannt") .. "^7")
debugPrint("^1Details: " .. tostring(result) .. "^7")
return nil
end
return result
end
2025-08-04 08:45:50 +02:00
-- EVENT HANDLER: Lizenz anfordern
2025-08-04 08:31:45 +02:00
RegisterNetEvent('license-system:server:requestLicense', function(targetId)
local src = source
debugPrint("=== Event: requestLicense ===")
2025-08-04 08:45:50 +02:00
debugPrint("Source: " .. src .. ", Target: " .. targetId)
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
if not hasPermission(src) then
debugPrint("Keine Berechtigung für Spieler: " .. src)
2025-08-04 08:31:45 +02:00
TriggerClientEvent('license-system:client:receiveLicense', src, nil)
2025-08-04 06:14:47 +02:00
return
end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
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
-- Erste verfügbare Lizenz finden
local foundLicense = nil
for licenseType, _ in pairs(Config.LicenseTypes) do
2025-08-04 08:51:13 +02:00
local license = safeDBOperation(function()
return getLicenseFromDB(citizenid, licenseType)
end, "Fehler beim Abrufen der Lizenz")
2025-08-04 08:45:50 +02:00
if license and license.is_active == 1 then
foundLicense = {
license = license,
config = Config.LicenseTypes[licenseType]
}
break
2025-08-04 06:14:47 +02:00
end
2025-08-04 08:45:50 +02:00
end
if foundLicense then
debugPrint("Sende Lizenz an Client: " .. foundLicense.license.license_type)
TriggerClientEvent('license-system:client:receiveLicense', src, foundLicense)
else
debugPrint("Keine aktive Lizenz gefunden")
TriggerClientEvent('license-system:client:receiveLicense', src, nil)
end
2025-08-04 06:14:47 +02:00
end)
2025-08-04 08:45:50 +02:00
-- EVENT HANDLER: Eigene Lizenz anfordern
2025-08-04 08:31:45 +02:00
RegisterNetEvent('license-system:server:requestMyLicense', function(licenseType)
local src = source
debugPrint("=== Event: requestMyLicense ===")
2025-08-04 08:45:50 +02:00
debugPrint("Source: " .. src .. ", LicenseType: " .. licenseType)
2025-08-04 06:14:47 +02:00
2025-08-04 08:31:45 +02:00
local Player = QBCore.Functions.GetPlayer(src)
2025-08-04 07:40:06 +02:00
if not Player then
2025-08-04 08:45:50 +02:00
debugPrint("Spieler nicht gefunden: " .. src)
2025-08-04 08:31:45 +02:00
TriggerClientEvent('license-system:client:receiveMyLicense', src, nil, licenseType)
2025-08-04 06:14:47 +02:00
return
end
2025-08-04 07:40:06 +02:00
local citizenid = Player.PlayerData.citizenid
2025-08-04 08:51:13 +02:00
local license = safeDBOperation(function()
return getLicenseFromDB(citizenid, licenseType)
end, "Fehler beim Abrufen der eigenen Lizenz")
2025-08-04 08:45:50 +02:00
if license and license.is_active == 1 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
2025-08-04 06:14:47 +02:00
end)
2025-08-04 08:45:50 +02:00
-- EVENT HANDLER: Alle Spieler-Lizenzen anfordern
2025-08-04 08:31:45 +02:00
RegisterNetEvent('license-system:server:requestPlayerLicenses', function(targetId)
local src = source
debugPrint("=== Event: requestPlayerLicenses ===")
2025-08-04 08:45:50 +02:00
debugPrint("Source: " .. src .. ", Target: " .. targetId)
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
if not hasPermission(src) then
debugPrint("Keine Berechtigung für Spieler: " .. src)
2025-08-04 08:31:45 +02:00
TriggerClientEvent('license-system:client:receivePlayerLicenses', src, {}, targetId, "Unbekannt")
2025-08-04 07:40:06 +02:00
return
2025-08-04 06:14:47 +02:00
end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
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
2025-08-04 08:12:36 +02:00
2025-08-04 08:45:50 +02:00
local citizenid = targetPlayer.PlayerData.citizenid
local targetName = getPlayerName(targetId)
2025-08-04 08:51:13 +02:00
local licenses = safeDBOperation(function()
return getAllPlayerLicenses(citizenid)
end, "Fehler beim Abrufen aller Spieler-Lizenzen") or {}
2025-08-04 08:12:36 +02:00
2025-08-04 08:45:50 +02:00
debugPrint("Sende " .. #licenses .. " Lizenzen für " .. targetName)
TriggerClientEvent('license-system:client:receivePlayerLicenses', src, licenses, targetId, targetName)
2025-08-04 07:40:06 +02:00
end)
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
-- EVENT HANDLER: Lizenz ausstellen
2025-08-04 07:40:06 +02:00
RegisterNetEvent('license-system:server:issueLicense', function(targetId, licenseType, classes)
2025-08-04 06:14:47 +02:00
local src = source
2025-08-04 08:31:45 +02:00
debugPrint("=== Event: issueLicense ===")
2025-08-04 08:45:50 +02:00
debugPrint("Source: " .. src .. ", Target: " .. targetId .. ", Type: " .. licenseType)
2025-08-04 08:12:36 +02:00
2025-08-04 08:45:50 +02:00
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)
2025-08-04 07:40:06 +02:00
return
end
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
local targetPlayer = QBCore.Functions.GetPlayer(targetId)
if not targetPlayer then
debugPrint("Ziel-Spieler nicht gefunden: " .. targetId)
TriggerClientEvent('QBCore:Notify', src, 'Spieler nicht gefunden!', 'error')
2025-08-04 06:14:47 +02:00
return
end
2025-08-04 08:45:50 +02:00
local issuerPlayer = QBCore.Functions.GetPlayer(src)
if not issuerPlayer then
debugPrint("Aussteller nicht gefunden: " .. src)
2025-08-04 07:40:06 +02:00
return
end
2025-08-04 08:45:50 +02:00
local targetCitizenId = targetPlayer.PlayerData.citizenid
local issuerCitizenId = issuerPlayer.PlayerData.citizenid
-- Prüfen ob Lizenz bereits existiert
2025-08-04 08:51:13 +02:00
local existingLicense = safeDBOperation(function()
return getLicenseFromDB(targetCitizenId, licenseType)
end, "Fehler beim Prüfen bestehender Lizenz")
2025-08-04 08:45:50 +02:00
if existingLicense and existingLicense.is_active == 1 then
debugPrint("Lizenz bereits vorhanden und aktiv")
TriggerClientEvent('QBCore:Notify', src, 'Spieler hat bereits eine aktive ' .. (Config.LicenseTypes[licenseType].label or licenseType) .. '!', 'error')
2025-08-04 07:40:06 +02:00
return
end
2025-08-04 08:45:50 +02:00
-- 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')
2025-08-04 07:40:06 +02:00
return
2025-08-04 06:14:47 +02:00
end
2025-08-04 07:40:06 +02:00
-- Geld abziehen
2025-08-04 08:45:50 +02:00
issuerPlayer.Functions.RemoveMoney('cash', config.price, 'license-issued')
TriggerClientEvent('QBCore:Notify', src, 'Lizenz-Gebühr bezahlt: $' .. config.price, 'success')
2025-08-04 07:40:06 +02:00
end
2025-08-04 08:45:50 +02:00
-- Lizenz in Datenbank speichern
2025-08-04 08:51:13 +02:00
local success = safeDBOperation(function()
return saveLicenseToDB(targetCitizenId, licenseType, issuerCitizenId, classes)
end, "Fehler beim Speichern der Lizenz")
2025-08-04 07:40:06 +02:00
if success then
2025-08-04 08:45:50 +02:00
local targetName = getPlayerName(targetId)
local issuerName = getPlayerName(src)
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
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
2025-08-04 08:31:45 +02:00
TriggerClientEvent('license-system:client:licenseIssued', src, targetId, licenseType)
2025-08-04 08:45:50 +02:00
TriggerClientEvent('license-system:client:refreshMenu', src)
2025-08-04 08:31:45 +02:00
2025-08-04 08:45:50 +02:00
-- Log
debugPrint("Lizenz " .. licenseType .. " ausgestellt von " .. issuerName .. " für " .. targetName)
2025-08-04 07:40:06 +02:00
else
2025-08-04 08:45:50 +02:00
debugPrint("^1Fehler beim Ausstellen der Lizenz^7")
2025-08-04 07:40:06 +02:00
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Ausstellen der Lizenz!', 'error')
end
2025-08-04 06:14:47 +02:00
end)
2025-08-04 08:45:50 +02:00
-- EVENT HANDLER: Lizenz entziehen
2025-08-04 07:40:06 +02:00
RegisterNetEvent('license-system:server:revokeLicense', function(targetId, licenseType)
2025-08-04 06:14:47 +02:00
local src = source
2025-08-04 08:31:45 +02:00
debugPrint("=== Event: revokeLicense ===")
2025-08-04 08:45:50 +02:00
debugPrint("Source: " .. src .. ", Target: " .. targetId .. ", Type: " .. licenseType)
2025-08-04 08:12:36 +02:00
2025-08-04 08:45:50 +02:00
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)
2025-08-04 07:40:06 +02:00
return
end
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
local targetPlayer = QBCore.Functions.GetPlayer(targetId)
if not targetPlayer then
debugPrint("Ziel-Spieler nicht gefunden: " .. targetId)
TriggerClientEvent('QBCore:Notify', src, 'Spieler nicht gefunden!', 'error')
2025-08-04 06:14:47 +02:00
return
end
2025-08-04 08:45:50 +02:00
local targetCitizenId = targetPlayer.PlayerData.citizenid
-- Lizenz entziehen
2025-08-04 08:51:13 +02:00
local success = safeDBOperation(function()
return revokeLicenseInDB(targetCitizenId, licenseType)
end, "Fehler beim Entziehen der Lizenz")
2025-08-04 08:45:50 +02:00
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
2025-08-04 06:14:47 +02:00
end)
2025-08-04 08:45:50 +02:00
-- EVENT HANDLER: Foto speichern
2025-08-04 07:40:06 +02:00
RegisterNetEvent('license-system:server:savePhoto', function(citizenid, photoData)
2025-08-04 06:14:47 +02:00
local src = source
2025-08-04 08:31:45 +02:00
debugPrint("=== Event: savePhoto ===")
2025-08-04 08:45:50 +02:00
debugPrint("Source: " .. src .. ", CitizenID: " .. citizenid)
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
-- Hier könnte das Foto in der Datenbank oder im Dateisystem gespeichert werden
debugPrint("Foto-Daten erhalten für: " .. citizenid)
TriggerClientEvent('QBCore:Notify', src, 'Foto gespeichert!', 'success')
2025-08-04 06:14:47 +02:00
end)
2025-08-04 08:45:50 +02:00
-- EXPORT FUNKTIONEN
exports('hasLicense', function(citizenid, licenseType)
if not citizenid or not licenseType then return false end
2025-08-04 07:40:06 +02:00
2025-08-04 08:51:13 +02:00
local license = safeDBOperation(function()
return getLicenseFromDB(citizenid, licenseType)
end, "Fehler beim Prüfen der Lizenz")
2025-08-04 08:45:50 +02:00
return license and license.is_active == 1
end)
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
exports('issueLicense', function(citizenid, licenseType, issuedBy, classes)
if not citizenid or not licenseType then return false end
2025-08-04 07:40:06 +02:00
2025-08-04 08:45:50 +02:00
issuedBy = issuedBy or 'system'
2025-08-04 08:51:13 +02:00
return safeDBOperation(function()
return saveLicenseToDB(citizenid, licenseType, issuedBy, classes)
end, "Fehler beim Ausstellen der Lizenz") or false
2025-08-04 08:45:50 +02:00
end)
exports('revokeLicense', function(citizenid, licenseType)
if not citizenid or not licenseType then return false end
2025-08-04 08:12:36 +02:00
2025-08-04 08:51:13 +02:00
return safeDBOperation(function()
return revokeLicenseInDB(citizenid, licenseType)
end, "Fehler beim Entziehen der Lizenz") or false
2025-08-04 08:45:50 +02:00
end)
exports('getPlayerLicenses', function(citizenid)
if not citizenid then return {} end
2025-08-04 07:40:06 +02:00
2025-08-04 08:51:13 +02:00
return safeDBOperation(function()
return getAllPlayerLicenses(citizenid)
end, "Fehler beim Abrufen der Spieler-Lizenzen") or {}
2025-08-04 08:45:50 +02:00
end)
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
exports('getPlayerLicense', function(citizenid, licenseType)
if not citizenid or not licenseType then return nil end
2025-08-04 08:51:13 +02:00
return safeDBOperation(function()
return getLicenseFromDB(citizenid, licenseType)
end, "Fehler beim Abrufen der Lizenz")
2025-08-04 08:45:50 +02:00
end)
2025-08-04 06:14:47 +02:00
2025-08-04 08:45:50 +02:00
-- INITIALISIERUNG
2025-08-04 07:40:06 +02:00
CreateThread(function()
2025-08-04 08:51:13 +02:00
debugPrint("License-System Server gestartet (MariaDB-kompatibel)")
2025-08-04 08:45:50 +02:00
-- Warten bis QBCore geladen ist
while not QBCore do
Wait(100)
2025-08-04 06:14:47 +02:00
end
2025-08-04 08:45:50 +02:00
debugPrint("QBCore erfolgreich geladen")
-- Datenbank-Verbindung testen
2025-08-04 08:51:13 +02:00
local testResult = safeDBOperation(function()
return MySQL.query.await("SELECT 1 as test")
end, "Datenbank-Verbindungstest")
2025-08-04 08:45:50 +02:00
if testResult then
debugPrint("Datenbank-Verbindung erfolgreich")
else
debugPrint("^1Datenbank-Verbindung fehlgeschlagen^7")
2025-08-04 06:51:25 +02:00
end
2025-08-04 08:45:50 +02:00
debugPrint("License-System Server vollständig initialisiert")
2025-08-04 06:51:25 +02:00
end)
2025-08-04 08:45:50 +02:00
-- CLEANUP
2025-08-04 07:40:06 +02:00
AddEventHandler('onResourceStop', function(resourceName)
if GetCurrentResourceName() == resourceName then
debugPrint("License-System Server gestoppt")
2025-08-04 08:12:36 +02:00
licenseCache = {}
2025-08-04 07:40:06 +02:00
end
2025-08-04 06:51:25 +02:00
end)
2025-08-04 08:45:50 +02:00
2025-08-04 08:51:13 +02:00
-- DEBUG COMMANDS
2025-08-04 08:45:50 +02:00
RegisterCommand('licensestats', function(source, args, rawCommand)
if source == 0 then -- Console only
2025-08-04 08:51:13 +02:00
local cacheCount = 0
for _ in pairs(licenseCache) do
cacheCount = cacheCount + 1
end
2025-08-04 08:45:50 +02:00
print("=== LICENSE SYSTEM STATS ===")
2025-08-04 08:51:13 +02:00
print("Cache Entries: " .. cacheCount)
print("Config License Types: " .. (Config.LicenseTypes and #Config.LicenseTypes or 0))
2025-08-04 08:45:50 +02:00
print("============================")
end
end, true)
2025-08-04 08:51:13 +02:00
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)
-- Erweiterte Logging-Funktion
local function logLicenseAction(action, src, targetId, licenseType, details)
local timestamp = os.date("%Y-%m-%d %H:%M:%S")
local srcName = getPlayerName(src)
local targetName = targetId and getPlayerName(targetId) or "N/A"
local logMessage = string.format(
"[%s] %s | Quelle: %s (%s) | Ziel: %s (%s) | Typ: %s | Details: %s",
timestamp, action, srcName, src, targetName, targetId or "N/A", licenseType or "N/A", details or "N/A"
)
debugPrint("LOG: " .. logMessage)
-- Hier könnte das Log in eine Datei oder Datenbank geschrieben werden
end
debugPrint("License-System Server vollständig geladen (MariaDB-kompatibel)")