diff options
-rw-r--r-- | builtin/chatcommands.lua | 122 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/server.cpp | 35 | ||||
-rw-r--r-- | src/servercommand.cpp | 191 | ||||
-rw-r--r-- | src/servercommand.h | 62 |
5 files changed, 109 insertions, 302 deletions
diff --git a/builtin/chatcommands.lua b/builtin/chatcommands.lua index 8e4639955..9f55f1afc 100644 --- a/builtin/chatcommands.lua +++ b/builtin/chatcommands.lua @@ -20,18 +20,13 @@ minetest.register_on_chat_message(function(name, message) end local cmd_def = minetest.chatcommands[cmd] if cmd_def then - if not cmd_def.func then - -- This is a C++ command - return false + local has_privs, missing_privs = minetest.check_player_privs(name, cmd_def.privs) + if has_privs then + cmd_def.func(name, param) 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 + 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 return false end) @@ -39,17 +34,15 @@ end) -- -- Chat commands -- +minetest.register_chatcommand("me", { + params = "<action>", + description = "chat action (eg. /me orders a pizza)", + privs = {shout=true}, + func = function(name, param) + minetest.chat_send_all("* " .. name .. " " .. param) + end, +}) --- Register C++ commands without functions -minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)", privs = {shout=true}}) -minetest.register_chatcommand("status", {description = "print server status line"}) -minetest.register_chatcommand("shutdown", {params = "", description = "shutdown server", 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("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}}) - --- Register other commands minetest.register_chatcommand("help", { privs = {}, params = "(nothing)/all/privs/<cmd>", @@ -575,3 +568,92 @@ minetest.register_chatcommand("rollback", { end, }) +minetest.register_chatcommand("status", { + params = "", + description = "print server status line", + privs = {}, + func = function(name, param) + minetest.chat_send_player(name, minetest.get_server_status()) + end, +}) + +minetest.register_chatcommand("time", { + params = "<0...24000>", + description = "set time of day", + privs = {settime=true}, + func = function(name, param) + if param == "" then + minetest.chat_send_player(name, "Missing parameter") + return + end + local newtime = tonumber(param) + if newtime == nil then + minetest.chat_send_player(name, "Invalid time") + else + minetest.env:set_timeofday((newtime % 24000) / 24000) + minetest.chat_send_player(name, "Time of day changed.") + minetest.log("action", name .. " sets time " .. newtime) + end + end, +}) + +minetest.register_chatcommand("shutdown", { + params = "", + description = "shutdown server", + privs = {server=true}, + func = function(name, param) + minetest.log("action", name .. " shuts down server") + minetest.request_shutdown() + minetest.chat_send_all("*** Server shutting down (operator request).") + end, +}) + +minetest.register_chatcommand("ban", { + params = "<name>", + description = "ban IP of player", + privs = {ban=true}, + func = function(name, param) + if param == "" then + minetest.chat_send_player(name, "Ban list: " .. minetest.get_ban_list()) + return + end + if not minetest.env:get_player_by_name(param) then + minetest.chat_send_player(name, "No such player") + return + end + if not minetest.ban_player(param) then + minetest.chat_send_player(name, "Failed to ban player") + else + local desc = minetest.get_ban_description(param) + minetest.chat_send_player(name, "Banned " .. desc .. ".") + minetest.log("action", name .. " bans " .. desc .. ".") + end + end, +}) + +minetest.register_chatcommand("unban", { + params = "<name/ip>", + description = "remove IP ban", + privs = {ban=true}, + func = function(name, param) + if not minetest.unban_player_or_ip(param) then + minetest.chat_send_player(name, "Failed to unban player/IP") + else + minetest.chat_send_player(name, "Unbanned " .. param) + minetest.log("action", name .. " unbans " .. param) + end + end, +}) + +minetest.register_chatcommand("clearobjects", { + params = "", + description = "clear all objects in world", + privs = {server=true}, + func = function(name, param) + minetest.log("action", name .. " clears all objects") + minetest.chat_send_all("Clearing all objects. This may take long. You may experience a timeout. (by " .. name .. ")") + minetest.env:clear_objects() + minetest.log("action", "object clearing done") + minetest.chat_send_all("*** Cleared all objects.") + end, +}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43d7f241a..8cdaa510d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -193,7 +193,6 @@ set(common_SRCS connection.cpp environment.cpp server.cpp - servercommand.cpp socket.cpp mapblock.cpp mapsector.cpp diff --git a/src/server.cpp b/src/server.cpp index 85e361ced..ba99f4707 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "constants.h" #include "voxel.h" #include "config.h" -#include "servercommand.h" #include "filesys.h" #include "mapblock.h" #include "serverobject.h" @@ -2653,36 +2652,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // Whether to send to other players bool send_to_others = false; - // Parse commands + // Commands are implemented in Lua, so only catch invalid + // commands that were not "eaten" and send an error back if(message[0] == L'/') { - size_t strip_size = 1; - if (message[1] == L'#') // support old-style commans - ++strip_size; - message = message.substr(strip_size); - - WStrfnd f1(message); - f1.next(L" "); // Skip over /#whatever - std::wstring paramstring = f1.next(L""); - - ServerCommandContext *ctx = new ServerCommandContext( - str_split(message, L' '), - paramstring, - this, - m_env, - player); - - std::wstring reply(processServerCommand(ctx)); - send_to_sender = ctx->flags & SEND_TO_SENDER; - send_to_others = ctx->flags & SEND_TO_OTHERS; - - if (ctx->flags & SEND_NO_PREFIX) - line += reply; + message = message.substr(1); + send_to_sender = true; + if(message.length() == 0) + line += L"-!- Empty command"; else - line += L"Server: " + reply; - - delete ctx; - + line += L"-!- Invalid command: " + str_split(message, L' ')[0]; } else { diff --git a/src/servercommand.cpp b/src/servercommand.cpp deleted file mode 100644 index f14e0fba1..000000000 --- a/src/servercommand.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -Part of Minetest-c55 -Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com> -Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com> - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "servercommand.h" -#include "settings.h" -#include "main.h" // For g_settings -#include "content_sao.h" - -#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" - -void cmd_status(std::wostringstream &os, - ServerCommandContext *ctx) -{ - os<<ctx->server->getStatusString(); -} - -void cmd_me(std::wostringstream &os, - ServerCommandContext *ctx) -{ - if(!ctx->server->checkPriv(ctx->player->getName(), "shout")) - { - os<<L"-!- You don't have permission to shout."; - return; - } - - std::wstring name = narrow_to_wide(ctx->player->getName()); - os << L"* " << name << L" " << ctx->paramstring; - ctx->flags |= SEND_TO_OTHERS | SEND_NO_PREFIX; -} - -void cmd_time(std::wostringstream &os, - ServerCommandContext *ctx) -{ - if(ctx->parms.size() != 2) - { - os<<L"-!- Missing parameter"; - return; - } - - if(!ctx->server->checkPriv(ctx->player->getName(), "settime")) - { - os<<L"-!- You don't have permission to do this."; - return; - } - - u32 time = stoi(wide_to_narrow(ctx->parms[1])); - ctx->server->setTimeOfDay(time); - os<<L"-!- Time of day changed."; - - actionstream<<ctx->player->getName()<<" sets time " - <<time<<std::endl; -} - -void cmd_shutdown(std::wostringstream &os, - ServerCommandContext *ctx) -{ - if(!ctx->server->checkPriv(ctx->player->getName(), "server")) - { - os<<L"-!- You don't have permission to do this."; - return; - } - - actionstream<<ctx->player->getName() - <<" shuts down server"<<std::endl; - - ctx->server->requestShutdown(); - - os<<L"*** Server shutting down (operator request)."; - ctx->flags |= SEND_TO_OTHERS; -} - -void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx) -{ - if(!ctx->server->checkPriv(ctx->player->getName(), "ban")) - { - os<<L"-!- You don't have permission to do this."; - return; - } - - if(ctx->parms.size() < 2) - { - std::string desc = ctx->server->getBanDescription(""); - os<<L"-!- Ban list: "<<narrow_to_wide(desc); - return; - } - if(ctx->parms[0] == L"ban") - { - Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str()); - - if(player == NULL) - { - os<<L"-!- No such player"; - return; - } - - try{ - Address address = ctx->server->getPeerAddress(player->peer_id); - std::string ip_string = address.serializeString(); - ctx->server->setIpBanned(ip_string, player->getName()); - os<<L"-!- Banned "<<narrow_to_wide(ip_string)<<L"|" - <<narrow_to_wide(player->getName()); - - actionstream<<ctx->player->getName()<<" bans " - <<player->getName()<<" / "<<ip_string<<std::endl; - } catch(con::PeerNotFoundException){ - dstream<<__FUNCTION_NAME<<": peer was not found"<<std::endl; - } - } - else - { - std::string ip_or_name = wide_to_narrow(ctx->parms[1]); - std::string desc = ctx->server->getBanDescription(ip_or_name); - ctx->server->unsetIpBanned(ip_or_name); - os<<L"-!- Unbanned "<<narrow_to_wide(desc); - - actionstream<<ctx->player->getName()<<" unbans " - <<ip_or_name<<std::endl; - } -} - -void cmd_clearobjects(std::wostringstream &os, - ServerCommandContext *ctx) -{ - if(!ctx->server->checkPriv(ctx->player->getName(), "server")) - { - os<<L"-!- You don't have permission to do this."; - return; - } - - actionstream<<ctx->player->getName() - <<" clears all objects"<<std::endl; - - { - std::wstring msg; - msg += L"Clearing all objects. This may take long."; - msg += L" You may experience a timeout. (by "; - msg += narrow_to_wide(ctx->player->getName()); - msg += L")"; - ctx->server->notifyPlayers(msg); - } - - ctx->env->clearAllObjects(); - - actionstream<<"object clearing done"<<std::endl; - - os<<L"*** Cleared all objects."; - ctx->flags |= SEND_TO_OTHERS; -} - - -std::wstring processServerCommand(ServerCommandContext *ctx) -{ - std::wostringstream os(std::ios_base::binary); - ctx->flags = SEND_TO_SENDER; // Default, unless we change it. - - if(ctx->parms.size() == 0) - os<<L"-!- Empty command"; - else if(ctx->parms[0] == L"status") - cmd_status(os, ctx); - else if(ctx->parms[0] == L"time") - cmd_time(os, ctx); - else if(ctx->parms[0] == L"shutdown") - cmd_shutdown(os, ctx); - else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban") - cmd_banunban(os, ctx); - else if(ctx->parms[0] == L"me") - cmd_me(os, ctx); - else if(ctx->parms[0] == L"clearobjects") - cmd_clearobjects(os, ctx); - else - os<<L"-!- Invalid command: " + ctx->parms[0]; - - return os.str(); -} - - diff --git a/src/servercommand.h b/src/servercommand.h deleted file mode 100644 index c0f78a9f2..000000000 --- a/src/servercommand.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -Part of Minetest-c55 -Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com> -Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com> - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef SERVERCOMMAND_HEADER -#define SERVERCOMMAND_HEADER - -#include <vector> -#include <sstream> -#include "irrlichttypes.h" -#include "player.h" -#include "server.h" - -#define SEND_TO_SENDER (1<<0) -#define SEND_TO_OTHERS (1<<1) -#define SEND_NO_PREFIX (1<<2) - -struct ServerCommandContext -{ - std::vector<std::wstring> parms; - std::wstring paramstring; - Server* server; - ServerEnvironment *env; - Player* player; - u32 flags; - - ServerCommandContext( - std::vector<std::wstring> parms, - std::wstring paramstring, - Server* server, - ServerEnvironment *env, - Player* player) - : parms(parms), paramstring(paramstring), - server(server), env(env), player(player) - { - } - -}; - -// Process a command sent from a client. The environment and connection -// should be locked when this is called. -// Returns a response message, to be dealt with according to the flags set -// in the context. -std::wstring processServerCommand(ServerCommandContext *ctx); - -#endif - - |