merged CiaranG's changes (player privileges)
This commit is contained in:
commit
94c9686020
|
@ -69,6 +69,7 @@ set(common_SRCS
|
||||||
connection.cpp
|
connection.cpp
|
||||||
environment.cpp
|
environment.cpp
|
||||||
server.cpp
|
server.cpp
|
||||||
|
servercommand.cpp
|
||||||
socket.cpp
|
socket.cpp
|
||||||
mapblock.cpp
|
mapblock.cpp
|
||||||
mapsector.cpp
|
mapsector.cpp
|
||||||
|
|
|
@ -23,6 +23,55 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "utility.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<<L"build,";
|
||||||
|
if(privs & PRIV_TELEPORT)
|
||||||
|
os<<L"teleport,";
|
||||||
|
if(privs & PRIV_SETTIME)
|
||||||
|
os<<L"settime,";
|
||||||
|
if(privs & PRIV_PRIVS)
|
||||||
|
os<<L"privs,";
|
||||||
|
if(os.tellp())
|
||||||
|
{
|
||||||
|
// Drop the trailing comma. (Why on earth can't
|
||||||
|
// you truncate a C++ stream anyway???)
|
||||||
|
std::wstring tmp = os.str();
|
||||||
|
return tmp.substr(0, tmp.length() -1);
|
||||||
|
}
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
u64 privs=0;
|
||||||
|
std::vector<std::wstring> pr;
|
||||||
|
pr=str_split(str, ',');
|
||||||
|
for(std::vector<std::wstring>::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():
|
Player::Player():
|
||||||
touching_ground(false),
|
touching_ground(false),
|
||||||
in_water(false),
|
in_water(false),
|
||||||
|
@ -34,7 +83,8 @@ Player::Player():
|
||||||
m_pitch(0),
|
m_pitch(0),
|
||||||
m_yaw(0),
|
m_yaw(0),
|
||||||
m_speed(0,0,0),
|
m_speed(0,0,0),
|
||||||
m_position(0,0,0)
|
m_position(0,0,0),
|
||||||
|
privs(PRIV_DEFAULT)
|
||||||
{
|
{
|
||||||
updateName("<not set>");
|
updateName("<not set>");
|
||||||
resetInventory();
|
resetInventory();
|
||||||
|
@ -100,6 +150,7 @@ void Player::serialize(std::ostream &os)
|
||||||
args.setV3F("position", m_position);
|
args.setV3F("position", m_position);
|
||||||
args.setBool("craftresult_is_preview", craftresult_is_preview);
|
args.setBool("craftresult_is_preview", craftresult_is_preview);
|
||||||
args.setS32("hp", hp);
|
args.setS32("hp", hp);
|
||||||
|
args.setU64("privs", privs);
|
||||||
|
|
||||||
args.writeLines(os);
|
args.writeLines(os);
|
||||||
|
|
||||||
|
@ -141,6 +192,20 @@ void Player::deSerialize(std::istream &is)
|
||||||
}catch(SettingNotFoundException &e){
|
}catch(SettingNotFoundException &e){
|
||||||
hp = 20;
|
hp = 20;
|
||||||
}
|
}
|
||||||
|
try{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
inventory.deSerialize(is);
|
inventory.deSerialize(is);
|
||||||
}
|
}
|
||||||
|
|
33
src/player.h
33
src/player.h
|
@ -28,11 +28,38 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,"
|
#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;
|
||||||
|
|
||||||
|
// 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;
|
class Map;
|
||||||
|
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
Player();
|
Player();
|
||||||
virtual ~Player();
|
virtual ~Player();
|
||||||
|
|
||||||
|
@ -123,6 +150,9 @@ public:
|
||||||
|
|
||||||
u16 hp;
|
u16 hp;
|
||||||
|
|
||||||
|
// Player's privileges - a bitmaps of PRIV_xxxx.
|
||||||
|
u64 privs;
|
||||||
|
|
||||||
u16 peer_id;
|
u16 peer_id;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -131,6 +161,9 @@ protected:
|
||||||
f32 m_yaw;
|
f32 m_yaw;
|
||||||
v3f m_speed;
|
v3f m_speed;
|
||||||
v3f m_position;
|
v3f m_position;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "materials.h"
|
#include "materials.h"
|
||||||
#include "mineral.h"
|
#include "mineral.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "servercommand.h"
|
||||||
|
|
||||||
#define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
|
#define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
|
||||||
|
|
||||||
|
@ -1994,6 +1995,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
if(datasize < 13)
|
if(datasize < 13)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if((player->privs & PRIV_BUILD) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[0] u16 command
|
[0] u16 command
|
||||||
[2] u8 button (0=left, 1=right)
|
[2] u8 button (0=left, 1=right)
|
||||||
|
@ -2075,6 +2079,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
if(datasize < 7)
|
if(datasize < 7)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if((player->privs & PRIV_BUILD) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
length: 7
|
length: 7
|
||||||
[0] u16 command
|
[0] u16 command
|
||||||
|
@ -2272,6 +2279,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
cannot_remove_node = true;
|
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
|
If node can't be removed, set block to be re-sent to
|
||||||
client and quit.
|
client and quit.
|
||||||
|
@ -2418,7 +2429,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
try{
|
try{
|
||||||
// Don't add a node if this is not a free space
|
// Don't add a node if this is not a free space
|
||||||
MapNode n2 = m_env.getMap().getNode(p_over);
|
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.
|
// Client probably has wrong data.
|
||||||
// Set block not sent, so that client will get
|
// Set block not sent, so that client will get
|
||||||
|
@ -2615,6 +2627,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
#endif
|
#endif
|
||||||
else if(command == TOSERVER_SIGNTEXT)
|
else if(command == TOSERVER_SIGNTEXT)
|
||||||
{
|
{
|
||||||
|
if((player->privs & PRIV_BUILD) == 0)
|
||||||
|
return;
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
v3s16 blockpos
|
v3s16 blockpos
|
||||||
|
@ -2672,6 +2686,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
else if(command == TOSERVER_SIGNNODETEXT)
|
else if(command == TOSERVER_SIGNNODETEXT)
|
||||||
{
|
{
|
||||||
|
if((player->privs & PRIV_BUILD) == 0)
|
||||||
|
return;
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
v3s16 p
|
v3s16 p
|
||||||
|
@ -2853,71 +2869,19 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
line += L"Server: ";
|
line += L"Server: ";
|
||||||
|
|
||||||
message = message.substr(commandprefix.size());
|
message = message.substr(commandprefix.size());
|
||||||
// Get player name as narrow string
|
|
||||||
std::string name_s = player->getName();
|
ServerCommandContext *ctx = new ServerCommandContext(
|
||||||
// Convert message to narrow string
|
str_split(message, L' '),
|
||||||
std::string message_s = wide_to_narrow(message);
|
this,
|
||||||
// Operator is the single name defined in config.
|
&m_env,
|
||||||
std::string operator_name = g_settings.get("name");
|
player
|
||||||
bool is_operator = (operator_name != "" &&
|
);
|
||||||
wide_to_narrow(name) == operator_name);
|
|
||||||
bool valid_command = false;
|
line += processServerCommand(ctx);
|
||||||
if(message_s == "help")
|
send_to_sender = ctx->flags & 1;
|
||||||
{
|
send_to_others = ctx->flags & 2;
|
||||||
line += L"-!- Available commands: ";
|
delete ctx;
|
||||||
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<<DTIME<<" Server: Operator requested shutdown."
|
|
||||||
<<std::endl;
|
|
||||||
m_shutdown_requested.set(true);
|
|
||||||
|
|
||||||
line += L"*** Server shutting down (operator request)";
|
|
||||||
send_to_sender = true;
|
|
||||||
valid_command = true;
|
|
||||||
}
|
|
||||||
else if(message_s.substr(0,8) == "setting ")
|
|
||||||
{
|
|
||||||
std::string confline = message_s.substr(8);
|
|
||||||
g_settings.parseConfigLine(confline);
|
|
||||||
line += L"-!- Setting changed.";
|
|
||||||
send_to_sender = true;
|
|
||||||
valid_command = true;
|
|
||||||
}
|
|
||||||
else if(message_s.substr(0,5) == "time ")
|
|
||||||
{
|
|
||||||
u32 time = stoi(message_s.substr(5));
|
|
||||||
m_time_of_day.set(time);
|
|
||||||
m_time_of_day_send_timer = 0;
|
|
||||||
line += L"-!- time_of_day changed.";
|
|
||||||
send_to_sender = true;
|
|
||||||
valid_command = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(valid_command == false)
|
|
||||||
{
|
|
||||||
line += L"-!- Invalid command: " + message;
|
|
||||||
send_to_sender = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
23
src/server.h
23
src/server.h
|
@ -387,6 +387,12 @@ public:
|
||||||
return time_to_daynight_ratio(m_time_of_day.get());
|
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()
|
bool getShutdownRequested()
|
||||||
{
|
{
|
||||||
return m_shutdown_requested.get();
|
return m_shutdown_requested.get();
|
||||||
|
@ -405,6 +411,19 @@ public:
|
||||||
Inventory* getInventory(InventoryContext *c, std::string id);
|
Inventory* getInventory(InventoryContext *c, std::string id);
|
||||||
void inventoryModified(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:
|
private:
|
||||||
|
|
||||||
// Virtual methods from con::PeerHandler.
|
// Virtual methods from con::PeerHandler.
|
||||||
|
@ -429,7 +448,6 @@ private:
|
||||||
void SendChatMessage(u16 peer_id, const std::wstring &message);
|
void SendChatMessage(u16 peer_id, const std::wstring &message);
|
||||||
void BroadcastChatMessage(const std::wstring &message);
|
void BroadcastChatMessage(const std::wstring &message);
|
||||||
void SendPlayerHP(Player *player);
|
void SendPlayerHP(Player *player);
|
||||||
void SendMovePlayer(Player *player);
|
|
||||||
/*
|
/*
|
||||||
Send a node removal/addition event to all clients except ignore_id.
|
Send a node removal/addition event to all clients except ignore_id.
|
||||||
Additionally, if far_players!=NULL, players further away than
|
Additionally, if far_players!=NULL, players further away than
|
||||||
|
@ -455,9 +473,6 @@ private:
|
||||||
// When called, connection mutex should be locked
|
// When called, connection mutex should be locked
|
||||||
RemoteClient* getClient(u16 peer_id);
|
RemoteClient* getClient(u16 peer_id);
|
||||||
|
|
||||||
// Connection must be locked when called
|
|
||||||
std::wstring getStatusString();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get a player from memory or creates one.
|
Get a player from memory or creates one.
|
||||||
If player is already connected, return NULL
|
If player is already connected, return NULL
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
void cmd_status(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
os<<ctx->server->getStatusString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_privs(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
if(ctx->parms.size() == 1)
|
||||||
|
{
|
||||||
|
os<<L"-!- " + privsToString(ctx->player->privs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ctx->player->privs & PRIV_PRIVS) == 0)
|
||||||
|
{
|
||||||
|
os<<L"-!- You don't have permission to do that";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
|
||||||
|
if(tp == NULL)
|
||||||
|
{
|
||||||
|
os<<L"-!- No such player";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
os<<L"-!- " + privsToString(tp->privs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_grantrevoke(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
if(ctx->parms.size() != 3)
|
||||||
|
{
|
||||||
|
os<<L"-!- Missing parameter";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ctx->player->privs & PRIV_PRIVS) == 0)
|
||||||
|
{
|
||||||
|
os<<L"-!- You don't have permission to do that";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 newprivs = stringToPrivs(ctx->parms[2]);
|
||||||
|
if(newprivs == PRIV_INVALID)
|
||||||
|
{
|
||||||
|
os<<L"-!- Invalid privileges specified";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
|
||||||
|
if(tp == NULL)
|
||||||
|
{
|
||||||
|
os<<L"-!- No such player";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->parms[0] == L"grant")
|
||||||
|
tp->privs |= newprivs;
|
||||||
|
else
|
||||||
|
tp->privs &= ~newprivs;
|
||||||
|
|
||||||
|
os<<L"-!- Privileges change to ";
|
||||||
|
os<<privsToString(tp->privs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_time(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
if(ctx->parms.size() != 2)
|
||||||
|
{
|
||||||
|
os<<L"-!- Missing parameter";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ctx->player->privs & PRIV_SETTIME) ==0)
|
||||||
|
{
|
||||||
|
os<<L"-!- You don't have permission to do that";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 time = stoi(wide_to_narrow(ctx->parms[1]));
|
||||||
|
ctx->server->setTimeOfDay(time);
|
||||||
|
os<<L"-!- time_of_day changed.";
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_shutdown(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
if((ctx->player->privs & PRIV_SERVER) ==0)
|
||||||
|
{
|
||||||
|
os<<L"-!- You don't have permission to do that";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dstream<<DTIME<<" Server: Operator requested shutdown."
|
||||||
|
<<std::endl;
|
||||||
|
ctx->server->requestShutdown();
|
||||||
|
|
||||||
|
os<<L"*** Server shutting down (operator request)";
|
||||||
|
ctx->flags |= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_setting(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
if((ctx->player->privs & PRIV_SERVER) ==0)
|
||||||
|
{
|
||||||
|
os<<L"-!- You don't have permission to do that";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string confline = wide_to_narrow(ctx->parms[1] + L" = " + ctx->parms[2]);
|
||||||
|
g_settings.parseConfigLine(confline);
|
||||||
|
os<< L"-!- Setting changed.";
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_teleport(std::wostringstream &os,
|
||||||
|
ServerCommandContext *ctx)
|
||||||
|
{
|
||||||
|
if((ctx->player->privs & PRIV_TELEPORT) ==0)
|
||||||
|
{
|
||||||
|
os<<L"-!- You don't have permission to do that";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->parms.size() != 2)
|
||||||
|
{
|
||||||
|
os<<L"-!- Missing parameter";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::wstring> coords = str_split(ctx->parms[1], L',');
|
||||||
|
if(coords.size() != 3)
|
||||||
|
{
|
||||||
|
os<<L"-!- You can only specify coordinates currently";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
v3f dest(stoi(coords[0])*10, stoi(coords[1])*10, stoi(coords[2])*10);
|
||||||
|
ctx->player->setPosition(dest);
|
||||||
|
ctx->server->SendMovePlayer(ctx->player);
|
||||||
|
|
||||||
|
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<<L"-!- Available commands: ";
|
||||||
|
os<<L"status privs ";
|
||||||
|
if(privs & PRIV_SERVER)
|
||||||
|
os<<L"shutdown setting ";
|
||||||
|
if(privs & PRIV_SETTIME)
|
||||||
|
os<<L" time";
|
||||||
|
if(privs & PRIV_TELEPORT)
|
||||||
|
os<<L" teleport";
|
||||||
|
if(privs & PRIV_PRIVS)
|
||||||
|
os<<L" grant revoke";
|
||||||
|
}
|
||||||
|
else if(ctx->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<<L"-!- Invalid command: " + ctx->parms[0];
|
||||||
|
}
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
|
||||||
|
|
||||||
|
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 <vector>
|
||||||
|
#include <sstream>
|
||||||
|
#include "common_irrlicht.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
|
struct ServerCommandContext
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<std::wstring> parms;
|
||||||
|
Server* server;
|
||||||
|
ServerEnvironment *env;
|
||||||
|
Player* player;
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
|
ServerCommandContext(
|
||||||
|
std::vector<std::wstring> parms,
|
||||||
|
Server* server,
|
||||||
|
ServerEnvironment *env,
|
||||||
|
Player* player)
|
||||||
|
: parms(parms), 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
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
#include <jthread.h>
|
#include <jthread.h>
|
||||||
#include <jmutex.h>
|
#include <jmutex.h>
|
||||||
#include <jmutexautolock.h>
|
#include <jmutexautolock.h>
|
||||||
|
@ -731,6 +732,19 @@ inline std::string wide_to_narrow(const std::wstring& wcs)
|
||||||
return *mbs;
|
return *mbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Split a string using the given delimiter. Returns a vector containing
|
||||||
|
// the component parts.
|
||||||
|
inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
|
||||||
|
{
|
||||||
|
std::vector<std::wstring> 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.
|
See test.cpp for example cases.
|
||||||
wraps degrees to the range of -360...360
|
wraps degrees to the range of -360...360
|
||||||
|
@ -791,6 +805,11 @@ inline s32 stoi(std::string s)
|
||||||
return atoi(s.c_str());
|
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)
|
inline float stof(std::string s)
|
||||||
{
|
{
|
||||||
float f;
|
float f;
|
||||||
|
|
Loading…
Reference in New Issue