--Respond to commands
re.OnServerEvent:Connect(function(plr, instruction, value, targetId)
	
	if table.find(admins, plr.UserId) then
		local adminChar = plr.Character
		
		local targetPlr
		if tonumber(targetId) then
			targetPlr = game.Players:GetPlayerByUserId(tonumber(targetId))
		end
		
		--CHARACTER COMMANDS
		if tonumber(targetId) then
			targetId = tonumber(targetId)
			if targetPlr and targetPlr.Character then
				local targetChar = targetPlr.Character
				
				if instruction == "GO TO" and adminChar then
					adminChar.HumanoidRootPart.CFrame = targetChar.HumanoidRootPart.CFrame
				elseif instruction == "BRING" then
					targetChar.HumanoidRootPart.CFrame = adminChar.HumanoidRootPart.CFrame
					
				elseif instruction == "FREEZE" then
					targetChar.HumanoidRootPart.Anchored = true
				elseif instruction == "UNFREEZE" then
					targetChar.HumanoidRootPart.Anchored = false
					
				elseif instruction == "SPEED" and tonumber(value) then
					targetChar.Humanoid.WalkSpeed = tonumber(value)
				elseif instruction == "JUMP" and tonumber(value) then
					if targetChar.Humanoid.UseJumpPower == true then
						targetChar.Humanoid.JumpPower = tonumber(value)
					else
						targetChar.Humanoid.JumpHeight = tonumber(value)
					end
					
				elseif instruction == "HEALTH" and tonumber(value) then
					targetChar.Humanoid.Health = tonumber(value)
				end
			end
			
		--MODERATION COMMANDS
			if instruction == "MUTE" and tonumber(value) then
				
				local muteStart = os.time()
				local muteEnd = muteStart + tonumber(value)
				
				local data = {muteEnd}
				
				pcall(function()
					ds:SetAsync(targetId .. "Muted", data)
					
					if targetPlr then
						channel:MuteSpeaker(targetPlr.Name)
						
						task.wait(tonumber(value))
						if targetPlr then
							channel:UnmuteSpeaker(targetPlr.Name)
						end
					else
						ms:PublishAsync(muteTopic, {targetId, tonumber(value)})
					end
				end)
			elseif instruction == "UNMUTE" then
				pcall(function()
					ds:RemoveAsync(targetId .. "Muted")
					
					if targetPlr then
						channel:UnmuteSpeaker(targetPlr.Name)
					else
						ms:PublishAsync(unmuteTopic, {targetId})
					end
				end)
				
			elseif instruction == "BAN" and tonumber(value[1]) then
				local banStart = os.time()
				local banEnd = banStart + tonumber(value[1])
				
				local banReason = value[2]
				
				local data = {banEnd, banReason}
				
				pcall(function()
					ds:SetAsync(targetId .. "Banned", data)
					
					local dateInfo = os.date("!*t", data[1])
					local dateFormatted = dateInfo["day"] .. "/" .. dateInfo["month"] .. "/" .. dateInfo["year"] .. "  " .. dateInfo["hour"] .. ":" .. dateInfo["min"] .. ":" .. dateInfo["sec"]
					local banMessage = "Banned for: " .. data[2] .. " | Ends: " .. dateFormatted
					
					if targetPlr then
						targetPlr:Kick(banMessage)
						
					else
						ms:PublishAsync(banTopic, {targetId, banMessage})
					end
				end)
			elseif instruction == "UNBAN" then
				pcall(function()
					ds:RemoveAsync(targetId .. "Banned")
				end)
				
			elseif instruction == "KICK" then
				if targetPlr then
					targetPlr:Kick(value)
				else
					ms:PublishAsync(kickTopic, {targetId, value})
				end
			end
			
		--COMMAND BAR
		elseif instruction == "COMMAND BAR" and value then
			pcall(function()
				loadstring(value)()
			end)
			
		--SYSTEM COMMANDS
		else
			if instruction == "ANNOUNCE" and value and targetId then
				local success, filtered = pcall(function()
					local filteredTextResult = ts:FilterStringAsync(value, plr.UserId):GetNonChatStringForBroadcastAsync()
					return filteredTextResult
				end)
				if success and filtered then
					
					if targetId == "GLOBAL" then
						ms:PublishAsync(announcementTopic, {filtered})
						
					else
						re:FireAllClients("ANNOUNCE", filtered)
					end
				end
					
			elseif instruction == "SHUT DOWN" then
				shuttingDown = true
				
				for i, plr in pairs(game.Players:GetPlayers()) do
					plr:Kick("This server is shutting down.")
				end
			end
		end
	end
end)