Poorly done AFK script?

Before I add all the bells and whistles I was wondering if this was a terrible or expensive way to do this. Also do these timers get removed on PlayerDissconnect?



hook.Add("PlayerInitialSpawn", "StartAFK_Timer", function(ply)
	
	timer.Create("AFK_Timer: " ..ply:Nick(), 15, 0, function() 
		ply:Kill()
		ply:SetTeam(TEAM_SPECTATOR)
	end)
	
end)

function ResetAFK_Status (ply, key)

	timer.Adjust("AFK_Timer: " ..ply:Nick(), 15, 0, function() 
		ply:Kill()
		ply:SetTeam(TEAM_SPECTATOR)
	end)
	
end
hook.Add( "KeyPress", "Reset AFK Timer", ResetAFK_Status )


I’ve seen some methods use ply:GetPos or ply:GetAngles, those methods seem flawed considering if they die or the round restarts they are not flagged as AFK anymore.

[editline]7th June 2014[/editline]

Would adding to a counter in the think hook then resetting the counter in the KeyPress hook be a more efficient?

What gamemode? I would think something like this:

In PlayerSpawn, assign spawn position to the player, like



hook.Add("PlayerSpawn", "fuckAFK", function( p )
	p.SpawnPos = p:GetPos()
end)

And when players die, check if only AFK guys are left:



local team = 1 -- Only check one team
hook.Add("PlayerSpawn", "fuckAFK", function()
	for id, p in pairs( player.GetAll() ) do
		if ( !p:Alive() || p:Team() != team ) then continue end
		if ( p:GetPos() != p.SpawnPos ) then return end -- Someone is not afk, bail
	end

	-- Everyone alive is AFK, kill em.
	for id, p in pairs( player.GetAll() ) do
		if ( !p:Alive() || p:Team() != team ) then continue end
		p:Kill()
		p:SetTeam( TEAM_SPECTATOR )
	end
end)

If they are, annihilate them.

Untested, but you get the idea. Should work perfectly for two team gamemode, like deathrun.

You used the same hook and hook name twice, also if you only checked one team, the AFK person could be on the other team. This also doesn’t work for things like DeathRun where the course can take several minutes for the runners to run and they get a free pass, while the death sits there AFK for forever.

Just hook into PlayerBindPress. Use that in addition to the position to see if they’re pressing keys or if they typed a command in the console to keep them moving, or spinning.

I don’t think that PlayerBindPress triggers on mouse movements. In that case you’d also want to save their EyeAngles and compare them.

With eye-angles you type one console command in and it’ll spin you forever. Key presses are best. For mouse-movement and buttons CreateMove will give you scroll-wheel and maybe more. vgui.GetWorldPanel or GetGamePanel for the global game vgui; you can hook into that / inject the mouse detection code so you can then detect mouse-movements.

Round based GM similar to CS. I like the fact that it doesn’t use timers or spam the KeyPress hook. I have not tested it but from the looks of it you could potentially have a 30 second round then get moved to Spectator and it’s only monitoring one team? But you got me thinking out of the box now, this is what I came up with this morning.

Working, but am I doing it in a unorthodox manner?



--It is getting the Vector length expensive enough that
--I should avoid it like the plague?
hook.Add("PlayerSpawn", "AFK-GetSpawnPosition", function( ply )

	--Rounded the Vector hoping it would make it less expensive 
	ply.SpawnPos = math.Round(ply:GetPos():Length())
	
	if ply.FlaggedAsAFK >= 2 then
		ply:Kill()
		ply:SetTeam(TEAM_SPECTATOR)	
		ply.FlaggedAsAFK = 0
	end
	
end)


--I will also have to compare positions in the GM Round End hook.
hook.Add("PlayerDeath", "CheckAFK", function( ply )
		--Rounded the Vector hoping it would make it less expensive 
		local deathPos = math.Round(ply:GetPos():Length())
		local comparePositions = ( ply.SpawnPos - deathPos )
		
		--Convert negative numbers to positive numbers
		if comparePositions <= -1 then
			comparePositions = (comparePositions * -1)
		end
		
		--Players are spawned in the air, and move slightly when landing on a slope.
		--I could have fixed this with a timer in the PlayerSpawn hook but im trying to 
		--avoid timers. More importantly players slightly move when attacked. 
		if comparePositions < 64 then
			ply.FlaggedAsAFK = ply.FlaggedAsAFK + 1
		else
			ply.FlaggedAsAFK = 0
		end
end)


You kind of lost me. Is detecting KB and mouse input really necessary? It seems like a lot of unneeded work. Sorry if I misinterpreted your method, like I said I am a little lost. But please give me your insight on my new approach.

Also thanks for the replies everyone!

Acecool loses everyone, he’s all in his own world.

As to Ozzy regarding Robot, he gave the first one as a brief example, and the second one was in more detail, incase you didn’t read close enough.

With the anti-afk script you’ve made, it seems like it would work, but it all depends on what your end result is striving to be.

Well I am happy to get away from timers and spamming the KeyPress hook. I wasn’t sure if getting the length of the vectors was expensive enough to care about.

Then do both? You don’t even need ridiculous console commands/code injection, anyone can use their keyboard software to write a macro in 10 seconds that will counter 99% of all anti-afk scripts for gmod. That demographic is such a small minority it’s not even worth mentioning. The guy just wants to write a script that will catch the average joe whole walks away from their computer for too long.

You’re going way over the top for what is being asked here. The guy actually had quite the elegant solution that could use a little touchup and I honestly have no idea where you’re going with what you’re saying. If checking for mouse movements is a must, then just cache gui.MousePos() and compare it at whatever intervals you’d like.