Prints a coloured [ADMIN]/[OWNER] prefix before an admin's chat, driven by access flags from configs/csb_tags.ini.
csb_admin_tag.sma v1.0.0
1
/*
2
* CSB Admin Tag
3
* Copyright (C) 2026 counter-strike-boost.com
4
*
5
* Prints a configurable coloured prefix (e.g. [ADMIN], [OWNER]) before an
6
* admin's chat line based on their access flags. Tags are read from
7
* configs/csb_tags.ini. The say/say_team message is intercepted and re-sent via
8
* the SayText user message so the *DEAD* marker and team colouring stay correct.
9
*
10
* Inspired by Admin Prefix by Alka. Independent GPL re-implementation; no
11
* original code is reused.
12
*
13
* This program is free software: you can redistribute it and/or modify it under
14
* the terms of the GNU General Public License as published by the Free Software
15
* Foundation, either version 3 of the License, or (at your option) any later
16
* version. It is distributed in the hope that it will be useful, but WITHOUT
17
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
* FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
19
*/
20
21
#include <amxmodx>
22
#include <amxmisc>
23
24
#define MAX_TAGS 24
25
26
new const PLUGIN[] = "CSB Admin Tag"
27
new const VERSION[] = "1.0.0"
28
new const AUTHOR[] = "counter-strike-boost.com"
29
30
new g_pEnabled
31
new g_msgSayText
32
33
new g_iTagFlags[MAX_TAGS]
34
new g_szTagText[MAX_TAGS][24]
35
new g_iTagCount = 0
36
37
public plugin_init()
38
{
39
register_plugin(PLUGIN, VERSION, AUTHOR)
40
41
g_pEnabled = register_cvar("csb_tag_enabled", "1")
42
43
register_clcmd("say", "hookSay")
44
register_clcmd("say_team", "hookSayTeam")
45
46
g_msgSayText = get_user_msgid("SayText")
47
48
loadTags()
49
}
50
51
loadTags()
52
{
53
new dir[128]
54
get_localinfo("amxx_configsdir", dir, charsmax(dir))
55
56
new path[160]
57
formatex(path, charsmax(path), "%s/csb_tags.ini", dir)
58
59
if (!file_exists(path))
60
{
61
/* seed a sane default so admins have something to edit */
62
write_file(path, "; CSB Admin Tag - one rule per line: <flags> <tag text>")
63
write_file(path, "; flags use AMXX access letters; first matching line wins.")
64
write_file(path, "z [OWNER]")
65
write_file(path, "b [ADMIN]")
66
write_file(path, "c [MOD]")
67
}
68
69
new f = fopen(path, "rt")
70
71
if (!f)
72
{
73
log_amx("[CSB Tag] could not open %s", path)
74
return
75
}
76
77
new line[128], flagStr[32], tag[24]
78
79
while (!feof(f) && g_iTagCount < MAX_TAGS)
80
{
81
fgets(f, line, charsmax(line))
82
trim(line)
83
84
if (!line[0] || line[0] == ';' || line[0] == '#')
85
continue
86
87
strtok(line, flagStr, charsmax(flagStr), tag, charsmax(tag), ' ')
88
trim(tag)
89
90
if (!flagStr[0] || !tag[0])
91
continue
92
93
g_iTagFlags[g_iTagCount] = read_flags(flagStr)
94
copy(g_szTagText[g_iTagCount], charsmax(g_szTagText[]), tag)
95
g_iTagCount++
96
}
97
98
fclose(f)
99
100
log_amx("[CSB Tag] loaded %d tag rule(s).", g_iTagCount)
101
}
102
103
tagFor(id, out[], len)
104
{
105
out[0] = 0
106
107
new flags = get_user_flags(id)
108
109
for (new i = 0; i < g_iTagCount; i++)
110
{
111
if (flags & g_iTagFlags[i])
112
{
113
copy(out, len, g_szTagText[i])
114
return
115
}
116
}
117
}
118
119
public hookSay(id)
120
{
121
return handleChat(id, false)
122
}
123
124
public hookSayTeam(id)
125
{
126
return handleChat(id, true)
127
}
128
129
handleChat(id, bool:teamOnly)
130
{
131
if (!get_pcvar_num(g_pEnabled) || !is_user_connected(id))
132
return PLUGIN_CONTINUE
133
134
new tag[24]
135
tagFor(id, tag, charsmax(tag))
136
137
if (!tag[0])
138
return PLUGIN_CONTINUE
139
140
new msg[160]
141
read_args(msg, charsmax(msg))
142
remove_quotes(msg)
143
trim(msg)
144
145
if (!msg[0])
146
return PLUGIN_HANDLED
147
148
/* leave command-style lines to the plugins that own them */
149
if (msg[0] == '/' || msg[0] == '!')
150
return PLUGIN_CONTINUE
151
152
new name[32]
153
get_user_name(id, name, charsmax(name))
154
155
new bool:dead = !is_user_alive(id)
156
new senderTeam = get_user_team(id)
157
158
new out[192]
159
formatex(out, charsmax(out), "%s^x04 %s ^x03%s^x01 : %s",
160
dead ? "*DEAD* " : "", tag, name, msg)
161
162
new players[32], num, pid
163
get_players(players, num, "ch")
164
165
for (new i = 0; i < num; i++)
166
{
167
pid = players[i]
168
169
if (teamOnly)
170
{
171
/* team chat: same team, or dead players see dead team chat */
172
if (get_user_team(pid) != senderTeam)
173
continue
174
}
175
176
message_begin(MSG_ONE, g_msgSayText, _, pid)
177
write_byte(id)
178
write_string(out)
179
message_end()
180
}
181
182
return PLUGIN_HANDLED
183
}
184









