/*
* CSB Command Access
* Copyright (C) 2026 counter-strike-boost.com
*
* Maps arbitrary console/chat commands to access flags from
* configs/csb_cmdaccess.ini. Each mapped command is registered and, when a
* player without the flag runs it, the plugin blocks it (PLUGIN_HANDLED) and
* prints a denial. Lets owners restrict third-party or say-based commands
* without recompiling them.
*
* 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
#define MAX_RULES 48
new const PLUGIN[] = "CSB Command Access"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_szCmd[MAX_RULES][40]
new g_iFlags[MAX_RULES]
new g_iRuleCount = 0
new g_pEnabled
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_cmdaccess_enabled", "1")
loadRules()
}
loadRules()
{
new dir[128]
get_localinfo("amxx_configsdir", dir, charsmax(dir))
new path[160]
formatex(path, charsmax(path), "%s/csb_cmdaccess.ini", dir)
if (!file_exists(path))
{
write_file(path, "; CSB Command Access - one rule per line: ")
write_file(path, "; the command is blocked for anyone missing the flags.")
write_file(path, "; example: restrict the say-based command /rtv to reserved slots")
write_file(path, "; say /rtv a")
}
new f = fopen(path, "rt")
if (!f)
{
log_amx("[CSB CmdAccess] could not open %s", path)
return
}
new line[96], cmd[40], flagStr[24]
while (!feof(f) && g_iRuleCount < MAX_RULES)
{
fgets(f, line, charsmax(line))
trim(line)
if (!line[0] || line[0] == ';' || line[0] == '#')
continue
strtok(line, cmd, charsmax(cmd), flagStr, charsmax(flagStr), ' ')
trim(cmd)
trim(flagStr)
if (!cmd[0] || !flagStr[0])
continue
copy(g_szCmd[g_iRuleCount], charsmax(g_szCmd[]), cmd)
g_iFlags[g_iRuleCount] = read_flags(flagStr)
register_clcmd(cmd, "blockCheck")
g_iRuleCount++
}
fclose(f)
log_amx("[CSB CmdAccess] loaded %d rule(s).", g_iRuleCount)
}
public blockCheck(id)
{
if (!get_pcvar_num(g_pEnabled))
return PLUGIN_CONTINUE
new cmd[40]
read_argv(0, cmd, charsmax(cmd))
/* say-based commands arrive as "say" + argv1; rebuild the full command */
if (equali(cmd, "say") || equali(cmd, "say_team"))
{
new rest[64]
read_args(rest, charsmax(rest))
remove_quotes(rest)
trim(rest)
formatex(cmd, charsmax(cmd), "%s %s", equali(cmd, "say") ? "say" : "say_team", rest)
}
for (new i = 0; i < g_iRuleCount; i++)
{
if (!equali(cmd, g_szCmd[i]))
continue
if (get_user_flags(id) & g_iFlags[i])
return PLUGIN_CONTINUE
client_print(id, print_chat, "[CSB] You do not have access to that command.")
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}