diff --git a/mods/CORE/mcl_commands/api.lua b/mods/CORE/mcl_commands/api.lua index c30d74d84..6b6f928af 100644 --- a/mods/CORE/mcl_commands/api.lua +++ b/mods/CORE/mcl_commands/api.lua @@ -1,189 +1,67 @@ local S = minetest.get_translator(minetest.get_current_modname()) local C = minetest.colorize ---TODO: like mc error message ---TODO: complex command handling ---TODO: mc like help system +local ipairs = ipairs + +local string = string mcl_commands.types = { - bool = { - lengh = 1, - msg = S("Invalid boolean"), - func = function(word) - if word == "true" then - return true, true - elseif world == "false" then - return true, false - else - return false, nil - end - end, - }, - int = { - lengh = 1, - msg = S("Invalid integer"), - func = function(int) - if tonumber(int) and tonumber(int) == math.round(int) then - return true, tonumber(int) - else - return false, nil - end - end, - }, - float = { - lengh = 1, - msg = S("Invalid integer"), - func = function(float) - if tonumber(float) then - return true, tonumber(float) - else - return false, nil - end - end, - }, word = { - lengh = 1, - msg = S("Invalid word"), - func = function(word) - if word then - return true, word - else - return false, nil - end - end, - }, - text = {}, - pos = { - lengh = 3, - msg = S("Invalid position"), - func = function(x, y, z) - --FIXME - if true then - return true, nil - else - return false, nil - end - end, - }, - target = { - lengh = 1, - msg = S("Invalid target selector"), - func = function(target) - --mcl_commands.get_target_selector(target_selector) - if minetest.player_exists(target) then - return true, target - else - return false, nil - end - end, - }, - playername = { - lengh = 1, - msg = S("Invalid player name"), - func = function(name) - if minetest.player_exists(name) then - return true, name - else - return false, nil - end - end, + }, } -function mcl_commands.match_param(table, index, type, params) - local typedef = mcl_commands.types[type] - if typedef.lengh > 1 then - return - else - local params = {} - typedef.func() - end +local old_minetest_register_chatcommand = minetest.register_chatcommand + +function minetest.register_chatcommand(cmd, def) + minetest.log("warning", "[mcl_commands] DEPRECATED") + old_minetest_register_chatcommand(cmd, def) end mcl_commands.registered_commands = {} -function mcl_commands.register_complex_command() -end - ---aims to avoid complexity for basic commands while keeping proper messages and privs management -function mcl_commands.register_basic_command(name, def) - local func - if def.params then - func = function(name, param) - local funcparams = {} - local i = 0 - for str in string.gmatch(params, "([^ ]+)") do - i = i + 1 - funcparams[i] = str - end - for _,type in pairs(def.params) do - mcl_commands.match_param(funcparams, index, type, params) - end - end - else - mcl_commands.registered_commands[name] = {type = "basic", description = def.desc, privs = def.privs} - func = function(name, param) - if param == "" then - local out, msg = def.func(name) - if out then - return true, C(mcl_colors.GRAY, msg) or C(mcl_colors.GRAY, S("succesful")) - else - return false, C(mcl_colors.RED, msg) or C(mcl_colors.RED, S("failed")) - end - else - return false, C(mcl_colors.RED, S("Invalid command usage")) - end - end +function mcl_commands.register_command(name, def) + --TODO: do sanity checks first + local params_count = 0 + for _,_ in ipairs(def.def) do + params_count = params_count + 1 end - minetest.register_chatcommand(name, { - description = def.desc, - privs = def.privs, - func = func, + + def.def._params_count = params_count + mcl_commands.registered_commands[name] = def + + --TODO: move registration on mods loaded + old_minetest_register_chatcommand(name, { + description = def.description, + func = function(pname, params) + --TODO: make sure player is online + return mcl_commands.handle_command(name, params, { + type = "player", + name = pname, + object = nil, --FIXME + op_level = 4, + }) + end, }) end ---[[ -mcl_commands.register_basic_command("test", { - description = S("testing command"), - params = nil, - func = function(name) - end, -}) -]] - -mcl_commands.register_basic_command("testb", { - description = S("testing command"), - params = { - {type="bool"}, - {type="int", params={min=1, max=10}} - }, - func = function(name, bool, int) - return true, "test: "..int - end, -}) - -function mcl_commands.alias_command(alias, original_name, bypass_setting) - if minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass_setting then - local def = minetest.registered_chatcommands[original_name] - minetest.register_chatcommand(alias, def) - minetest.log("action", string.format("[mcl_commands] Aliasing [%s] command to [%s]", original_name, alias)) - else - minetest.log("action", string.format("[mcl_commands] Aliasing [%s] command to [%s] skipped according to setting", original_name, alias)) - end +local function match_param(param, str) + local p_source = string.find("", str) end -function mcl_commands.rename_command(new_name, original_name, bypass_setting) - if minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass_setting then - local def = minetest.registered_chatcommands[original_name] - minetest.register_chatcommand(new_name, def) - minetest.unregister_chatcommand(original_name) - minetest.log("action", string.format("[mcl_commands] Renaming [%s] command to [%s]", original_name, new_name)) +function mcl_commands.handle_command(name, params, context) + local cdef = mcl_commands.registered_commands[name] + + if cdef.def._params_count == 0 then + return cdef.def.execute(context) else - minetest.log("action", string.format("[mcl_commands] Renaming [%s] command to [%s] skipped according to setting", original_name, new_name)) + local paramtable = {} + for _,p in ipairs(cdef.def) do + + end end end - --0: succesfull, table --1: not connected player, nil --2: invalid target selector, nil @@ -195,7 +73,10 @@ function mcl_commands.get_target_selector(target_selector) else return 1, nil end - else - return 0, {} + elseif string.sub(1, 1) == "@" then + local selector_type = string.sub(2, 2) + if selector_type == "a" then + return 0, minetest.get_connected_players() + end end end \ No newline at end of file diff --git a/mods/CORE/mcl_commands/api_old.lua b/mods/CORE/mcl_commands/api_old.lua new file mode 100644 index 000000000..9ef5bb1da --- /dev/null +++ b/mods/CORE/mcl_commands/api_old.lua @@ -0,0 +1,204 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize + +--TODO: like mc error message +--TODO: complex command handling +--TODO: mc like help system + +mcl_commands.types = { + bool = { + lengh = 1, + msg = S("Invalid boolean"), + func = function(word) + if word == "true" then + return true, true + elseif world == "false" then + return true, false + else + return false, nil + end + end, + }, + int = { + lengh = 1, + msg = S("Invalid integer"), + func = function(int) + if tonumber(int) and tonumber(int) == math.round(int) then + return true, tonumber(int) + else + return false, nil + end + end, + }, + float = { + lengh = 1, + msg = S("Invalid integer"), + func = function(float) + if tonumber(float) then + return true, tonumber(float) + else + return false, nil + end + end, + }, + word = { + lengh = 1, + msg = S("Invalid word"), + func = function(word) + if word then + return true, word + else + return false, nil + end + end, + }, + text = {}, + pos = { + lengh = 3, + msg = S("Invalid position"), + func = function(x, y, z) + --FIXME + if true then + return true, vector.new(x, y, z) + else + return false, nil + end + end, + }, + target = { + lengh = 1, + msg = S("Invalid target selector"), + func = function(target) + --mcl_commands.get_target_selector(target_selector) + if minetest.player_exists(target) then + return true, target + else + return false, nil + end + end, + }, + playername = { + lengh = 1, + msg = S("Invalid player name"), + func = function(name) + if minetest.player_exists(name) then + return true, name + else + return false, nil + end + end, + }, +} + +function mcl_commands.match_param(table, index, type, params) + local typedef = mcl_commands.types[type] + if typedef.lengh > 1 then + return + else + local params = {} + typedef.func() + end +end + +mcl_commands.registered_commands = {} + +function mcl_commands.register_complex_command() +end + +--aims to avoid complexity for basic commands while keeping proper messages and privs management +function mcl_commands.register_basic_command(name, def) + local func + if def.params then + func = function(name, param) + local funcparams = {} + local i = 0 + for str in string.gmatch(params, "([^ ]+)") do + i = i + 1 + funcparams[i] = str + end + for _,type in pairs(def.params) do + mcl_commands.match_param(funcparams, index, type, params) + end + end + else + mcl_commands.registered_commands[name] = {type = "basic", description = def.desc, privs = def.privs} + func = function(name, param) + if param == "" then + local out, msg = def.func(name) + if out then + return true, C(mcl_colors.GRAY, msg) or C(mcl_colors.GRAY, S("succesful")) + else + return false, C(mcl_colors.RED, msg) or C(mcl_colors.RED, S("failed")) + end + else + return false, C(mcl_colors.RED, S("Invalid command usage")) + end + end + end + minetest.register_chatcommand(name, { + description = def.desc, + privs = def.privs, + func = func, + }) +end + +--[[ +mcl_commands.register_basic_command("test", { + description = S("testing command"), + params = nil, + func = function(name) + end, +}) +]] + +mcl_commands.register_basic_command("testb", { + description = S("testing command"), + params = { + {type="bool"}, + {type="int", params={min=1, max=10}} + }, + func = function(name, bool, int) + return true, "test: "..int + end, +}) + +function mcl_commands.alias_command(alias, original_name, bypass_setting) + if minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass_setting then + local def = minetest.registered_chatcommands[original_name] + minetest.register_chatcommand(alias, def) + minetest.log("action", string.format("[mcl_commands] Aliasing [%s] command to [%s]", original_name, alias)) + else + minetest.log("action", string.format("[mcl_commands] Aliasing [%s] command to [%s] skipped according to setting", original_name, alias)) + end +end + +function mcl_commands.rename_command(new_name, original_name, bypass_setting) + if minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass_setting then + local def = minetest.registered_chatcommands[original_name] + minetest.register_chatcommand(new_name, def) + minetest.unregister_chatcommand(original_name) + minetest.log("action", string.format("[mcl_commands] Renaming [%s] command to [%s]", original_name, new_name)) + else + minetest.log("action", string.format("[mcl_commands] Renaming [%s] command to [%s] skipped according to setting", original_name, new_name)) + end +end + + +--0: succesfull, table +--1: not connected player, nil +--2: invalid target selector, nil +function mcl_commands.get_target_selector(target_selector) + if minetest.player_exists(target_selector) then + local obj = minetest.get_player_by_name(target_selector) + if obj then + return 0, {obj} + else + return 1, nil + end + elseif string.sub(1, 1) == "@" then + local selector_type = string.sub(2, 2) + if selector_type == "a" then + return 0, minetest.get_connected_players() + end + end +end \ No newline at end of file diff --git a/mods/CORE/mcl_commands/init.lua b/mods/CORE/mcl_commands/init.lua index d47758e62..d41562d5f 100644 --- a/mods/CORE/mcl_commands/init.lua +++ b/mods/CORE/mcl_commands/init.lua @@ -3,7 +3,8 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) mcl_commands = {} dofile(modpath.."/api.lua") - +dofile(modpath.."/test_commands.lua") +--[[ dofile(modpath.."/register/kill.lua") dofile(modpath.."/register/setblock.lua") dofile(modpath.."/register/seed.lua") @@ -12,5 +13,6 @@ dofile(modpath.."/register/say.lua") dofile(modpath.."/register/list.lua") dofile(modpath.."/register/sound.lua") dofile(modpath.."/register/banlist.lua") +]] -dofile(modpath.."/alias.lua") \ No newline at end of file +--dofile(modpath.."/alias.lua") \ No newline at end of file diff --git a/mods/CORE/mcl_commands/proof-of-concept.lua b/mods/CORE/mcl_commands/proof-of-concept.lua index 2b7b1e194..48056402f 100644 --- a/mods/CORE/mcl_commands/proof-of-concept.lua +++ b/mods/CORE/mcl_commands/proof-of-concept.lua @@ -1,16 +1,56 @@ -mcl_commands.register_basic_command("person", { +mcl_commands.register_command("test", { description = S("testing command"), def = { {type="target", name="t"}, {type="subcommand", subcommands = { {name = "set", {type="int", name="age", params={min=0,max=100}}, - {type="choice", name="sexe", params={values={"man", "woman"}}}, - execute = function(params, subcommand_params) - return true, params.t..":"..subcommand_params.age..":"..subcommand_params.sexe + {type="choice", name="other", params={values={"man", "woman"}}}, + require = 1, + execute = function(context, params, subcommand_params) + return true, params.t..":"..subcommand_params.age..":"..subcommand_params.other end, } }}, }, -}) \ No newline at end of file +}) + +local exemple_context = { + type = "player", + name = "playername", + object = player, --is ALWAYS a valid object + op_level = get_player_op_level(player), +} + + +--we need a way for mods to run commands on offline players, but this should be avoided +local exemple_context2 = { + type = "offline_player", + name = "playername", + object = player, --is a valid object if the player is online + op_level = get_player_op_level(player), + pos = player_pos, +} + +local exemple_context3 = { + type = "mod", --required + name = "mcl_redstone:commandblock", --valid nodename + op_level = commandblock_op_level, --required + pos = node_pos, +} + + +mcl_commands.register_command("test", { + description = S("testing command"), + def = { + {type="player", name="player"}, --player object (got by name) + require = 4, --required OP level + execute = function(context, params) --function executed + return true, params.player + end, + }, +}) + +--the command actually registered in minetest.registered_command will be a wrapper around this function +mcl_commands.call_command("test", "@a grant all", exemple_context3) \ No newline at end of file diff --git a/mods/CORE/mcl_commands/test_commands.lua b/mods/CORE/mcl_commands/test_commands.lua new file mode 100644 index 000000000..709c72166 --- /dev/null +++ b/mods/CORE/mcl_commands/test_commands.lua @@ -0,0 +1,9 @@ +mcl_commands.register_command("test1", { + description = "testing command 1", + def = { + {type="player", name="t"}, + execute = function(context, params, subcommand_params) + return true, dump(context) + end, + }, +}) \ No newline at end of file