Promote server
csb-chat-logger / addons / amxmodx / scripting / csb_chat_logger.sma
134 lines 3.5 KiB Pawn Raw Permalink History
/*
 * CSB Chat Logger
 * Copyright (C) 2026 counter-strike-boost.com
 *
 * Captures every say / say_team message with the player's name, SteamID, team
 * and alive state and appends it to a per-day log file. Admins can run
 * amx_lastchat to dump the last lines held in memory to their console.
 *
 * 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>

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

#define MAX_BUFFER 20
#define LINE_LEN   160

new g_pEnabled, g_pToFile
new g_szBuffer[MAX_BUFFER][LINE_LEN]
new g_iBufCount = 0
new g_iBufHead  = 0

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

    g_pEnabled = register_cvar("csb_chatlog_enabled", "1")
    g_pToFile  = register_cvar("csb_chatlog_tofile", "1")

    register_clcmd("say", "cmdSay")
    register_clcmd("say_team", "cmdSayTeam")

    register_concmd("amx_lastchat", "cmdLastChat", ADMIN_KICK, "- dump the last chat lines to your console")
}

public cmdSay(id)
{
    logChat(id, "ALL")
    return PLUGIN_CONTINUE
}

public cmdSayTeam(id)
{
    logChat(id, "TEAM")
    return PLUGIN_CONTINUE
}

logChat(id, const channel[])
{
    if (!get_pcvar_num(g_pEnabled))
        return

    new said[128]
    read_args(said, charsmax(said))
    remove_quotes(said)
    trim(said)

    if (!said[0])
        return

    /* ignore command-style messages handled by other plugins */
    if (said[0] == '/' || said[0] == '!')
        return

    new name[32], authid[35]
    get_user_name(id, name, charsmax(name))
    get_user_authid(id, authid, charsmax(authid))

    new teamName[16]
    get_user_team(id, teamName, charsmax(teamName))

    if (!teamName[0])
        copy(teamName, charsmax(teamName), "SPEC")

    new stamp[24]
    get_time("%H:%M:%S", stamp, charsmax(stamp))

    new line[LINE_LEN]
    formatex(line, charsmax(line), "[%s] (%s) %s %s <%s>: %s",
        stamp, channel, teamName, name, authid, said)

    /* ring buffer for amx_lastchat */
    copy(g_szBuffer[g_iBufHead], charsmax(g_szBuffer[]), line)
    g_iBufHead = (g_iBufHead + 1) % MAX_BUFFER

    if (g_iBufCount < MAX_BUFFER)
        g_iBufCount++

    if (get_pcvar_num(g_pToFile))
    {
        new day[16]
        get_time("%Y-%m-%d", day, charsmax(day))

        new file[64]
        formatex(file, charsmax(file), "csb_chat_%s.log", day)

        write_file(file, line)
    }
}

public cmdLastChat(id, level, cid)
{
    if (!cmd_access(id, level, cid, 1))
        return PLUGIN_HANDLED

    if (!g_iBufCount)
    {
        console_print(id, "[CSB] No chat has been logged yet this map.")
        return PLUGIN_HANDLED
    }

    console_print(id, "----- CSB Chat Logger: last %d line(s) -----", g_iBufCount)

    /* walk the ring buffer oldest -> newest */
    new start = (g_iBufHead - g_iBufCount + MAX_BUFFER) % MAX_BUFFER

    for (new i = 0; i < g_iBufCount; i++)
    {
        new idx = (start + i) % MAX_BUFFER
        console_print(id, "%s", g_szBuffer[idx])
    }

    console_print(id, "--------------------------------------------")
    return PLUGIN_HANDLED
}