diff --git a/mods/CORE/mcl_commands/API.md b/mods/CORE/mcl_commands/API.md index 41ef2d02d9..ea01cf4bed 100644 --- a/mods/CORE/mcl_commands/API.md +++ b/mods/CORE/mcl_commands/API.md @@ -3,10 +3,12 @@ The mcl_commands API allows you to register and overide complex commands. This mod is derivated from ChatCommandBuilder by rubenwardy +Some public functions are not documented here but they are for internal use only. + ## Technical differences from ChatCommandBuilder * subcommand aditional specific privs -* new types: `json` an maybe more in the future +* new types: `json`, `color`, `nodename` an maybe more in the future ## Public Functions @@ -69,4 +71,4 @@ If not specified, a value will be by default with the word pattern. * username: value must be a valid username * json: value must be a json string (will be parsed automaticaly) * color value must be a color string or a valid named color -* nodename value must be a valid node name +* nodename value must be a valid (existing) node or item name diff --git a/mods/CORE/mcl_commands/init.lua b/mods/CORE/mcl_commands/init.lua index 755b5def9b..e8e8550996 100644 --- a/mods/CORE/mcl_commands/init.lua +++ b/mods/CORE/mcl_commands/init.lua @@ -8,6 +8,7 @@ local mod_death_messages = minetest.get_modpath("mcl_death_messages") local modpath = minetest.get_modpath(minetest.get_current_modname()) local parse_json = minetest.parse_json +local get_modpath = minetest.get_modpath mcl_commands = {} @@ -27,6 +28,120 @@ mcl_commands.types = { nodename = "([A-Za-z_]+)", } +mcl_commands.types = { + pos = {"%(? *(%-?[%d.]+) *, *(%-?[%d.]+) *, *(%-?[%d.]+) *%)?", + function(res, pointer) + local pos = { + x = tonumber(res[pointer]), + y = tonumber(res[pointer + 1]), + z = tonumber(res[pointer + 2]) + } + if pos.x and pos.y and pos.z then + return nil, pos, pointer+3 + else + return S("Pos is invalid!") + end + end}, + text = {"(.+)", + function(res, pointer) + if res[pointer] == tostring(res[pointer]) then + return nil, res[pointer], pointer+1 + else + return S("Text is invalid!") + end + end}, + number = {"(%-?[%d.]+)}", + function(res, pointer) + if res[pointer] == tonumber(res[pointer]) then + return nil, tonumber(res[pointer]), pointer+1 + else + return S("Number is invalid!") + end + end}, + int = {"(%-?[%d]+)}", + function(res, pointer) + if res[pointer] == math.floor(tonumber(res[pointer])) then + return nil, tonumber(res[pointer]), pointer+1 + else + return S("Int is invalid!") + end + end}, + word = {"([^ ]+)", + function(res, pointer) + if res[pointer] == tostring(res[pointer]) then + return nil, tostring(res[pointer]), pointer+1 + else + return S("Word is invalid!") + end + end}, + alpha = {"([A-Za-z]+)}", + function(res, pointer) + if res[pointer] then + return nil, res[pointer], pointer+1 + else + return S("Alpha is invalid!") + end + end}, + modname = {"([a-z0-9_]+)}", + function(res, pointer) + if get_modpath(res[pointer]) then + return nil, res[pointer], pointer+1 + else + return S("Modname is invalid!") + end + end}, + alphascore = {"([A-Za-z_]+)", + function(res, pointer) + if res[pointer] then --What is alphascore? + return nil, res[pointer], pointer+1 + else + return S("Alphascore is invalid!") + end + end}, + alphanumeric = {"([A-Za-z0-9]+)}", + function(res, pointer) + if res[pointer] then --What is alphanumerical? + return nil, res[pointer], pointer+1 + else + return S("Alphanumerical is invalid!") + end + end}, + username = {"([A-Za-z0-9-_]+)}", + function(res, pointer) + --if minetest.player_exists(res[pointer]) then + return nil, res[pointer], pointer+1 + --else + --return S("Player doesn't exist.") + --end + end}, + json = {"(.+)", --FIXME + function(res, pointer) + local parsed = parse_json(res[pointer]) + if parsed then + return nil, parsed, pointer+1 + else + return S("Json failed to parse!") + end + end}, + color = {"([^ ]+)", --FIXME + function(res, pointer) + local color = mcl_util.get_color(res[pointer]) + if color then + return nil, color, pointer+1 + else + return S("Color is not a valid color name or hexadecimal!") + end + end}, + nodename = {"([A-Za-z_]+)", + function(res, pointer) + if minetest.registered_items[res[pointer]] then + return nil, res[pointer], pointer+1 + else + return S("Nodename is invalid") + end + end}, +} + function mcl_commands.register_command(name, def) def = def or {} local cmd = mcl_commands.build(name, def) @@ -91,7 +206,7 @@ function mcl_commands.build(name, chat_def) if param ~= "" and param_type ~= "" then dprint(" - Found param " .. param .. " type " .. param_type) - local pattern = mcl_commands.types[param_type] + local pattern = mcl_commands.types[param_type][1] if not pattern then error("Unrecognised param_type=" .. param_type) end @@ -181,6 +296,7 @@ function mcl_commands.build(name, chat_def) end cmd.func = function(name, param) + local msg for i = 1, #cmd._subs do local sub = cmd._subs[i] local res = { string.match(param, sub.pattern) } @@ -189,30 +305,10 @@ function mcl_commands.build(name, chat_def) local params = { name } for j = 1, #sub.params do local param = sub.params[j] - if param == "pos" then - local pos = { - x = tonumber(res[pointer]), - y = tonumber(res[pointer + 1]), - z = tonumber(res[pointer + 2]) - } - table.insert(params, pos) - pointer = pointer + 3 - elseif param == "number" or param == "int" then - table.insert(params, tonumber(res[pointer])) - pointer = pointer + 1 - elseif param == "json" then - table.insert(params, parse_json(res[pointer])) - pointer = pointer + 1 - elseif param == "color" then - table.insert(params, mcl_util.get_color(res[pointer])) - pointer = pointer + 1 - elseif param == "nodename" then - if minetest.registered_nodes[res[pointer]] then - table.insert(params, res[pointer]) - pointer = pointer + 1 - else - return false, S("Param "..pointer.." must be a valid nodename!") - end + local value + if mcl_commands.types[param] then + msg, value, pointer = mcl_commands.check_type(param, res, pointer) + table.insert(params, value) else table.insert(params, res[pointer]) pointer = pointer + 1 @@ -240,7 +336,7 @@ function mcl_commands.build(name, chat_def) end end end - return false, "Invalid parameters!" + return false, msg end if chat_def.params then cmd.params = chat_def.params @@ -252,6 +348,10 @@ function mcl_commands.build(name, chat_def) return cmd end +function mcl_commands.check_type(type, res, pointer) + return mcl_commands.types[type][2](res, pointer) +end + function mcl_commands.register_chatcommand_alias(alias, cmd, bypass) if not bypass then bypass = false end if minetest.registered_chatcommands[alias] then @@ -266,7 +366,7 @@ end function mcl_commands.rename_chatcommand(newname, cmd, bypass) if not bypass then bypass = false end - if minetest.registered_chatcommands[alias] then + if minetest.registered_chatcommands[newname] then minetest.log("warning", "[mcl_commands] trying to rename ["..cmd.."] to already existing ["..alias.."] command") elseif minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass then minetest.register_chatcommand(newname, minetest.chatcommands[cmd])