local QBCore = exports['qb-core']:GetCoreObject() -- BAC-Abbaurate (wie viel BAC pro Minute abnimmt) local BAC_DECAY_RATE = Config.BACDecayRate -- Player BAC Cache um übermäßige Datenbankaufrufe zu vermeiden local playerBAC = {} -- Funktion zum Aktualisieren des BAC-Levels eines Spielers local function UpdatePlayerBAC(citizenid, addAmount) -- Initialisieren, falls nicht vorhanden if not playerBAC[citizenid] then playerBAC[citizenid] = { bac = 0.0, lastUpdated = os.time() } end -- Zeitbasierten Abbau berechnen local currentTime = os.time() local minutesPassed = (currentTime - playerBAC[citizenid].lastUpdated) / 60 -- Abbau anwenden, aber nicht unter 0 local decayAmount = BAC_DECAY_RATE * minutesPassed local newBAC = math.max(0.0, playerBAC[citizenid].bac - decayAmount) -- Neuen Alkoholwert hinzufügen newBAC = newBAC + addAmount -- Bei realistischem Maximum begrenzen (0.5% wäre tödlich) newBAC = math.min(0.5, newBAC) -- Cache aktualisieren playerBAC[citizenid] = { bac = newBAC, lastUpdated = currentTime } -- Datenbank aktualisieren MySQL.Async.execute('INSERT INTO player_bac (citizenid, bac_level) VALUES (?, ?) ON DUPLICATE KEY UPDATE bac_level = ?, last_updated = CURRENT_TIMESTAMP', {citizenid, newBAC, newBAC}) end -- Funktion zum Abrufen des aktuellen BAC-Levels eines Spielers mit Abbauberechnung local function GetCurrentBAC(citizenid) -- Wenn wir Cache-Daten haben if playerBAC[citizenid] then local currentTime = os.time() local minutesPassed = (currentTime - playerBAC[citizenid].lastUpdated) / 60 -- Abbau anwenden, aber nicht unter 0 local decayAmount = BAC_DECAY_RATE * minutesPassed local currentBAC = math.max(0.0, playerBAC[citizenid].bac - decayAmount) -- Cache mit abgebautem Wert aktualisieren playerBAC[citizenid] = { bac = currentBAC, lastUpdated = currentTime } -- Datenbank mit neuem abgebautem Wert aktualisieren MySQL.Async.execute('UPDATE player_bac SET bac_level = ?, last_updated = CURRENT_TIMESTAMP WHERE citizenid = ?', {currentBAC, citizenid}) return currentBAC else -- Wenn nicht im Cache, aus Datenbank abrufen local result = MySQL.Sync.fetchAll('SELECT bac_level, last_updated FROM player_bac WHERE citizenid = ?', {citizenid}) if result and result[1] then local storedBAC = result[1].bac_level local lastUpdated = result[1].last_updated -- MySQL-Zeitstempel in Unix-Zeitstempel umwandeln local pattern = "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)" local year, month, day, hour, min, sec = lastUpdated:match(pattern) local lastUpdateTime = os.time({year=year, month=month, day=day, hour=hour, min=min, sec=sec}) local currentTime = os.time() local minutesPassed = (currentTime - lastUpdateTime) / 60 -- Abbau anwenden, aber nicht unter 0 local decayAmount = BAC_DECAY_RATE * minutesPassed local currentBAC = math.max(0.0, storedBAC - decayAmount) -- Cache aktualisieren playerBAC[citizenid] = { bac = currentBAC, lastUpdated = currentTime } -- Datenbank mit neuem abgebautem Wert aktualisieren MySQL.Async.execute('UPDATE player_bac SET bac_level = ?, last_updated = CURRENT_TIMESTAMP WHERE citizenid = ?', {currentBAC, citizenid}) return currentBAC else -- Kein Eintrag gefunden, mit 0 initialisieren playerBAC[citizenid] = { bac = 0.0, lastUpdated = os.time() } return 0.0 end end end -- Anbindung an das Konsumsystem -- Dieses Event sollte ausgelöst werden, wenn ein Spieler ein alkoholisches Item konsumiert RegisterNetEvent('qb-alcoholtest:server:alcoholConsumed') AddEventHandler('qb-alcoholtest:server:alcoholConsumed', function(itemName, intensity) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end local citizenid = Player.PlayerData.citizenid local alcoholContent = 0.0 -- Prüfen, ob das konsumierte Item alkoholisch ist if Config.AlcoholItems[itemName] then alcoholContent = Config.AlcoholItems[itemName] -- Basierend auf Intensität anpassen, falls angegeben if intensity then alcoholContent = alcoholContent * intensity end -- BAC des Spielers aktualisieren UpdatePlayerBAC(citizenid, alcoholContent) -- Spieler benachrichtigen if Config.Debug then TriggerClientEvent('QBCore:Notify', src, 'Du spürst die Wirkung des Alkohols.', 'primary') end end end) -- Verwendbares Alkoholtester-Item erstellen QBCore.Functions.CreateUseableItem('breathalyzer', function(source, item) local src = source TriggerClientEvent('qb-alcoholtest:client:useBreathalyzer', src) end) -- Alkoholtester-Events RegisterServerEvent('qb-alcoholtest:server:doBacTest') AddEventHandler('qb-alcoholtest:server:doBacTest', function(target) TriggerClientEvent('qb-alcoholtest:client:requestBac', target, source, target) end) RegisterServerEvent('qb-alcoholtest:server:refusedBac') AddEventHandler('qb-alcoholtest:server:refusedBac', function(leo, target) TriggerClientEvent('qb-alcoholtest:client:bacRefused', leo, target) end) RegisterServerEvent('qb-alcoholtest:server:acceptedBac') AddEventHandler('qb-alcoholtest:server:acceptedBac', function(leo, target) TriggerClientEvent('qb-alcoholtest:client:acceptedBac', leo, target) end) -- Neues Event, um den tatsächlichen BAC-Wert aus dem System zu erhalten RegisterServerEvent('qb-alcoholtest:server:getActualBAC') AddEventHandler('qb-alcoholtest:server:getActualBAC', function(leo, target) local targetPlayer = QBCore.Functions.GetPlayer(target) if not targetPlayer then return end local citizenid = targetPlayer.PlayerData.citizenid local currentBAC = GetCurrentBAC(citizenid) -- BAC auf 2 Dezimalstellen formatieren local formattedBAC = string.format("%.2f", currentBAC) -- Farbe basierend auf gesetzlichem Limit bestimmen local color = '--color-black' if currentBAC > Config.LegalLimit then color = '--color-red' end -- BAC-Ergebnis an den Beamten senden TriggerClientEvent('qb-alcoholtest:client:displayBac', leo, formattedBAC, color) end) -- Öffentliche Funktion für andere Ressourcen exports('GetPlayerBAC', function(citizenid) return GetCurrentBAC(citizenid) end) -- Öffentliche Funktion zum Aktualisieren des BAC-Werts exports('UpdatePlayerBAC', function(citizenid, amount) UpdatePlayerBAC(citizenid, amount) end) -- Sicherstellen, dass die Datenbanktabelle existiert, wenn die Ressource startet MySQL.ready(function() MySQL.Async.execute([[ CREATE TABLE IF NOT EXISTS `player_bac` ( `citizenid` varchar(50) NOT NULL, `bac_level` float NOT NULL DEFAULT 0.0, `last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`citizenid`) ); ]]) end)