PHP Code:
/* Plugin generated by AMXX-Studio */
#include <amxmodx>
#include <amxmisc>
#include <celltrie>
#include <sqlx>
#define PLUGIN "Universal Anti KzHack"
#define VERSION "1.7"
#define AUTHOR "hunter"
//Credits: ConnorMcLeod
//Idea: wext
#define KZH_NUM 2
new const g_kzh_cmds[2][] = // You can to add here kzh commands
{
"kzh_exec",
"zhy_exec"
}
enum {
KICK = 1,
BAN
}
enum {
AUTHID = 1,
IP
}
enum {
AMX_BAN_AUTO,
AMX_BAN_OLD,
AMX_BAN_NEW,
AMX_BAN_DEFAULT
}
enum {
AMXBANS_NO,
AMXBANS_5,
AMXBANS_6
}
new p_punishtype // 1 - kick(default), 2 - ban
new p_ban_type // 1 - authid(default), 2 - ip
new p_amxban_type
// 0 - automatic determine type of amx_ban (recomended)
// 1 - old amx_ban ( amx_ban <time_in_minutes> <nickname|steamid|IP> <reason> )
// 2 - new amx_ban ( amx_ban <nickname|steamid|IP> <time_in_minutes> <reason> )
// 3 - amxmodx amx_ban ( amx_ban <nickname|userid> <time_in_minutes> <reason>)
new p_bantime // ban time in minutes
new p_reason // reason of kick/ban
new p_notify_players // 1 - notify players, 0 - not notify
new gs_response_cmd[10]
new g_responsed_num[33]
new bool:g_kzh_checked[33][KZH_NUM]
new bool:g_kzh_rechecked[33]
new Trie:g_kzh_trie
new g_installed_amxbans = AMXBANS_NO
new gp_amxbans_use_newbancmd
new g_msgSayText
new logs_path[64]
new kzh_logs_path[128]
new g_CvarHost, g_CvarUser, g_CvarPassword, g_CvarDB, g_CvarPrefix
new Handle:g_SQL_Connection, Handle:g_SQL_Tuple
new g_prefix[10]
enum Color
{
YELLOW = 1,
GREEN,
TEAM_COLOR,
GREY,
RED,
BLUE,
}
new TeamInfo;
new SayText;
new MaxSlots;
new TeamName[][] =
{
"",
"TERRORIST",
"CT",
"SPECTATOR"
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR)
p_punishtype = register_cvar("kzh_punishtype", "2")
p_ban_type = register_cvar("kzh_ban_type", "2")
p_amxban_type = register_cvar("kzh_amxban_type", "0")
p_bantime = register_cvar("kzh_ban_time", "10080")
p_reason = register_cvar("kzh_reason", "KzHack")
p_notify_players = register_cvar("kzh_notify_players", "1")
g_msgSayText = get_user_msgid("SayText")
// Generates command for checking the response of a player
for (new i = 0; i < 9; i++)
{
gs_response_cmd[i] = random_num('a', 'z')
}
// Create and Fill Trie
g_kzh_trie = TrieCreate()
for (new i = 0; i < KZH_NUM; i++) TrieSetCell(g_kzh_trie, g_kzh_cmds[i], i+1)
TrieSetCell(g_kzh_trie, gs_response_cmd, 0)
if ((g_CvarHost = get_cvar_pointer("players_host")))
{
g_CvarDB = get_cvar_pointer("player_db")
g_CvarUser = get_cvar_pointer("player_user")
g_CvarPassword = get_cvar_pointer("players_password")
g_CvarPrefix = get_cvar_pointer("player_prefix")
}
else
{
g_CvarHost = register_cvar("players_host", "193.46.83.7")
g_CvarDB = register_cvar("player_db", "edgarass_drbans")
g_CvarUser = register_cvar("player_user", "edgarass_drbans")
g_CvarPassword = register_cvar("players_password", "grybas")
g_CvarPrefix = register_cvar("player_prefix", "")
}
register_clcmd("say", "cmdSay")
TeamInfo = get_user_msgid("TeamInfo")
SayText = get_user_msgid("SayText")
MaxSlots = get_maxplayers()
}
public plugin_cfg()
{
// Determine type of amx_ban
if ( is_plugin_loaded("AMXBans Main") != -1 ) // AMXBANS 6
{
g_installed_amxbans = AMXBANS_6
gp_amxbans_use_newbancmd = get_cvar_pointer("amxbans_use_newbancmd")
}
else if ( is_plugin_loaded("AMXBans") != -1 ) g_installed_amxbans = AMXBANS_5 // AMXBANS 5
get_localinfo("amxx_logs", logs_path, 64)
formatex(kzh_logs_path, 127, "%s\!!!KZHackers.txt", logs_path)
new cfgdir[32]
get_localinfo("amxx_configsdir", cfgdir, charsmax(cfgdir))
server_cmd("exec %s/sql.cfg", cfgdir)
server_exec()
new host[32], db[32], user[32], password[32]
get_pcvar_string(g_CvarHost, host, 31)
get_pcvar_string(g_CvarDB, db, 31)
get_pcvar_string(g_CvarUser, user, 31)
get_pcvar_string(g_CvarPassword, password, 31)
get_pcvar_string(g_CvarPrefix, g_prefix, 9)
g_SQL_Tuple = SQL_MakeDbTuple(host,user,password,db)
new err, error[256]
g_SQL_Connection = SQL_Connect(g_SQL_Tuple, err, error, charsmax(error))
if(g_SQL_Connection)
log_amx("Conected to db")
else
log_amx("Connect error %d (%s)", err, error)
}
public cmdSay(id)
{
new args[64]
read_args(args, 63)
remove_quotes(args)
new name[32]
parse(args, args, 63, name, 31)
if (!equal(args, "/kzh"))
return PLUGIN_CONTINUE
new target
if ((target = cmd_target(id, name, CMDTARGET_ALLOW_SELF)))
{
get_user_name(target, name, 31)
new authid[35]
get_user_authid(target, authid, 34)
new quotedName[64]
SQL_QuoteString(g_SQL_Connection, quotedName, 63, name)
new Handle:q = SQL_PrepareQuery(g_SQL_Connection,
"SELECT `kz_hacks` FROM `%s_players` \
WHERE `steam` = '%s' OR `name` = '%s'", g_prefix, authid, quotedName)
new count
SQL_Execute(q)
if (SQL_NumResults(q))
count = SQL_ReadResult(q, 0)
SQL_FreeHandle(q)
ColorChat(0, GREY, "^x03[Noptor-group] ^x04%s^x03 cought for ^x01%d^x03 time with ^x01kzh^x03!",
name, count)
}
else
ColorChat(0, GREY, "^x03[Noptor-group] Player ^x04%s^x03 not in the server!",
name)
return PLUGIN_HANDLED
}
public client_putinserver(id)
{
if ( is_user_bot(id) || is_user_hltv(id) ) return PLUGIN_CONTINUE
g_kzh_rechecked[id] = false
set_send_tasks(id)
return PLUGIN_CONTINUE
}
public client_disconnect(id)
{
remove_task(id)
}
public set_send_tasks(id)
{
// Clear variables
for (new i = 0; i < KZH_NUM; i++) g_kzh_checked[id][i] = false
g_responsed_num[id] = 0
// UDP - unreliable protocol. I did this to prevent casual punish
set_task(2.0, "send_kzh_exec", id)
set_task(3.0, "send_kzh_exec", id)
set_task(4.0, "send_kzh_exec", id)
set_task(7.0, "check_and_punish", id)
}
public send_kzh_exec(id)
{
for (new i = 0; i < KZH_NUM; i++) client_cmd(id, g_kzh_cmds[i])
client_cmd(id, gs_response_cmd)
}
public check_and_punish(id)
{
for (new i = 0; i < KZH_NUM; i++)
{
if (!g_kzh_checked[id][i])
{
if (g_responsed_num[id] == 3) // depends on number of set_task for send_kzh_exec
{
new reason[128]
get_pcvar_string(p_reason, reason, 127)
new username[33]
get_user_name(id, username, 32)
switch ( get_pcvar_num(p_punishtype) )
{
case KICK:
{
new userid = get_user_userid(id)
server_cmd("kick #%i ^"%s^"", userid, reason)
if ( get_pcvar_num(p_notify_players) )
ColorMsgToAll("^3%s ^4has been kicked for ^3%s ^4!!!", username, reason)
}
case BAN:
{
new bantime = get_pcvar_num(p_bantime)
new amx_ban_type = get_pcvar_num(p_amxban_type)
if (amx_ban_type == AMX_BAN_AUTO)
{
switch (g_installed_amxbans)
{
case AMXBANS_5:
{
amx_ban_type = AMX_BAN_OLD
}
case AMXBANS_6:
{
if ( get_pcvar_num(gp_amxbans_use_newbancmd) ) amx_ban_type = AMX_BAN_NEW
else amx_ban_type = AMX_BAN_OLD
}
default:
amx_ban_type = AMX_BAN_DEFAULT
}
}
switch ( amx_ban_type )
{
case AMX_BAN_NEW:
{
switch ( get_pcvar_num(p_ban_type) )
{
case AUTHID:
{
new authid[32]
get_user_authid(id, authid, 31)
server_cmd("amx_ban %s %i ^"%s^"", authid, bantime, reason)
}
case IP:
{
new userip[16]
get_user_ip(id, userip, 15, 1)
server_cmd("amx_ban %s %i ^"%s^"", userip, bantime, reason)
}
}
}
case AMX_BAN_OLD:
{
switch ( get_pcvar_num(p_ban_type) )
{
case AUTHID:
{
new authid[32]
get_user_authid(id, authid, 31)
server_cmd("amx_ban %i %s ^"%s^"", bantime, authid, reason)
}
case IP:
{
new userip[16]
get_user_ip(id, userip, 15, 1)
server_cmd("amx_ban %i %s ^"%s^"", bantime, userip, reason)
}
}
}
case AMX_BAN_DEFAULT:
{
new userid = get_user_userid(id)
server_cmd("amx_ban #%i %i ^"%s^"", userid, bantime, reason)
}
}
if ( get_pcvar_num(p_notify_players) )
ColorMsgToAll("^3%s ^4has been banned for ^3%s ^4!!!", username, reason)
}
}
LogKZH(id)
}
else {
if ( !g_kzh_rechecked[id] ) {
g_kzh_rechecked[id] = true
set_send_tasks(id)
} else {
new userid = get_user_userid(id)
server_cmd("kick #%i ^"Sorry. Ping timeout^"", userid)
}
}
return
}
}
}
public client_command(id)
{
new cmd[16]
read_argv(0, cmd, 15)
new value
if ( TrieGetCell(g_kzh_trie, cmd, value) )
{
if (value == 0) { // gs_response_cmd
g_responsed_num[id]++
return PLUGIN_HANDLED
} else { // kzh zhy
g_kzh_checked[id][value-1] = true
return PLUGIN_HANDLED
}
}
return PLUGIN_CONTINUE
}
public ColorMsgToAll(const sFormat[], ...)
{
new sMessage[192];
vformat(sMessage, 191, sFormat, 2);
message_begin(MSG_ALL, g_msgSayText, _, 0);
write_byte(1);
write_string(sMessage);
message_end();
}
public LogKZH(id)
{
new Date[20]
get_time("%m/%d/%y %H:%M:%S", Date, 20)
new username[33]
get_user_name(id, username, 32)
new userip[16]
get_user_ip(id, userip, 15, 1)
new authid[35]
get_user_authid(id, authid, 34)
new main_text[128], punish_text[64], bantime
new quotedName[64]
SQL_QuoteString(g_SQL_Connection, quotedName, 63, username)
new Handle:q = SQL_PrepareQuery(g_SQL_Connection,
"SELECT `id` FROM `%s_players` \
WHERE `steam` = '%s' OR `name` = '%s'", g_prefix, authid, quotedName)
SQL_Execute(q)
new dbId = 0
if (SQL_NumResults(q))
dbId = SQL_ReadResult(q, 0)
SQL_FreeHandle(q)
if (!dbId)
{
q = SQL_PrepareQuery(g_SQL_Connection,
"INSERT INTO `%s_players` (`name`, `steam`) \
VALUES ('%s', '%s')", g_prefix, quotedName, authid)
SQL_Execute(q)
dbId = SQL_GetInsertId(q)
}
SQL_QueryAndIgnore(g_SQL_Connection,
"UPDATE `%s_players` SET `kz_hacks` = `kz_hacks` + 1 WHERE `id` = %d",
g_prefix, dbId)
switch (get_pcvar_num(p_punishtype))
{
case KICK:
formatex(punish_text, 63, "Kick")
case BAN:
{
bantime = get_pcvar_num(p_bantime)
if (bantime == 0) formatex(punish_text, 63, "Permanent Ban")
else formatex(punish_text, 63, "Ban (%d minutes)", bantime)
}
}
formatex(main_text, 127, "%s |%-32s|%-34s|%-15s|%s", Date, username, authid, userip, punish_text)
write_file(kzh_logs_path, main_text, -1)
}
public plugin_end()
{
TrieDestroy(g_kzh_trie)
if (g_SQL_Tuple)
SQL_FreeHandle(g_SQL_Tuple)
if (g_SQL_Connection)
SQL_FreeHandle(g_SQL_Connection)
}
public ColorChat(id, Color:type, const msg[], {Float,Sql,Result,_}:...)
{
static message[256];
switch(type)
{
case YELLOW:
{
message[0] = 0x01
}
case GREEN:
{
message[0] = 0x04
}
default:
{
message[0] = 0x03
}
}
vformat(message[1], 251, msg, 4);
message[192] = '^0'
new team, ColorChange, index, MSG_Type
if(!id)
{
index = FindPlayer()
MSG_Type = MSG_ALL
} else {
MSG_Type = MSG_ONE
index = id
}
team = get_user_team(index);
ColorChange = ColorSelection(index, MSG_Type, type)
ShowColorMessage(index, MSG_Type, message)
if(ColorChange)
{
Team_Info(index, MSG_Type, TeamName[team])
}
}
ShowColorMessage(id, type, message[])
{
message_begin(type, SayText, _, id)
write_byte(id)
write_string(message)
message_end()
}
Team_Info(id, type, team[])
{
message_begin(type, TeamInfo, _, id)
write_byte(id)
write_string(team)
message_end()
return 1
}
ColorSelection(index, type, Color:Type)
{
switch(Type)
{
case RED:
{
return Team_Info(index, type, TeamName[1])
}
case BLUE:
{
return Team_Info(index, type, TeamName[2])
}
case GREY:
{
return Team_Info(index, type, TeamName[0])
}
}
return 0
}
FindPlayer()
{
new i = -1;
while(i <= MaxSlots)
{
if(is_user_connected(++i))
{
return i
}
}
return -1
}