So i have this give tool command, but it doesn’t work with spaces. How can i make the tool argument accept spaces in the string? (e.g “/give player Special Tool”)
-- Handle /give plr tool command to give players special tools
if giveCommand then
local args = {}
-- Split message into individual words for command arguments
for word in message:gmatch("%S+") do
table.insert(args, word)
end
-- Parse target player and tool name
local targetPlayerName = args[2]
local toolName = args[3] -- Keep original case for tool name check
-- Determine if "all" is being used as the tool name
local giveToAllTools = (toolName and string.lower(toolName) == "all")
-- Look for a specific tool by matching lowercase names in toolsFolder
local tool = nil
if not giveToAllTools then
for _, t in pairs(toolsFolder:GetChildren()) do
if string.lower(t.Name) == string.lower(toolName) then
tool = t
break
end
end
end
-- Check if tool exists if "all" is not specified
if not giveToAllTools and not tool then
sendNotifEV:FireClient(player, "Invalid Tool", "Tool not found. Please check the name and try again.")
return
end
-- Distribute tool based on the target player argument
if targetPlayerName == "me" then
-- Give tool to the player who issued the command
if giveToAllTools then
-- If "all" is specified, give all tools in the toolsFolder
for _, t in pairs(toolsFolder:GetChildren()) do
local clone = t:Clone()
clone.Parent = player.Backpack
end
sendNotifEV:FireClient(player, "All Tools Given", "All tools were successfully awarded to you.")
else
local clone = tool:Clone()
clone.Parent = player.Backpack
sendNotifEV:FireClient(player, "Tool Given", tool.Name.." was successfully awarded to you.")
end
elseif targetPlayerName == "all" then
-- Give all tools to all players in the aliveTeam
for _, p in pairs(Players:GetPlayers()) do
if p.Team == aliveTeam then
if giveToAllTools then
-- Give all tools to the player
for _, t in pairs(toolsFolder:GetChildren()) do
local clone = t:Clone()
clone.Parent = p.Backpack
end
else
local clone = tool:Clone()
clone.Parent = p.Backpack
end
end
end
if giveToAllTools then
sendNotifEV:FireClient(player, "All Tools Given", "All tools were successfully awarded to all players in the server.")
sendNotifEV:FireAllClients("All Tools Given", "All tools were given to all players in the server.")
else
sendNotifEV:FireClient(player, "Tools Given", tool.Name.." was successfully awarded to all players in the server.")
sendNotifEV:FireAllClients("Tools Given", tool.Name.." was given to all players in the server.")
end
else
-- Try to find the specified target player by name
local targetPlayer = game.Players:FindFirstChild(targetPlayerName)
if targetPlayer and targetPlayer.Team == aliveTeam then
if giveToAllTools then
-- Give all tools to the specified player
for _, t in pairs(toolsFolder:GetChildren()) do
local clone = t:Clone()
clone.Parent = targetPlayer.Backpack
end
sendNotifEV:FireClient(player, "All Tools Given", "All tools were successfully awarded to "..targetPlayer.DisplayName)
else
local clone = tool:Clone()
clone.Parent = targetPlayer.Backpack
sendNotifEV:FireClient(player, "Tool Given", tool.Name.." was successfully awarded to "..targetPlayer.DisplayName)
end
else
sendNotifEV:FireClient(player, "Invalid Command", "That player or tool was not found. Make sure you aren't using their DisplayName, and that the player is alive.")
end
end
end
I didn’t have enough time to read all of your code, but assuming those are the arguments you would essentially replace the empty table with it.
-- Handle /give plr tool command to give players special tools
if giveCommand then
local args = message:split(" ")
-- Parse target player and tool name
local targetPlayerName = args[2]
local toolName = args[3] -- Keep original case for tool name check
-- Determine if "all" is being used as the tool name
local giveToAllTools = (toolName and string.lower(toolName) == "all")
-- Look for a specific tool by matching lowercase names in toolsFolder
local tool = nil
if not giveToAllTools then
for _, t in pairs(toolsFolder:GetChildren()) do
if string.lower(t.Name) == string.lower(toolName) then
tool = t
break
end
end
end
-- Check if tool exists if "all" is not specified
if not giveToAllTools and not tool then
sendNotifEV:FireClient(player, "Invalid Tool", "Tool not found. Please check the name and try again.")
return
end
-- Distribute tool based on the target player argument
if targetPlayerName == "me" then
-- Give tool to the player who issued the command
if giveToAllTools then
-- If "all" is specified, give all tools in the toolsFolder
for _, t in pairs(toolsFolder:GetChildren()) do
local clone = t:Clone()
clone.Parent = player.Backpack
end
sendNotifEV:FireClient(player, "All Tools Given", "All tools were successfully awarded to you.")
else
local clone = tool:Clone()
clone.Parent = player.Backpack
sendNotifEV:FireClient(player, "Tool Given", tool.Name.." was successfully awarded to you.")
end
elseif targetPlayerName == "all" then
-- Give all tools to all players in the aliveTeam
for _, p in pairs(Players:GetPlayers()) do
if p.Team == aliveTeam then
if giveToAllTools then
-- Give all tools to the player
for _, t in pairs(toolsFolder:GetChildren()) do
local clone = t:Clone()
clone.Parent = p.Backpack
end
else
local clone = tool:Clone()
clone.Parent = p.Backpack
end
end
end
if giveToAllTools then
sendNotifEV:FireClient(player, "All Tools Given", "All tools were successfully awarded to all players in the server.")
sendNotifEV:FireAllClients("All Tools Given", "All tools were given to all players in the server.")
else
sendNotifEV:FireClient(player, "Tools Given", tool.Name.." was successfully awarded to all players in the server.")
sendNotifEV:FireAllClients("Tools Given", tool.Name.." was given to all players in the server.")
end
else
-- Try to find the specified target player by name
local targetPlayer = game.Players:FindFirstChild(targetPlayerName)
if targetPlayer and targetPlayer.Team == aliveTeam then
if giveToAllTools then
-- Give all tools to the specified player
for _, t in pairs(toolsFolder:GetChildren()) do
local clone = t:Clone()
clone.Parent = targetPlayer.Backpack
end
sendNotifEV:FireClient(player, "All Tools Given", "All tools were successfully awarded to "..targetPlayer.DisplayName)
else
local clone = tool:Clone()
clone.Parent = targetPlayer.Backpack
sendNotifEV:FireClient(player, "Tool Given", tool.Name.." was successfully awarded to "..targetPlayer.DisplayName)
end
else
sendNotifEV:FireClient(player, "Invalid Command", "That player or tool was not found. Make sure you aren't using their DisplayName, and that the player is alive.")
end
end
end
Actually, nevermind. I just realized you were using the string.match function. I will try and set up something like this in a game so that I can test it and come up with results.
just get the players to put an underscore (look at Minecraft commands for example). If the tool names have spaces in them then you can use string.gsub to replace the underscores with spaces
So basically this is what I assumed your system looked like.
This should solve the problem, but it would have to be done this way.
You can use this as an example if you want to keep your current method, but this way makes it pretty easy in my opinion to add commands and stuff. Essentially all you have to do is make a command in the “Commands” table with an array of the arguments it takes and a function in the last spot.
Here is the code. Enjoy!
local Players = game:GetService("Players")
local Storage = game:GetService("ServerStorage")
local Folder = Storage:WaitForChild("Tools")
local Prefix = "!"
local Commands = {
["give"] = {"Player", "Tool", function(Player, Args)
if not Player or not Player:IsA("Player") then return end
local ToolName = table.concat(Args, " ")
if ToolName == "all" then
for _, child in pairs(Folder:GetChildren()) do
if not child:IsA("Tool") then continue end
child:Clone().Parent = Player:WaitForChild("Backpack")
end
end
for _, child in pairs(Folder:GetChildren()) do
if not child:IsA("Tool") then continue end
if child.Name:lower():sub(1, #ToolName) == ToolName then
child:Clone().Parent = Player:WaitForChild("Backpack")
break
end
end
end;}
}
local function DoForAll(Message)
if Message:sub(1, 1) ~= Prefix then return end
local Splits = Message:sub(2):lower():split(" ")
local CommandTable = Commands[Splits[1]]
if not CommandTable then return end
for i = 1, #CommandTable - 1 do
if not Splits[i] then return end
end
if Splits[2] ~= "all" then return end
table.remove(Splits, 1)
table.remove(Splits, 1)
for _, player in pairs(Players:GetPlayers()) do
CommandTable[#CommandTable](player, Splits)
end
end
local function ExecuteCommand(Message)
if Message:sub(1, 1) ~= Prefix then return end
local Splits = Message:sub(2):lower():split(" ")
local CommandTable = Commands[Splits[1]]
if not CommandTable then return end
for i = 1, #CommandTable - 1 do
if not Splits[i] then return end
end
if Splits[2] == "all" then DoForAll(Message) return end
local Player = nil
for _, player in pairs(Players:GetPlayers()) do
if player.Name:lower():sub(1, #Splits[2]) ~= Splits[2] and player.DisplayName:lower():sub(1, #Splits[2]) ~= Splits[2] then continue end
Player = player
end
table.remove(Splits, 1)
table.remove(Splits, 1)
CommandTable[#CommandTable](Player, Splits)
end
local function PlayerAdded(Player)
Player.Chatted:Connect(function(Message)
ExecuteCommand(Message)
end)
end
Players.PlayerAdded:Connect(PlayerAdded)
Here’s how i structured my code. It doesn’t work or error. What am i doing wrong?
local Commands = {
["setDiff"] = {"Difficulty", function(Player, Args)
local difficultyValue = tonumber(Args[1])
if difficultyValue and difficultyValue >= 1 then
difficulty = difficultyValue
refreshGameForDifficulty()
sendNotifEV:FireAllClients("Difficulty Adjustment", "The round difficulty was set to " .. difficulty .. " by " .. Player.DisplayName .. ".")
else
sendNotifEV:FireClient(Player, "Invalid Difficulty", "Please enter a valid difficulty level.")
end
end};
["setRate"] = {"SpawnRate", function(Player, Args)
local spawnRateValue = tonumber(Args[1])
if spawnRateValue and spawnRateValue > 0 then
minSpawnInterval, maxSpawnInterval = spawnRateValue, spawnRateValue
sendNotifEV:FireAllClients("Spawn Rate Adjustment", "The zombie spawn rate was set to " .. spawnRateValue .. " by " .. Player.DisplayName .. ".")
else
sendNotifEV:FireClient(Player, "Invalid Spawn Rate", "Please enter a valid spawn rate.")
end
end};
["resetRate"] = {"Reset", function(Player)
minSpawnInterval = math.max(BASE_MIN_SPAWN_INTERVAL - math.log(difficulty + 1), 1)
maxSpawnInterval = math.max(BASE_MAX_SPAWN_INTERVAL - math.log(difficulty + 1), 2)
sendNotifEV:FireAllClients("Reset Spawn Rate", "The zombie spawn rate was reset by ".. Player.DisplayName .. ".")
end};
["god"] = {"Player", function(Player, Args)
local targetPlayer = Args[1] == "me" and Player or Players:FindFirstChild(Args[1])
if targetPlayer then
local targetChar = targetPlayer.Character or targetPlayer.CharacterAdded:Wait()
local ff = targetChar:FindFirstChildOfClass("ForceField")
if ff then ff:Destroy() else Instance.new("ForceField", targetChar) end
sendNotifEV:FireClient(targetPlayer, "Forcefield Toggled", "Your forcefield was toggled by " .. Player.DisplayName .. ".")
else
sendNotifEV:FireClient(Player, "Invalid Player", "Player not found.")
end
end};
["give"] = {"Player", "Tool", function(Player, Args)
local targetPlayerName, toolName = Args[1], Args[2]
local targetPlayer = targetPlayerName == "me" and Player or Players:FindFirstChild(targetPlayerName)
local tool = toolsFolder:FindFirstChild(toolName)
if targetPlayer and tool then
tool:Clone().Parent = targetPlayer.Backpack
sendNotifEV:FireClient(Player, "Tool Given", toolName .. " given to " .. targetPlayer.DisplayName)
else
sendNotifEV:FireClient(Player, "Invalid Command", "Check player and tool name.")
end
end};
}
local function DoForAll(Message)
if Message:sub(1, 1) ~= COMMAND_PREFIX then return end
local Splits = Message:sub(2):lower():split(" ")
local CommandTable = Commands[Splits[1]]
if not CommandTable then return end
for _, player in pairs(Players:GetPlayers()) do
CommandTable[#CommandTable](player, {table.unpack(Splits, 2)})
end
end
local function ExecuteCommand(Message, Player)
if Message:sub(1, 1) ~= COMMAND_PREFIX then return end
local Splits = Message:sub(2):lower():split(" ")
local CommandTable = Commands[Splits[1]]
if not CommandTable then return end
table.remove(Splits, 1)
CommandTable[#CommandTable](Player, Splits)
end
Players.PlayerAdded:Connect(function(player)
player.Chatted:Connect(function(message)
if player.UserId == game.CreatorId or player.UserId == game.PrivateServerOwnerId then
ExecuteCommand(message, player)
end
end)
end)
Nah I was under the assumption that every single command was going to need a player.
You kind of have to edit the lines where I removed the first two arguments. Just do something like remove the first one, then use an if statement on the second one to check if u should remove another one.
Like this:
if CommandTable[1]:lower() == "player" then table.remove(Splits, 1) end
Essentially just replace the second table.remove with this. From now on, you have to make sure you are using some variation (any amount of capital or lowercase letters) when you want a player to be an arguement. For example, this command has player as an argument so I used “Player” in the table. All of this is to say don’t make “plr” an argument.