/*
*
* MMMMMMM ,MMMMMMMMMMMMMMMMMMMMMMMM MMMM .aMMMMM
* 0MMMMMMMMMi MMMMMMMMMMMMMMMMMMMMMMMM MMMM MMMMMr
* MMMMMMMMMM: MMMM MMMM MMMMMM
* 7MMM2 MMMM MMMM MMMM .MMMMM.
* MMMMMM MMMMMM MMMM MMMM MMMMMM
* MMMM MMMM MMMM MMMM rMMMMM
* .iMMMM WMMMMr MMMM MMMM XMMMMM8
* rMMMM MMMM MMMM;WWWWWWWWWWWWWM0 MMMM @MMMM.
* MMMMMM MMMMMM MMMMMMMMMMMMMMMMMMMM MMMMZMMMMMM
* MMMM SMMMM MMMMMMMMMMMMMMMMMMMM MMMMMMMMMMMM8
* MMMM, MMMM2 MMMM MMMMMMM SMMMMM
* 2MMMMa ,ZMMMM MMMM MMMMW MMMMMM
* MMMM irrrrrrr: MMMM MMMM MMMM ;MMMMMi 7Zrrrrrrrr7
* BMMMMMMMMMMMMMMMMMMMMMM0r MMMM MMMM MMMMMX MMMMMMMMMMM
* MMMMMMMMMMMMMMMMMMMMMMMM: MMMM MMMM @MMMMM
* MMMMM8 MMMMMM MMMM MMMM MMMMMZ
* MMMM MMMM MMMM MMMM ZMMMMM
* MMMM ;MMMM MMMM MMMM MMMMM@
* MMMZ2 rMMMMZ ,MMMM MMMM XMMMM
*
*
*
*
* MMM BMMMW ;MMM r @MMMMMMMMM0 . . 0MMMMMMMMM@ r 2MMMMMMMMMM i
* MMM MMMM0 ;MMM MMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMM:
* MMM WMMMW @MMMa @MMMM BMMMW ZMMMM. MMMMM rMMMM
* MMM rMMMM iMMM MMMi MMM MMMa MMM MMMX
* MMM MMMMr MZM 2MMM; .MMMS MMMZ
* MMM MMMMM rMMM MMMM, MMMMS MMMMM
* MMM MMMM MMM @MMMMMMMM rrrX, MMMMMMMMMrrrr77 BMMMMMMMMZ;rrr8
* MMMMMMMMMM MMM MMMMMMMMMMMMMM MMMMMMMMMMMMMM ZMMMMMMMMMMMMMi
* MMMMB MMMMr MMM @ZZZSMMMMM MZZZ20MMMM, ZZZZa2MMMM.
* MMM ZMMMM MMM iMMMM: MMMMX MMM0
* MMM WMMM@ MMM .S,X MMM: 2,7 MMMZ Z,r WMM
* MMM MMMM0 MMM MMMMM MMM: WMMMM MMMZ XMMMM @MM
* MMM SMMMM MMM MMM XMMMM. MMM ,MMMMr MMMi MMMZ
* MMM BMMMM MMM rMMMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMMMi iMMMMM@MMMMMMMMMMMM:
* MMM 7MMM0 ,MMM S MMMMMMMMMMMM S i.BMMMMMMMMMMM 7 :aMMMMMMMMMMM 7
*
*
*
*
* Kick/Slay/Spec-Switcher for CS with bombdrop
* based on AFK-Kicker by Cheesy Peteza
* Code revision and some nice hints by juKay
*
* Date: 01-Jul-2005
*
*
* Description: AFK Slay/Kicker for CS. Kicks after mp_afktime and slays player
* if last surviver and afk and minimum afk_minplayers.
* Textmessage elsewhere
* Drops bomb after 25 sec afk
* AFK-Count-Message at roundstart
* AFK-Players are renamed and get their old name back when playing again or being switched spec
* (never the less their afk-name will show up during spectime)
* Able to kick specs after a certain time
*
* Cvars:
* afk_kicktime 150 // Kick people AFK longer than this time
* afk_slaytime 60 // Slay people AFK longer than this time and last survivor
* afk_minplayers 8 // Only kick AFKs when there is atleast this many players on the server
* afk_slayplayers 1 // Shall we slay or shall we not
* afk_adminimmunity 1 // Admins immun from slaying
* // Will show message anyway!
* afk_adminkickimmunity 1 // Admins immun from kicking
* afk_options 1 // 1 - Kick player after kicktime, 0 - switch to spec after kicktime
* afk_rename 1 // Set to 1, it renames AFK players as described before
*
*
*
* Requirements: AMXModX (cstrike and engine module)
*
*
*
*
* Need help with this?
*
*
*
*/
#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <engine>
#define MIN_AFK_TIME 30 // I use this incase stupid admins accidentally set afk_kicktime to something silly.
#define WARNING_TIME 15 // Start warning the user this many seconds before they are about to be kicked.
#define CHECK_FREQ 5 // This is also the warning message frequency.
#define BOMB_DROP_TIME 25 // Time until bomb gets dropped, it is also afk recognition time
#define SHOW_FREQ 20 // Frequence of afk-count-messages, only needed if the CVAR afk_show_counter is set to 1
#define SPEC_ASK_TIME 30 // Time until demo-menu will pop up ...
new g_oldangles[33][3]
new g_spawnpos[33][3]
new g_afktime[33]
new g_spectime[33]
new st_afk_name[33][33]
new bool:g_spawned[33] = {true, ...}
new bool:g_demorec[33] = {false, ...}
new bool:g_afkname[33] = {false, ...}
new CsTeams:team
new AfkCT
new AfkT
new bombcarrier
new numCT
new numT
// At mapchange init this
public plugin_init() {
register_plugin("AFK KiSSS","2.5.2","Isobold & Cheesy Peteza")
register_cvar("afkslay_version", "2.5.2", FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_SPONLY)
register_cvar("afk_options", "0") // kirúgja az embereket a megadott idő után (1), vagy spectbe rakja (0)
register_cvar("afk_kicktime", "70") // ennyi másodperc után rúgja ki a játékost
register_cvar("afk_slaytime", "40") // ha az adott csapatban egyedül van a tétlen ember, ennyi másodperc után megöli
register_cvar("afk_minplayers", "6") // csak akkor lép működésbe a plugin, ha legalább ennyi ember van a szerveren
register_cvar("afk_slayplayers", "1") // megöli a tétlen embereket (1), vagy nem (0)
register_cvar("afk_adminimmunity", "0") // adminok védettek ellene (1), vagy nem (0)
register_cvar("afk_adminkickimmunity", "0") // ha az afk_adminimmunity 0, és ez 1, akkor nem rúgja ki az adminokat, csak megöli őket
register_cvar("afk_show_counter", "0") // mutassa a visszaszámlálót (1), vagy nem (0)
register_cvar("afk_rename", "0") // átnevezze a tétlen játékosokat (1), vagy nem (0)
register_cvar("afk_speckick", "0") // kirúgja a spectelőket is (1), vagy nem (0)
register_cvar("afk_speckicktime", "300") // ha afk_speckik 1, ennyi mp után rúgja ki a specteket
set_task(float(CHECK_FREQ),"checkPlayers",_,_,_,"b")
register_event("ResetHUD", "playerSpawned", "be")
register_dictionary("afkkicker.txt")
register_logevent("event_RoundStart",2,"0=World triggered","1=Round_Start")
register_logevent("bomb_events", 3, "1=triggered", "2=Spawned_With_The_Bomb", "2=Dropped_The_Bomb", "2=Got_The_Bomb", "2=Planted_The_Bomb")
new keys = MENU_KEY_1|MENU_KEY_2
register_menucmd(register_menuid("Recording a demo?"), keys, "recDemo")
//register_menucmd(register_menuid("Recording a demo?"), 1023, "recDemo")
}
// Check wether one or more players is/are afk
public checkPlayers() {
new playerCount, i, cplayer
new cplayers[32]
get_players(cplayers, playerCount, "ac")
get_alive_nums()
for (i=0; i<playerCount; i++) {
cplayer = cplayers[i]
if (is_user_connected(cplayer) && !is_user_bot(cplayer) && !is_user_hltv(cplayer) && is_user_alive(cplayer) && g_spawned[cplayer]) {
new newangle[3]
g_demorec[cplayer] = false
get_user_origin(cplayer, newangle)
if ( newangle[0] == g_spawnpos[cplayer][0] && newangle[1] == g_spawnpos[cplayer][1] && newangle[2] == g_spawnpos[cplayer][2] ) {
g_afktime[cplayer] += CHECK_FREQ
check_afktime(cplayer)
if(get_cvar_num("afk_rename") && get_cvar_num("afk_slaytime") && !(g_afkname[cplayer])) {
new AFKName[32]
get_user_name(cplayer, st_afk_name[cplayer], 31)
format(AFKName, 31, "[AFK] %s", st_afk_name[cplayer])
set_user_info(cplayer, "name", AFKName)
g_afkname[cplayer] = true
}
if(get_cvar_num("afk_slayplayers"))
check_team(cplayer)
} else {
get_user_origin(cplayer, newangle, 3)
if ( newangle[0] == g_oldangles[cplayer][0] && newangle[1] == g_oldangles[cplayer][1] && newangle[2] == g_oldangles[cplayer][2] ) {
g_afktime[cplayer] += CHECK_FREQ
check_afktime(cplayer)
if(get_cvar_num("afk_rename") && get_cvar_num("afk_slaytime") && !(g_afkname[cplayer])) {
new AFKName[32]
get_user_name(cplayer, st_afk_name[cplayer], 31)
format(AFKName, 31, "[AFK] %s", st_afk_name[cplayer])
set_user_info(cplayer, "name", AFKName)
g_afkname[cplayer] = true
}
if(get_cvar_num("afk_slayplayers"))
check_team(cplayer)
} else {
g_oldangles[cplayer][0] = newangle[0]
g_oldangles[cplayer][1] = newangle[1]
g_oldangles[cplayer][2] = newangle[2]
if(g_afkname[cplayer]) {
new AFKName[32]
format(AFKName, 31, "%s", st_afk_name[cplayer])
set_user_info(cplayer, "name", AFKName)
g_afkname[cplayer] = false
}
g_afktime[cplayer] = 0
}
}
if(g_afktime[cplayer] > BOMB_DROP_TIME && cplayer == bombcarrier) {
client_cmd(cplayer,"use weapon_c4")
client_cmd(cplayer,"drop")
client_print(0, print_chat, "[AFK KiSSS] - Bomb Drop")
}
} else {
if (is_user_connected(cplayer) && !is_user_bot(cplayer) && !is_user_hltv(cplayer))
checkspec(cplayer)
}
}
return PLUGIN_HANDLED
}
// All players in your team afk or not?
check_team(id) {
if(g_afktime[id] < get_cvar_num("afk_slaytime")) {
} else {
team = cs_get_user_team(id)
if((team == CS_TEAM_T && numT > 0) || (team == CS_TEAM_CT && numCT > 0)) {
} else {
if(get_playersnum() < get_cvar_num("afk_minplayers") || (get_user_flags(id)&ADMIN_IMMUNITY && get_cvar_num("afk_adminimmunity"))) {
client_print(0, print_chat, "[AFK KiSSS]: %L", LANG_PLAYER, "AFK_INFO_MSG")
} else {
new sid[1]
sid[0] = id
delayed_wc3_slay(sid)
new pname[32]
get_user_name(id, pname, 31)
client_print(0, print_chat, "[AFK KiSSS]: %L", LANG_PLAYER, "AFK_KILL_MSG", pname)
}
}
}
}
// Check what to do when afk
check_afktime(id) {
new numplayers = get_playersnum()
new minplayers = get_cvar_num("afk_minplayers")
if(!(get_user_flags(id)&ADMIN_IMMUNITY && get_cvar_num("afk_adminkickimmunity")))
{
if (numplayers >= minplayers) {
new maxafktime = get_cvar_num("afk_kicktime")
if (maxafktime < MIN_AFK_TIME) {
// log_amx("cvar afk_kicktime %i is too low. Minimum value is %i.", maxafktime, MIN_AFK_TIME)
maxafktime = MIN_AFK_TIME
set_cvar_num("afk_kicktime", MIN_AFK_TIME)
}
new name[32]
get_user_name(id, name, 31)
if(get_cvar_num("afk_options")==1) {
if ( maxafktime-WARNING_TIME <= g_afktime[id] < maxafktime) {
new timeleft = maxafktime - g_afktime[id]
client_print(id, print_chat, "[AFK] %L", id, "AFK_TIMELEFT", timeleft)
} else if (g_afktime[id] > maxafktime) {
client_print(0, print_chat, "[AFK]: %L", LANG_PLAYER, "AFK_KICKED", name, maxafktime)
// log_amx("%s was kicked for being AFK longer than %i seconds", name, maxafktime)
server_cmd("kick #%d ^"You were kicked for being AFK longer than %i seconds^"", get_user_userid(id), maxafktime)
}
} else {
if ( maxafktime-WARNING_TIME <= g_afktime[id] < maxafktime) {
new timeleft = maxafktime - g_afktime[id]
client_print(id, print_chat, "[AFK] %L", id, "AFK_STIME", timeleft)
} else if (g_afktime[id] > maxafktime) {
// log_amx("%s was switched to spec for being AFK longer than %i seconds", name, maxafktime)
client_cmd(id,"kill")
cs_set_user_team(id, CS_TEAM_SPECTATOR)
client_print(0, print_chat, "[AFK] - Spec-be Atrakva!")
g_afktime[id] = 0
g_spectime[id] = 0
new sid[1]
sid[0] = id
set_task(0.5,"delayed_wc3_slay",_,sid)
if(get_cvar_num("afk_rename") && g_afkname[id]) {
new AFKName[32]
format(AFKName, 31, "%s", st_afk_name[id])
set_user_info(id, "name", AFKName)
g_afkname[id] = false
}
}
}
}
}
}
checkspec(cplayer) {
// log_amx("Checkspec for id: %i", cplayer)
if(get_cvar_num("afk_speckick") == 1 && cs_get_user_team(cplayer) == CS_TEAM_SPECTATOR && g_demorec[cplayer] == false) {
if(!(get_user_flags(cplayer)&ADMIN_IMMUNITY && get_cvar_num("afk_adminkickimmunity"))) {
// Spectatorbehandlung hier rein
new maxspectime = get_cvar_num("afk_speckicktime")
new sname[32]
get_user_name(cplayer, sname, 31)
if(g_spectime[cplayer] > SPEC_ASK_TIME) {
// log_amx("Showing demo menu to %s - id: %i", sname, cplayer)
ShowDemoMenu(cplayer)
}
g_spectime[cplayer] += CHECK_FREQ
if(g_spectime[cplayer] > maxspectime) {
client_print(0, print_chat, "[AFK KiSSS]: %L", LANG_PLAYER, "AFK_KICKED", sname, maxspectime)
// log_amx("%s was kicked for being spec longer than %i seconds", sname, maxspectime)
server_cmd("kick #%d ^"You were kicked for being spec longer than %i seconds^"", cplayer, maxspectime)
}
}
}
}
// just connected you are not afk for shure <!-- s;) --><img src=\"{SMILIES_PATH}/icon_e_wink.gif\" alt=\";)\" title=\"kacsintás\" /><!-- s;) -->
public client_connect(id) {
g_afktime[id] = 0
g_spectime[id] = 0
g_demorec[id] = false
g_afkname[id] = false
get_user_name(id, st_afk_name[id], 31)
return PLUGIN_HANDLED
}
// just connected you are not afk for shure <!-- s;) --><img src=\"{SMILIES_PATH}/icon_e_wink.gif\" alt=\";)\" title=\"kacsintás\" /><!-- s;) -->
public client_putinserver(id) {
g_afktime[id] = 0
g_spectime[id] = 0
g_demorec[id] = false
g_afkname[id] = false
get_user_name(id, st_afk_name[id], 31)
return PLUGIN_HANDLED
}
// get player position after spawn
public playerSpawned(id) {
g_spawned[id] = false
g_demorec[id] = false
new sid[1]
sid[0] = id
set_task(0.75, "delayedSpawn",_, sid, 1) // Give the player time to drop to the floor when spawning
return PLUGIN_HANDLED
}
// Used to get playerposition after spawn and drop
public delayedSpawn(sid[]) {
get_user_origin(sid[0], g_oldangles[sid[0]], 3)
get_user_origin(sid[0], g_spawnpos[sid[0]])
g_spawned[sid[0]] = true
return PLUGIN_HANDLED
}
public event_RoundStart() {
new playerCount, Players[32], l
if(task_exists (95729,0)) remove_task (95729,0)
get_players(Players, playerCount, "ac")
for(l=0;l<32;l++) {
if(task_exists (2945 + l,0)) remove_task (2945 + l,0)
}
set_task(2.0, "afk_rs_msg")
if(get_cvar_num("afk_show_counter") == 1) set_task(float(SHOW_FREQ),"afk_rs_msg",95729,_,_,"b")
return PLUGIN_HANDLED
}
// Collect and displays informations about number and team of afk-players
public afk_rs_msg() {
new playerCount, i, player
new Players[32]
get_players(Players, playerCount, "ac")
AfkT = 0
AfkCT = 0
for (i=0; i<playerCount; i++) {
player = Players[i]
if(g_afktime[player] > BOMB_DROP_TIME) {
if(cs_get_user_team(player) == CS_TEAM_T)
AfkT++
if(cs_get_user_team(player) == CS_TEAM_CT)
AfkCT++
}
}
if(AfkT > 0 || AfkCT > 0) client_print(0, print_chat, "[AFK KiSSS]: %i T AFK - %i CT AFK", AfkT, AfkCT)
return PLUGIN_HANDLED
}
// Tracks the bombholder
public bomb_events() {
new arg0[64], action[64], name[33], userid, id;
// Read the log data that we need
read_logargv(0,arg0,63)
read_logargv(2,action,63)
// Find the id of the player that triggered the log
parse_loguser(arg0,name,32,userid)
id = find_player("k",userid)
// Find out what action it was
if (equal(action,"Spawned_With_The_Bomb")) {
bombcarrier = id;
} else if (equal(action,"Dropped_The_Bomb")) {
bombcarrier = 0;
} else if (equal(action,"Got_The_Bomb")) {
bombcarrier = id;
} else if (equal(action, "Planted_The_Bomb")) {
bombcarrier = 0;
}
return PLUGIN_HANDLED
}
// Retrieves the number of non-afk alive players
get_alive_nums() {
new playerCount, i, gplayer
new Players[32]
get_players(Players, playerCount, "ac")
numCT = 0
numT = 0
for (i=0; i<playerCount; i++) {
gplayer = Players[i]
if(cs_get_user_team(gplayer) == CS_TEAM_T && g_afktime[gplayer] < BOMB_DROP_TIME)
numT++
if(cs_get_user_team(gplayer) == CS_TEAM_CT && g_afktime[gplayer] < BOMB_DROP_TIME)
numCT++
}
}
public delayed_wc3_slay(sid[]) {
new id
id = sid[0]
// log_amx("Trying to wc3-slay %i",id)
if(is_user_alive(id)) {
client_cmd(id,"kill")
set_task(2.0,"delayed_wc3_slay",2945 + id,sid)
}
}
public ShowDemoMenu(specid)
{
new menu[192]
new keys = MENU_KEY_1|MENU_KEY_2
format(menu, 191, "Recording a demo?^n^n1. Yes^n2. No")
show_menu(specid, keys, menu)
}
public recDemo(specid, key)
{
// if they pressed yes...
if ( key == 0 )
g_demorec[specid] = true // If recording a demo, don't bother him anymore, only kick real afk-specs
}