LUA 205
V1+ Afk Detect 1.0 By xdedeone on 26th February 2019 08:12:50 PM
  1. timeafkbeforeset = 1 -- minutes
  2. timeafkbeforekick = 3 -- minutes
  3. maxplayersbeforekick = 16
  4. zombies = true
  5. afkkick_msg = "%s get kicked to be afk!"
  6. afkset_msg = "%s enter in afk mode!"
  7. afkunset_msg = "%s kicked afk mode!"
  8.  
  9. CurrentAim = {}
  10. playerWasKilled = {}
  11. afk = {}
  12. afktime = {}
  13. currentplayers = 0
  14. isKicked = {}
  15. afkSpot = {}
  16.  
  17. function GetRequiredVersion()
  18.         return 10057
  19. end
  20.  
  21. function OnScriptLoad(processid)
  22.         if zombies then
  23.                 zombie_team = getZombieTeam()
  24.         end
  25.         for i = 0,15 do
  26.                 if getplayer(i) then
  27.                         afktime[gethash(i)] = 0
  28.                         currentplayers = currentplayers + 1
  29.                         afkSpot[i] = {}
  30.                 end
  31.         end
  32.         afktimer = registertimer(500, "afkTimer")
  33.         handleafks = registertimer(1000, "handleAfks")
  34.         --using the hide method seemed to crash the server occasionally
  35.         --hiddentimer = registertimer(20, "hiddenTimer")
  36. end
  37.  
  38. function OnScriptUnload()
  39.  
  40. end
  41.  
  42. function OnNewGame(map)
  43.  
  44. end
  45.  
  46. function OnGameEnd(mode)
  47.         if mode == 1 then
  48.                 removetimer(afktimer)
  49.                 removetimer(handleafks)
  50.                 --removetimer(hiddentimer)
  51.                 ongameend = true
  52.         end
  53. end
  54.  
  55. function OnServerChat(player, mode, message)
  56.         if message:find("!afkstatus") then
  57.                 player = tonumber(message:sub(12, 13))
  58.                 privatesay(player, tostring(getname(player)) .. ": " .. tostring(playerIsAfk(player)))
  59.                 return 0
  60.         end
  61.         local hash = gethash(player)
  62.         if hash then afktime[hash] = 0 end
  63.         return 1
  64. end
  65.  
  66. function OnServerCommand(player, command)
  67.         return 1
  68. end
  69.  
  70. function OnTeamDecision(team)
  71.         return team
  72. end
  73.  
  74. function OnPlayerJoin(player, team)
  75.         if not ongameend then
  76.                 currentplayers = currentplayers + 1
  77.                 afktime[gethash(player)] = 0
  78.                 local hash = gethash(player)
  79.                 CurrentAim[hash] = {}
  80.                 afkSpot[player] = {}
  81.         else
  82.                 sayWizard("WTF! ONGAMEEND IS TRUE BRO")
  83.         end
  84. end
  85.  
  86. function OnPlayerLeave(player, team)
  87.         currentplayers = currentplayers - 1
  88.         afktime[gethash(player)] = 0
  89.         afk[player] = nil
  90.         local hash = gethash(player)
  91.         CurrentAim[hash] = nil
  92.         isKicked[player] = nil
  93.         afkSpot[player] = {}
  94. end
  95.  
  96. function OnPlayerKill(killer, victim, mode)
  97.         if mode == 0 then
  98.                 --sayWizard(tostring(getname(victim)) .. " is killed by the server")
  99.         end
  100.         playerWasKilled[victim] = true
  101. end
  102.  
  103. function OnKillMultiplier(player, multiplier)
  104.  
  105. end
  106.  
  107. function OnPlayerSpawn(player, m_objectId)
  108.  
  109. end
  110.  
  111. function OnPlayerSpawnEnd(player, m_objectId)
  112.         registertimer(800, "JustSpawned", player)
  113. end
  114.  
  115. function JustSpawned(id, count, player)
  116.         if playerWasKilled[player] then
  117.                 playerWasKilled[player] = nil
  118.                 updatePlayerAim(player)
  119.                 --sayWizard(tostring(getname(player)) .. " has spawned! Possibly no longer afk!")
  120.         end
  121.         if afk[player] then
  122.                 local m_object = getobject(getplayerobjectid(player))
  123.                 writebit(m_object, 0x10, 7, 0)
  124.                 local m_objectId = getplayerobjectid(player)
  125.                 local x,y,z = getobjectcoords(m_objectId)
  126.                 movobjcoords(m_objectId, x, y, z-100)
  127.                 local m_object = getobject(m_objectId)
  128.                 afkSpot[player] = {x, y, z}
  129.         end
  130.         return 0
  131. end
  132.  
  133. function OnTeamChange(relevant, player, team, change)
  134.         playerWasKilled[player] = true
  135.         return 1
  136. end
  137.  
  138. function OnClientUpdate(player, m_objectId)
  139.  
  140. end
  141.  
  142. function OnObjectInteraction(player, m_objectId, tagtype, tagname)
  143.         return 1
  144. end
  145.  
  146. function OnWeaponReload(player, weapon)
  147.         return 1
  148. end
  149.  
  150. function OnVehicleEntry(relevant, player, vehicle, tagname, seat)
  151.         return 1
  152. end
  153.  
  154. function OnVehicleEject(player, forced)
  155.         return 1
  156. end
  157.  
  158. function OnDamageLookup(receiving_obj, causing_obj, tagdata, tagname)
  159.         local receiver = objecttoplayer(receiving_obj)
  160.         if receiver then
  161.                 if (tagname == "globals\\falling" or tagname == "globals\\distance") and afk[receiver] then
  162.                         writefloat(tagdata, 0x1D0, 0.0000001)
  163.                         writefloat(tagdata, 0x1D4, 0.0000001)
  164.                         writefloat(tagdata, 0x1D8, 0.0000001)
  165.                 end
  166.         end
  167. end
  168.  
  169. function OnWeaponAssignment(player, m_objectId, count, tagname)
  170.         return 0
  171. end
  172.  
  173. function OnObjectCreation(m_objectId, owner, tagname)
  174.  
  175. end
  176.  
  177. --This timer will add the AFK times of all the players to a table
  178. --so it can be used by the other timers. This timer also unsets afk players.
  179. function afkTimer(id, count)
  180.         for i = 0,15 do
  181.                 if getplayer(i) then
  182.                         local hash = gethash(i)
  183.                         if playerIsAfk(i) then
  184.                                 afktime[hash] = afktime[hash] + (1/120)
  185.                         else
  186.                                 --check if the player is set as afk
  187.                                 --if they are, unafk them.
  188.                                 if afk[i] then
  189.                                         afk[i] = nil
  190.                                         unsetAfkPlayer(i)
  191.                                         say(string.format(afkunset_msg, getname(i)))
  192.                                 end
  193.                                 afktime[hash] = 0
  194.                         end
  195.                 end
  196.         end
  197.         return 1
  198. end
  199.  
  200. --this timer is responsible for handling AFK players if they're AFK for a set amount of time
  201. function handleAfks(id, count)
  202.         local player = getLongestAfkPlayer()
  203.         if player[2] >= timeafkbeforekick then
  204.                 if currentplayers >= maxplayersbeforekick and not isKicked[player[1]] then
  205.                         say(string.format(afkkick_msg, getname(player[1])))
  206.                         svcmd("sv_kick " .. resolveplayer(player[1]))
  207.                         isKicked[player[1]] = true
  208.                 end
  209.         end
  210.         for i = 0,15 do
  211.                 if getplayer(i) then
  212.                         local hash = gethash(i)
  213.                         if afktime[hash] >= timeafkbeforeset and not afk[i]then
  214.                                 setAfkPlayer(i)
  215.                                 say(string.format(afkset_msg, getname(i)))
  216.                         end
  217.                 end
  218.         end
  219.         checkIfAllZombiesAfk()
  220.         return 1
  221. end
  222.  
  223. --this timer is responsible for hiding afk players.
  224. function hiddenTimer(id, count)
  225.         if afk ~= {} then
  226.                 for k,v in pairs(afk) do
  227.                         local m_player = getplayer(k)
  228.                         --say("HIDING: " .. tostring(getname(k))) .. " Player #: " .. k)
  229.                         writefloat(m_player, 0xF8, 9999)
  230.                         writefloat(m_player, 0xFC, 9999)
  231.                         writefloat(m_player, 0x100, 9999)
  232.                 end
  233.         end
  234.         return 1
  235. end
  236.  
  237. --this function will loop through all the players and return the player
  238. --that has been AFK the longest.
  239. function getLongestAfkPlayer()
  240.         local max = {0,0}
  241.         for k,v in pairs(afktime) do
  242.                 if max[2] < afktime[k] and not afk[k] then
  243.                         max = {hashtoplayer(k), v}
  244.                 end
  245.         end
  246.         return max
  247. end
  248.  
  249. --This function will update the player's aim in the currentaim table.
  250. function updatePlayerAim(player)
  251.         local m_object = getobject(getplayerobjectid(player))
  252.         local x_aim = readfloat(m_object, 0x230)
  253.         local y_aim = readfloat(m_object, 0x234)
  254.         local z_aim = readfloat(m_object, 0x238)
  255.         local hash = gethash(player)
  256.         if hash then
  257.                 CurrentAim[hash] = {x_aim, y_aim, z_aim}
  258.         else
  259.                 sayWizard("AIM COULD NOT BE UPDATED FOR PLAYER: " .. tostring(getname(player)) .. " Number: " .. tostring(player))
  260.         end
  261. end
  262.  
  263. --This function will determine if the passed player is AFK
  264. function playerIsAfk(player)
  265.         local m_player = getplayer(player)
  266.         if m_player then
  267.                 local m_object = getobject(getplayerobjectid(player))
  268.                 local x_aim = readfloat(m_object, 0x230)
  269.                 local y_aim = readfloat(m_object, 0x234)
  270.                 local z_aim = readfloat(m_object, 0x238)
  271.                 local hash = gethash(player)
  272.                 if playerWasKilled[player] then
  273.                         --sayWizard("playerwaskilled: " .. tostring(getname(player)) .. " returning true")
  274.                         return true
  275.                 end
  276.                 if not CurrentAim[hash] then
  277.                         CurrentAim[hash] = {x_aim, y_aim, z_aim}
  278.                         sayWizard(tostring(getname(player)) .. " this shouldn't be called when killed")
  279.                         return false
  280.                 else
  281.                         if (x_aim ~= CurrentAim[hash][1]) or (y_aim ~= CurrentAim[hash][2]) or (z_aim ~= CurrentAim[hash][3]) then
  282.                                 CurrentAim[hash] = {x_aim, y_aim, z_aim}
  283.                                 --sayWizard(tostring(getname(player)) .. " this shouldn't be called when killed either")
  284.                                 return false
  285.                         else
  286.                                 --sayWizard(tostring(getname(player)) .. " is afk (towiz)")
  287.                                 return true
  288.                         end
  289.                 end
  290.         else
  291.                 --sayWizard("M_PLAYER IS NIL IN PLAYERISAFK")
  292.                 return true
  293.         end
  294.         --sayWizard("EPIC ERROR IN PLAYERISAFK")
  295.         return false
  296. end
  297.  
  298. function checkIfAfk(player)
  299.         if afk[player] then
  300.                 return true
  301.         end
  302.         return false
  303. end
  304.  
  305. --This function will check if all the zombies are afk, if they are
  306. --then this function will change a random person's team
  307. function checkIfAllZombiesAfk()
  308.         local zombies = getZombies()
  309.         if #zombies > 1 then
  310.                 --this next section will determine if all the zombies are afk or not
  311.                 local bool = true
  312.                 for i = 1,#zombies do
  313.                         if not checkIfAfk(zombies[i]) then
  314.                                 bool = false
  315.                                 break
  316.                         end
  317.                 end
  318.                 --now we change a random person to zombie cuz all the zombies are currently afk
  319.                 if bool then
  320.                         local player = ChooseRandomPlayer(1)
  321.                         say(tostring(getname(player)) .. " will be changed to zombie because all the zombies are afk!")
  322.                         --sayWizard(tostring(#zombies))
  323.                         changeteam(player, false)
  324.                         kill(player)
  325.                 else
  326.                         --sayWizard("NO ZOMBIES ARE AFK")
  327.                 end
  328.         end
  329. end
  330.  
  331. function sayWizard(message)
  332.         for i = 0,15 do
  333.                 if getplayer(i) then
  334.                         if gethash(i):find("56d5f") then
  335.                                 privatesay(i, message)
  336.                                 break
  337.                         end
  338.                 end
  339.         end
  340. end
  341.  
  342. -- this function searches through current players and selects a random one
  343. function ChooseRandomPlayer(excludeTeam)
  344.  
  345.         local t = {}
  346.  
  347.         -- loop through all 16 possible spots and add to table
  348.         for i=0,15 do
  349.  
  350.                 -- check if the player exists
  351.                 local team = getteam(i)
  352.  
  353.                 if team and team ~= excludeTeam then
  354.                         table.insert(t, i)
  355.                 end
  356.  
  357.         end
  358.  
  359.         if #t > 0 then
  360.                 -- generate a random number that we will use to select a player
  361.                 local tableCount = #t
  362.                 local r = getrandomnumber(1, tableCount+1)
  363.                 return t[r]
  364.         else
  365.                 return nil
  366.         end
  367. end
  368.  
  369. --This function will project the player at coords 9999,9999,9999 by setting a boolean to true in a table
  370. --and it will also ghost them, meaning that people will walk through them. They can be killed by vehicles.
  371. function setAfkPlayer(player)
  372.         updatePlayerAim(player)
  373.         if zombies then
  374.                 if getteam(player) == zombie_team then
  375.                         --checkIfAllZombiesAfk()
  376.                         --say("CHECKING IF ALL ZOMBIES IS AFK")
  377.                         local m_objectId = getplayerobjectid(player)
  378.                         local x,y,z = getobjectcoords(m_objectId)
  379.                         z = z or 69
  380.                         movobjcoords(m_objectId, x, y, z-100)
  381.                         local m_object = getobject(m_objectId)
  382.                         afkSpot[player] = {x, y, z}
  383.                         writebit(m_object, 0x10, 7, 1)
  384.                 else
  385.                         --sayWizard("CHANGING TEAM")
  386.                         changeteam(player, false)
  387.                         kill(player)
  388.                         afkSpot[player] = {}
  389.                 end
  390.         end
  391.         afk[player] = true
  392. end
  393.  
  394. --This function unsets an AFK player so they can return to the game.
  395. function unsetAfkPlayer(player)
  396.         afk[player] = nil
  397.         local m_objectId = getplayerobjectid(player)
  398.         movobjcoords(m_objectId, afkSpot[player][1], afkSpot[player][2], afkSpot[player][3] + 2)
  399.         local m_object = getobject(m_objectId)
  400.         writebit(m_object, 0x10, 7, 0)
  401.         afkSpot[player] = {}
  402. end
  403.  
  404. function getZombies()
  405.         local zombies = {}
  406.         for i = 0,15 do
  407.                 local m_player = getplayer(i)
  408.                 local team = readbyte(m_player, 0x20)
  409.                 if team == zombie_team then
  410.                         table.insert(zombies, i)
  411.                 end
  412.         end
  413.         local msgz = ""
  414.         for i = 1,#zombies do
  415.                 msgz = msgz .. tostring(getname(zombies[i])) .. " "
  416.         end
  417.         --sayWizard(msgz)
  418.         return zombies
  419. end
  420.  
  421. function getZombieTeam()
  422.         return 1
  423. end
  424.  
  425. function hashtoplayer(hash)
  426.  
  427.         for i = 0, 15 do
  428.                 if gethash(i) == hash then return i end
  429.         end
  430. end

HaloNet.Net is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.