diff --git a/builtin/chatcommands.lua b/builtin/chatcommands.lua index 8e46399..9f55f1a 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 = "", + 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 = "", description = "ban IP of player", privs = {ban=true}}) -minetest.register_chatcommand("unban", {params = "", description = "remove IP ban", privs = {ban=true}}) - --- Register other commands minetest.register_chatcommand("help", { privs = {}, params = "(nothing)/all/privs/", @@ -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 = "", + 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 = "", + 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 43d7f24..8cdaa51 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 85e361c..ba99f47 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 f14e0fb..0000000 --- a/src/servercommand.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -Part of Minetest-c55 -Copyright (C) 2010-11 celeron55, Perttu Ahola -Copyright (C) 2011 Ciaran Gultnieks - -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<server->getStatusString(); -} - -void cmd_me(std::wostringstream &os, - ServerCommandContext *ctx) -{ - if(!ctx->server->checkPriv(ctx->player->getName(), "shout")) - { - os<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<server->checkPriv(ctx->player->getName(), "settime")) - { - os<parms[1])); - ctx->server->setTimeOfDay(time); - os<player->getName()<<" sets time " - <server->checkPriv(ctx->player->getName(), "server")) - { - os<player->getName() - <<" shuts down server"<server->requestShutdown(); - - os<flags |= SEND_TO_OTHERS; -} - -void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx) -{ - if(!ctx->server->checkPriv(ctx->player->getName(), "ban")) - { - os<parms.size() < 2) - { - std::string desc = ctx->server->getBanDescription(""); - os<parms[0] == L"ban") - { - Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str()); - - if(player == NULL) - { - os<server->getPeerAddress(player->peer_id); - std::string ip_string = address.serializeString(); - ctx->server->setIpBanned(ip_string, player->getName()); - os<getName()); - - actionstream<player->getName()<<" bans " - <getName()<<" / "<parms[1]); - std::string desc = ctx->server->getBanDescription(ip_or_name); - ctx->server->unsetIpBanned(ip_or_name); - os<player->getName()<<" unbans " - <server->checkPriv(ctx->player->getName(), "server")) - { - os<player->getName() - <<" clears all objects"<player->getName()); - msg += L")"; - ctx->server->notifyPlayers(msg); - } - - ctx->env->clearAllObjects(); - - actionstream<<"object clearing done"<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<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<parms[0]; - - return os.str(); -} - - diff --git a/src/servercommand.h b/src/servercommand.h deleted file mode 100644 index c0f78a9..0000000 --- a/src/servercommand.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -Part of Minetest-c55 -Copyright (C) 2010-11 celeron55, Perttu Ahola -Copyright (C) 2011 Ciaran Gultnieks - -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 -#include -#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 parms; - std::wstring paramstring; - Server* server; - ServerEnvironment *env; - Player* player; - u32 flags; - - ServerCommandContext( - std::vector 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 - -