Move chat commands to Lua and remove servercommand.{cpp,h}
authorMatthew I <matttpt@gmail.com>
Sun, 22 Jul 2012 13:42:43 +0000 (09:42 -0400)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 12 Aug 2012 13:45:58 +0000 (16:45 +0300)
Commands moved:
 /me
 /status
 /time
 /shutdown
 /ban
 /clearobjects

builtin/chatcommands.lua
src/CMakeLists.txt
src/server.cpp
src/servercommand.cpp [deleted file]
src/servercommand.h [deleted file]

index 8e4639955b468d5a853e9d93551291d9bfc2e7cd..9f55f1afcbddd9441098fadadf7445ed4d577f6d 100644 (file)
@@ -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,
+})
index 43d7f241a9e6557a088c1ccf452aaea7341631cf..8cdaa510d891fd01842ffeb7488c45954fa9d24f 100644 (file)
@@ -193,7 +193,6 @@ set(common_SRCS
        connection.cpp
        environment.cpp
        server.cpp
-       servercommand.cpp
        socket.cpp
        mapblock.cpp
        mapsector.cpp
index 85e361cede0cbd6f29f83926a7875f0756f6fc18..ba99f47071f74a1db4d0abe5feb687f38e9d55e2 100644 (file)
@@ -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 (file)
index f14e0fb..0000000
+++ /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 (file)
index c0f78a9..0000000
+++ /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
-
-