I have a function that I made for some admin I'm working on that will scan text to look for the Prefix character, which signals the beginning of a new command, and separates all the command sections from each other. This is supposed to allow the user to have multiple commands in one line.

For example:

:kill me :m I am dead!

Would run the kill command first, and then the message command, while still being on the same command line.

Also, I needed my function to check if the word after was a command name, so that you could put the prefix character in colons. This is the main reason why I just didn't use string.gmatch

For example:

:m Rules: There are none!

The everything after "Rules:" would be cut off if I simply used string.gmatch because of the colon in the message.

My function works well but it's horribly expensive to run through, so I was wondering if there is a better way to do it. If you need anything to be explained, let me know (It is a bit complex to read!)

My function:

local returnCommandSections = function(text) -- Separates multiple commands and their arguments after each prefix (Ex: :kill me :m Ded :m Placing at xx:40)
	local sections = {}
	local textBrokenDown = {} -- Array of all the characters in the text
	
	for x in string.gmatch(text, ".") do -- Separates all the characters into separate strings, then inserts them in the textBrokenDown array
		table.insert(textBrokenDown, x) 
	end
	
	for i, v in next, textBrokenDown do -- Main loop that goes through each character in textBrokenDown
		if v == _settings.Prefix then 
			local startPrefixIndex = i
			local newSection = {}
			for v = i, #textBrokenDown do
				if textBrokenDown[v] ~= _settings.Prefix then -- If statement that checks whether or not the prefix character goes in the section or starts a new section
					table.insert(newSection, textBrokenDown[v])
				elseif textBrokenDown[v] == _settings.Prefix and v ~= startPrefixIndex then
					local everythingAfter = table.concat(textBrokenDown, "", v)
					local command = returnArgs (everythingAfter:sub(2)) -- This function just checks if the word after is a command
					
					if command and command.Name ~= nil then
						break
					else
						table.insert(newSection, everythingAfter)
						table.insert(sections, table.concat(newSection))
						return sections
					end 
				end
			end
			table.insert(sections, table.concat(newSection))
		end
	end
		
	return sections
end	

2 comments

1

Not gonna read through the code as it will take too long, but perhaps you can remove the first detected command from the string (i.e.":kill me :m I am dead!" --> ":m I am dead") after it is executed, and then reiterate that process until there's no more commands detected.

0

smart