2025-08-04 06:14:47 +02:00
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 )
2025-08-04 06:51:25 +02:00
-- Spieler-Foto aus QBCore holen
RegisterNetEvent ( ' license-system:server:getPlayerPhoto ' , function ( targetId )
local src = source
local TargetPlayer = QBCore.Functions . GetPlayer ( targetId )
if TargetPlayer then
-- Mugshot vom Spieler machen
TriggerClientEvent ( ' license-system:client:takePlayerPhoto ' , src , targetId )
end
end )
-- Foto-URL speichern
RegisterNetEvent ( ' license-system:server:savePlayerPhoto ' , function ( citizenid , photoUrl )
MySQL.Async . execute ( ' UPDATE player_licenses SET photo_url = ? WHERE citizenid = ? AND id = ? ' , {
photoUrl ,
citizenid ,
-- Hier die aktuelle Lizenz-ID
} )
end )