Sunucu tanitimi
csb-session-stats / addons / amxmodx / scripting / csb_session_stats.sma
190 lines 4.8 KiB Pawn Raw Permalink History
/*
 * CSB Session Stats
 * Copyright (C) 2026 counter-strike-boost.com
 *
 * Keeps a per-slot, in-memory summary of the current session: kills, deaths,
 * headshots, damage dealt, rounds won, time played and best killstreak. Shows
 * it on say /session, on disconnect (to the AMXX log) and a short line at round
 * end. Nothing is persisted - it resets when the player leaves.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version. It is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
 */

#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>

new const PLUGIN[] = "CSB Session Stats"
new const VERSION[] = "1.0.0"
new const AUTHOR[]  = "counter-strike-boost.com"

new g_iKills[33]
new g_iDeaths[33]
new g_iHs[33]
new g_iDamage[33]
new g_iRoundsWon[33]
new g_iStreak[33]
new g_iBestStreak[33]
new g_iJoinTime[33]

new g_pEnabled, g_pRoundLine

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)

    g_pEnabled   = register_cvar("csb_session_enabled", "1")
    g_pRoundLine = register_cvar("csb_session_roundline", "1")

    register_event("DeathMsg", "eventDeath", "a", "1>0")
    register_event("SendAudio", "eventWin", "a")
    register_logevent("eventRoundEnd", 2, "1=Round_End")

    RegisterHam(Ham_TakeDamage, "player", "hamTakeDamage")

    register_clcmd("say /session", "cmdSession")
    register_clcmd("say_team /session", "cmdSession")
}

public client_putinserver(id)
{
    resetPlayer(id)
    g_iJoinTime[id] = get_systime()
}

public client_disconnected(id)
{
    if (g_iKills[id] || g_iDeaths[id])
    {
        new name[32]
        get_user_name(id, name, charsmax(name))
        log_amx("[CSB Session] %s left - %d kills, %d deaths, %d hs, %d dmg, best streak %d",
            name, g_iKills[id], g_iDeaths[id], g_iHs[id], g_iDamage[id], g_iBestStreak[id])
    }

    resetPlayer(id)
}

resetPlayer(id)
{
    g_iKills[id] = 0
    g_iDeaths[id] = 0
    g_iHs[id] = 0
    g_iDamage[id] = 0
    g_iRoundsWon[id] = 0
    g_iStreak[id] = 0
    g_iBestStreak[id] = 0
    g_iJoinTime[id] = get_systime()
}

public hamTakeDamage(victim, inflictor, attacker, Float:damage, damagebits)
{
    if (attacker < 1 || attacker > 32 || attacker == victim)
        return HAM_IGNORED

    g_iDamage[attacker] += floatround(damage)
    return HAM_IGNORED
}

public eventDeath()
{
    new killer = read_data(1)
    new victim = read_data(2)
    new hs = read_data(3)

    if (victim >= 1 && victim <= 32)
    {
        g_iDeaths[victim]++
        g_iStreak[victim] = 0
    }

    if (killer >= 1 && killer <= 32 && killer != victim)
    {
        g_iKills[killer]++
        g_iStreak[killer]++

        if (g_iStreak[killer] > g_iBestStreak[killer])
            g_iBestStreak[killer] = g_iStreak[killer]

        if (hs)
            g_iHs[killer]++
    }
}

public eventWin()
{
    new audio[48]
    read_data(2, audio, charsmax(audio))

    new winTeam = 0

    if (containi(audio, "terwin") != -1)
        winTeam = 1
    else if (containi(audio, "ctwin") != -1)
        winTeam = 2

    if (!winTeam)
        return

    new players[32], num, pid
    get_players(players, num, "ae")

    for (new i = 0; i < num; i++)
    {
        pid = players[i]

        if (get_user_team(pid) == winTeam)
            g_iRoundsWon[pid]++
    }
}

public eventRoundEnd()
{
    if (!get_pcvar_num(g_pRoundLine))
        return

    new players[32], num, pid
    get_players(players, num, "c")

    for (new i = 0; i < num; i++)
    {
        pid = players[i]

        if (g_iKills[pid] || g_iDeaths[pid])
            printSummary(pid, pid, true)
    }
}

public cmdSession(id)
{
    if (!get_pcvar_num(g_pEnabled))
        return PLUGIN_HANDLED

    printSummary(id, id, false)
    return PLUGIN_HANDLED
}

printSummary(id, target, bool:shortLine)
{
    new mins = (get_systime() - g_iJoinTime[target]) / 60

    if (shortLine)
    {
        client_print(id, print_chat, "[CSB] Session: %d-%d, %d hs, best streak %d.",
            g_iKills[target], g_iDeaths[target], g_iHs[target], g_iBestStreak[target])
        return
    }

    new Float:kdr = g_iDeaths[target] ? float(g_iKills[target]) / float(g_iDeaths[target]) : float(g_iKills[target])

    client_print(id, print_chat, "[CSB] --- Your session so far ---")
    client_print(id, print_chat, "[CSB] Kills: %d | Deaths: %d | K/D: %.2f | Headshots: %d",
        g_iKills[target], g_iDeaths[target], kdr, g_iHs[target])
    client_print(id, print_chat, "[CSB] Damage: %d | Rounds won: %d | Best streak: %d | Time: %d min",
        g_iDamage[target], g_iRoundsWon[target], g_iBestStreak[target], mins)
}