/*
* CSB Match Command Block
* Copyright (C) 2026 counter-strike-boost.com
*
* While a match is flagged live this plugin blocks disruptive client commands:
* it rate-limits the radio, stops dead players from using team chat (anti-ghost),
* blocks a small list of third-party / +hook style commands, and refuses buy
* commands once the buy time is over. Toggle the live state with amx_matchlive.
*
* 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 Match Command Block"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_pEnabled, g_pLive, g_pRadioMax, g_pRadioWin
new g_iRadio[33]
new Float:g_fRadioStart[33]
new Float:g_fRoundStart
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_block_enabled", "1")
g_pLive = register_cvar("csb_block_live", "0")
g_pRadioMax = register_cvar("csb_block_radiomax", "4")
g_pRadioWin = register_cvar("csb_block_radiowin", "10.0")
register_concmd("amx_matchlive", "cmdSetLive", ADMIN_BAN, "<0|1> - toggle live command blocking")
new const radios[][] = { "radio1", "radio2", "radio3" }
for (new i = 0; i < sizeof(radios); i++)
register_clcmd(radios[i], "cmdRadio")
new const blocked[][] = { "+hook", "+lookatweapon", "spec_menu", "unbindall" }
for (new i = 0; i < sizeof(blocked); i++)
register_clcmd(blocked[i], "cmdBlocked")
register_clcmd("buy", "cmdBuy")
register_clcmd("buyammo1", "cmdBuy")
register_clcmd("buyammo2", "cmdBuy")
register_clcmd("autobuy", "cmdBuy")
register_clcmd("rebuy", "cmdBuy")
register_clcmd("say_team", "cmdSayTeam")
register_logevent("evRoundStart", 2, "1=Round_Start")
}
bool:blockActive()
{
return get_pcvar_num(g_pEnabled) != 0 && get_pcvar_num(g_pLive) != 0
}
public cmdSetLive(id, level, cid)
{
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED
new arg[4]
read_argv(1, arg, charsmax(arg))
set_pcvar_num(g_pLive, str_to_num(arg) ? 1 : 0)
client_print(0, print_chat, "[CSB] Match command blocking is now %s.", get_pcvar_num(g_pLive) ? "ON (live)" : "OFF")
return PLUGIN_HANDLED
}
public cmdRadio(id)
{
if (!blockActive())
return PLUGIN_CONTINUE
new Float:now = get_gametime()
new Float:win = get_pcvar_float(g_pRadioWin)
if (now - g_fRadioStart[id] > win)
{
g_fRadioStart[id] = now
g_iRadio[id] = 0
}
g_iRadio[id]++
if (g_iRadio[id] > get_pcvar_num(g_pRadioMax))
{
client_print(id, print_chat, "[CSB] Radio is rate-limited during the match.")
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public cmdBlocked(id)
{
if (!blockActive())
return PLUGIN_CONTINUE
client_print(id, print_chat, "[CSB] That command is disabled during a live match.")
return PLUGIN_HANDLED
}
public cmdBuy(id)
{
if (!blockActive())
return PLUGIN_CONTINUE
new Float:buytime = get_cvar_float("mp_buytime") * 60.0
if (get_gametime() - g_fRoundStart > buytime)
{
client_print(id, print_chat, "[CSB] Buy time is over.")
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public cmdSayTeam(id)
{
if (blockActive() && is_user_connected(id) && !is_user_alive(id))
{
client_print(id, print_chat, "[CSB] Dead players cannot use team chat during a live match.")
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public evRoundStart()
{
g_fRoundStart = get_gametime()
for (new i = 1; i <= 32; i++)
{
g_iRadio[i] = 0
g_fRadioStart[i] = 0.0
}
}