minetest.register_chatcommand(cmd, def)

This commit is contained in:
Perttu Ahola 2012-03-30 01:45:23 +03:00
parent 9d456ca87a
commit b9ffb5f30d
4 changed files with 126 additions and 20 deletions

View File

@ -821,6 +821,116 @@ function minetest.after(time, func, param)
table.insert(minetest.timers_to_add, {time=time, func=func, param=param}) table.insert(minetest.timers_to_add, {time=time, func=func, param=param})
end end
function minetest.check_player_privs(name, privs)
local player_privs = minetest.get_player_privs(name)
local missing_privileges = {}
for priv, val in pairs(privs) do
if val then
if not player_privs[priv] then
table.insert(missing_privileges, priv)
end
end
end
if #missing_privileges > 0 then
return false, missing_privileges
end
return true, ""
end
--
-- Chat commands
--
minetest.chatcommands = {}
function minetest.register_chatcommand(cmd, def)
def = def or {}
def.params = def.params or ""
def.description = def.description or ""
def.privs = def.privs or {}
minetest.chatcommands[cmd] = def
end
-- Register the help command
minetest.register_chatcommand("help", {
privs = {},
params = "(nothing)/all/<cmd>",
description = "Get help for commands",
func = function(name, param)
local format_help_line = function(cmd, def)
local msg = "/"..cmd
if def.params and def.params ~= "" then msg = msg .. " " .. def.params end
if def.description and def.description ~= "" then msg = msg .. ": " .. def.description end
return msg
end
if not param or param == "" then
local msg = ""
cmds = {}
for cmd, def in pairs(minetest.chatcommands) do
if minetest.check_player_privs(name, def.privs) then
table.insert(cmds, cmd)
end
end
minetest.chat_send_player(name, "Available commands: "..table.concat(cmds, " "))
minetest.chat_send_player(name, "Use '/help <cmd>' to get more information, or '/help all' to list everything.")
elseif param == "all" then
minetest.chat_send_player(name, "Available commands:")
for cmd, def in pairs(minetest.chatcommands) do
if minetest.check_player_privs(name, def.privs) then
minetest.chat_send_player(name, format_help_line(cmd, def))
end
end
else
local cmd = param
def = minetest.chatcommands[cmd]
if not def then
minetest.chat_send_player(name, "Command not available: "..cmd)
else
minetest.chat_send_player(name, format_help_line(cmd, def))
end
end
end,
})
-- Register C++ commands without functions
minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)"})
minetest.register_chatcommand("status", {description = "print server status line"})
minetest.register_chatcommand("privs", {params = "<name>", description = "print out privileges of player"})
minetest.register_chatcommand("shutdown", {params = "", description = "shutdown server", privs = {server=true}})
minetest.register_chatcommand("setting", {params = "<name> = <value>", description = "set line in configuration file", privs = {server=true}})
minetest.register_chatcommand("clearobjects", {params = "", description = "clear all objects in world", privs = {server=true}})
minetest.register_chatcommand("time", {params = "<0...24000>", description = "set time of day", privs = {settime=true}})
minetest.register_chatcommand("teleport", {params = "<X>,<Y>,<Z>", description = "teleport to given position", privs = {teleport=true}})
minetest.register_chatcommand("grant", {params = "<name> <privilege>", description = "Give privilege to player", privs = {privs=true}})
minetest.register_chatcommand("revoke", {params = "<name> <privilege>", description = "Remove privilege from player", privs = {privs=true}})
minetest.register_chatcommand("ban", {params = "<name>", description = "ban IP of player", privs = {ban=true}})
minetest.register_chatcommand("unban", {params = "<name/ip>", description = "remove IP ban", privs = {ban=true}})
minetest.register_chatcommand("setpassword", {params = "<name> <password>", description = "set given password", privs = {password=true}})
minetest.register_chatcommand("clearpassword", {params = "<name>", description = "set empty password", privs = {password=true}})
--
-- Builtin chat handler
--
minetest.register_on_chat_message(function(name, message)
local cmd, param = string.match(message, "/([^ ]+) *(.*)")
local cmd_def = minetest.chatcommands[cmd]
if cmd_def then
if not cmd_def.func then
-- This is a C++ command
return false
else
local has_privs, missing_privs = minetest.check_player_privs(name, cmd_def.privs)
if has_privs then
cmd_def.func(name, param)
else
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
end
return true -- handled chat message
end
end
return false
end)
-- --
-- Set random seed -- Set random seed
-- --

View File

@ -499,6 +499,7 @@ minetest.register_on_respawnplayer(func(ObjectRef))
^ return true in func to disable regular player placement ^ return true in func to disable regular player placement
^ currently called _before_ repositioning of player occurs ^ currently called _before_ repositioning of player occurs
minetest.register_on_chat_message(func(name, message)) minetest.register_on_chat_message(func(name, message))
minetest.register_chatcommand(cmd, chatcommand definition)
minetest.add_to_creative_inventory(itemstring) minetest.add_to_creative_inventory(itemstring)
minetest.setting_get(name) -> string or nil minetest.setting_get(name) -> string or nil
@ -507,6 +508,7 @@ minetest.setting_getbool(name) -> boolean value or nil
minetest.chat_send_all(text) minetest.chat_send_all(text)
minetest.chat_send_player(name, text) minetest.chat_send_player(name, text)
minetest.get_player_privs(name) -> set of privs minetest.get_player_privs(name) -> set of privs
minetest.check_player_privs(name, {priv1=true,...}) -> bool, missing_privs
minetest.get_inventory(location) -> InvRef minetest.get_inventory(location) -> InvRef
^ location = eg. {type="player", name="celeron55"} ^ location = eg. {type="player", name="celeron55"}
{type="node", pos={x=, y=, z=}} {type="node", pos={x=, y=, z=}}
@ -858,4 +860,11 @@ Recipe (furnace fuel):
burntime = 1, burntime = 1,
} }
Chatcommand definition (register_chatcommand)
{
params = "<name> <privilege>", -- short parameter description
description = "Remove privilege from player", -- full description
privs = {privs=true}}, -- require the "privs" privilege to run
func = function(name, param), -- called when command is run
}

View File

@ -36,6 +36,8 @@ std::set<std::string> privsToSet(u64 privs)
s.insert("settime"); s.insert("settime");
if(privs & PRIV_PRIVS) if(privs & PRIV_PRIVS)
s.insert("privs"); s.insert("privs");
if(privs & PRIV_SERVER)
s.insert("server");
if(privs & PRIV_SHOUT) if(privs & PRIV_SHOUT)
s.insert("shout"); s.insert("shout");
if(privs & PRIV_BAN) if(privs & PRIV_BAN)
@ -60,6 +62,8 @@ std::string privsToString(u64 privs)
os<<"settime,"; os<<"settime,";
if(privs & PRIV_PRIVS) if(privs & PRIV_PRIVS)
os<<"privs,"; os<<"privs,";
if(privs & PRIV_SERVER)
os<<"server,";
if(privs & PRIV_SHOUT) if(privs & PRIV_SHOUT)
os<<"shout,"; os<<"shout,";
if(privs & PRIV_BAN) if(privs & PRIV_BAN)
@ -98,6 +102,8 @@ u64 stringToPrivs(std::string str)
privs |= PRIV_SETTIME; privs |= PRIV_SETTIME;
else if(s == "privs") else if(s == "privs")
privs |= PRIV_PRIVS; privs |= PRIV_PRIVS;
else if(s == "server")
privs |= PRIV_SERVER;
else if(s == "shout") else if(s == "shout")
privs |= PRIV_SHOUT; privs |= PRIV_SHOUT;
else if(s == "ban") else if(s == "ban")

View File

@ -376,26 +376,7 @@ std::wstring processServerCommand(ServerCommandContext *ctx)
std::wostringstream os(std::ios_base::binary); std::wostringstream os(std::ios_base::binary);
ctx->flags = SEND_TO_SENDER; // Default, unless we change it. ctx->flags = SEND_TO_SENDER; // Default, unless we change it.
u64 privs = ctx->privs; if(ctx->parms[0] == L"status")
if(ctx->parms.size() == 0 || ctx->parms[0] == L"help")
{
os<<L"-!- Available commands: ";
os<<L"me status privs";
if(privs & PRIV_SERVER)
os<<L" shutdown setting clearobjects";
if(privs & PRIV_SETTIME)
os<<L" time";
if(privs & PRIV_TELEPORT)
os<<L" teleport";
if(privs & PRIV_PRIVS)
os<<L" grant revoke";
if(privs & PRIV_BAN)
os<<L" ban unban";
if(privs & PRIV_PASSWORD)
os<<L" setpassword clearpassword";
}
else if(ctx->parms[0] == L"status")
cmd_status(os, ctx); cmd_status(os, ctx);
else if(ctx->parms[0] == L"privs") else if(ctx->parms[0] == L"privs")
cmd_privs(os, ctx); cmd_privs(os, ctx);