forked from Simnation/Main
ed
This commit is contained in:
parent
354019affc
commit
7932af55cb
3 changed files with 1311 additions and 715 deletions
|
@ -1,312 +1,530 @@
|
|||
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
|
||||
local function debugPrint(message)
|
||||
if Config.Debug then
|
||||
print("^2[License-System] " .. message .. "^7")
|
||||
end
|
||||
end
|
||||
|
||||
local function safeCallback(cb, ...)
|
||||
if cb and type(cb) == "function" then
|
||||
cb(...)
|
||||
else
|
||||
debugPrint("^1Callback ist keine Funktion!^7")
|
||||
end
|
||||
end
|
||||
|
||||
local function formatDate(date)
|
||||
if not date then return nil end
|
||||
return os.date("%d.%m.%Y", date)
|
||||
end
|
||||
|
||||
local function addDaysToDate(days)
|
||||
return os.time() + (days * 24 * 60 * 60)
|
||||
end
|
||||
|
||||
local function isLicenseExpired(expireDate)
|
||||
if not expireDate then return false end
|
||||
return os.time() > expireDate
|
||||
end
|
||||
|
||||
local function getDaysUntilExpiry(expireDate)
|
||||
if not expireDate then return nil end
|
||||
local diff = expireDate - os.time()
|
||||
return math.ceil(diff / (24 * 60 * 60))
|
||||
end
|
||||
|
||||
-- Spieler-Daten abrufen
|
||||
local function getPlayerData(source)
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
if not Player then return nil end
|
||||
|
||||
return {
|
||||
citizenid = Player.PlayerData.citizenid,
|
||||
name = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname,
|
||||
birthday = Player.PlayerData.charinfo.birthdate,
|
||||
gender = Player.PlayerData.charinfo.gender,
|
||||
job = Player.PlayerData.job.name,
|
||||
money = Player.PlayerData.money.cash
|
||||
}
|
||||
end
|
||||
|
||||
-- Berechtigung prüfen
|
||||
local function hasPermission(source, licenseType)
|
||||
local playerData = getPlayerData(source)
|
||||
if not playerData then return false end
|
||||
|
||||
-- Admin-Check
|
||||
if QBCore.Functions.HasPermission(source, 'admin') then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Job-Check
|
||||
if Config.AuthorizedJobs[playerData.job] then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Spezifische Lizenz-Berechtigung
|
||||
local licenseConfig = Config.LicenseTypes[licenseType]
|
||||
if licenseConfig and licenseConfig.required_job then
|
||||
return playerData.job == licenseConfig.required_job
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Erweiterte Funktionen für Lizenzverwaltung
|
||||
-- Benötigte Items prüfen
|
||||
local function hasRequiredItems(source, licenseType)
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
if not Player then return false end
|
||||
|
||||
local licenseConfig = Config.LicenseTypes[licenseType]
|
||||
if not licenseConfig or not licenseConfig.required_items then return true end
|
||||
|
||||
for _, item in ipairs(licenseConfig.required_items) do
|
||||
local hasItem = Player.Functions.GetItemByName(item)
|
||||
if not hasItem or hasItem.amount < 1 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
RegisterNetEvent('license-system:server:searchPlayer', function(searchTerm)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
-- Lizenz erstellen
|
||||
local function createLicense(citizenid, licenseType, issuedBy, classes)
|
||||
local licenseConfig = Config.LicenseTypes[licenseType]
|
||||
if not licenseConfig then return false end
|
||||
|
||||
if not Player then return end
|
||||
local issueDate = os.time()
|
||||
local expireDate = nil
|
||||
|
||||
-- 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')
|
||||
if licenseConfig.can_expire and licenseConfig.validity_days then
|
||||
expireDate = addDaysToDate(licenseConfig.validity_days)
|
||||
end
|
||||
|
||||
local licenseData = {
|
||||
citizenid = citizenid,
|
||||
license_type = licenseType,
|
||||
issue_date = formatDate(issueDate),
|
||||
expire_date = expireDate and formatDate(expireDate) or nil,
|
||||
issued_by = issuedBy,
|
||||
is_active = true,
|
||||
classes = classes and json.encode(classes) or '[]',
|
||||
created_at = issueDate
|
||||
}
|
||||
|
||||
MySQL.Async.insert('INSERT INTO player_licenses (citizenid, license_type, issue_date, expire_date, issued_by, is_active, classes, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', {
|
||||
licenseData.citizenid,
|
||||
licenseData.license_type,
|
||||
licenseData.issue_date,
|
||||
licenseData.expire_date,
|
||||
licenseData.issued_by,
|
||||
licenseData.is_active,
|
||||
licenseData.classes,
|
||||
licenseData.created_at
|
||||
}, function(insertId)
|
||||
if insertId then
|
||||
debugPrint("Lizenz erstellt: " .. licenseType .. " für " .. citizenid)
|
||||
return true
|
||||
else
|
||||
debugPrint("^1Fehler beim Erstellen der Lizenz!^7")
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Callbacks
|
||||
QBCore.Functions.CreateCallback('license-system:server:getLicense', function(source, cb, targetId)
|
||||
debugPrint("getLicense aufgerufen für Spieler: " .. tostring(targetId))
|
||||
|
||||
local TargetPlayer = QBCore.Functions.GetPlayer(targetId)
|
||||
if not TargetPlayer then
|
||||
debugPrint("^1Ziel-Spieler nicht gefunden!^7")
|
||||
safeCallback(cb, nil)
|
||||
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 .. '%'
|
||||
local citizenid = TargetPlayer.PlayerData.citizenid
|
||||
|
||||
MySQL.Async.fetchAll('SELECT * FROM player_licenses WHERE citizenid = ? AND is_active = TRUE ORDER BY created_at DESC LIMIT 1', {
|
||||
citizenid
|
||||
}, 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
|
||||
})
|
||||
if result and result[1] then
|
||||
local license = result[1]
|
||||
|
||||
-- Spieler-Daten hinzufügen
|
||||
license.name = TargetPlayer.PlayerData.charinfo.firstname .. ' ' .. TargetPlayer.PlayerData.charinfo.lastname
|
||||
license.birthday = TargetPlayer.PlayerData.charinfo.birthdate
|
||||
license.gender = TargetPlayer.PlayerData.charinfo.gender
|
||||
|
||||
-- Aussteller-Name abrufen
|
||||
if license.issued_by then
|
||||
MySQL.Async.fetchScalar('SELECT CONCAT(JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.firstname")), " ", JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.lastname"))) FROM players WHERE citizenid = ?', {
|
||||
license.issued_by
|
||||
}, function(issuerName)
|
||||
license.issued_by_name = issuerName or 'Unbekannt'
|
||||
|
||||
local licenseData = {
|
||||
license = license,
|
||||
config = Config.LicenseTypes[license.license_type] or {
|
||||
label = license.license_type,
|
||||
icon = 'fas fa-id-card'
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint("Lizenz gefunden: " .. license.license_type)
|
||||
safeCallback(cb, licenseData)
|
||||
end)
|
||||
else
|
||||
license.issued_by_name = 'System'
|
||||
|
||||
local licenseData = {
|
||||
license = license,
|
||||
config = Config.LicenseTypes[license.license_type] or {
|
||||
label = license.license_type,
|
||||
icon = 'fas fa-id-card'
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint("Lizenz gefunden: " .. license.license_type)
|
||||
safeCallback(cb, licenseData)
|
||||
end
|
||||
else
|
||||
debugPrint("Keine Lizenz gefunden für: " .. citizenid)
|
||||
safeCallback(cb, nil)
|
||||
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)
|
||||
QBCore.Functions.CreateCallback('license-system:server:getMyLicense', function(source, cb, licenseType)
|
||||
debugPrint("getMyLicense aufgerufen für Typ: " .. tostring(licenseType))
|
||||
|
||||
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')
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
if not Player then
|
||||
safeCallback(cb, nil)
|
||||
return
|
||||
end
|
||||
|
||||
local citizenid = Player.PlayerData.citizenid
|
||||
|
||||
MySQL.Async.fetchAll('SELECT * FROM player_licenses WHERE citizenid = ? AND license_type = ? AND is_active = TRUE ORDER BY created_at DESC LIMIT 1', {
|
||||
citizenid,
|
||||
licenseType
|
||||
}, function(result)
|
||||
if result and result[1] then
|
||||
local license = result[1]
|
||||
|
||||
-- Spieler-Daten hinzufügen
|
||||
license.name = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
|
||||
license.birthday = Player.PlayerData.charinfo.birthdate
|
||||
license.gender = Player.PlayerData.charinfo.gender
|
||||
|
||||
-- Aussteller-Name abrufen
|
||||
if license.issued_by then
|
||||
MySQL.Async.fetchScalar('SELECT CONCAT(JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.firstname")), " ", JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.lastname"))) FROM players WHERE citizenid = ?', {
|
||||
license.issued_by
|
||||
}, function(issuerName)
|
||||
license.issued_by_name = issuerName or 'Unbekannt'
|
||||
|
||||
local licenseData = {
|
||||
license = license,
|
||||
config = Config.LicenseTypes[license.license_type] or {
|
||||
label = license.license_type,
|
||||
icon = 'fas fa-id-card'
|
||||
}
|
||||
}
|
||||
|
||||
safeCallback(cb, licenseData)
|
||||
end)
|
||||
else
|
||||
license.issued_by_name = 'System'
|
||||
|
||||
local licenseData = {
|
||||
license = license,
|
||||
config = Config.LicenseTypes[license.license_type] or {
|
||||
label = license.license_type,
|
||||
icon = 'fas fa-id-card'
|
||||
}
|
||||
}
|
||||
|
||||
safeCallback(cb, licenseData)
|
||||
end
|
||||
else
|
||||
debugPrint("Keine Lizenz vom Typ " .. licenseType .. " gefunden")
|
||||
safeCallback(cb, nil)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
QBCore.Functions.CreateCallback('license-system:server:getPlayerLicenses', function(source, cb, targetId)
|
||||
debugPrint("getPlayerLicenses aufgerufen für Spieler: " .. tostring(targetId))
|
||||
|
||||
local TargetPlayer = QBCore.Functions.GetPlayer(targetId)
|
||||
if not TargetPlayer then
|
||||
safeCallback(cb, {})
|
||||
return
|
||||
end
|
||||
|
||||
local citizenid = TargetPlayer.PlayerData.citizenid
|
||||
|
||||
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)
|
||||
if result then
|
||||
-- Spieler-Daten zu jeder Lizenz hinzufügen
|
||||
for i, license in ipairs(result) do
|
||||
license.name = TargetPlayer.PlayerData.charinfo.firstname .. ' ' .. TargetPlayer.PlayerData.charinfo.lastname
|
||||
license.birthday = TargetPlayer.PlayerData.charinfo.birthdate
|
||||
license.gender = TargetPlayer.PlayerData.charinfo.gender
|
||||
end
|
||||
|
||||
debugPrint("Gefundene Lizenzen: " .. #result)
|
||||
safeCallback(cb, result)
|
||||
else
|
||||
debugPrint("Keine Lizenzen gefunden")
|
||||
safeCallback(cb, {})
|
||||
end
|
||||
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
|
||||
QBCore.Functions.CreateCallback('license-system:server:canIssueLicense', function(source, cb, licenseType)
|
||||
local hasAuth = hasPermission(source, licenseType)
|
||||
safeCallback(cb, hasAuth)
|
||||
end)
|
||||
|
||||
-- Erweiterte Revoke-Funktion mit Grund
|
||||
RegisterNetEvent('license-system:server:revokeLicenseWithReason', function(licenseId, reason)
|
||||
-- Events
|
||||
RegisterNetEvent('license-system:server:issueLicense', function(targetId, licenseType, classes)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
local TargetPlayer = QBCore.Functions.GetPlayer(targetId)
|
||||
|
||||
if not Player or not TargetPlayer then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_players_nearby.message, Config.Notifications.no_players_nearby.type)
|
||||
return
|
||||
end
|
||||
|
||||
-- Berechtigung prüfen
|
||||
if not hasPermission(src, licenseType) then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_permission.message, Config.Notifications.no_permission.type)
|
||||
return
|
||||
end
|
||||
|
||||
-- Lizenz-Konfiguration prüfen
|
||||
local licenseConfig = Config.LicenseTypes[licenseType]
|
||||
if not licenseConfig then
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Unbekannter Lizenztyp!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
-- Benötigte Items prüfen
|
||||
if not hasRequiredItems(targetId, licenseType) then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.missing_items.message, Config.Notifications.missing_items.type)
|
||||
return
|
||||
end
|
||||
|
||||
-- Geld prüfen (falls Kosten anfallen)
|
||||
if licenseConfig.price > 0 then
|
||||
if TargetPlayer.PlayerData.money.cash < licenseConfig.price then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.insufficient_funds.message, Config.Notifications.insufficient_funds.type)
|
||||
return
|
||||
end
|
||||
|
||||
-- Geld abziehen
|
||||
TargetPlayer.Functions.RemoveMoney('cash', licenseConfig.price, 'license-fee')
|
||||
end
|
||||
|
||||
-- Alte Lizenz deaktivieren
|
||||
MySQL.Async.execute('UPDATE player_licenses SET is_active = FALSE WHERE citizenid = ? AND license_type = ?', {
|
||||
TargetPlayer.PlayerData.citizenid,
|
||||
licenseType
|
||||
})
|
||||
|
||||
-- Neue Lizenz erstellen
|
||||
local success = createLicense(TargetPlayer.PlayerData.citizenid, licenseType, Player.PlayerData.citizenid, classes)
|
||||
|
||||
if success then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.license_granted.message, Config.Notifications.license_granted.type)
|
||||
TriggerClientEvent('QBCore:Notify', targetId, 'Du hast eine neue ' .. licenseConfig.label .. ' erhalten!', 'success')
|
||||
|
||||
-- Log erstellen
|
||||
debugPrint(Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname .. ' hat ' .. TargetPlayer.PlayerData.charinfo.firstname .. ' ' .. TargetPlayer.PlayerData.charinfo.lastname .. ' eine ' .. licenseConfig.label .. ' ausgestellt')
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Ausstellen der Lizenz!', 'error')
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('license-system:server:revokeLicense', function(targetId, licenseType)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
local TargetPlayer = QBCore.Functions.GetPlayer(targetId)
|
||||
|
||||
if not Player or not TargetPlayer then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_players_nearby.message, Config.Notifications.no_players_nearby.type)
|
||||
return
|
||||
end
|
||||
|
||||
-- Berechtigung prüfen
|
||||
if not hasPermission(src, licenseType) then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.no_permission.message, Config.Notifications.no_permission.type)
|
||||
return
|
||||
end
|
||||
|
||||
-- Lizenz deaktivieren
|
||||
MySQL.Async.execute('UPDATE player_licenses SET is_active = FALSE WHERE citizenid = ? AND license_type = ? AND is_active = TRUE', {
|
||||
TargetPlayer.PlayerData.citizenid,
|
||||
licenseType
|
||||
}, function(affectedRows)
|
||||
if affectedRows > 0 then
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.license_revoked.message, Config.Notifications.license_revoked.type)
|
||||
TriggerClientEvent('QBCore:Notify', targetId, 'Deine ' .. (Config.LicenseTypes[licenseType]?.label or licenseType) .. ' wurde entzogen!', 'error')
|
||||
|
||||
-- Log erstellen
|
||||
debugPrint(Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname .. ' hat ' .. TargetPlayer.PlayerData.charinfo.firstname .. ' ' .. TargetPlayer.PlayerData.charinfo.lastname .. ' die ' .. (Config.LicenseTypes[licenseType]?.label or licenseType) .. ' entzogen')
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Keine aktive Lizenz gefunden!', 'error')
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('license-system:server:savePhoto', function(citizenid, photoData)
|
||||
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
|
||||
-- Foto in der Datenbank speichern
|
||||
MySQL.Async.execute('UPDATE player_licenses SET photo_url = ? WHERE citizenid = ? AND is_active = TRUE', {
|
||||
photoData,
|
||||
citizenid
|
||||
}, function(affectedRows)
|
||||
if affectedRows > 0 then
|
||||
addLicenseHistory(licenseId, 'revoked', Player.PlayerData.citizenid, playerName, reason)
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Lizenz erfolgreich entzogen!', 'success')
|
||||
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.photo_saved.message, Config.Notifications.photo_saved.type)
|
||||
debugPrint("Foto gespeichert für: " .. citizenid)
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Entziehen der Lizenz!', 'error')
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Speichern des Fotos!', 'error')
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Automatische Lizenz-Überprüfung (läuft alle 24 Stunden)
|
||||
-- Admin-Kommandos
|
||||
QBCore.Commands.Add('givelicense', 'Lizenz an Spieler vergeben', {
|
||||
{name = 'id', help = 'Spieler ID'},
|
||||
{name = 'type', help = 'Lizenztyp'},
|
||||
{name = 'classes', help = 'Klassen (optional)'}
|
||||
}, true, function(source, args)
|
||||
local targetId = tonumber(args[1])
|
||||
local licenseType = args[2]
|
||||
local classes = args[3] and {args[3]} or nil
|
||||
|
||||
if not targetId or not licenseType then
|
||||
TriggerClientEvent('QBCore:Notify', source, 'Verwendung: /givelicense [id] [typ] [klassen]', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
if not Config.LicenseTypes[licenseType] then
|
||||
TriggerClientEvent('QBCore:Notify', source, 'Unbekannter Lizenztyp!', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
TriggerEvent('license-system:server:issueLicense', targetId, licenseType, classes)
|
||||
end, 'admin')
|
||||
|
||||
QBCore.Commands.Add('revokelicense', 'Lizenz entziehen', {
|
||||
{name = 'id', help = 'Spieler ID'},
|
||||
{name = 'type', help = 'Lizenztyp'}
|
||||
}, true, function(source, args)
|
||||
local targetId = tonumber(args[1])
|
||||
local licenseType = args[2]
|
||||
|
||||
if not targetId or not licenseType then
|
||||
TriggerClientEvent('QBCore:Notify', source, 'Verwendung: /revokelicense [id] [typ]', 'error')
|
||||
return
|
||||
end
|
||||
|
||||
TriggerEvent('license-system:server:revokeLicense', targetId, licenseType)
|
||||
end, 'admin')
|
||||
|
||||
-- Cleanup-Task für abgelaufene Lizenzen
|
||||
if Config.Database.auto_cleanup then
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(24 * 60 * 60 * 1000) -- Einmal täglich
|
||||
|
||||
local cutoffDate = os.time() - (Config.Database.cleanup_days * 24 * 60 * 60)
|
||||
|
||||
MySQL.Async.execute('DELETE FROM player_licenses WHERE is_active = FALSE AND created_at < ?', {
|
||||
cutoffDate
|
||||
}, function(affectedRows)
|
||||
if affectedRows > 0 then
|
||||
debugPrint("Cleanup: " .. affectedRows .. " alte Lizenzen gelöscht")
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Lizenz-Ablauf-Checker
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(24 * 60 * 60 * 1000) -- 24 Stunden
|
||||
Wait(60 * 60 * 1000) -- Jede Stunde
|
||||
|
||||
-- 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.')
|
||||
MySQL.Async.fetchAll('SELECT * FROM player_licenses WHERE is_active = TRUE AND expire_date IS NOT NULL', {}, function(result)
|
||||
if result then
|
||||
for _, license in ipairs(result) do
|
||||
local expireTime = os.time({
|
||||
year = tonumber(string.sub(license.expire_date, 7, 10)),
|
||||
month = tonumber(string.sub(license.expire_date, 4, 5)),
|
||||
day = tonumber(string.sub(license.expire_date, 1, 2))
|
||||
})
|
||||
|
||||
if isLicenseExpired(expireTime) then
|
||||
-- Lizenz als abgelaufen markieren
|
||||
MySQL.Async.execute('UPDATE player_licenses SET is_active = FALSE WHERE id = ?', {
|
||||
license.id
|
||||
})
|
||||
|
||||
debugPrint("Lizenz abgelaufen: " .. license.license_type .. " für " .. license.citizenid)
|
||||
end
|
||||
end
|
||||
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)
|
||||
|
||||
-- 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)
|
||||
-- Resource Start/Stop Events
|
||||
AddEventHandler('onResourceStart', function(resourceName)
|
||||
if GetCurrentResourceName() == resourceName then
|
||||
debugPrint("License-System Server gestartet")
|
||||
|
||||
-- Datenbank-Tabelle erstellen falls nicht vorhanden
|
||||
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,
|
||||
issue_date VARCHAR(20) NOT NULL,
|
||||
expire_date VARCHAR(20) NULL,
|
||||
issued_by VARCHAR(50) NULL,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
classes TEXT NULL,
|
||||
photo_url TEXT NULL,
|
||||
notes TEXT NULL,
|
||||
created_at BIGINT NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_citizenid (citizenid),
|
||||
INDEX idx_license_type (license_type),
|
||||
INDEX idx_active (is_active)
|
||||
)
|
||||
]])
|
||||
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
|
||||
})
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if GetCurrentResourceName() == resourceName then
|
||||
debugPrint("License-System Server gestoppt")
|
||||
end
|
||||
end)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue