/*
* CSB Immunity Manager
* Copyright (C) 2026 counter-strike-boost.com
*
* A small library plugin that centralises admin immunity. It exposes a native,
* csb_has_immunity(admin, target), that other kick/ban/slay plugins can call
* instead of duplicating flag checks. A target is immune if their SteamID is in
* configs/csb_immunity.ini, or if they hold ADMIN_IMMUNITY and outrank the
* acting admin by flag weight.
*
* 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_PROTECTED 64
new const PLUGIN[] = "CSB Immunity Manager"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_szProtected[MAX_PROTECTED][35]
new g_iProtectedCount = 0
public plugin_natives()
{
register_native("csb_has_immunity", "native_has_immunity", 0)
}
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_concmd("amx_immunitylist", "cmdList", ADMIN_CFG, "- list protected SteamIDs loaded from csb_immunity.ini")
loadProtected()
}
loadProtected()
{
new dir[128]
get_localinfo("amxx_configsdir", dir, charsmax(dir))
new path[160]
formatex(path, charsmax(path), "%s/csb_immunity.ini", dir)
if (!file_exists(path))
{
write_file(path, "; CSB Immunity Manager - one SteamID per line, always protected")
write_file(path, "; STEAM_0:1:12345678")
}
new f = fopen(path, "rt")
if (!f)
{
log_amx("[CSB Immunity] could not open %s", path)
return
}
new line[64]
while (!feof(f) && g_iProtectedCount < MAX_PROTECTED)
{
fgets(f, line, charsmax(line))
trim(line)
if (!line[0] || line[0] == ';' || line[0] == '#')
continue
copy(g_szProtected[g_iProtectedCount], charsmax(g_szProtected[]), line)
g_iProtectedCount++
}
fclose(f)
log_amx("[CSB Immunity] loaded %d protected SteamID(s).", g_iProtectedCount)
}
bool:isProtectedId(id)
{
if (!g_iProtectedCount)
return false
new authid[35]
get_user_authid(id, authid, charsmax(authid))
for (new i = 0; i < g_iProtectedCount; i++)
{
if (equal(authid, g_szProtected[i]))
return true
}
return false
}
flagWeight(id)
{
/* rank by how many access letters the admin holds */
new flags = get_user_flags(id)
new weight = 0
for (new i = 0; i < 26; i++)
{
if (flags & (1 << i))
weight++
}
return weight
}
bool:computeImmunity(admin, target)
{
if (target < 1 || target > 32 || !is_user_connected(target))
return false
/* self is never blocked */
if (admin == target)
return false
if (isProtectedId(target))
return true
/* target must actually carry the immunity flag to outrank anyone */
if (!(get_user_flags(target) & ADMIN_IMMUNITY))
return false
/* console (admin 0) can act on everyone */
if (admin < 1)
return false
return (flagWeight(target) >= flagWeight(admin)) ? true : false
}
public native_has_immunity(plugin, params)
{
new admin = get_param(1)
new target = get_param(2)
return computeImmunity(admin, target) ? 1 : 0
}
public cmdList(id, level, cid)
{
if (!cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED
console_print(id, "----- CSB Immunity: %d protected SteamID(s) -----", g_iProtectedCount)
for (new i = 0; i < g_iProtectedCount; i++)
console_print(id, "%s", g_szProtected[i])
console_print(id, "-------------------------------------------------")
return PLUGIN_HANDLED
}