
   /* AMXMOD script - dod_tk_manager
   *
   *  Team Killer manager for DOD - by Fractal (fractal323@comcast.net)
   *  Provides simple automated control over TKers
   *  Uses  log  messages  to determine TKers so you need to have logging
   turned on
   *  (this is so it still works with Death Messages turned off)
   *
   *  Based on the original LogD Team_Kill plugin by Bud-Froggy
   *  (http://logd.sourceforge.net/)
   *
   *  Commands  to  forgive  tks  are  any  of "forgivetk", "forgive tk",
   "!forgivetk", "!forgive tk"
   *  (can be upper or lower case)
   *
   *
   *  Cvar settings (put in amx.cfg):
   *  -------------------------------
   *  amx_tk_limit  <value>               -  number of TKs allowed before
   banning
   *  amx_tk_bantime  <minutes>           -  how  long  to  ban  if limit
   exceeded (0=permanent)
   *  amx_tk_adminimmunity   <0|1>         -  prevent  admin  from  being
   kicked/banned for TKing
   *                                        (for  admins  with  ADMIN_BAN
   access)
   *  amx_tk_forgivetype   <0|1|2>         -  how   to   forgive,  0="say
   forgivetk", 1=Yes/No menu, 2=both
   *  amx_tk_useeffects <0|1>            -  use special slay effects
   *  amx_tk_usemapmemory  <0|1>          -  use  map  specific TK memory
   (prevents TKers from
   *                                        resetting  their  counter  by
   disconnecting/reconnecting)
   *  amx_tk_roundprotect  <0|1>          -  punish  players for TKing at
   beginning of round
   *  amx_tk_roundprotecttime  <seconds>  -  how long from start of round
   to punish
   *  amx_tk_roundprotecttype   <0|1>      -  what   punishment   to  use
   (slay=0, kick=1)
   *  amx_tk_infomessages   <0|1>          -  show  information  messages
   (chat text)
   *  amx_tk_usehostname <0|1>           -  use hostname in messages
   *
   *
   *  default settings
   *  ----------------
   *  amx_tk_limit 5
   *  amx_tk_bantime 1440
   *  amx_tk_adminimmunity 1
   *  amx_tk_forgivetype 2
   *  amx_tk_useeffects 1
   *  amx_tk_usemapmemory 1
   *  amx_tk_roundprotect 1
   *  amx_tk_roundprotecttime 8
   *  amx_tk_roundprotecttype 0
   *  amx_tk_infomessages 1
   *  amx_tk_usehostname 1
   *
   */
   #include <amxmod>
   #include <amxmisc>
   new g_TKlimit
   new g_TKbantime
   new g_adminimmunity
   new g_forgivetype
   new g_useeffects
   new g_roundprotecttype
   new g_check_spawnTK = 0
   new g_infomessages
   new g_white
   new g_servername[32]
   new g_player_authid[33][40]
   new g_player_authenticated[33]
   new g_TKcount[33]
   new g_FGmenu_killerid[33]
   new LastTKer = 0
   new LastTKed = 0
   new BeLastTKer = 0
   new BeLastTKed = 0
   /* main */
   public plugin_init()
   {
       register_plugin("DoD TK Manager","0.9.4","Fractal")
       register_event("RoundState", "round_start","a","1=1")
       register_logevent("log_kill",5,"1=killed")
       register_menucmd(register_menuid("Forgive"),1023,"actionFGMenu")
       register_clcmd("say","HandleSay")
       register_clcmd("say_team","HandleSay")
       register_concmd("amx_forgivetk","admin_forgivetk",ADMIN_BAN,"<new|
   old> : forgives most recent or least recent TK")
       register_cvar("amx_tk_limit","5")
       register_cvar("amx_tk_bantime","1440")
       register_cvar("amx_tk_adminimmunity","1")
       register_cvar("amx_tk_forgivetype","2")
       register_cvar("amx_tk_useeffects","1")
       register_cvar("amx_tk_usemapmemory","1")
       register_cvar("amx_tk_roundprotect","1")
       register_cvar("amx_tk_roundprotecttime","8")
       register_cvar("amx_tk_roundprotecttype","0")
       register_cvar("amx_tk_infomessages","1")
       register_cvar("amx_tk_usehostname","1")
       set_task(0.6,"load_settings")
       return PLUGIN_CONTINUE
   }
   public load_settings()
   {
       g_TKlimit = get_cvar_num("amx_tk_limit")
       g_TKbantime = get_cvar_num("amx_tk_bantime")
       g_adminimmunity = get_cvar_num("amx_tk_adminimmunity")
       g_forgivetype = get_cvar_num("amx_tk_forgivetype")
       g_useeffects = get_cvar_num("amx_tk_useeffects")
       g_roundprotecttype = get_cvar_num("amx_tk_roundprotecttype")
       g_infomessages = get_cvar_num("amx_tk_infomessages")
       if (get_cvar_num("amx_tk_usehostname"))
           get_cvar_string("hostname",g_servername,31)
       else
           format(g_servername,31,"this server")
       return PLUGIN_CONTINUE
   }
   public plugin_precache()
   {
       g_white = precache_model("sprites/white.spr")
       return PLUGIN_CONTINUE
   }
   public client_connect(id)
   {
       g_player_authenticated[id] = 0
       return PLUGIN_CONTINUE
   }
   public client_putinserver(id)
   {
       get_user_authid(id,g_player_authid[id],39)
       g_player_authenticated[id] = 1
       g_TKcount[id] = 0
       if (!get_cvar_num("amx_tk_usemapmemory"))
           return PLUGIN_CONTINUE

       new TKfile[64]
       format(TKfile,63,"addons/amx/tkvault/%s.txt",g_player_authid[id])
       //fix for VALVE id problem
       replace(TKfile,63,":","_")
       replace(TKfile,63,":","_")
       if (file_exists(TKfile))
       {
           new currmap[32]
           get_mapname(currmap,31)
           new text[32]
           new a = 0
           if (read_file(TKfile,1,text,31,a) && equali(currmap,text))
           {
               if (read_file(TKfile,2,text,31,a))
                   g_TKcount[id] = strtonum(text)
           }
           else
               delete_file(TKfile)
       }
       return PLUGIN_CONTINUE
   }
   public client_disconnect(id)
   {
       if (!get_cvar_num("amx_tk_usemapmemory"))
           return PLUGIN_CONTINUE
       if (g_player_authenticated[id] && g_TKcount[id] > 0)
       {
           new TKfile[64]
           format(TKfile,63,"addons/amx/tkvault/%s.txt",g_player_authid[i
   d])
           replace(TKfile,63,":","_")
           replace(TKfile,63,":","_")
           new currmap[32]
           get_mapname(currmap,31)
           write_file(TKfile,currmap,1)
           new text[8]
           numtostr(g_TKcount[id],text,7)
           write_file(TKfile,text,2)
       }
       return PLUGIN_CONTINUE
   }
   public round_start()
   {
       if (get_cvar_num("amx_tk_roundprotect"))
       {
           g_check_spawnTK = 1
           set_task(get_cvar_float("amx_tk_roundprotecttime"),"roundprote
   ct_off")
       }
       return PLUGIN_CONTINUE
   }
   public roundprotect_off()
   {
       g_check_spawnTK = 0
       return PLUGIN_CONTINUE
   }
   public log_kill()
   {
       new killer[64]
       read_logargv(0,killer,63)
       new victim[64]
       read_logargv(2,victim,63)
       new weapon[32]
       read_logargv(4,weapon,31)
       new name[32], userid, authid[32], k_team[12], v_team[12]
       parse_loguser(killer,name,31,userid,authid,31,k_team,11)
       new id1 = get_user_index(name)
       parse_loguser(victim,name,31,userid,authid,31,v_team,11)
       new id2 = get_user_index(name)

       if (id1 && (id1!=id2))
       {
           if (equali(k_team,v_team))
           {
               TKPunish(id1, id2, weapon)
               BeLastTKer = LastTKer
               BeLastTKed = LastTKed
               LastTKer = id1
               LastTKed = id2
           }
       }
       return PLUGIN_CONTINUE
   }
   public admin_forgivetk(id,level,cid)
   {
       if (!cmd_access(id,level,cid,2))
           return PLUGIN_HANDLED
       new text[4]
       read_argv(1,text,3)
       if (equali(text,"new") == 0)
           forgiveNewTK()
       else if (equali(text,"old") == 0)
           forgiveOldTK()
       return PLUGIN_HANDLED
   }
   public HandleSay(id)
   {
       if (g_forgivetype==1)
           return PLUGIN_CONTINUE
       new text[12]
       read_argv(1,text,11)
       if (forgivetk(text))
       {
           new menuid, keys
           if (id == LastTKed)
           {
               // if they still have menu on screen then cancel it
               if            (get_user_menu(id,menuid,keys)            &&
   g_FGmenu_killerid[id]==LastTKer)
                   client_cmd(id,"slot3")
               forgiveNewTK()
           }
           else if (id == BeLastTKed)
           {
               if            (get_user_menu(id,menuid,keys)            &&
   g_FGmenu_killerid[id]==BeLastTKer)
                   client_cmd(id,"slot3")
               forgiveOldTK()
           }
       }
       return PLUGIN_CONTINUE
   }
   forgivetk(text[])
   {
       if (containi(text,"forgivetk") == 0)
           return 1
       if (containi(text,"!forgivetk") == 0)
           return 1
       if (containi(text,"forgive tk") == 0)
           return 1
       if (containi(text,"!forgive tk") == 0)
           return 1
       return 0
   }
   TKPunish(killer, victim, weaponname[])
   {
       g_TKcount[killer]++
       if (g_TKcount[killer] < 1)
           return 0
       new name[32], userid
       get_user_name(killer,name,31)
       //get rid of the "amer/ger/brit"
       if (containi(weaponname,"knife") != -1)
           copy(weaponname,6,"knife")
       if (g_check_spawnTK)
       {
           if(g_roundprotecttype==0)
           {
               slay_user(killer)
               set_hudmessage(255,  255,  255, 0.05, 0.575, 0, 3.0, 10.0,
   0.1, 0.5, 8)
               show_hudmessage(0,"%s^nSlayed for TKing at round start^nTK
   warning %i of %i", name, g_TKcount[killer], g_TKlimit)
               log_message("[ADMIN]  %s  Slayed for TKing at round start,
   TK warning %i of %i", name, g_TKcount[killer], g_TKlimit)
           }
           else   if   (!g_adminimmunity  ||  !(get_user_flags(killer)  &
   ADMIN_BAN))
           {
               set_hudmessage(255,  255,  255, 0.05, 0.575, 0, 3.0, 10.0,
   0.1, 0.5, 8)
               show_hudmessage(0,"%s^nKicked for TKing at round start^n",
   name)
               log_message("[ADMIN]  %s Kicked for TKing at round start",
   name)
               userid = get_user_userid(killer)
               server_cmd("kick #%d",userid)
               return PLUGIN_CONTINUE
           }
       }
       else if (g_TKcount[killer] < g_TKlimit)
       {
           set_hudmessage(255,  255, 255, 0.05, 0.575, 0, 3.0, 10.0, 0.1,
   0.5, 8)
           if (equal(weaponname,"knife") || equal(weaponname,"spade"))
           {
               slay_user(killer)
               show_hudmessage(0,"%s^nSlayed   for   TKing   with  %s^nTK
   warning %i of %i", name, weaponname, g_TKcount[killer], g_TKlimit)
               log_message("[ADMIN]  %s  Slayed  for  TKing  with  %s, TK
   warning %i of %i", name, weaponname, g_TKcount[killer], g_TKlimit)
           }
           else
           {
               show_hudmessage(0,"%s^nTK   warning   %i   of  %i",  name,
   g_TKcount[killer], g_TKlimit)
               log_message("[ADMIN]  %s  TK  warning  %i  of  %i",  name,
   g_TKcount[killer], g_TKlimit)
           }
       }
       else if (g_TKcount[killer] == g_TKlimit)
       {
           slay_user(killer)
           set_hudmessage(255,  255, 255, 0.05, 0.575, 0, 3.0, 10.0, 0.1,
   0.5, 8)
           show_hudmessage(0,"%s^nSlayed  for  violating  %i TK warning",
   name, g_TKlimit)
           log_message("[ADMIN]  %s  Slayed for violating %i TK warning",
   name, g_TKlimit)
       }
       else
       {
           slay_user(killer)
           set_hudmessage(255, 0, 0, 0.05, 0.575, 0, 3.0, 11.0, 0.1, 0.5,
   8)
           if (g_adminimmunity && (get_user_flags(killer) & ADMIN_BAN))
           {
               show_hudmessage(0,"%s^nExceeded   %i   TK   limit",  name,
   g_TKlimit)
               log_message("[ADMIN]  %s  Exceeded  %i  TK  limit",  name,
   g_TKlimit)
           }
           else
           {
               if ((g_TKbantime % 1440)==0)
               {
                   show_hudmessage(0,"%s^nExceeded  %i  TK  limit  and is
   BANNED for %d hours", name, g_TKlimit, (g_TKbantime / 60))
                   log_message("[ADMIN]  %s  Exceeded  %i TK limit and is
   BANNED for %d hours", name, g_TKlimit, (g_TKbantime / 60))
               }
               else if (g_TKbantime < 60)
               {
                   show_hudmessage(0,"%s^nExceeded  %i  TK  limit  and is
   BANNED for %d minutes", name, g_TKlimit, (g_TKbantime % 1440))
                   log_message("[ADMIN]  %s  Exceeded  %i TK limit and is
   BANNED for %d minutes", name, g_TKlimit, (g_TKbantime % 1440))
               }
               else
               {
                   show_hudmessage(0,"%s^nExceeded  %i  TK  limit  and is
   BANNED  for %d hours %d minutes", name, g_TKlimit, (g_TKbantime / 60),
   (g_TKbantime % 1440))
                   log_message("[ADMIN]  %s  Exceeded  %i TK limit and is
   BANNED  for %d hours %d minutes", name, g_TKlimit, (g_TKbantime / 60),
   (g_TKbantime % 1440))
               }
               userid = get_user_userid(killer)
               server_cmd("banid %d.0 #%d",g_TKbantime,userid)
               server_cmd("writeid")
               server_cmd("kick #%d",userid)
           }
           return PLUGIN_CONTINUE
       }
       if (g_infomessages)
       {
           client_print(0,print_chat,"[ADMIN]  %i team kills will get you
   slayed", g_TKlimit)
           if ((g_TKbantime % 1440)==0)
               client_print(0,print_chat,"[ADMIN]  %i team kills will get
   you   a   %d   HOUR   ban   from   %s",g_TKlimit  +  1,(g_TKbantime  /
   60),g_servername)
           else if (g_TKbantime < 60)
               client_print(0,print_chat,"[ADMIN]  %i team kills will get
   you   a   %d   MINUTE   ban  from  %s",g_TKlimit  +  1,(g_TKbantime  %
   1440),g_servername)
           else
               client_print(0,print_chat,"[ADMIN]  %i team kills will get
   you  a  %d  HOUR  %d  MINUTE ban from %s",g_TKlimit + 1,(g_TKbantime /
   60),(g_TKbantime % 1440),g_servername)
           client_print(0,print_chat,"[ADMIN]   Team   killers   can   be
   forgiven by saying forgivetk")
       }
       if (g_forgivetype!=0)
       {
           new menuBody[192]
           format(menuBody,191,"Forgive  %s's  TK?^n^n1. Yes^n2. No^n^n3.
   Exit^n",name)
           new keys = (1<<0)|(1<<1)|(1<<2)
           g_FGmenu_killerid[victim] = killer
           show_menu(victim,keys,menuBody,30)
       }
       return PLUGIN_CONTINUE
   }
   public actionFGMenu(id,key)
   {
       switch(key)
       {
           case 0:
           {
               g_TKcount[g_FGmenu_killerid[id]]--
               new NameV[32], NameK[32]
               get_user_name(id,NameV,31)
               get_user_name(g_FGmenu_killerid[id],NameK,31)
               set_hudmessage(0, 90, 235, 0.05, 0.675, 0, 3.0, 11.0, 0.1,
   0.5, 9)
               show_hudmessage(0,"%s   has  forgiven  %s's  TK.",  NameV,
   NameK)
               log_message("[ADMIN]  %s  has  forgiven  %s's TK.", NameV,
   NameK)
           }
       }
       return PLUGIN_HANDLED
   }
   /* Adminmod style slay */
   slay_user(id)
   {
       if (g_useeffects)
       {
           new origin[3]
           get_user_origin(id,origin)
           explode(origin)
       }
       user_kill(id,1)
   }
   /* special effects for slay */
   explode(vec1[3])
   {
       //TE_BEAMCYLINDER (blast circle)
       message_begin( MSG_BROADCAST,SVC_TEMPENTITY,vec1)
       write_byte( 21 )
       write_coord(vec1[0])
       write_coord(vec1[1])
       write_coord(vec1[2] + 16)
       write_coord(vec1[0])
       write_coord(vec1[1])
       write_coord(vec1[2] + 1536)
       write_short( g_white )
       write_byte( 0 ) // startframe
       write_byte( 0 ) // framerate
       write_byte( 2 ) // life
       write_byte( 16 ) // width
       write_byte( 0 ) // noise
       write_byte( 188 ) // r
       write_byte( 220 ) // g
       write_byte( 255 ) // b
       write_byte( 255 ) //brightness
       write_byte( 0 ) // speed
       message_end()
       //TE_EXPLOSION2
       message_begin( MSG_BROADCAST,SVC_TEMPENTITY)
       write_byte( 12 )
       write_coord(vec1[0])
       write_coord(vec1[1])
       write_coord(vec1[2])
       write_byte( 188 ) // start color
       write_byte( 10 ) // num colors
       message_end()
   }
   forgiveNewTK()
   {
       //these checks are to make sure we don't touch any numbers
       //if the player doesn't exist (aka this TK was already forgiven)
       if ( LastTKed == 0 || LastTKer == 0 )
           return 0
       g_TKcount[LastTKer]--
       new NameV[32]
       get_user_name(LastTKed,NameV,31)
       new NameK[32]
       get_user_name(LastTKer,NameK,31)
       set_hudmessage(0,  90,  235,  0.05, 0.675, 0, 3.0, 11.0, 0.1, 0.5,
   9)
       show_hudmessage(0,"%s has forgiven %s's TK.", NameV, NameK)
       log_message("[ADMIN] %s has forgiven %s's TK.", NameV, NameK)
       LastTKed = BeLastTKed
       LastTKer = BeLastTKer
       BeLastTKed = 0
       BeLastTKer = 0
       return 1
   }
   forgiveOldTK()
   {
       //these checks are to make sure we don't touch any numbers
       //if the player doesn't exist (aka this TK was already forgiven)
       if (BeLastTKed == 0 || BeLastTKer == 0)
           return 0
       g_TKcount[BeLastTKer]--
       new NameV[32]
       get_user_name(BeLastTKed,NameV,31)
       new NameK[32]
       get_user_name(BeLastTKer,NameK,31)
       set_hudmessage(0,  90,  235,  0.05, 0.675, 0, 3.0, 11.0, 0.1, 0.5,
   9)
       show_hudmessage(0,"%s has forgiven %s's TK.", NameV, NameK)
       log_message("[ADMIN] %s has forgiven %s's TK.", NameV, NameK)
       BeLastTKed = 0
       BeLastTKer = 0
       return 1
   }
