Maps arbitrary console/chat commands to access flags in an ini and blocks anyone without the flag - no recompiling.
csb_command_access.sma v1.0.0
1
/*
2
* CSB Command Access
3
* Copyright (C) 2026 counter-strike-boost.com
4
*
5
* Maps arbitrary console/chat commands to access flags from
6
* configs/csb_cmdaccess.ini. Each mapped command is registered and, when a
7
* player without the flag runs it, the plugin blocks it (PLUGIN_HANDLED) and
8
* prints a denial. Lets owners restrict third-party or say-based commands
9
* without recompiling them.
10
*
11
* This program is free software: you can redistribute it and/or modify it under
12
* the terms of the GNU General Public License as published by the Free Software
13
* Foundation, either version 3 of the License, or (at your option) any later
14
* version. It is distributed in the hope that it will be useful, but WITHOUT
15
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
* FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
17
*/
18
19
#include <amxmodx>
20
#include <amxmisc>
21
22
#define MAX_RULES 48
23
24
new const PLUGIN[] = "CSB Command Access"
25
new const VERSION[] = "1.0.0"
26
new const AUTHOR[] = "counter-strike-boost.com"
27
28
new g_szCmd[MAX_RULES][40]
29
new g_iFlags[MAX_RULES]
30
new g_iRuleCount = 0
31
32
new g_pEnabled
33
34
public plugin_init()
35
{
36
register_plugin(PLUGIN, VERSION, AUTHOR)
37
38
g_pEnabled = register_cvar("csb_cmdaccess_enabled", "1")
39
40
loadRules()
41
}
42
43
loadRules()
44
{
45
new dir[128]
46
get_localinfo("amxx_configsdir", dir, charsmax(dir))
47
48
new path[160]
49
formatex(path, charsmax(path), "%s/csb_cmdaccess.ini", dir)
50
51
if (!file_exists(path))
52
{
53
write_file(path, "; CSB Command Access - one rule per line: <command> <flags>")
54
write_file(path, "; the command is blocked for anyone missing the flags.")
55
write_file(path, "; example: restrict the say-based command /rtv to reserved slots")
56
write_file(path, "; say /rtv a")
57
}
58
59
new f = fopen(path, "rt")
60
61
if (!f)
62
{
63
log_amx("[CSB CmdAccess] could not open %s", path)
64
return
65
}
66
67
new line[96], cmd[40], flagStr[24]
68
69
while (!feof(f) && g_iRuleCount < MAX_RULES)
70
{
71
fgets(f, line, charsmax(line))
72
trim(line)
73
74
if (!line[0] || line[0] == ';' || line[0] == '#')
75
continue
76
77
strtok(line, cmd, charsmax(cmd), flagStr, charsmax(flagStr), ' ')
78
trim(cmd)
79
trim(flagStr)
80
81
if (!cmd[0] || !flagStr[0])
82
continue
83
84
copy(g_szCmd[g_iRuleCount], charsmax(g_szCmd[]), cmd)
85
g_iFlags[g_iRuleCount] = read_flags(flagStr)
86
87
register_clcmd(cmd, "blockCheck")
88
g_iRuleCount++
89
}
90
91
fclose(f)
92
93
log_amx("[CSB CmdAccess] loaded %d rule(s).", g_iRuleCount)
94
}
95
96
public blockCheck(id)
97
{
98
if (!get_pcvar_num(g_pEnabled))
99
return PLUGIN_CONTINUE
100
101
new cmd[40]
102
read_argv(0, cmd, charsmax(cmd))
103
104
/* say-based commands arrive as "say" + argv1; rebuild the full command */
105
if (equali(cmd, "say") || equali(cmd, "say_team"))
106
{
107
new rest[64]
108
read_args(rest, charsmax(rest))
109
remove_quotes(rest)
110
trim(rest)
111
formatex(cmd, charsmax(cmd), "%s %s", equali(cmd, "say") ? "say" : "say_team", rest)
112
}
113
114
for (new i = 0; i < g_iRuleCount; i++)
115
{
116
if (!equali(cmd, g_szCmd[i]))
117
continue
118
119
if (get_user_flags(id) & g_iFlags[i])
120
return PLUGIN_CONTINUE
121
122
client_print(id, print_chat, "[CSB] You do not have access to that command.")
123
return PLUGIN_HANDLED
124
}
125
126
return PLUGIN_CONTINUE
127
}
128









