Admin Commands Only Working on One Player per Server

I was creating a ban/warning system where basically I type ;warnPlayer [player]. Then it gives me a UI where I send a personalized message to the player and a warning to follow the rules. The only issue is that it only works on one player per server.

If you don’t understand what I mean, look here:

  1. I use ;warnPlayer on Player1 to tell them to follow the rules. Everything works successfully.
  2. I use ;warnPlayer on another player, Player2 to be specific, because they were exploiting. However, it gives the warning to Player1 and Player2 gets no warning.

I scripted the commands based on Alvin Blox’s admin command video, and I added my own touch to give the GUIs and such.

Here is my script in ServerScriptService:

local commands = {}
local prefix = ";"

local function findPlayer(name) -- finds player object based on the username typed
	for i, player in pairs(game.Players:GetPlayers()) do
		if string.lower(player.Name) == name then
			return player
		else
			return nil
		end
	end
end

commands.warnplayer = function(sender, arguments) --the function
	if sender.Name == "ActiveFrenzy" then -- I am the only person who can do this
		for i, object in pairs(arguments) do
			print(object)
		end
		
		local recipientName = arguments[1]
		game.ReplicatedStorage.InputWarning:FireClient(sender) -- enables a GUI on my side so that I can send a personalized message that the entire server won't see
		
		if recipientName then
			local playerToSendWarningTo = findPlayer(recipientName)
			if playerToSendWarningTo then
				game.ReplicatedStorage.GiveWarningToServer.OnServerEvent:Connect(function(confirmer, message) -- this is fired when I give my input
					if confirmer == sender then -- makes sure an exploiter doesn't try to give random warnings to people
						if message == "Cancel" then return end -- this happens if I click the X button to cancel the GUI and the warning
						game.ReplicatedStorage.GiveWarning:FireClient(playerToSendWarningTo, message) -- gives warning to player
						return
					end
				end)
			end
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message, recipient) -- checks if player chatted
		message = string.lower(message)
		
		local splitString = message:split(" ")
		
		local slashCommand = splitString[1]
		local cmd = slashCommand:split(prefix)
		local cmdName = cmd[2]
		
		if commands[cmdName] then
			local arguments = {}
			for i = 2, #splitString, 1 do
				table.insert(arguments, splitString[i])
			end
			
			commands[cmdName](player, arguments) -- in this case, it fires warnPlayer()
		end
		
	end)
end)

I’m honestly really confused as to why this happens and would appreciate if anyone could help me figure this out, as I don’t want to warn the wrong players. Thank you in advance!

3 Likes

What happens if you print sender? Does it print a table, by any chance?

Would just like to point out that the findPlayer function won’t be working if the player’s name has upper case letters as you compare only one of them using string.lower.

1 Like

I think I may know what the error is. In the findPlayer() function, it goes through the players to see if the name matches the target Player’s name, however, if it does not match, it returns nil causing the for loop to end before it can move on to the next player. All you have to do is delete the else statement and put return nil under the for loop.

2 Likes

Yes you’re right but during a 2 player test atleast, that should not be affecting it.

EDIT: The 2 problems might be causing the failure, be sure to fix them.

1 Like

I believe it will still go wrong since alphabetically, it would check Player1 first and if it does not match, it returns nil and the for loop stops, skipping Player2.

1 Like

Yes, although no iterator follows an alphabetical order, it should always return nil as the function would either compare player1 with Player1 or player2 with Player2.

1 Like

For edit: When the findPlayer() function is activated, the name parameter is from arguments[1], which is made from a string.split() method on the message. On the message, the string.lower() method is used, causing the whole message and it’s arguments to be lowercase, so that could not be the problem.

1 Like

Yes you’re right just noticed that thanks for letting me know.

@ActiveFrenzy You can use table.find() to search through arrays, you dont need the loop for that. Or rather something simple as a :FindFirstChild() for instances. In this case:

local Players = game:GetService("Players")

function findPlayer(name)
    return Players:FindFirstChild(name)
end

Considering you don’t have any additional checks.

1 Like

Hi, I tried using your method but the same issue as before occurred. It sent the warning to the same player although I changed the parameter.

And to everyone else, I tried your solutions and a different issue popped up: it sent a warning to one player at first, but the second time I activated the command it sent to the first player and the new one. So the issue has changed but hasn’t been fixed, unfortunately.