Вот полностью вариант от меня. Если кто-то сможет сделать замеры (хотя думаю и без них ясно, что вариант оптимальнее), я буду рад.
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#define PLUGIN "Random Name Generator"
#define VERSION "0.6"
#define AUTHOR "Chuvi / maeStro"
#if AMXX_VERSION_NUM < 183
#define MAX_NAME_LENGTH 32
#include <colorchat>
#else
#define DontChange print_team_default
#define Blue print_team_blue
#define Red print_team_red
#define Grey print_team_grey
#define ColorChat client_print_color
#endif
#define LenMin 6
#define LenMax 10
new Trie:g_tBadNames
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_forward(FM_ClientUserInfoChanged, "ClientUserInfoChanged")
register_clcmd("BadNameUpdate", "ReadConfig", ADMIN_CFG, "Re-read banned names");
g_tBadNames = TrieCreate();
ReadConfig(0, 0, 0);
}
public ReadConfig(id, level, cid)
{
if(id && !cmd_access(id, level, cid, 1, false)) return PLUGIN_HANDLED;
TrieClear(g_tBadNames)
static CfgFile[255]; get_configsdir(CfgFile,charsmax(CfgFile));
add(CfgFile, charsmax(CfgFile), "/BadNames.ini");
if(!file_exists(CfgFile))
{
server_print("[RndName] BadNames.ini not found in cfg dir^n");
return 0;
}
new sString[32];
new f = fopen(CfgFile, "rt");
while(!feof(f))
{
fgets(f, sString, charsmax(sString));
trim(sString);
strtolower(sString);
if(!sString[0] || sString[0] == ';' || sString[0] == '/') continue;
TrieSetCell(g_tBadNames, sString, true);
}
fclose(f);
return 1;
}
public client_putinserver(id)
{
new ClientName[MAX_NAME_LENGTH];
get_user_info(id, "name", ClientName, charsmax(ClientName));
if(ClientName[0] == '(' && ClientName[2] == ')')
{
return equali_name(id, ClientName[3]);
}
return equali_name(id, ClientName);
}
public ClientUserInfoChanged(id)
{
new name[MAX_NAME_LENGTH], oldname[MAX_NAME_LENGTH];
pev(id, pev_netname, oldname, charsmax(oldname));
if(!oldname[0]) return FMRES_IGNORED;
get_user_info(id, "name", name, charsmax(name));
strtolower(name);
if(!equal(name, oldname, strlen(oldname)))
{
if(equali_name(id, name))
{
ColorChat(0, id, "^3[RndName] ^1Игрок ^4%s ^1хотел поставить запрещённый ник ^4%s", oldname, name);
return FMRES_HANDLED;
}
}
return FMRES_IGNORED;
}
public plugin_end()
{
TrieDestroy(g_tBadNames);
}
stock equali_name(id, const name[])
{
if(TrieKeyExists(g_tBadNames, name))
{
cl_RandomName(id, name);
return 1;
}
return 0;
}
stock cl_RandomName(id, const name[])
{
new sNewName[MAX_NAME_LENGTH]; GetRandomName(sNewName, random_num(LenMin,LenMax));
ColorChat(0, id, "^3[RndName] ^1Ник игрока ^4%s ^1был автоматически изменён на ^4%s", name, sNewName);
set_user_info(id, "name", sNewName);
}
stock GetRandomName(word[],len)
{
if(len < 2) return;
static const cons_start[][]=
{
// single consonants. Beware of Q, it"s often awkward in words
"b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "r", "s", "t", "v", "w", "x", "z",
// possible combinations excluding those which cannot start a word
"pt", "gl", "gr", "ch", "ph", "ps", "sh", "st", "th", "wh"
};
static const cons_all[][]=
{
// single consonants. Beware of Q, it"s often awkward in words
"b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "r", "s", "t", "v", "w", "x", "z",
// possible combinations excluding those which cannot start a word
"pt", "gl", "gr", "ch", "ph", "ps", "sh", "st", "th", "wh" ,
"ck", "cm",
"dr", "ds",
"ft",
"gh", "gn",
"kr", "ks",
"ls", "lt", "lr",
"mp", "mt", "ms",
"ng", "ns",
"rd", "rg", "rs", "rt",
"ss",
"ts", "tch"
}
static const vows[][]=
{
// single vowels
"a", "e", "i", "o", "u", "y",
// vowel combinations your language allows
"ee", "oa", "oo"
}
format(word, len, "");
new cur = random_num(0, 1);
new rnd;
new rndlen;
formatex(word, len, "%s", cur ? vows[random_num(0, charsmax(vows))] : cons_start[random_num(0, charsmax(cons_start))]);
word[0] -= ('a'-'A'); //для заглавной буквы
cur =! cur;
while( strlen(word) <len)
{
rnd = cur ? random_num(0, charsmax(vows)) : random_num(0, charsmax(cons_all));
rndlen = cur ? strlen(vows[rnd]) : strlen(cons_all[rnd])
// check if random sign fits in word length
if( strlen(word)+rndlen <=len)
{
formatex(word[strlen(word)], len, "%s", cur ? vows[rnd] : cons_all[rnd]);
// alternate sounds
cur=!cur;
}
}
}