From 248d7c8469f8cb37406ea0ce56d0945e38334cfb Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Mon, 16 May 2011 10:41:19 +0100 Subject: Improved server commands and added player permissions. --HG-- extra : rebase_source : 178fe08f10b7de3ebaba088bd24faad795114216 --- src/CMakeLists.txt | 1 + src/player.cpp | 9 +- src/player.h | 72 ++++++++++++++++ src/server.cpp | 91 ++++++-------------- src/server.h | 23 ++++- src/servercommand.cpp | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/servercommand.h | 76 ++++++++++++++++ src/utility.h | 19 ++++ 8 files changed, 454 insertions(+), 70 deletions(-) create mode 100644 src/servercommand.cpp create mode 100644 src/servercommand.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e6f54303..42260b3ae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -69,6 +69,7 @@ set(common_SRCS connection.cpp environment.cpp server.cpp + servercommand.cpp socket.cpp mapblock.cpp mapsector.cpp diff --git a/src/player.cpp b/src/player.cpp index 64780de75..a6ddeee64 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -34,7 +34,8 @@ Player::Player(): m_pitch(0), m_yaw(0), m_speed(0,0,0), - m_position(0,0,0) + m_position(0,0,0), + privs(PRIV_DEFAULT) { updateName(""); resetInventory(); @@ -100,6 +101,7 @@ void Player::serialize(std::ostream &os) args.setV3F("position", m_position); args.setBool("craftresult_is_preview", craftresult_is_preview); args.setS32("hp", hp); + args.setU64("privs", privs); args.writeLines(os); @@ -141,6 +143,11 @@ void Player::deSerialize(std::istream &is) }catch(SettingNotFoundException &e){ hp = 20; } + try{ + privs = args.getU64("privs"); + }catch(SettingNotFoundException &e){ + privs = PRIV_DEFAULT; + } inventory.deSerialize(is); } diff --git a/src/player.h b/src/player.h index f70b52fe7..778bb54b3 100644 --- a/src/player.h +++ b/src/player.h @@ -28,11 +28,29 @@ with this program; if not, write to the Free Software Foundation, Inc., #define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.," +// Player privileges. These form a bitmask stored in the privs field +// of the player, and define things they're allowed to do. See also +// the static methods Player::privsToString and stringToPrivs that +// convert these to human-readable form. +const u64 PRIV_BUILD = 1; // Can build - i.e. modify the world + // (not enforced yet) +const u64 PRIV_TELEPORT = 2; // Can teleport +const u64 PRIV_SETTIME = 4; // Can set the time +const u64 PRIV_PRIVS = 8; // Can grant and revoke privileges +const u64 PRIV_SERVER = 16; // Can manage the server (e.g. shutodwn ,settings) + +const u64 PRIV_DEFAULT = PRIV_BUILD; +const u64 PRIV_ALL = 0x7FFFFFFFFFFFFFFFULL; +const u64 PRIV_INVALID = 0x8000000000000000ULL; + + class Map; class Player { public: + + Player(); virtual ~Player(); @@ -123,6 +141,9 @@ public: u16 hp; + // Player's privileges - a bitmaps of PRIV_xxxx. + u64 privs; + u16 peer_id; protected: @@ -131,6 +152,57 @@ protected: f32 m_yaw; v3f m_speed; v3f m_position; + +public: + + // Converst a prvileges value into a human-readable string, + // with each component separated by a comma. + static std::wstring privsToString(u64 privs) + { + std::wostringstream os(std::ios_base::binary); + if(privs & PRIV_BUILD) + os< pr; + pr=str_split(str, ','); + for(std::vector::iterator i = pr.begin(); + i != pr.end(); ++i) + { + if(*i == L"build") + privs |= PRIV_BUILD; + else if(*i == L"teleport") + privs |= PRIV_TELEPORT; + else if(*i == L"settime") + privs |= PRIV_SETTIME; + else if(*i == L"privs") + privs |= PRIV_PRIVS; + else + return PRIV_INVALID; + } + return privs; + } + }; /* diff --git a/src/server.cpp b/src/server.cpp index b5a38aa06..f77b4f3c6 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "materials.h" #include "mineral.h" #include "config.h" +#include "servercommand.h" #define BLOCK_EMERGE_FLAG_FROMDISK (1<<0) @@ -1994,6 +1995,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) if(datasize < 13) return; + if((player->privs & PRIV_BUILD) == 0) + return; + /* [0] u16 command [2] u8 button (0=left, 1=right) @@ -2075,6 +2079,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) if(datasize < 7) return; + if((player->privs & PRIV_BUILD) == 0) + return; + /* length: 7 [0] u16 command @@ -2167,6 +2174,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) { if(datasize < 17) return; + if((player->privs & PRIV_BUILD) == 0) + return; /* length: 17 [0] u16 command @@ -2615,6 +2624,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) #endif else if(command == TOSERVER_SIGNTEXT) { + if((player->privs & PRIV_BUILD) == 0) + return; /* u16 command v3s16 blockpos @@ -2672,6 +2683,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } else if(command == TOSERVER_SIGNNODETEXT) { + if((player->privs & PRIV_BUILD) == 0) + return; /* u16 command v3s16 p @@ -2853,71 +2866,19 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) line += L"Server: "; message = message.substr(commandprefix.size()); - // Get player name as narrow string - std::string name_s = player->getName(); - // Convert message to narrow string - std::string message_s = wide_to_narrow(message); - // Operator is the single name defined in config. - std::string operator_name = g_settings.get("name"); - bool is_operator = (operator_name != "" && - wide_to_narrow(name) == operator_name); - bool valid_command = false; - if(message_s == "help") - { - line += L"-!- Available commands: "; - line += L"status "; - if(is_operator) - { - line += L"shutdown setting time "; - } - else - { - } - send_to_sender = true; - valid_command = true; - } - else if(message_s == "status") - { - line = getStatusString(); - send_to_sender = true; - valid_command = true; - } - else if(is_operator) - { - if(message_s == "shutdown") - { - dstream<flags & 1; + send_to_others = ctx->flags & 2; + delete ctx; + } else { diff --git a/src/server.h b/src/server.h index 4603f98ed..d8b47aef9 100644 --- a/src/server.h +++ b/src/server.h @@ -387,6 +387,12 @@ public: return time_to_daynight_ratio(m_time_of_day.get()); } + void setTimeOfDay(u32 time) + { + m_time_of_day.set(time); + m_time_of_day_send_timer = 0; + } + bool getShutdownRequested() { return m_shutdown_requested.get(); @@ -405,6 +411,19 @@ public: Inventory* getInventory(InventoryContext *c, std::string id); void inventoryModified(InventoryContext *c, std::string id); + // Connection must be locked when called + std::wstring getStatusString(); + + void requestShutdown(void) + { + m_shutdown_requested.set(true); + } + + + // Envlock and conlock should be locked when calling this + void SendMovePlayer(Player *player); + + private: // Virtual methods from con::PeerHandler. @@ -429,7 +448,6 @@ private: void SendChatMessage(u16 peer_id, const std::wstring &message); void BroadcastChatMessage(const std::wstring &message); void SendPlayerHP(Player *player); - void SendMovePlayer(Player *player); /* Send a node removal/addition event to all clients except ignore_id. Additionally, if far_players!=NULL, players further away than @@ -455,9 +473,6 @@ private: // When called, connection mutex should be locked RemoteClient* getClient(u16 peer_id); - // Connection must be locked when called - std::wstring getStatusString(); - /* Get a player from memory or creates one. If player is already connected, return NULL diff --git a/src/servercommand.cpp b/src/servercommand.cpp new file mode 100644 index 000000000..fa841a1bb --- /dev/null +++ b/src/servercommand.cpp @@ -0,0 +1,233 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola +Copyright (C) 2011 Ciaran Gultnieks + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "servercommand.h" +#include "utility.h" + +// 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 ServerCommand::processCommand(ServerCommandContext *ctx) +{ + + std::wostringstream os(std::ios_base::binary); + ctx->flags = 1; // Default, unless we change it. + + u64 privs = ctx->player->privs; + + if(ctx->parms.size() == 0 || ctx->parms[0] == L"help") + { + os<parms[0] == L"status") + { + cmd_status(os, ctx); + } + else if(ctx->parms[0] == L"privs") + { + cmd_privs(os, ctx); + } + else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke") + { + cmd_grantrevoke(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"setting") + { + cmd_setting(os, ctx); + } + else if(ctx->parms[0] == L"teleport") + { + cmd_teleport(os, ctx); + } + else + { + os<parms[0]; + } + return os.str(); +} + +void ServerCommand::cmd_status(std::wostringstream &os, + ServerCommandContext *ctx) +{ + os<server->getStatusString(); +} + +void ServerCommand::cmd_privs(std::wostringstream &os, + ServerCommandContext *ctx) +{ + if(ctx->parms.size() == 1) + { + os<player->privs); + return; + } + + if((ctx->player->privs & PRIV_PRIVS) == 0) + { + os<env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str()); + if(tp == NULL) + { + os<privs); +} + +void ServerCommand::cmd_grantrevoke(std::wostringstream &os, + ServerCommandContext *ctx) +{ + if(ctx->parms.size() != 3) + { + os<player->privs & PRIV_PRIVS) == 0) + { + os<parms[2]); + if(newprivs == PRIV_INVALID) + { + os<env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str()); + if(tp == NULL) + { + os<parms[0] == L"grant") + tp->privs |= newprivs; + else + tp->privs &= ~newprivs; + + os<privs); +} + +void ServerCommand::cmd_time(std::wostringstream &os, + ServerCommandContext *ctx) +{ + if(ctx->parms.size() != 2) + { + os<player->privs & PRIV_SETTIME) ==0) + { + os<parms[1])); + ctx->server->setTimeOfDay(time); + os<player->privs & PRIV_SERVER) ==0) + { + os<server->requestShutdown(); + + os<flags |= 2; +} + +void ServerCommand::cmd_setting(std::wostringstream &os, + ServerCommandContext *ctx) +{ + if((ctx->player->privs & PRIV_SERVER) ==0) + { + os<parms[1] + L" = " + ctx->parms[2]); + g_settings.parseConfigLine(confline); + os<< L"-!- Setting changed."; +} + +void ServerCommand::cmd_teleport(std::wostringstream &os, + ServerCommandContext *ctx) +{ + if((ctx->player->privs & PRIV_TELEPORT) ==0) + { + os<parms.size() != 2) + { + os< coords = str_split(ctx->parms[1], L','); + if(coords.size() != 3) + { + os<player->setPosition(dest); + ctx->server->SendMovePlayer(ctx->player); + + os<< L"-!- Teleported."; +} + diff --git a/src/servercommand.h b/src/servercommand.h new file mode 100644 index 000000000..01efcae06 --- /dev/null +++ b/src/servercommand.h @@ -0,0 +1,76 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola +Copyright (C) 2011 Ciaran Gultnieks + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef SERVERCOMMAND_HEADER +#define SERVERCOMMAND_HEADER + +#include +#include +#include "common_irrlicht.h" +#include "player.h" +#include "server.h" + +struct ServerCommandContext +{ + + std::vector parms; + Server* server; + ServerEnvironment *env; + Player* player; + u32 flags; + + ServerCommandContext( + std::vector parms, + Server* server, + ServerEnvironment *env, + Player* player) + : parms(parms), server(server), env(env), player(player) + { + } + +}; + +class ServerCommand +{ +public: + + static std::wstring processCommand(ServerCommandContext *ctx); + +private: + + static void cmd_status(std::wostringstream &os, + ServerCommandContext *ctx); + static void cmd_privs(std::wostringstream &os, + ServerCommandContext *ctx); + static void cmd_grantrevoke(std::wostringstream &os, + ServerCommandContext *ctx); + static void cmd_time(std::wostringstream &os, + ServerCommandContext *ctx); + static void cmd_shutdown(std::wostringstream &os, + ServerCommandContext *ctx); + static void cmd_setting(std::wostringstream &os, + ServerCommandContext *ctx); + static void cmd_teleport(std::wostringstream &os, + ServerCommandContext *ctx); +}; + +#endif + + diff --git a/src/utility.h b/src/utility.h index 12d732bea..326ebf161 100644 --- a/src/utility.h +++ b/src/utility.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include #include #include @@ -731,6 +732,19 @@ inline std::string wide_to_narrow(const std::wstring& wcs) return *mbs; } +// Split a string using the given delimiter. Returns a vector containing +// the component parts. +inline std::vector str_split(const std::wstring &str, wchar_t delimiter) +{ + std::vector parts; + std::wstringstream sstr(str); + std::wstring part; + while(std::getline(sstr, part, delimiter)) + parts.push_back(part); + return parts; +} + + /* See test.cpp for example cases. wraps degrees to the range of -360...360 @@ -791,6 +805,11 @@ inline s32 stoi(std::string s) return atoi(s.c_str()); } +inline s32 stoi(std::wstring s) +{ + return atoi(wide_to_narrow(s).c_str()); +} + inline float stof(std::string s) { float f; -- cgit v1.2.3 From 50c48219a7ee6fe11566779f03e5e80361155b3f Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Mon, 16 May 2011 11:32:49 +0100 Subject: Allow "all" to be specified in player config file for privileges --- src/player.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/player.cpp b/src/player.cpp index a6ddeee64..2ebf158a6 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -144,7 +144,16 @@ void Player::deSerialize(std::istream &is) hp = 20; } try{ - privs = args.getU64("privs"); + std::string sprivs = args.get("privs"); + if(sprivs == "all") + { + privs = PRIV_ALL; + } + else + { + std::istringstream ss(sprivs); + ss>>privs; + } }catch(SettingNotFoundException &e){ privs = PRIV_DEFAULT; } -- cgit v1.2.3 From 7cdd988f88ae3fc5b1ca342c3c5e176eec0ba8f9 Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Mon, 16 May 2011 11:34:06 +0100 Subject: Better synchronisation of build/mine attempts when the player isn't allowed to --- src/server.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server.cpp b/src/server.cpp index f77b4f3c6..338b528e7 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2174,8 +2174,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) { if(datasize < 17) return; - if((player->privs & PRIV_BUILD) == 0) - return; /* length: 17 [0] u16 command @@ -2281,6 +2279,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) cannot_remove_node = true; } + // Make sure the player is allowed to do it + if((player->privs & PRIV_BUILD) == 0) + cannot_remove_node = true; + /* If node can't be removed, set block to be re-sent to client and quit. @@ -2427,7 +2429,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) try{ // Don't add a node if this is not a free space MapNode n2 = m_env.getMap().getNode(p_over); - if(content_buildable_to(n2.d) == false) + if(content_buildable_to(n2.d) == false + || (player->privs & PRIV_BUILD) ==0) { // Client probably has wrong data. // Set block not sent, so that client will get -- cgit v1.2.3 From 1520d49310c07b1f8500582b6ac22baedcc80dcb Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Mon, 16 May 2011 16:13:17 +0100 Subject: Privileges to/from string conversion functions standalone, not static members --- src/player.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++ src/player.h | 57 ++++++++------------------------------------------- src/servercommand.cpp | 8 ++++---- 3 files changed, 62 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/player.cpp b/src/player.cpp index 2ebf158a6..e568d7dee 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -23,6 +23,55 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "constants.h" #include "utility.h" +// Convert a privileges value into a human-readable string, +// with each component separated by a comma. +std::wstring privsToString(u64 privs) +{ + std::wostringstream os(std::ios_base::binary); + if(privs & PRIV_BUILD) + os< pr; + pr=str_split(str, ','); + for(std::vector::iterator i = pr.begin(); + i != pr.end(); ++i) + { + if(*i == L"build") + privs |= PRIV_BUILD; + else if(*i == L"teleport") + privs |= PRIV_TELEPORT; + else if(*i == L"settime") + privs |= PRIV_SETTIME; + else if(*i == L"privs") + privs |= PRIV_PRIVS; + else + return PRIV_INVALID; + } + return privs; +} + + Player::Player(): touching_ground(false), in_water(false), diff --git a/src/player.h b/src/player.h index 778bb54b3..be93766fd 100644 --- a/src/player.h +++ b/src/player.h @@ -43,6 +43,15 @@ const u64 PRIV_DEFAULT = PRIV_BUILD; const u64 PRIV_ALL = 0x7FFFFFFFFFFFFFFFULL; const u64 PRIV_INVALID = 0x8000000000000000ULL; +// Convert a privileges value into a human-readable string, +// with each component separated by a comma. +std::wstring privsToString(u64 privs); + +// Converts a comma-seperated list of privilege values into a +// privileges value. The reverse of privsToString(). Returns +// PRIV_INVALID if there is anything wrong with the input. +u64 stringToPrivs(std::wstring str); + class Map; @@ -155,54 +164,6 @@ protected: public: - // Converst a prvileges value into a human-readable string, - // with each component separated by a comma. - static std::wstring privsToString(u64 privs) - { - std::wostringstream os(std::ios_base::binary); - if(privs & PRIV_BUILD) - os< pr; - pr=str_split(str, ','); - for(std::vector::iterator i = pr.begin(); - i != pr.end(); ++i) - { - if(*i == L"build") - privs |= PRIV_BUILD; - else if(*i == L"teleport") - privs |= PRIV_TELEPORT; - else if(*i == L"settime") - privs |= PRIV_SETTIME; - else if(*i == L"privs") - privs |= PRIV_PRIVS; - else - return PRIV_INVALID; - } - return privs; - } - }; /* diff --git a/src/servercommand.cpp b/src/servercommand.cpp index fa841a1bb..21483b548 100644 --- a/src/servercommand.cpp +++ b/src/servercommand.cpp @@ -93,7 +93,7 @@ void ServerCommand::cmd_privs(std::wostringstream &os, { if(ctx->parms.size() == 1) { - os<player->privs); + os<player->privs); return; } @@ -110,7 +110,7 @@ void ServerCommand::cmd_privs(std::wostringstream &os, return; } - os<privs); + os<privs); } void ServerCommand::cmd_grantrevoke(std::wostringstream &os, @@ -128,7 +128,7 @@ void ServerCommand::cmd_grantrevoke(std::wostringstream &os, return; } - u64 newprivs = Player::stringToPrivs(ctx->parms[2]); + u64 newprivs = stringToPrivs(ctx->parms[2]); if(newprivs == PRIV_INVALID) { os<privs &= ~newprivs; os<privs); + os<privs); } void ServerCommand::cmd_time(std::wostringstream &os, -- cgit v1.2.3 From b3268ff3896097abdd9199e4bb8ee826afda8388 Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Mon, 16 May 2011 17:13:33 +0100 Subject: Server commands without classes --- src/server.cpp | 2 +- src/servercommand.cpp | 132 +++++++++++++++++++++++++------------------------- src/servercommand.h | 28 ++--------- 3 files changed, 71 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/server.cpp b/src/server.cpp index 338b528e7..d3ca32ac7 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2877,7 +2877,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) player ); - line += ServerCommand::processCommand(ctx); + line += processServerCommand(ctx); send_to_sender = ctx->flags & 1; send_to_others = ctx->flags & 2; delete ctx; diff --git a/src/servercommand.cpp b/src/servercommand.cpp index 21483b548..215dc0d27 100644 --- a/src/servercommand.cpp +++ b/src/servercommand.cpp @@ -22,73 +22,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "servercommand.h" #include "utility.h" -// 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 ServerCommand::processCommand(ServerCommandContext *ctx) -{ - - std::wostringstream os(std::ios_base::binary); - ctx->flags = 1; // Default, unless we change it. - - u64 privs = ctx->player->privs; - - if(ctx->parms.size() == 0 || ctx->parms[0] == L"help") - { - os<parms[0] == L"status") - { - cmd_status(os, ctx); - } - else if(ctx->parms[0] == L"privs") - { - cmd_privs(os, ctx); - } - else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke") - { - cmd_grantrevoke(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"setting") - { - cmd_setting(os, ctx); - } - else if(ctx->parms[0] == L"teleport") - { - cmd_teleport(os, ctx); - } - else - { - os<parms[0]; - } - return os.str(); -} - -void ServerCommand::cmd_status(std::wostringstream &os, +void cmd_status(std::wostringstream &os, ServerCommandContext *ctx) { os<server->getStatusString(); } -void ServerCommand::cmd_privs(std::wostringstream &os, +void cmd_privs(std::wostringstream &os, ServerCommandContext *ctx) { if(ctx->parms.size() == 1) @@ -113,7 +53,7 @@ void ServerCommand::cmd_privs(std::wostringstream &os, os<privs); } -void ServerCommand::cmd_grantrevoke(std::wostringstream &os, +void cmd_grantrevoke(std::wostringstream &os, ServerCommandContext *ctx) { if(ctx->parms.size() != 3) @@ -151,7 +91,7 @@ void ServerCommand::cmd_grantrevoke(std::wostringstream &os, os<privs); } -void ServerCommand::cmd_time(std::wostringstream &os, +void cmd_time(std::wostringstream &os, ServerCommandContext *ctx) { if(ctx->parms.size() != 2) @@ -171,7 +111,7 @@ void ServerCommand::cmd_time(std::wostringstream &os, os<player->privs & PRIV_SERVER) ==0) @@ -188,7 +128,7 @@ void ServerCommand::cmd_shutdown(std::wostringstream &os, ctx->flags |= 2; } -void ServerCommand::cmd_setting(std::wostringstream &os, +void cmd_setting(std::wostringstream &os, ServerCommandContext *ctx) { if((ctx->player->privs & PRIV_SERVER) ==0) @@ -202,7 +142,7 @@ void ServerCommand::cmd_setting(std::wostringstream &os, os<< L"-!- Setting changed."; } -void ServerCommand::cmd_teleport(std::wostringstream &os, +void cmd_teleport(std::wostringstream &os, ServerCommandContext *ctx) { if((ctx->player->privs & PRIV_TELEPORT) ==0) @@ -231,3 +171,61 @@ void ServerCommand::cmd_teleport(std::wostringstream &os, os<< L"-!- Teleported."; } + +std::wstring processServerCommand(ServerCommandContext *ctx) +{ + + std::wostringstream os(std::ios_base::binary); + ctx->flags = 1; // Default, unless we change it. + + u64 privs = ctx->player->privs; + + if(ctx->parms.size() == 0 || ctx->parms[0] == L"help") + { + os<parms[0] == L"status") + { + cmd_status(os, ctx); + } + else if(ctx->parms[0] == L"privs") + { + cmd_privs(os, ctx); + } + else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke") + { + cmd_grantrevoke(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"setting") + { + cmd_setting(os, ctx); + } + else if(ctx->parms[0] == L"teleport") + { + cmd_teleport(os, ctx); + } + else + { + os<parms[0]; + } + return os.str(); +} + + diff --git a/src/servercommand.h b/src/servercommand.h index 01efcae06..bc7823c66 100644 --- a/src/servercommand.h +++ b/src/servercommand.h @@ -47,29 +47,11 @@ struct ServerCommandContext }; -class ServerCommand -{ -public: - - static std::wstring processCommand(ServerCommandContext *ctx); - -private: - - static void cmd_status(std::wostringstream &os, - ServerCommandContext *ctx); - static void cmd_privs(std::wostringstream &os, - ServerCommandContext *ctx); - static void cmd_grantrevoke(std::wostringstream &os, - ServerCommandContext *ctx); - static void cmd_time(std::wostringstream &os, - ServerCommandContext *ctx); - static void cmd_shutdown(std::wostringstream &os, - ServerCommandContext *ctx); - static void cmd_setting(std::wostringstream &os, - ServerCommandContext *ctx); - static void cmd_teleport(std::wostringstream &os, - ServerCommandContext *ctx); -}; +// 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 -- cgit v1.2.3