Script will, out of nowhere, stop my server

So, I made this script with my blood, sweat, and tears. I think it’s a very cool and neat addition to my TTT server. Unfortunately, the script will continuously crash/stop my server.

What the script does is it respawns everyone on the server two times. Once when the round ends, and again when the end round timer hits 0:14. It will also give randomized weapons on spawn.

It also keeps track of their kills, and rewards the winner points based on kill count.

There are no errors in console whatsoever. The server will just stop printing anything in console and all players on at the time will lose connection. Usually, the server will need to be manually restarted.

I’m at a loss at why this would happen. If anyone could help me or, at the very least, point me in the right direction I’d greatly appreciate it.

Here’s the script:



if SERVER then

	-- Initialize PRDM vars
	local prdmWinner = ""
	local prdmWinnerKC = 0
	local prdmWinnerENT = ""
	
	local pistolWepID = { "pistol", "magnum", "revolver" }
	local rifleWepID = { "m16", "rifle", "ak47", "galil", "famas", "m3", "p90", "sg552", "shotgun", "sledge" }
	local specialWepID = { "awp", "dragonsbreath", "medgun", "jihad" }
	local wepID = ""
			
	local pistolWepName = { "Five-SeveN", "Magnum", "Desert Eagle" }
	local rifleWepName = { "M16", "Scout", "AK47", "Galil", "Famas", "M3", "P90", "SG552", "XM1014", "useless piece of sh- I mean a H.U.G.E-249" }
	local specialWepName = { "AWP", "Dragon's Breath", "Med-Gun", "Billy Bomb" }
	local wepName = ""

	-- PRDM Respawn function
	function prdmRespawn()
		for k, v in pairs(player.GetAll()) do
			
			-- Intializing random weapon vars
			local randWepCategory = math.random(1,100)
			local randPistol = math.random(1,3)
			local randRifle = math.random(1,10)
			local randSpecial = math.random(1,4)
			
			-- Handling weapon IDs and names
			-- Category: Pistol
			if randWepCategory <= 45 then
				wepID = pistolWepID[randPistol]
				wepName = pistolWepName[randPistol]
			-- Category: Rifle/Shotgun
			elseif randWepCategory > 45 and randWepCategory <= 90 then
				wepID = rifleWepID[randRifle]
				wepName = rifleWepName[randRifle]
			-- Category: Special
			else
				wepID = specialWepID[randSpecial]
				wepName = specialWepName[randSpecial]
			end
				
			-- PointShop perma weapon checker
			local permWepCount = v:PS_NumItemsEquippedFromCategory('Weapons')
			
			-- The actual respawn
			if !v:Alive() and IsValid(v) then
				-- Find corpse
				local corpse = corpse_find(v)
				if corpse then corpse_remove(corpse) end
				
				-- RESPAWN
				v:SpawnForRound()
				
				-- Give random weapon
				-- zm IDs
				if permWepCount == 0 then
					if wepID == "pistol" or wepID == "revolver" or wepID == "rifle" or wepID == "shotgun" or wepID == "sledge" then
						v:Give("weapon_zm_" .. wepID)
						v:SelectWeapon("weapon_zm_" .. wepID)
					-- ttt IDs
					else
						v:Give("weapon_ttt_" .. wepID)
						v:SelectWeapon("weapon_ttt_" .. wepID)
					end
					-- Print out weapon received
					v:PrintColor(WF_TC_WHITE, "You've been given a ", WF_TC_RED, wepName, WF_TC_WHITE, "!")
				end
			end
		end
	end

	hook.Add("TTTEndRound", "PRDM", function()
	
		-- Setting to default values.
		prdmWinner = ""
		prdmWinnerKC = 0
		prdmWinnerENT = ""
		
		-- Set PRDM kill counts back to 0 and health to 100.
		for k, v in pairs(player.GetAll()) do
			v:SetFrags(0)
			v:SetHealth(100)
		end
		
		-- Set PRDM state and respawn first time.
		prdmState = true
		prdmRespawn()
		
		-- PRDM respawn timer
		timer.Simple(15, function()
			prdmRespawn()
		end )
		
		-- Timer for kill count check and rewards.
		timer.Simple(27, function()
			-- Check kill counts and find winner.
			for k, v in pairs(player.GetAll()) do
				if v:Frags() > prdmWinnerKC then
					prdmWinnerKC = v:Frags()
					prdmWinner = v:Name()
					prdmWinnerENT = v
				end
			end
			
			-- If winner got more than 1 kill
			if prdmWinnerKC > 1 then
				for k, ply in pairs(player.GetAll()) do
					ply:PrintColor(WF_TC_RED, prdmWinner .. " won ", WF_TC_WHITE, "PRDM with ", WF_TC_RED, prdmWinnerKC .. " kills", WF_TC_WHITE, "!")
				end
				prdmWinnerENT:PS_Notify("You've been given ", (25 * prdmWinnerKC), " points for winning PRDM!")
				prdmWinnerENT:PS_GivePoints(25 * prdmWinnerKC)
			-- If winner only got 1 kill
			elseif prdmWinnerKC == 1 then
				for k, ply in pairs(player.GetAll()) do
					ply:PrintColor(WF_TC_RED, prdmWinner .. " won ", WF_TC_WHITE, "PRDM with ", WF_TC_RED, prdmWinnerKC .. " kill", WF_TC_WHITE, "!")
				end
				prdmWinnerENT:PS_Notify("You've been given ", (25 * prdmWinnerKC), " points for winning PRDM!")
				prdmWinnerENT:PS_GivePoints(25 * prdmWinnerKC)
			-- If no one won PRDM
			else
				for k, ply in pairs(player.GetAll()) do
					ply:PrintColor(WF_TC_RED, "No one won ", WF_TC_WHITE, "PRDM!")
				end
			end
			
			-- Set prdm state to false
			prdmState = false
		end )
	
	end )

	--[[hook.Add("TTTPrepareRound", "EndPRDM", function()
		
		-- Stop PRDM
		prdmState = false
		timer.Remove("PRDMRespawnTimer")
		timer.Remove("PRDMWinnerCheckTimer")
		
	end )]]

	hook.Add("PlayerDeath", "PrintDeaths", function(victim, weapon, attacker)
		
		-- Check if PRDM and attacker and victim are players and valid
		if prdmState == true and IsValid(victim) and IsValid(attacker) and victim:IsPlayer() and attacker:IsPlayer() then
			
			-- Suicide
			if (victim == attacker) then
				for k, ply in pairs(player.GetAll()) do
					ply:PrintColor(WF_TC_RED, victim:Name(), WF_TC_WHITE, " commited suicide.")
				end
			-- Actual kill
			else
				for k, ply in pairs(player.GetAll()) do
					ply:PrintColor(WF_TC_RED, victim:Name(), WF_TC_WHITE, " was killed by ", WF_TC_RED, attacker:Name(), WF_TC_WHITE, ".")
				end
				-- Add to kill count and give points.
				attacker:AddFrags(1)
				attacker:PS_Notify("You've been given 5 points for killing someone in PRDM!")
				attacker:PS_GivePoints(5)
			end
			
		end
		
	end )


end


Bump because I still need help, if anyone is willing to offer.

I would try removing bits of code until it doesn’t crash anymore.

Add debug messages to see where and when things are getting called.

I’ve tried this, even stripping it to it’s bare basics and just respawning. The version excluded kill counts and everything. It was strictly respawning.

The server still crashed.

Could it be a problem with timers? This has me so confused. There are no errors in console whatsoever. The server doesn’t stop every end round, and even sometimes stops mid-round.

I’m at a loss. :confused:

If there are no errors in the console, add some.
If youhave to, put a print("LOADING LINE #334) to every and each line, until you find the source of the problem.

Also, when does the server crash exactly?

Can you post the code for these two functions:

corpse_find
corpse_remove

I made prints like this to the console and it didn’t help anything as the server usually just crashes at 0:00 in end round phase.

[editline]20th January 2017[/editline]

The functions are used from ULX TTT commands.



--[[corpse_find][Finds the corpse of a given player.]
@param  {[PlayerObject]} v       [The player that to find the corpse for.]
--]]
function corpse_find(v)
	for _, ent in pairs( ents.FindByClass( "prop_ragdoll" )) do
		if ent.uqid == v:UniqueID() and IsValid(ent) then
			return ent or false
		end
	end
end

--[[corpse_remove][removes the corpse given.]
@param  {[Ragdoll]} corpse [The corpse to be removed.]
--]]
function corpse_remove(corpse)
	CORPSE.SetFound(corpse, false)
	if string.find(corpse:GetModel(), "zm_", 6, true) then
		corpse:Remove()
	elseif corpse.player_ragdoll then
		corpse:Remove()
	end
end


It all looks fine at a glance so I don’t know.

But what is the point of this

[lua]
prdmRespawn()

	-- PRDM respawn timer
	timer.Simple(15, function()
		prdmRespawn()
	end )

[/lua]

Put your function in the TTTBeginRound or whatever hook TTT uses, don’t rely on these things.

Also I would change all of those timer.Simple’s to each individual timer.Create’s. If something happens and you restart the round within those 15 seconds the function will be called twice instead of once with a timer.Simple

That would defeat the entire purpose of the script. The prdmRespawn function was created by me to respawn IN END ROUND.