/*
* 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 for details.
*/
#include
#include
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
}