I'm trying to make a sort of admin command type script, where you can type :moderator Player and it will grant that player moderator permissions, but when I try to index the player through game.Players:FindFirstChild(Player), it returns saying that the Player is not a valid member of game.Players.
if string.sub(chatInput.Text,1,string.len(":moderator")) == ":moderator" then local playerToAdd = string.sub(chatInput.Text,string.len(":moderator")+1) if game.Players:FindFirstChild(playerToAdd) then _M.addModerator(player.UserId,game.Players:FindFirstChild(playerToAdd).UserId) _M.getModeratorsInGame() else addMessage(player,(playerToAdd.." is not a valid member of players!")) print'could not find player!' end end
So say if I input the text, :moderator Player1 (Player1 IS a valid member, it's me..) it will respond saying "Player1 is not a valid member of players!"
For the full script
local ContextActionService = game:GetService("ContextActionService") local _M = require(game.ReplicatedStorage.MainModule) local MAX_MESSAGES = 10 local MESSAGE_HEIGHT = 25 local player = game.Players.LocalPlayer local messages = {} local chatMessageEvent = game.ReplicatedStorage.ChatMessage local chatScreen = script.Parent local chatFrame = chatScreen:WaitForChild("ChatFrame") local chatInput = chatFrame:WaitForChild("ChatInput") local messageFrame = chatFrame:WaitForChild("MessageFrame") local messageTemplate = messageFrame.Message:Clone() messageFrame.Message:Destroy() local function findFirstChild(instance, name) for _, child in pairs(instance:GetChildren()) do if string.lower(child.Name) == string.lower(name) then return child end end end local function addMessage(sender, message) if #messages >= MAX_MESSAGES then table.remove(messages, #messages):Destroy() end for i = 1, #messages do local y = (MAX_MESSAGES - i - 1) * MESSAGE_HEIGHT messages[i].Position = UDim2.new(0, 0, 0, y) end local newMessage = messageTemplate:Clone() newMessage.NameLabel.Text = "[".._M.PlayerType(game.Players.LocalPlayer.UserId).."] "..sender.Name .. ": " newMessage.Content.Text = message newMessage.Parent = messageFrame newMessage.Position = UDim2.new(0, 0, 0, (MAX_MESSAGES - 1) * MESSAGE_HEIGHT) newMessage.NameLabel.TextColor3 = _M.chatColors(_M.PlayerType(game.Players.LocalPlayer.UserId)) newMessage.Content.TextColor3 = Color3.new(1,1,1) table.insert(messages, 1, newMessage) end local function onFocusLost(enterPressed, inputObject) if enterPressed then if string.sub(chatInput.Text,1,string.len(":moderator")) == ":moderator" then local playerToAdd = string.sub(chatInput.Text,string.len(":moderator")+1) if game.Players:FindFirstChild(playerToAdd) then _M.addModerator(player.UserId,game.Players:FindFirstChild(playerToAdd).UserId) _M.getModeratorsInGame() else addMessage(player,(playerToAdd.." is not a valid member of players!")) print'could not find player!' end else local filtered = game:GetService("Chat"):FilterStringForBroadcast(chatInput.Text,game.Players.LocalPlayer) addMessage(player, filtered) chatMessageEvent:FireServer(filtered) chatInput.Text = "Click here or press '/' to type!" end end end local function onSlashPressed(actionName, inputState, inputObject) if inputState == Enum.UserInputState.End then chatInput:CaptureFocus() end end game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, false) chatMessageEvent.OnClientEvent:connect(addMessage) chatInput.FocusLost:connect(onFocusLost) ContextActionService:BindAction("Chatting", onSlashPressed, false, Enum.KeyCode.Slash)
^ Taken from the tutorial, but I have changed several elements to my needs using a module script, which personally has a lot of the dataStore services and keys for them, sooo.... ^
As a style suggestion: use msg:sub(...)
instead of string.sub(msg, ...)
because it is much shorter. Similarly for :len()
, but really you should use the #
operator instead of :len()
.
The problem is simple; you could debug it by printing the following:
print("/" .. playerToAdd .. "/")
If you input :moderator Player
, you will get the following as output:
/ Player1/
Notice that there is a an empty space between the
/
and Player1
?
There isn't a player in the game called " Player1", there is one in the game called "Player1". You have an extra space in front.
There are several paths forward.
Consider this correct, and it's the user using it wrong. You have to say moderator:Player1
with no space.
Modify the pattern to search for to be "moderator: "
instead of "moderator:"
(with a space at the end), which would make using a singe space mandatory
Actually allow any number of space characters after the :
I think (3) is the most ergonomic and reasonable option.
To accomplish it, first I want to refactor the code.
(TODO)
local moderator = chatInput.Text:match("^moderator:%s*(.+)") if moderator then local player = game.Players:FindFirstChild(moderator)