1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
proc = {}
commands = {}
-- simple example of a command definition
-- these could be defined throughout your admin scripts
commands["!broadcast"] = {
	enabled = true,
	permission = "any", -- handle this however you like
	arguments = 1,
	syntax = "<Message>",
	func = function(id,arguments)
		local message = arguments[1]
		if not message then return false end
		-- example of a good use for string.sub()
		-- prevent @C at end of message, showing message centered
		if message:sub(-2) == "@C" then message = message:sub(1, string.len(message) - 2) end
		msg(player(id,"name") .. " (broadcast): " .. message)
	end
}
-- check if the player has used a chat command
function proc.check(id,txt)
	-- gets the first word if it starts with a single "!" or "@" with optional space
	local cmd = txt:match("^([!|@][%w]+)[%s]?")
	if not cmd then return 0 end
	-- check if the command exists
	if commands[cmd] == nil then
		msg2(id,"Command not found")
		return 1
	end
	-- get everything after the first space
	local aftercmd = txt:match("[%s](.*)")
	-- send to command processor
	proc.process(id,cmd,aftercmd)
	return 1 -- don't output command to chat
end
function proc.process(id,cmd,txt)
	-- check if command is enabled
	if commands[cmd].enabled == false then
		msg2(id,"Command Disabled")
		return
	end
	-- get command arguments, we know how many there should be
	-- from the command definition
	local arg_count = commands[cmd].arguments
	local arguments = {}
	if arg_count > 0 then
		if not txt then -- argument(s) are missing, show how it should be
			msg2(id, "Wrong Syntax")
			msg2(id, "Syntax: " .. cmd .. " " .. commands[cmd].syntax)
			return
		end
		local count = 0
		for word in txt:gmatch("[^%s]+") do -- loop through each word
			count = count + 1
			if count <= arg_count then -- argument expected, let's cache it
				table.insert(arguments, word)
			else
				-- no more arguments expected
				-- let's just add this word to the last argument
				arguments[#arguments] = arguments[#arguments] .. " " .. word
			end
		end
		if count < arg_count then -- not enough arguments for this command
			msg2(id, "Wrong Syntax")
			msg2(id, "Syntax: " .. cmd .. " " .. commands[cmd].syntax)
			return
		end
	-- we didn't expect any arguments but something was included
	-- we'll pass it all as one argument
	elseif arg_count <= 0 and txt ~= nil and txt ~= " " then
		arguments = {txt}
	end
	-- check permissions here
	-- let's run the function for this command and pass the args
	local ret
	if #arguments > 0 then
		ret = commands[cmd].func(id,arguments)
	else
		ret = commands[cmd].func(id)
	end
	-- check the return value from the command function
	if ret ~= nil then
		-- something was returned, check for error
		-- you can do this however you like, it's just a bool in this example
		if ret == false then
			msg2(id,"You fail.")
			return
		end
	end
	-- command processed successfully, log it
	print("*** Command Used by " .. player(id,"name") .. "\n*** CMD: " .. cmd .. (txt and " " .. txt or ""))
end
-- of course, to get it started, we need to add a hook
addhook("say","proc.say")
function proc.say(id,txt)
	local ret = proc.check(id,txt)
	if ret ~= nil then return ret end
end
msg("Example Command Processor by VaiN")