Simple Chat Command System (for coders)

I made this a while ago for my gamemode but now i decided to release it.

[lua]
//Credits: SweetTea.
if(SERVER) then
local meta = FindMetaTable(“Player”)

CHAT_COMMANDS = {}

function IsValidChatCommand©
if© then
for k,v in pairs(CHAT_COMMANDS) do
if(v.c == c) then
return true
end
end
end
end

function AddChatCommand(name, func)
table.insert(CHAT_COMMANDS,{c = name, f=func})
end

function CommandPlayerSay(ply, t, p)
if(string.find(t,"/")) then
local code = t
local exp = string.Explode(" “, t)
table.remove(exp, 1)
local real = string.Explode(” “, string.Explode(”/", code)[2])[1]
if!(tostring(string.ToTable(code)[1]) == tostring("/")) then
return t
else
if(IsValidChatCommand(real)) then
for k,v in pairs(CHAT_COMMANDS) do
if(v.c == real) then
v.f(ply, exp)
return “”
end
end
end
end
end
end
hook.Add( “PlayerSay”, “CommandPlayerSay”, CommandPlayerSay );
end

[/lua]

Examples:

[lua]
AddChatCommand(“hello”, function(ply, arg)
ply:ChatPrint(“Hello !”)
PrintTable(arg)
end)

AddChatCommand(“rtd”, function(ply, arg)
if(arg[1]) then
if(arg[2]) then
if(tonumber(arg[1])) then
if(tonumber(arg[2])) then
local a1 = tonumber(arg[1])
local a2 = tonumber(arg[2])
if(a1 > 0 and a1 < a2) then
if(a2 > 0 and a2 > a1) then
local r = math.random(a1, a2)
for k,v in pairs(player.GetAll()) do
v:ChatPrint(ply:Nick() … " Rolled the dice and got number " … r)
end
end
end
end
end
end
end
end)

So you type /rtd <1-100> <1-100>
Example:
/rtd 1 15

It will roll a number between 1 and 15.
[/lua]

Type /hello in your chat to see what happens.

It also supports arguments like /hello 1 2 3 4 5 bla bla bla bla123

You should really use tab when you code.

At least this uses arg as a table not a string, but why do people who make chat command systems never use cmd, the 2nd arg in concommand.Add’s callback?

That way you can make a concommand with args as well as a chat command without doing anything differently.

Erk. You’re making it much more complicated than it has to be. string.match or string.find will do all the work you’re doing by yourself, and calling string.Explode three times in a row is rarely ever necessary.

All you really need is something like this:

[lua]
– Hold chat commands, indexed by command name
local commands = {}

– Add a chat command.
– The hook should take the same arguments as handleChatCommands
– except that ‘text’ will be the text after the command (or false
– if there wasn’t any).
local function chatcmd(name, hook)
commands[name] = hook
end

– The hook to parse for and run chat commands.
local function handleChatCommands(ply, text, teamonly, isdead)
– check for a command
local cmd, msg = string.match("^/(%S)%s*(.)%s$")
if not cmd then return end

-- real command?
if not commands[cmd] then
	ply:ChatPrint("Bad chat command: '" .. cmd .. "'")
	return true
end

-- let the hook deal with it
commands[cmd](ply, #msg &gt; 0 and msg, teamonly, isdead)
return true

end
hook.Add(“OnPlayerChat”, handleChatCommands)
[/lua]

[lua]
– Rolls dice. Derp.
chatcmd(“roll”, function(ply, text, teamonly, isdead)
if isdead then
ply:ChatPrint(“Dead men roll no dice.”)
return
end

-- Default to 1d6
local num, sides = 1, 6

-- Did he actually specify dice to roll?
if text then
	num, sides = string.match(text, "%s*(-?%d+)%s*d%s*(-?%d+)%s*")
	if not num then
		ply:ChatPrint("Huh? Try: /roll 2d6")
		return
	end
	num = tonumber(num)
	sides = tonumber(sides)

	-- For sanity.
	if num &lt; 1 or num &gt; 10 or sides &lt; 2 or sides &gt; 100 then
		ply:GetPrint("Don't be silly.")
		return
	end
end

local total = 0
for i = 1, num do
	total = total + math.random(1, sides)
end

ply:ChatPrint(string.format("Rolled %id%i and got %i.", num, sides, total))
local str = string.format("%s rolls %id%i and gets %i.", ply:Nick(), num, sides, total)
for k, v in pairs(player.GetAll()) do
	if v ~= ply then
		v:ChatPrint(str)
	end
end

end)
[/lua]

Aint got no time for that


(User was banned for this post ("Image macro" - Swebonny))