Update Lib ChatCmdBuilder
This commit is contained in:
parent
ebf4316594
commit
aa0cc1ab53
2 changed files with 116 additions and 41 deletions
|
@ -19,7 +19,7 @@ globals = {
|
||||||
}
|
}
|
||||||
|
|
||||||
read_globals = {
|
read_globals = {
|
||||||
string = {fields = {"split"}},
|
string = {fields = {"split", "trim"}},
|
||||||
table = {fields = {"copy", "getn"}},
|
table = {fields = {"copy", "getn"}},
|
||||||
|
|
||||||
"dump", "DIR_DELIM",
|
"dump", "DIR_DELIM",
|
||||||
|
|
|
@ -32,14 +32,28 @@ local function escape(char)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ChatCmdBuilder.build(func)
|
local dprint = function() end
|
||||||
|
|
||||||
|
ChatCmdBuilder.types = {
|
||||||
|
pos = "%(? *(%-?[%d.]+) *, *(%-?[%d.]+) *, *(%-?[%d.]+) *%)?",
|
||||||
|
text = "(.+)",
|
||||||
|
number = "(%-?[%d.]+)",
|
||||||
|
int = "(%-?[%d]+)",
|
||||||
|
word = "([^ ]+)",
|
||||||
|
alpha = "([A-Za-z]+)",
|
||||||
|
modname = "([a-z0-9_]+)",
|
||||||
|
alphascore = "([A-Za-z_]+)",
|
||||||
|
alphanumeric = "([A-Za-z0-9]+)",
|
||||||
|
username = "([A-Za-z0-9-_]+)",
|
||||||
|
}
|
||||||
|
|
||||||
|
function ChatCmdBuilder.build(rfunc)
|
||||||
local cmd = {
|
local cmd = {
|
||||||
_subs = {}
|
_subs = {}
|
||||||
}
|
}
|
||||||
function cmd:sub(route, func, def)
|
function cmd:sub(route, func, _)
|
||||||
print("Parsing " .. route)
|
dprint("Parsing " .. route)
|
||||||
|
|
||||||
def = def or {}
|
|
||||||
if string.trim then
|
if string.trim then
|
||||||
route = string.trim(route)
|
route = string.trim(route)
|
||||||
end
|
end
|
||||||
|
@ -56,25 +70,15 @@ function ChatCmdBuilder.build(func)
|
||||||
local should_be_eos = false
|
local should_be_eos = false
|
||||||
local function finishParam()
|
local function finishParam()
|
||||||
if param ~= "" and param_type ~= "" then
|
if param ~= "" and param_type ~= "" then
|
||||||
print(" - Found param " .. param .. " type " .. param_type)
|
dprint(" - Found param " .. param .. " type " .. param_type)
|
||||||
|
|
||||||
if param_type == "pos" then
|
local pattern = ChatCmdBuilder.types[param_type]
|
||||||
sub.pattern = sub.pattern .. "%(? *(%-?[%d.]+) *, *(%-?[%d.]+) *, *(%-?[%d.]+) *%)?"
|
if not pattern then
|
||||||
elseif param_type == "text" then
|
error("Unrecognised param_type=" .. param_type)
|
||||||
sub.pattern = sub.pattern .. "(*+)"
|
|
||||||
should_be_eos = true
|
|
||||||
elseif param_type == "number" then
|
|
||||||
sub.pattern = sub.pattern .. "([%d.]+)"
|
|
||||||
elseif param_type == "int" then
|
|
||||||
sub.pattern = sub.pattern .. "([%d]+)"
|
|
||||||
else
|
|
||||||
if param_type ~= "word" then
|
|
||||||
print("Unrecognised param_type=" .. param_type .. ", using 'word' type instead")
|
|
||||||
param_type = "word"
|
|
||||||
end
|
|
||||||
sub.pattern = sub.pattern .. "([^ ]+)"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sub.pattern = sub.pattern .. pattern
|
||||||
|
|
||||||
table.insert(sub.params, param_type)
|
table.insert(sub.params, param_type)
|
||||||
|
|
||||||
param = ""
|
param = ""
|
||||||
|
@ -84,6 +88,9 @@ function ChatCmdBuilder.build(func)
|
||||||
|
|
||||||
-- Iterate through the route to find params
|
-- Iterate through the route to find params
|
||||||
local state = STATE_READY
|
local state = STATE_READY
|
||||||
|
local catching_space = false
|
||||||
|
local match_space = " " -- change to "%s" to also catch tabs and newlines
|
||||||
|
local catch_space = match_space.."+"
|
||||||
for i = 1, #route do
|
for i = 1, #route do
|
||||||
local c = route:sub(i, i)
|
local c = route:sub(i, i)
|
||||||
if should_be_eos then
|
if should_be_eos then
|
||||||
|
@ -92,19 +99,33 @@ function ChatCmdBuilder.build(func)
|
||||||
|
|
||||||
if state == STATE_READY then
|
if state == STATE_READY then
|
||||||
if c == ":" then
|
if c == ":" then
|
||||||
print(" - Found :, entering param")
|
dprint(" - Found :, entering param")
|
||||||
state = STATE_PARAM
|
state = STATE_PARAM
|
||||||
param_type = "word"
|
param_type = "word"
|
||||||
|
catching_space = false
|
||||||
|
elseif c:match(match_space) then
|
||||||
|
print(" - Found space")
|
||||||
|
if not catching_space then
|
||||||
|
catching_space = true
|
||||||
|
sub.pattern = sub.pattern .. catch_space
|
||||||
|
end
|
||||||
else
|
else
|
||||||
|
catching_space = false
|
||||||
sub.pattern = sub.pattern .. escape(c)
|
sub.pattern = sub.pattern .. escape(c)
|
||||||
end
|
end
|
||||||
elseif state == STATE_PARAM then
|
elseif state == STATE_PARAM then
|
||||||
if c == ":" then
|
if c == ":" then
|
||||||
print(" - Found :, entering param type")
|
dprint(" - Found :, entering param type")
|
||||||
state = STATE_PARAM_TYPE
|
state = STATE_PARAM_TYPE
|
||||||
param_type = ""
|
param_type = ""
|
||||||
|
elseif c:match(match_space) then
|
||||||
|
print(" - Found whitespace, leaving param")
|
||||||
|
state = STATE_READY
|
||||||
|
finishParam()
|
||||||
|
catching_space = true
|
||||||
|
sub.pattern = sub.pattern .. catch_space
|
||||||
elseif c:match("%W") then
|
elseif c:match("%W") then
|
||||||
print(" - Found nonalphanum, leaving param")
|
dprint(" - Found nonalphanum, leaving param")
|
||||||
state = STATE_READY
|
state = STATE_READY
|
||||||
finishParam()
|
finishParam()
|
||||||
sub.pattern = sub.pattern .. escape(c)
|
sub.pattern = sub.pattern .. escape(c)
|
||||||
|
@ -112,8 +133,14 @@ function ChatCmdBuilder.build(func)
|
||||||
param = param .. c
|
param = param .. c
|
||||||
end
|
end
|
||||||
elseif state == STATE_PARAM_TYPE then
|
elseif state == STATE_PARAM_TYPE then
|
||||||
if c:match("%W") then
|
if c:match(match_space) then
|
||||||
print(" - Found nonalphanum, leaving param type")
|
print(" - Found space, leaving param type")
|
||||||
|
state = STATE_READY
|
||||||
|
finishParam()
|
||||||
|
catching_space = true
|
||||||
|
sub.pattern = sub.pattern .. catch_space
|
||||||
|
elseif c:match("%W") then
|
||||||
|
dprint(" - Found nonalphanum, leaving param type")
|
||||||
state = STATE_READY
|
state = STATE_READY
|
||||||
finishParam()
|
finishParam()
|
||||||
sub.pattern = sub.pattern .. escape(c)
|
sub.pattern = sub.pattern .. escape(c)
|
||||||
|
@ -122,22 +149,22 @@ function ChatCmdBuilder.build(func)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
print(" - End of route")
|
dprint(" - End of route")
|
||||||
finishParam()
|
finishParam()
|
||||||
sub.pattern = sub.pattern .. "$"
|
sub.pattern = sub.pattern .. "$"
|
||||||
print("Pattern: " .. sub.pattern)
|
dprint("Pattern: " .. sub.pattern)
|
||||||
|
|
||||||
table.insert(self._subs, sub)
|
table.insert(self._subs, sub)
|
||||||
end
|
end
|
||||||
|
|
||||||
if func then
|
if rfunc then
|
||||||
func(cmd)
|
rfunc(cmd)
|
||||||
end
|
end
|
||||||
|
|
||||||
cmd.run = function(name, param)
|
cmd.run = function(name, message)
|
||||||
for i = 1, #cmd._subs do
|
for i = 1, #cmd._subs do
|
||||||
local sub = cmd._subs[i]
|
local sub = cmd._subs[i]
|
||||||
local res = { string.match(param, sub.pattern) }
|
local res = { string.match(message, sub.pattern) }
|
||||||
if #res > 0 then
|
if #res > 0 then
|
||||||
local pointer = 1
|
local pointer = 1
|
||||||
local params = { name }
|
local params = { name }
|
||||||
|
@ -159,10 +186,16 @@ function ChatCmdBuilder.build(func)
|
||||||
pointer = pointer + 1
|
pointer = pointer + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return sub.func(unpack(params))
|
if table.unpack then
|
||||||
|
-- lua 5.2 or later
|
||||||
|
return sub.func(table.unpack(params))
|
||||||
|
else
|
||||||
|
-- lua 5.1 or earlier
|
||||||
|
return sub.func(unpack(params))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
print("No matches")
|
return false, "Invalid command"
|
||||||
end
|
end
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -175,7 +208,7 @@ local function run_tests()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end))("singleplayer", "bar abc and def") then
|
end)).run("singleplayer", "bar abc and def") then
|
||||||
error("Test 1 failed")
|
error("Test 1 failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -186,7 +219,7 @@ local function run_tests()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end)
|
end).run
|
||||||
if not move("singleplayer", "move player1 to 0,1,2") then
|
if not move("singleplayer", "move player1 to 0,1,2") then
|
||||||
error("Test 2 failed")
|
error("Test 2 failed")
|
||||||
end
|
end
|
||||||
|
@ -206,13 +239,13 @@ local function run_tests()
|
||||||
error("Test 7 failed")
|
error("Test 7 failed")
|
||||||
end
|
end
|
||||||
if not move("singleplayer", "move player1 to ( 0 ,1 ,2)") then
|
if not move("singleplayer", "move player1 to ( 0 ,1 ,2)") then
|
||||||
error("Test 7 failed")
|
error("Test 8 failed")
|
||||||
end
|
end
|
||||||
if move("singleplayer", "move player1 to abc,def,sdosd") then
|
if move("singleplayer", "move player1 to abc,def,sdosd") then
|
||||||
error("Test 8 failed")
|
error("Test 9 failed")
|
||||||
end
|
end
|
||||||
if move("singleplayer", "move player1 to abc def sdosd") then
|
if move("singleplayer", "move player1 to abc def sdosd") then
|
||||||
error("Test 8 failed")
|
error("Test 10 failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not (ChatCmdBuilder.build(function(cmd)
|
if not (ChatCmdBuilder.build(function(cmd)
|
||||||
|
@ -221,9 +254,51 @@ local function run_tests()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end))("singleplayer", "does 1 plus 2 equal 3") then
|
end)).run("singleplayer", "does 1 plus 2 equal 3") then
|
||||||
error("Test 9 failed")
|
error("Test 11 failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local checknegint = ChatCmdBuilder.build(function(cmd)
|
||||||
|
cmd:sub("checknegint :x:int", function(name, x)
|
||||||
|
return x
|
||||||
|
end)
|
||||||
|
end).run
|
||||||
|
if checknegint("checker","checknegint -2") ~= -2 then
|
||||||
|
error("Test 12 failed")
|
||||||
|
end
|
||||||
|
|
||||||
|
local checknegnumber = ChatCmdBuilder.build(function(cmd)
|
||||||
|
cmd:sub("checknegnumber :x:number", function(name, x)
|
||||||
|
return x
|
||||||
|
end)
|
||||||
|
end).run
|
||||||
|
if checknegnumber("checker","checknegnumber -3.3") ~= -3.3 then
|
||||||
|
error("Test 13 failed")
|
||||||
|
end
|
||||||
|
|
||||||
|
local checknegpos = ChatCmdBuilder.build(function(cmd)
|
||||||
|
cmd:sub("checknegpos :pos:pos", function(name, pos)
|
||||||
|
return pos
|
||||||
|
end)
|
||||||
|
end).run
|
||||||
|
local negpos = checknegpos("checker","checknegpos (-13.3,-4.6,-1234.5)")
|
||||||
|
if negpos.x ~= -13.3 or negpos.y ~= -4.6 or negpos.z ~= -1234.5 then
|
||||||
|
error("Test 14 failed")
|
||||||
|
end
|
||||||
|
|
||||||
|
local checktypes = ChatCmdBuilder.build(function(cmd)
|
||||||
|
cmd:sub("checktypes :int:int :number:number :pos:pos :word:word :text:text", function(name, int, number, pos, word, text)
|
||||||
|
return int, number, pos.x, pos.y, pos.z, word, text
|
||||||
|
end)
|
||||||
|
end).run
|
||||||
|
local int, number, posx, posy, posz, word, text
|
||||||
|
int, number, posx, posy, posz, word, text = checktypes("checker","checktypes -1 -2.4 (-3,-5.3,6.12) some text to finish off with")
|
||||||
|
--dprint(int, number, posx, posy, posz, word, text)
|
||||||
|
if int ~= -1 or number ~= -2.4 or posx ~= -3 or posy ~= -5.3 or posz ~= 6.12 or word ~= "some" or text ~= "text to finish off with" then
|
||||||
|
error("Test 15 failed")
|
||||||
|
end
|
||||||
|
dprint("All tests passed")
|
||||||
|
|
||||||
end
|
end
|
||||||
if not minetest then
|
if not minetest then
|
||||||
run_tests()
|
run_tests()
|
||||||
|
|
Loading…
Reference in a new issue