local QBCore = exports['qb-core']:GetCoreObject() -- Datenbank Setup MySQL.ready(function() MySQL.Async.execute([[ CREATE TABLE IF NOT EXISTS player_licenses ( id INT AUTO_INCREMENT PRIMARY KEY, citizenid VARCHAR(50) NOT NULL, license_type VARCHAR(50) NOT NULL, name VARCHAR(100) NOT NULL, birthday VARCHAR(20), gender VARCHAR(20), issue_date VARCHAR(20) NOT NULL, expire_date VARCHAR(20), classes TEXT, issued_by VARCHAR(50) NOT NULL, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX(citizenid), INDEX(license_type) ) ]]) end) -- Command registrieren QBCore.Commands.Add(Config.Command, 'Öffne das Lizenz-Menü', {}, false, function(source, args) TriggerClientEvent('license-system:client:openMenu', source) end) -- Events RegisterNetEvent('license-system:server:getLicenses', function() local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end MySQL.Async.fetchAll('SELECT * FROM player_licenses WHERE citizenid = ?', { Player.PlayerData.citizenid }, function(result) TriggerClientEvent('license-system:client:receiveLicenses', src, result) end) end) RegisterNetEvent('license-system:server:getNearbyPlayers', function() local src = source TriggerClientEvent('license-system:client:receiveNearbyPlayers', src, QBCore.Functions.GetPlayers()) end) RegisterNetEvent('license-system:server:showLicense', function(targetId, licenseData) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end TriggerClientEvent('license-system:client:viewLicense', targetId, licenseData, Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname) end) RegisterNetEvent('license-system:server:issueLicense', function(targetId, licenseType, licenseData) local src = source local Player = QBCore.Functions.GetPlayer(src) local TargetPlayer = QBCore.Functions.GetPlayer(targetId) if not Player or not TargetPlayer then return end -- Job-Berechtigung prüfen local playerJob = Player.PlayerData.job.name if not Config.AuthorizedJobs[playerJob] or not hasPermission(Config.AuthorizedJobs[playerJob].canIssue, licenseType) then TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Aktion!', 'error') return end -- Lizenz in Datenbank speichern MySQL.Async.execute('INSERT INTO player_licenses (citizenid, license_type, name, birthday, gender, issue_date, expire_date, classes, issued_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', { TargetPlayer.PlayerData.citizenid, licenseType, licenseData.name, licenseData.birthday, licenseData.gender, licenseData.issue_date, licenseData.expire_date, json.encode(licenseData.classes or {}), Player.PlayerData.citizenid }, function(insertId) if insertId then TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich ausgestellt!', 'success') TriggerClientEvent('QBCore:Notify', targetId, 'Du hast eine neue Lizenz erhalten: ' .. Config.Licenses[licenseType].label, 'success') else TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Ausstellen der Lizenz!', 'error') end end) end) RegisterNetEvent('license-system:server:revokeLicense', function(targetId, licenseId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end -- Job-Berechtigung prüfen local playerJob = Player.PlayerData.job.name if not Config.AuthorizedJobs[playerJob] then TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Aktion!', 'error') return end MySQL.Async.execute('UPDATE player_licenses SET is_active = FALSE WHERE id = ?', { licenseId }, function(affectedRows) if affectedRows > 0 then TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich entzogen!', 'success') if targetId then TriggerClientEvent('QBCore:Notify', targetId, 'Eine deiner Lizenzen wurde entzogen!', 'error') end else TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Entziehen der Lizenz!', 'error') end end) end) RegisterNetEvent('license-system:server:restoreLicense', function(targetId, licenseId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end -- Job-Berechtigung prüfen local playerJob = Player.PlayerData.job.name if not Config.AuthorizedJobs[playerJob] then TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Aktion!', 'error') return end MySQL.Async.execute('UPDATE player_licenses SET is_active = TRUE WHERE id = ?', { licenseId }, function(affectedRows) if affectedRows > 0 then TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich wiederhergestellt!', 'success') if targetId then TriggerClientEvent('QBCore:Notify', targetId, 'Eine deiner Lizenzen wurde wiederhergestellt!', 'success') end else TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Wiederherstellen der Lizenz!', 'error') end end) end) -- Hilfsfunktionen function hasPermission(permissions, licenseType) for _, permission in ipairs(permissions) do if permission == licenseType then return true end end return false end -- Erweiterte Funktionen für Lizenzverwaltung RegisterNetEvent('license-system:server:searchPlayer', function(searchTerm) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end -- Job-Berechtigung prüfen local playerJob = Player.PlayerData.job.name if not Config.AuthorizedJobs[playerJob] then TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Aktion!', 'error') return end -- Spieler suchen MySQL.Async.fetchAll('SELECT citizenid, charinfo FROM players WHERE JSON_EXTRACT(charinfo, "$.firstname") LIKE ? OR JSON_EXTRACT(charinfo, "$.lastname") LIKE ? LIMIT 10', { '%' .. searchTerm .. '%', '%' .. searchTerm .. '%' }, function(result) local players = {} for _, player in ipairs(result) do local charinfo = json.decode(player.charinfo) table.insert(players, { citizenid = player.citizenid, name = charinfo.firstname .. ' ' .. charinfo.lastname }) end TriggerClientEvent('license-system:client:receiveSearchResults', src, players) end) end) RegisterNetEvent('license-system:server:getPlayerLicenses', function(citizenid) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end -- Job-Berechtigung prüfen local playerJob = Player.PlayerData.job.name if not Config.AuthorizedJobs[playerJob] then TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Aktion!', 'error') return end MySQL.Async.fetchAll('SELECT * FROM player_licenses WHERE citizenid = ? ORDER BY created_at DESC', { citizenid }, function(result) TriggerClientEvent('license-system:client:receivePlayerLicenses', src, result, citizenid) end) end) -- Lizenz-Historie hinzufügen function addLicenseHistory(licenseId, action, performedBy, performedByName, reason) MySQL.Async.execute('INSERT INTO license_history (license_id, action, performed_by, performed_by_name, reason) VALUES (?, ?, ?, ?, ?)', { licenseId, action, performedBy, performedByName, reason or '' }) end -- Erweiterte Revoke-Funktion mit Grund RegisterNetEvent('license-system:server:revokeLicenseWithReason', function(licenseId, reason) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end local playerJob = Player.PlayerData.job.name if not Config.AuthorizedJobs[playerJob] then TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Aktion!', 'error') return end local playerName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname MySQL.Async.execute('UPDATE player_licenses SET is_active = FALSE, revoked_by = ?, revoked_by_name = ?, revoked_date = NOW(), revoked_reason = ? WHERE id = ?', { Player.PlayerData.citizenid, playerName, reason, licenseId }, function(affectedRows) if affectedRows > 0 then addLicenseHistory(licenseId, 'revoked', Player.PlayerData.citizenid, playerName, reason) TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich entzogen!', 'success') else TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Entziehen der Lizenz!', 'error') end end) end) -- Automatische Lizenz-Überprüfung (läuft alle 24 Stunden) CreateThread(function() while true do Wait(24 * 60 * 60 * 1000) -- 24 Stunden -- Abgelaufene Lizenzen deaktivieren MySQL.Async.execute('UPDATE player_licenses SET is_active = FALSE WHERE expire_date < CURDATE() AND is_active = TRUE', {}, function(affectedRows) if affectedRows > 0 then print('^3[License-System]^7 ' .. affectedRows .. ' abgelaufene Lizenzen wurden deaktiviert.') end end) end end) -- Export-Funktionen für andere Ressourcen exports('hasLicense', function(citizenid, licenseType) local result = MySQL.Sync.fetchScalar('SELECT COUNT(*) FROM player_licenses WHERE citizenid = ? AND license_type = ? AND is_active = TRUE', { citizenid, licenseType }) return result > 0 end) exports('getLicenses', function(citizenid) return MySQL.Sync.fetchAll('SELECT * FROM player_licenses WHERE citizenid = ? AND is_active = TRUE', { citizenid }) end) exports('hasLicenseClass', function(citizenid, class) local result = MySQL.Sync.fetchAll('SELECT classes FROM player_licenses WHERE citizenid = ? AND license_type = "drivers_license" AND is_active = TRUE', { citizenid }) for _, license in ipairs(result) do if license.classes then local classes = json.decode(license.classes) for _, licenseClass in ipairs(classes) do if licenseClass == class then return true end end end end return false end)