#include <amxmodx>
#include <amxmisc>
#define AUTHOR "Lev"
#define PLUGIN "Better High Ping Kicker"
#define VERSION "2.7"
#define VERSION_CVAR "bhpk_version"
#define MAXSLOTS 32#define ALWAYS_KICK_MULTIPLIER 2 // Player will be kicked even there is less then or equal min_players if player's ping exceed night max ping by this factor.
#define DELAY_BEFORE_START_TESTING 20.0 // Delay before showing warning and start ping checking. Real testing starts after hpk_ping_time also passed.
const TASK_ID_BASE = 52635; // random number
const min_hpk_ping_max = 10;
const min_hpk_ping_time = 10;
const min_hpk_ping_tests = 4;
enum Color
{
YELLOW = 1, // Yellow
GREEN, // Green Color
TEAM_COLOR, // Red, grey, blue
GREY, // grey
RED, // Red
BLUE, // Blue
}
new TeamInfo;
new SayText;
new MaxSlots;
new TeamName[][] =
{
"",
"TERRORIST",
"CT",
"SPECTATOR"
}
new bool:IsConnected[MAXSLOTS + 1];new pcvar_hpk_ping_max;
new pcvar_hpk_ping_max_night;
new pcvar_hpk_ping_time;
new pcvar_hpk_ping_tests;
new pcvar_hpk_min_players;
new pcvar_hpk_night_start_hour;
new pcvar_hpk_night_end_hour;
new ping_violations[33];
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR);
register_cvar(VERSION_CVAR, VERSION, FCVAR_SERVER);
pcvar_hpk_ping_max = register_cvar("hpk_ping_max", "175");
pcvar_hpk_ping_max_night = register_cvar("hpk_ping_max_night", "300");
pcvar_hpk_ping_time = register_cvar("hpk_ping_time", "10");
pcvar_hpk_ping_tests = register_cvar("hpk_ping_tests", "5");
pcvar_hpk_min_players = register_cvar("hpk_min_players", "6");
pcvar_hpk_night_start_hour = register_cvar("hpk_night_start_hour", "1");
pcvar_hpk_night_end_hour = register_cvar("hpk_night_end_hour", "9");
register_dictionary("bhpk.txt");
TeamInfo = get_user_msgid("TeamInfo");
SayText = get_user_msgid("SayText");
MaxSlots = get_maxplayers();}
public client_putinserver(plrid)
{
ping_violations[plrid] = 0;
if (!is_user_bot(plrid) && !is_user_hltv(plrid))
set_task(DELAY_BEFORE_START_TESTING, "showInfo", TASK_ID_BASE + plrid);
return PLUGIN_CONTINUE;
}
public client_infochanged(plrid)
{
remove_task(TASK_ID_BASE + plrid);
if (!is_user_bot(plrid) && !is_user_hltv(plrid))
set_task(DELAY_BEFORE_START_TESTING, "showInfo", TASK_ID_BASE + plrid);
return PLUGIN_CONTINUE;
}
public client_disconnect(plrid)
{
remove_task(TASK_ID_BASE + plrid);
return PLUGIN_CONTINUE;
}
public showInfo(taskid)
{
new plrid = taskid - TASK_ID_BASE;
if (access(plrid, ADMIN_IMMUNITY) || access(plrid, ADMIN_RESERVATION))
ColorChat(plrid, RED, "%L %L", LANG_PLAYER, "BHPK_PREFIX", LANG_PLAYER, "BHPK_CHECK_ADMIN");
else
{
ColorChat(plrid, RED, "%L %L", LANG_PLAYER, "BHPK_PREFIX", LANG_PLAYER, "BHPK_CHECK", get_hpk_ping_max());
set_task(float(get_hpk_ping_time()), "checkPing", TASK_ID_BASE + plrid, _, _, "b");
}
return PLUGIN_CONTINUE;
}
public checkPing(taskid)
{
new plrid = taskid - TASK_ID_BASE;
new ping, loss;
get_user_ping(plrid, ping, loss);
if (ping > get_hpk_ping_max()) ping_violations[plrid]++;
else if (ping_violations[plrid] > 0) ping_violations[plrid]--;
new hpk_ping_tests = get_hpk_ping_tests();
if (ping_violations[plrid] >= hpk_ping_tests)
{
static players[32];
new playerCount;
get_players(players, playerCount, "ch");
// Allow player to stay if there is less or equal than 'min_players' players and player ping is not too high.
if (playerCount <= get_pcvar_num(pcvar_hpk_min_players) &&
ping < get_pcvar_num(pcvar_hpk_ping_max_night) * ALWAYS_KICK_MULTIPLIER)
{
ping_violations[plrid] = hpk_ping_tests;
return PLUGIN_CONTINUE;
}
kickPlayer(plrid, ping);
}
return PLUGIN_CONTINUE;
}
kickPlayer(plrid, ping)
{
new name[33], ip[15];
new userid = get_user_userid(plrid);
get_user_ip(plrid, ip, charsmax(ip), 1);
get_user_name(plrid, name, charsmax(name));
new szMsg[192];
format(szMsg, 191, "%L", plrid, "BHPK_KICK_PLAYER");
server_cmd("kick #%d ^"%s^"; addip 1 ^"%s^"", userid, szMsg, ip);
ColorChat(0, GREY, "%L %L", LANG_PLAYER, "BHPK_PREFIX", LANG_PLAYER, "BHPK_KICK_SERVER", name);
log_amx("^"%s^" was kicked due to high ping (%dms).", name, ping);
return PLUGIN_CONTINUE;
}
get_hpk_ping_max()
{
new ping_max;
new hour, minute, second;
time(hour, minute, second);
// At night we use different CVAR
if (hour >= get_pcvar_num(pcvar_hpk_night_start_hour) &&
hour < get_pcvar_num(pcvar_hpk_night_end_hour))
ping_max = get_pcvar_num(pcvar_hpk_ping_max_night);
else
ping_max = get_pcvar_num(pcvar_hpk_ping_max);
// Check to be no less then minimum value
if (ping_max < min_hpk_ping_max) return min_hpk_ping_max;
return ping_max;
}
get_hpk_ping_time()
{
new time = get_pcvar_num(pcvar_hpk_ping_time);
// Check to be no less then minimum value
if (time < min_hpk_ping_time) return min_hpk_ping_time;
return time;
}
get_hpk_ping_tests()
{
new tests = get_pcvar_num(pcvar_hpk_ping_tests);
// Check to be no less then minimum value
if (tests < min_hpk_ping_tests) return min_hpk_ping_tests;
return tests;
}
public ColorChat(id, Color:type, const msg[], {Float,Sql,Result,_}:...)
{
static message[256];
switch(type)
{
case YELLOW: // Yellow
{
message[0] = 0x01;
}
case GREEN: // Green
{
message[0] = 0x04;
}
default: // White, Red, Blue
{
message[0] = 0x03;
}
}
vformat(message[1], 251, msg, 4);
replace_all(message, 190, "!g", "^x04")
replace_all(message, 190, "!n", "^x01")
replace_all(message, 190, "!t", "^x03")
// Make sure message is not longer than 192 character. Will crash the server.
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(IsConnected[++i])
{
return i;
}
}
return -1;}