562 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			562 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local QBCore = exports['qb-core']:GetCoreObject()
 | 
						|
 | 
						|
-- Game Management
 | 
						|
local activeGames = {}
 | 
						|
local gameIdCounter = 1
 | 
						|
 | 
						|
-- Debug-Funktion für Konsole
 | 
						|
local function debugPrint(message)
 | 
						|
    print("^2[TDM SERVER]^7 " .. message)
 | 
						|
end
 | 
						|
 | 
						|
-- Events
 | 
						|
RegisterNetEvent('tdm:createGame', function(gameName, fieldId, gameType, password)
 | 
						|
    local src = source
 | 
						|
    local Player = QBCore.Functions.GetPlayer(src)
 | 
						|
    
 | 
						|
    if not Player then 
 | 
						|
        debugPrint("Spielerstellung fehlgeschlagen - Spieler nicht gefunden: " .. src)
 | 
						|
        return 
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Prüfen ob Spielfeld bereits belegt
 | 
						|
    for gameId, gameData in pairs(activeGames) do
 | 
						|
        if gameData.fieldId == fieldId then
 | 
						|
            debugPrint("Spielerstellung abgelehnt - Feld bereits belegt: " .. fieldId)
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Dieses Spielfeld ist bereits belegt!', 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    local gameId = 'game_' .. gameIdCounter
 | 
						|
    gameIdCounter = gameIdCounter + 1
 | 
						|
    
 | 
						|
    activeGames[gameId] = {
 | 
						|
        id = gameId,
 | 
						|
        name = gameName,
 | 
						|
        fieldId = fieldId,
 | 
						|
        admin = src,
 | 
						|
        adminName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname,
 | 
						|
        gameType = gameType,
 | 
						|
        password = password,
 | 
						|
        hasPassword = password ~= nil,
 | 
						|
        status = 'waiting',
 | 
						|
        team1 = {},
 | 
						|
        team2 = {},
 | 
						|
        score = {team1 = 0, team2 = 0},
 | 
						|
        startTime = nil,
 | 
						|
        maxTime = Config.maxGameTime,
 | 
						|
        maxHits = Config.maxHits,
 | 
						|
        playerStats = {} -- Spieler-Statistiken initialisieren
 | 
						|
    }
 | 
						|
    
 | 
						|
    local typeText = gameType == 'public' and 'öffentliches' or 'privates'
 | 
						|
    TriggerClientEvent('QBCore:Notify', src, 'Dein ' .. typeText .. ' Spiel "' .. gameName .. '" wurde erstellt!', 'success')
 | 
						|
    
 | 
						|
    updateGamesListForAll()
 | 
						|
    debugPrint("Spiel erstellt: " .. gameId .. " von " .. Player.PlayerData.name .. " (Feld: " .. fieldId .. ")")
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:requestGamesList', function()
 | 
						|
    local src = source
 | 
						|
    debugPrint("Spiele-Liste angefordert von: " .. src)
 | 
						|
    TriggerClientEvent('tdm:updateGamesList', src, activeGames)
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:requestJoinGame', function(gameId, password)
 | 
						|
    local src = source
 | 
						|
    local Player = QBCore.Functions.GetPlayer(src)
 | 
						|
    
 | 
						|
    if not Player or not activeGames[gameId] then 
 | 
						|
        debugPrint("Spielbeitritt fehlgeschlagen - Spieler oder Spiel nicht gefunden: " .. src .. ", " .. gameId)
 | 
						|
        return 
 | 
						|
    end
 | 
						|
    
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    local playerName = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
 | 
						|
    
 | 
						|
    debugPrint("Beitrittsanfrage von " .. playerName .. " (ID: " .. src .. ") für Spiel " .. gameId)
 | 
						|
    
 | 
						|
    -- Passwort prüfen falls vorhanden
 | 
						|
    if game.hasPassword and game.password ~= password then
 | 
						|
        debugPrint("Beitritt abgelehnt - Falsches Passwort")
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Falsches Passwort!', 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Spieler bereits im Spiel?
 | 
						|
    for _, playerId in ipairs(game.team1) do
 | 
						|
        if playerId == src then
 | 
						|
            debugPrint("Beitritt abgelehnt - Spieler bereits in Team 1")
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Du bist bereits in diesem Spiel!', 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
    end
 | 
						|
    for _, playerId in ipairs(game.team2) do
 | 
						|
        if playerId == src then
 | 
						|
            debugPrint("Beitritt abgelehnt - Spieler bereits in Team 2")
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Du bist bereits in diesem Spiel!', 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Max Spieler erreicht?
 | 
						|
    local currentPlayers = #game.team1 + #game.team2
 | 
						|
    local maxPlayers = Config.gameFields[game.fieldId].maxPlayers
 | 
						|
    
 | 
						|
    if currentPlayers >= maxPlayers then
 | 
						|
        debugPrint("Beitritt abgelehnt - Spiel ist voll")
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Spiel ist voll!', 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Prüfen ob Admin online ist (für private Spiele)
 | 
						|
    if game.gameType == 'private' then
 | 
						|
        local AdminPlayer = QBCore.Functions.GetPlayer(game.admin)
 | 
						|
        if not AdminPlayer then
 | 
						|
            debugPrint("Beitritt abgelehnt - Admin nicht online")
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Der Spiel-Admin ist nicht online!', 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Join Logic basierend auf Spiel Typ
 | 
						|
    if game.gameType == 'public' then
 | 
						|
        debugPrint("Öffentliches Spiel - Direkter Beitritt")
 | 
						|
        joinPlayerToGame(src, gameId)
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Du bist dem öffentlichen Spiel beigetreten!', 'success')
 | 
						|
    else
 | 
						|
        debugPrint("Privates Spiel - Sende Anfrage an Admin")
 | 
						|
        TriggerClientEvent('tdm:joinRequest', game.admin, gameId, playerName, src)
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Join-Anfrage gesendet an ' .. game.adminName, 'info')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:approveJoinRequest', function(gameId, playerId, approved)
 | 
						|
    local src = source
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    
 | 
						|
    if not game or game.admin ~= src then 
 | 
						|
        debugPrint("Join-Anfrage Bearbeitung fehlgeschlagen - Ungültiges Spiel oder nicht Admin")
 | 
						|
        return 
 | 
						|
    end
 | 
						|
    
 | 
						|
    if approved then
 | 
						|
        debugPrint("Join-Anfrage genehmigt für Spieler " .. playerId .. " in Spiel " .. gameId)
 | 
						|
        joinPlayerToGame(playerId, gameId)
 | 
						|
        TriggerClientEvent('tdm:joinRequestResult', playerId, true, game.name)
 | 
						|
    else
 | 
						|
        debugPrint("Join-Anfrage abgelehnt für Spieler " .. playerId .. " in Spiel " .. gameId)
 | 
						|
        TriggerClientEvent('tdm:joinRequestResult', playerId, false, game.name)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:leaveGame', function()
 | 
						|
    local src = source
 | 
						|
    debugPrint("Spieler " .. src .. " möchte alle Spiele verlassen")
 | 
						|
    
 | 
						|
    for gameId, game in pairs(activeGames) do
 | 
						|
        removePlayerFromGame(src, gameId)
 | 
						|
    end
 | 
						|
    
 | 
						|
    TriggerClientEvent('tdm:leaveGame', src)
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:playerWasHit', function(gameId, victimTeam, attackerId)
 | 
						|
    local victim = source
 | 
						|
    
 | 
						|
    if not activeGames[gameId] then 
 | 
						|
        debugPrint("Hit registriert, aber Spiel " .. gameId .. " existiert nicht!")
 | 
						|
        return 
 | 
						|
    end
 | 
						|
    
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    
 | 
						|
    debugPrint("Hit registriert - Opfer: " .. victim .. " (Team: " .. victimTeam .. "), Angreifer: " .. (attackerId or "Unbekannt"))
 | 
						|
    
 | 
						|
    -- Spieler Stats initialisieren falls nicht vorhanden
 | 
						|
    if not game.playerStats then
 | 
						|
        game.playerStats = {}
 | 
						|
    end
 | 
						|
    
 | 
						|
    if not game.playerStats[victim] then
 | 
						|
        game.playerStats[victim] = {hits = 0, deaths = 0}
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Wichtig: Nur wenn ein Angreifer identifiziert wurde, zähle den Kill
 | 
						|
    if attackerId then
 | 
						|
        if not game.playerStats[attackerId] then
 | 
						|
            game.playerStats[attackerId] = {hits = 0, deaths = 0}
 | 
						|
        end
 | 
						|
        
 | 
						|
        -- Stats updaten
 | 
						|
        game.playerStats[victim].deaths = (game.playerStats[victim].deaths or 0) + 1
 | 
						|
        game.playerStats[attackerId].hits = (game.playerStats[attackerId].hits or 0) + 1
 | 
						|
        
 | 
						|
        -- Benachrichtigung an den Angreifer senden
 | 
						|
        TriggerClientEvent('tdm:hitRegistered', attackerId)
 | 
						|
        debugPrint("Treffer von " .. attackerId .. " gegen " .. victim .. " registriert")
 | 
						|
        
 | 
						|
        -- Team Score erhöhen
 | 
						|
        if victimTeam == 'team1' then
 | 
						|
            game.score.team2 = game.score.team2 + 1
 | 
						|
            debugPrint("Punkt für Team 2 - Neuer Score: " .. game.score.team2)
 | 
						|
        else
 | 
						|
            game.score.team1 = game.score.team1 + 1
 | 
						|
            debugPrint("Punkt für Team 1 - Neuer Score: " .. game.score.team1)
 | 
						|
        end
 | 
						|
    else
 | 
						|
        debugPrint("Treffer gegen " .. victim .. " von unbekanntem Angreifer registriert - Kein Punkt vergeben")
 | 
						|
    end
 | 
						|
    
 | 
						|
    TriggerClientEvent('tdm:deathRegistered', victim)
 | 
						|
    
 | 
						|
    -- Score an alle Spieler senden
 | 
						|
    updateScoreForGame(gameId)
 | 
						|
    
 | 
						|
    -- Spiel beenden prüfen
 | 
						|
    if game.score.team1 >= game.maxHits or game.score.team2 >= game.maxHits then
 | 
						|
        local winnerTeam = game.score.team1 >= game.maxHits and 'team1' or 'team2'
 | 
						|
        debugPrint("Max Punkte erreicht - Beende Spiel. Gewinner: " .. winnerTeam)
 | 
						|
        endGame(gameId, winnerTeam)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:playerDied', function(gameId)
 | 
						|
    local src = source
 | 
						|
    debugPrint("Spieler " .. src .. " ist gestorben in Spiel " .. gameId)
 | 
						|
    removePlayerFromGame(src, gameId)
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:requestScoreUpdate', function(gameId)
 | 
						|
    local src = source
 | 
						|
    
 | 
						|
    if activeGames[gameId] then
 | 
						|
        debugPrint("Score-Update angefordert von " .. src .. " für Spiel " .. gameId)
 | 
						|
        updateScoreForGame(gameId)
 | 
						|
    else
 | 
						|
        debugPrint("Score-Update fehlgeschlagen - Spiel " .. gameId .. " nicht gefunden")
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('tdm:debugPlayerStats', function(gameId)
 | 
						|
    local src = source
 | 
						|
    if activeGames[gameId] and activeGames[gameId].playerStats and activeGames[gameId].playerStats[src] then
 | 
						|
        local stats = activeGames[gameId].playerStats[src]
 | 
						|
        debugPrint("Stats für Spieler " .. src .. ": Hits=" .. (stats.hits or 0) .. ", Deaths=" .. (stats.deaths or 0))
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Server Stats - Hits: ' .. (stats.hits or 0) .. ', Deaths: ' .. (stats.deaths or 0), 'info')
 | 
						|
    else
 | 
						|
        debugPrint("Keine Stats gefunden für Spieler " .. src .. " in Spiel " .. gameId)
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'Keine Stats gefunden!', 'error')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Funktionen
 | 
						|
function joinPlayerToGame(playerId, gameId)
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    if not game then 
 | 
						|
        debugPrint("Spielbeitritt fehlgeschlagen - Spiel nicht gefunden: " .. gameId)
 | 
						|
        return 
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Team mit weniger Spielern wählen
 | 
						|
    local team = #game.team1 <= #game.team2 and 'team1' or 'team2'
 | 
						|
    
 | 
						|
    table.insert(game[team], playerId)
 | 
						|
    
 | 
						|
    -- Spieler-Stats initialisieren
 | 
						|
    if not game.playerStats then
 | 
						|
        game.playerStats = {}
 | 
						|
    end
 | 
						|
    
 | 
						|
    game.playerStats[playerId] = {hits = 0, deaths = 0}
 | 
						|
    
 | 
						|
    -- Spiel starten wenn mindestens 2 Spieler
 | 
						|
    if #game.team1 + #game.team2 >= 2 and game.status == 'waiting' then
 | 
						|
        game.status = 'active'
 | 
						|
        game.startTime = os.time()
 | 
						|
        debugPrint("Spiel " .. gameId .. " gestartet - Mindestens 2 Spieler erreicht")
 | 
						|
        
 | 
						|
        -- Game Timer starten
 | 
						|
        startGameTimer(gameId)
 | 
						|
    end
 | 
						|
    
 | 
						|
    TriggerClientEvent('tdm:joinGame', playerId, gameId, team, game.fieldId)
 | 
						|
    updateScoreForGame(gameId)
 | 
						|
    updateGamesListForAll()
 | 
						|
    
 | 
						|
    debugPrint("Spieler " .. playerId .. " ist Spiel " .. gameId .. " beigetreten (Team: " .. team .. ")")
 | 
						|
end
 | 
						|
 | 
						|
function removePlayerFromGame(playerId, gameId)
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    if not game then return end
 | 
						|
    
 | 
						|
    -- Spieler aus Teams entfernen
 | 
						|
    local removed = false
 | 
						|
    
 | 
						|
    for i, id in ipairs(game.team1) do
 | 
						|
        if id == playerId then
 | 
						|
            table.remove(game.team1, i)
 | 
						|
            debugPrint("Spieler " .. playerId .. " aus Team 1 entfernt")
 | 
						|
            removed = true
 | 
						|
            break
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    if not removed then
 | 
						|
        for i, id in ipairs(game.team2) do
 | 
						|
            if id == playerId then
 | 
						|
                table.remove(game.team2, i)
 | 
						|
                debugPrint("Spieler " .. playerId .. " aus Team 2 entfernt")
 | 
						|
                removed = true
 | 
						|
                break
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    if not removed then
 | 
						|
        debugPrint("Spieler " .. playerId .. " nicht in Spiel " .. gameId .. " gefunden")
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Wenn Admin das Spiel verlässt, Spiel beenden
 | 
						|
    if game.admin == playerId then
 | 
						|
        debugPrint("Admin hat das Spiel verlassen - Beende Spiel " .. gameId)
 | 
						|
        endGame(gameId, nil, 'Admin hat das Spiel verlassen')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    checkGameEnd(gameId)
 | 
						|
    updateGamesListForAll()
 | 
						|
end
 | 
						|
 | 
						|
function endGame(gameId, winnerTeam, reason)
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    if not game then 
 | 
						|
        debugPrint("Spielende fehlgeschlagen - Spiel nicht gefunden: " .. gameId)
 | 
						|
        return 
 | 
						|
    end
 | 
						|
    
 | 
						|
    game.status = 'finished'
 | 
						|
    
 | 
						|
    local allPlayers = {}
 | 
						|
    for _, playerId in ipairs(game.team1) do
 | 
						|
        table.insert(allPlayers, playerId)
 | 
						|
    end
 | 
						|
    for _, playerId in ipairs(game.team2) do
 | 
						|
        table.insert(allPlayers, playerId)
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Game End Event an alle Spieler
 | 
						|
    for _, playerId in ipairs(allPlayers) do
 | 
						|
        debugPrint("Sende Spielende-Event an Spieler " .. playerId)
 | 
						|
        TriggerClientEvent('tdm:gameEnded', playerId, winnerTeam, game.score.team1, game.score.team2)
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Spiel nach 10 Sekunden löschen
 | 
						|
    SetTimeout(10000, function()
 | 
						|
        activeGames[gameId] = nil
 | 
						|
        updateGamesListForAll()
 | 
						|
        debugPrint("Spiel " .. gameId .. " aus der Liste entfernt")
 | 
						|
    end)
 | 
						|
    
 | 
						|
    if reason then
 | 
						|
        debugPrint("Spiel " .. gameId .. " beendet: " .. reason)
 | 
						|
    else
 | 
						|
        debugPrint("Spiel " .. gameId .. " beendet. Gewinner: " .. (winnerTeam or "Unentschieden"))
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function startGameTimer(gameId)
 | 
						|
    CreateThread(function()
 | 
						|
        local game = activeGames[gameId]
 | 
						|
        if not game then return end
 | 
						|
        
 | 
						|
        local maxTime = game.maxTime
 | 
						|
        local startTime = os.time()
 | 
						|
        
 | 
						|
        debugPrint("Timer für Spiel " .. gameId .. " gestartet. Maximale Zeit: " .. maxTime .. " Sekunden")
 | 
						|
        
 | 
						|
        while game and game.status == 'active' and (os.time() - startTime) < maxTime do
 | 
						|
            Wait(1000)
 | 
						|
            game = activeGames[gameId] -- Refresh game data
 | 
						|
            
 | 
						|
            -- Alle 30 Sekunden Debug-Info
 | 
						|
            if (os.time() - startTime) % 30 == 0 then
 | 
						|
                debugPrint("Spiel " .. gameId .. " läuft seit " .. (os.time() - startTime) .. " Sekunden")
 | 
						|
            end
 | 
						|
        end
 | 
						|
        
 | 
						|
        -- Zeit abgelaufen
 | 
						|
        if game and game.status == 'active' then
 | 
						|
            local winnerTeam = game.score.team1 > game.score.team2 and 'team1' or 
 | 
						|
                              game.score.team2 > game.score.team1 and 'team2' or nil
 | 
						|
            debugPrint("Spielzeit abgelaufen - Beende Spiel " .. gameId)
 | 
						|
            endGame(gameId, winnerTeam, 'Zeit abgelaufen')
 | 
						|
        end
 | 
						|
    end)
 | 
						|
end
 | 
						|
 | 
						|
function checkGameEnd(gameId)
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    if not game then return end
 | 
						|
    
 | 
						|
    local totalPlayers = #game.team1 + #game.team2
 | 
						|
    
 | 
						|
    if totalPlayers < 2 and game.status == 'active' then
 | 
						|
        debugPrint("Zu wenig Spieler - Beende Spiel " .. gameId)
 | 
						|
        endGame(gameId, nil, 'Zu wenig Spieler')
 | 
						|
    elseif totalPlayers == 0 then
 | 
						|
        activeGames[gameId] = nil
 | 
						|
        updateGamesListForAll()
 | 
						|
        debugPrint("Spiel " .. gameId .. " gelöscht (keine Spieler)")
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function updateScoreForGame(gameId)
 | 
						|
    local game = activeGames[gameId]
 | 
						|
    if not game then 
 | 
						|
        debugPrint("Score-Update fehlgeschlagen - Spiel nicht gefunden: " .. gameId)
 | 
						|
        return 
 | 
						|
    end
 | 
						|
    
 | 
						|
    debugPrint("Score Update für Spiel " .. gameId .. ": Team1=" .. game.score.team1 .. ", Team2=" .. game.score.team2)
 | 
						|
    
 | 
						|
    for _, playerId in ipairs(game.team1) do
 | 
						|
        local playerStats = game.playerStats[playerId] or {hits = 0, deaths = 0}
 | 
						|
        TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2, {
 | 
						|
            hits = playerStats.hits or 0,
 | 
						|
            deaths = playerStats.deaths or 0
 | 
						|
        })
 | 
						|
    end
 | 
						|
    
 | 
						|
    for _, playerId in ipairs(game.team2) do
 | 
						|
        local playerStats = game.playerStats[playerId] or {hits = 0, deaths = 0}
 | 
						|
        TriggerClientEvent('tdm:updateScore', playerId, game.score.team1, game.score.team2, {
 | 
						|
            hits = playerStats.hits or 0,
 | 
						|
            deaths = playerStats.deaths or 0
 | 
						|
        })
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function updateGamesListForAll()
 | 
						|
    local players = QBCore.Functions.GetPlayers()
 | 
						|
    for _, playerId in pairs(players) do
 | 
						|
        TriggerClientEvent('tdm:updateGamesList', playerId, activeGames)
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-- Player Disconnect Handler
 | 
						|
AddEventHandler('playerDropped', function()
 | 
						|
    local src = source
 | 
						|
    
 | 
						|
    for gameId, game in pairs(activeGames) do
 | 
						|
        removePlayerFromGame(src, gameId)
 | 
						|
    end
 | 
						|
    
 | 
						|
    debugPrint("Spieler " .. src .. " hat den Server verlassen - aus allen Spielen entfernt")
 | 
						|
end)
 | 
						|
 | 
						|
-- Server Start - Games Liste leeren
 | 
						|
AddEventHandler('onResourceStart', function(resourceName)
 | 
						|
    if GetCurrentResourceName() == resourceName then
 | 
						|
        activeGames = {}
 | 
						|
        gameIdCounter = 1
 | 
						|
        debugPrint("TeamDeathmatch System gestartet!")
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
AddEventHandler('onResourceStop', function(resourceName)
 | 
						|
    if GetCurrentResourceName() == resourceName then
 | 
						|
        -- Alle Spieler aus TDM entfernen
 | 
						|
        for gameId, game in pairs(activeGames) do
 | 
						|
            local allPlayers = {}
 | 
						|
            for _, playerId in ipairs(game.team1) do
 | 
						|
                table.insert(allPlayers, playerId)
 | 
						|
            end
 | 
						|
            for _, playerId in ipairs(game.team2) do
 | 
						|
                table.insert(allPlayers, playerId)
 | 
						|
            end
 | 
						|
            
 | 
						|
            for _, playerId in ipairs(allPlayers) do
 | 
						|
                TriggerClientEvent('tdm:leaveGame', playerId)
 | 
						|
            end
 | 
						|
        end
 | 
						|
        
 | 
						|
        activeGames = {}
 | 
						|
        debugPrint("TeamDeathmatch System gestoppt!")
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Admin-Befehle
 | 
						|
RegisterCommand('tdmreset', function(source, args)
 | 
						|
    local src = source
 | 
						|
    if src > 0 then -- Spieler
 | 
						|
        local Player = QBCore.Functions.GetPlayer(src)
 | 
						|
        if not Player or not Player.PlayerData.job or Player.PlayerData.job.name ~= 'admin' then
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung!', 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Alle Spieler aus TDM entfernen
 | 
						|
    for gameId, game in pairs(activeGames) do
 | 
						|
        local allPlayers = {}
 | 
						|
        for _, playerId in ipairs(game.team1) do
 | 
						|
            table.insert(allPlayers, playerId)
 | 
						|
        end
 | 
						|
        for _, playerId in ipairs(game.team2) do
 | 
						|
            table.insert(allPlayers, playerId)
 | 
						|
        end
 | 
						|
        
 | 
						|
        for _, playerId in ipairs(allPlayers) do
 | 
						|
            TriggerClientEvent('tdm:leaveGame', playerId)
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    activeGames = {}
 | 
						|
    gameIdCounter = 1
 | 
						|
    
 | 
						|
    debugPrint("TeamDeathmatch System zurückgesetzt!")
 | 
						|
    
 | 
						|
    if src > 0 then
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'TDM System zurückgesetzt!', 'success')
 | 
						|
    end
 | 
						|
end, true)
 | 
						|
 | 
						|
-- Debug-Befehl für Server-Status
 | 
						|
RegisterCommand('tdmstatus', function(source, args)
 | 
						|
    local src = source
 | 
						|
    if src > 0 then -- Spieler
 | 
						|
        local Player = QBCore.Functions.GetPlayer(src)
 | 
						|
        if not Player or not Player.PlayerData.job or Player.PlayerData.job.name ~= 'admin' then
 | 
						|
            TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung!', 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    debugPrint("=== TDM STATUS ===")
 | 
						|
    debugPrint("Aktive Spiele: " .. table.count(activeGames))
 | 
						|
    
 | 
						|
    for gameId, game in pairs(activeGames) do
 | 
						|
        debugPrint("Spiel: " .. gameId .. " - " .. game.name)
 | 
						|
        debugPrint("  Status: " .. game.status)
 | 
						|
        debugPrint("  Feld: " .. game.fieldId)
 | 
						|
        debugPrint("  Team 1: " .. #game.team1 .. " Spieler, Score: " .. game.score.team1)
 | 
						|
        debugPrint("  Team 2: " .. #game.team2 .. " Spieler, Score: " .. game.score.team2)
 | 
						|
    end
 | 
						|
    
 | 
						|
    if src > 0 then
 | 
						|
        TriggerClientEvent('QBCore:Notify', src, 'TDM Status in Server-Konsole', 'info')
 | 
						|
    end
 | 
						|
end, true)
 | 
						|
 | 
						|
-- Hilfsfunktion für table.count
 | 
						|
table.count = function(tbl)
 | 
						|
    local count = 0
 | 
						|
    for _, _ in pairs(tbl) do
 | 
						|
        count = count + 1
 | 
						|
    end
 | 
						|
    return count
 | 
						|
end
 |