Код:
/*
Name & Say Guardian, он же NSG. Облегченная версия Key & Say Guardian, он же KSG.
Особенности:
* Фиксит баги с + и # в никах
* Работает быстрее KSG
* Использует Fakemeta, это позволяет избежать сообщений в чате о том, что игрок сменил ник...
* Имеется иммунитет от функций плагина. По умолчанию флаг a
* Антифлуд ником. Наверное, каждый видел как заходит какой нибудь укроп и начинает очень быстро менять ники. Вот эта функция от таких укропов;)
Credits:
* AndrewZ - автор KSG. Оригинальный код
* radius_r16 - автор первого ремейка KSG
* PRoSToTeM@ - консультации по коду и оптимизации
* serfreeman1337 - помощь по коду. Фикс баги с info changed
*/
#include <amxmodx>
#include <fakemeta>
// Configure
#define TIME_WAIT 5.0 // [Время между сменами ника] Antiflood name. Защита от быстрой смены ника. Дополнение к Hacks Detector by Lev
#define DEFAULT_NAME "[Neugomon.Ru] User" // Дефолтное имя, на которое менять. Меняет только визуально. При выходе сервера будет старый ник.
#define FLAG_IMMUNITY ADMIN_IMMUNITY // Иммунитет к фукнциям плагина.
// Для нескольких флагов используйте такую конструкцию: (ADMIN_MENU|ADMIN_LEVEL_H)
// End
#define get_bit(%1,%2) (%1 & (1 << (%2 & 31)))
#define set_bit(%1,%2) %1 |= (1 << (%2 & 31))
#define clr_bit(%1,%2) %1 &= ~(1 << (%2 & 31))
new blocked_msgs[128][128], blockedMsgsCounter;
new blocked_names[128][32], blockedNamesCounter;
new client_immunity, client_checked, client_connected;
public plugin_init()
{
register_plugin("Name & Say Guardian", "1.3b", "neygomon");
register_forward(FM_ClientUserInfoChanged, "fw_ClientUserInfoChanged");
register_clcmd("say", "hook_say");
register_clcmd("say_team", "hook_say");
}
public plugin_cfg()
{
new file_fullname[64], file_handle;
formatex(file_fullname, 63, "addons/amxmodx/configs/nsg/nsg_messages.ini");
file_handle = fopen(file_fullname, "rt");
if(file_handle)
{
new buffer[128];
while(!feof(file_handle))
{
fgets(file_handle, buffer, charsmax(buffer));
if(buffer[0] != ';' && parse(buffer, blocked_msgs[blockedMsgsCounter], charsmax(blocked_msgs[])))
blockedMsgsCounter++;
}
fclose(file_handle);
}
else set_fail_state("[Error] Couldn't read file ^"nsg_messages.ini^"");
formatex(file_fullname, 63, "addons/amxmodx/configs/nsg/nsg_names.ini");
file_handle = fopen(file_fullname, "rt");
if(file_handle)
{
new buffer[32];
while(!feof(file_handle))
{
fgets(file_handle, buffer, charsmax(buffer));
if(buffer[0] != ';' && parse(buffer, blocked_names[blockedNamesCounter], charsmax(blocked_names[])))
blockedNamesCounter++;
}
fclose(file_handle);
}
else set_fail_state("[Error] Couldn't read file ^"nsg_names.ini^"");
}
public client_putinserver(id)
{
clr_bit(client_checked, id);
clr_bit(client_immunity, id);
clr_bit(client_connected, id);
if(ClientHasImmunity(id))
set_bit(client_immunity, id);
set_bit(client_connected, id);
}
public client_disconnect(id)
clr_bit(client_connected, id);
public fw_ClientUserInfoChanged(id, infobuffer)
{
if(get_bit(client_immunity, id) || !get_bit(client_connected, id))
return FMRES_IGNORED;
static newname[32], oldname[32], Float:flCurrentTime, Float:flWaitName[33];
pev(id, pev_netname, oldname, charsmax(oldname));
engfunc(EngFunc_InfoKeyValue, infobuffer, "name", newname, charsmax(newname));
if(strcmp(newname, oldname) || !get_bit(client_checked, id))
{
if(!is_name_valid(newname))
ClientChangeName(id, DEFAULT_NAME, infobuffer);
else
{
new bool:iChange;
for(new i; newname[i] != '^0'; i++)
{
if(newname[i] == '#' || newname[i] == '+')
{
newname[i] = ' '; iChange = true;
}
}
if(iChange)
ClientChangeName(id, newname, infobuffer);
}
if(get_bit(client_checked, id) && is_user_alive(id))
{
flCurrentTime = get_gametime();
if(flWaitName[id] > flCurrentTime)
{
flWaitName[id] = flCurrentTime + TIME_WAIT;
ClientChangeName(id, oldname, infobuffer);
return FMRES_SUPERCEDE;
}
flWaitName[id] = flCurrentTime + TIME_WAIT;
}
set_bit(client_checked, id);
}
return FMRES_IGNORED;
}
public hook_say(id)
{
if(get_bit(client_immunity, id))
return PLUGIN_CONTINUE;
static szMessage[128]; read_args(szMessage, charsmax(szMessage));
static last_msg[33], said_len; said_len = strlen(szMessage);
if(last_msg[id] == said_len)
return PLUGIN_HANDLED;
else last_msg[id] = said_len;
for(new i; i < blockedMsgsCounter; i++)
if(containi(szMessage, blocked_msgs[i]) != -1)
return PLUGIN_HANDLED;
return PLUGIN_CONTINUE;
}
bool:ClientHasImmunity(id)
return (is_user_bot(id) || is_user_hltv(id) || get_user_flags(id) & FLAG_IMMUNITY) ? true : false;
bool:is_name_valid(const name[])
{
if(containi(name, DEFAULT_NAME) != -1) return true;
for(new i; i < blockedNamesCounter; i++)
{
if(containi(name, blocked_names[i]) != -1) return false;
}
return true;
}
ClientChangeName(const id, const szName[], const buffer)
engfunc(EngFunc_SetClientKeyValue, id, buffer, "name", szName);