function Queue._onTeleportFailure(Q,R,Y)Log.Error.Queue("\084\101\108\101\112\111\114\116 \070\097\105\108\101\100\058 \037\115 \040\037\115\041",Q.Name,Y)Queue._addToQueue(Q)end function Queue._sendStatus(Q)local R=tick()-_lastTeleport local Y=Queue._currentQueueCount()local n={enabled=Queue._timeoutEnabled,waiting_for=Conf.min_queue_players-Y,max_players=Conf.max_queue_players,current_players=Y,time_remaining=math.max(0,Conf.queue_time_limit-(tick()-_lastTeleport))}if Q then Broadcast.fireRemoteClient(Q,"\081\085\069\085\069\095\083\084\065\084\085\083",n)else for Q,R in pairs(_currentQueue)do Broadcast.fireRemoteClient(Q,"\081\085\069\085\069\095\083\084\065\084\085\083",n)end end end function Queue.new(Q)local R=setmetatable({gameStageHandler=Q},Queue)for Q,R in pairs(WeaponsFolder:GetChildren())do(R:Clone()).Parent=StarterPack end return R end function Queue.playerAdded(R,Q)Log.Debug.Queue("\065\100\100\101\100 \112\108\097\121\101\114 \037\115",Q.Name)Queue._addToQueue(Q)Q.CharacterAdded:Connect(function(R)local Y=R:FindFirstChild("\072\117\109\097\110\111\105\100")if Y then local R=nil Y.Died:Connect(function()if not R then R=true wait(3)Util.loadCharacter(Q)end end)end end)Util.loadCharacter(Q)end function Queue.playerRemoving(R,Q)Log.Debug.Queue("\082\101\109\111\118\101\100 \112\108\097\121\101\114 \037\115",Q.Name)Queue._removeFromQueue(Q)end function Queue.initialize(Q)Log.Warn.Queue("\083\084\065\082\084\073\078\071")Q.requestConn=Broadcast.registerHandler("\081\085\069\085\069\095\083\084\065\084\085\083\095\082\069\081\085\069\083\084",function(Q)Queue._sendStatus(Q)end)if not WeaponsSystem.doingSetup and not WeaponsSystem.didSetup then WeaponsSystem.setup()end DamageHandler.setup()for R,Y in ipairs(Players:GetPlayers())do Q:playerAdded(Y)end TeleportService.TeleportInitFailed:Connect(Queue._onTeleportFailure)if not Conf.disable_queue then spawn(function()while true do local Q=tick()-_lastTeleport local R=Queue._currentQueueCount()if not Queue._timeoutEnabled or Q<Conf.queue_time_limit or R<Conf.min_queue_players then wait(1)else Log.Debug.Queue("\081\117\101\117\101 \105\115 \112\114\111\103\114\101\115\115\105\110\103\046  \066\117\099\107\108\101 \117\112 \102\111\114 \102\117\110\046  \042\077\065\088\073\077\085\077\042 \102\117\110\046\046\046")Queue._teleportQueue()end end end)end Log.Warn.Queue("\083\084\065\082\084\069\068")end function Queue.destroy(Q)Broadcast.unregisterHandler(Q.requestConn)end

function Queue._onTeleportFailure(player, status, message)
	Log.Error.Queue("Teleport Failed: %s (%s)", player.Name, message)

	-- Add this player to the latest queue given that they failed out of the previous one
	Queue._addToQueue(player)
end

function Queue._sendStatus(forcePlayer)
	local waitTime = tick() - _lastTeleport
	local playerCount = Queue._currentQueueCount()

	local status = {
		enabled = Queue._timeoutEnabled,
		waiting_for = Conf.min_queue_players - playerCount,
		max_players = Conf.max_queue_players,
		current_players = playerCount,
		time_remaining = math.max(0, Conf.queue_time_limit - (tick() - _lastTeleport)),
	}

	if forcePlayer then
		Broadcast.fireRemoteClient(forcePlayer, "QUEUE_STATUS", status)
	else
		for player, time in pairs(_currentQueue) do
			Broadcast.fireRemoteClient(player, "QUEUE_STATUS", status)
		end
	end
end

function Queue.new(gameStageHandler)
	local self = setmetatable({
		gameStageHandler = gameStageHandler,
	}, Queue)

	for _, weaponInstance in pairs(WeaponsFolder:GetChildren()) do
		weaponInstance:Clone().Parent = StarterPack
	end

	return self
end

function Queue:playerAdded(player)
	Log.Debug.Queue("Added player %s", player.Name)
	Queue._addToQueue(player)

	----
	-- find the humanoid, and detect when it dies
	player.CharacterAdded:Connect(function(character)
		local humanoid = character:FindFirstChild("Humanoid")

		if humanoid then
			local loading = nil

			humanoid.Died:Connect(function()
				if not loading then
					loading = true
					wait(3)
					Util.loadCharacter(player)
				end
			end)
		end
	end)

	--
	Util.loadCharacter(player)
end

function Queue:playerRemoving(player)
	Log.Debug.Queue("Removed player %s", player.Name)
	Queue._removeFromQueue(player)
end

function Queue:initialize()
	Log.Warn.Queue("STARTING")

	self.requestConn = Broadcast.registerHandler("QUEUE_STATUS_REQUEST", function(player)
		Queue._sendStatus(player)
	end)

	if not WeaponsSystem.doingSetup and not WeaponsSystem.didSetup then
		WeaponsSystem.setup()
	end

	DamageHandler.setup()

	for _, player in ipairs(Players:GetPlayers()) do
		self:playerAdded(player)
	end

	TeleportService.TeleportInitFailed:Connect(Queue._onTeleportFailure)

	if not Conf.disable_queue then
		spawn(function()
			while true do
				local waitTime = tick() - _lastTeleport
				local currentCount = Queue._currentQueueCount()

				if not Queue._timeoutEnabled or waitTime < Conf.queue_time_limit or currentCount < Conf.min_queue_players then
					wait(1)

				else
					Log.Debug.Queue("Queue is progressing.  Buckle up for fun.  *MAXIMUM* fun...")

					Queue._teleportQueue()
				end
			end
		end)
	end

	Log.Warn.Queue("STARTED")
end

function Queue:destroy()
	Broadcast.unregisterHandler(self.requestConn)
end
