forked from Mirrorlandia_minetest/minetest
player passwords and privileges in world/auth.txt
--HG-- extra : rebase_source : 7260636295d9068fbeeddf4143c89f2b8a91446c
This commit is contained in:
parent
99c2ac0125
commit
63611932eb
@ -1,4 +1,5 @@
|
|||||||
map/*
|
map/*
|
||||||
|
world/*
|
||||||
CMakeFiles/*
|
CMakeFiles/*
|
||||||
src/CMakeFiles/*
|
src/CMakeFiles/*
|
||||||
src/Makefile
|
src/Makefile
|
||||||
|
@ -13,6 +13,7 @@ X:
|
|||||||
- Slightly updated map format
|
- Slightly updated map format
|
||||||
- Player passwords
|
- Player passwords
|
||||||
- All textures first searched from texture_path
|
- All textures first searched from texture_path
|
||||||
|
- Map directory ("map") has been renamed to "world" (just rename it to load an old world)
|
||||||
|
|
||||||
2011-04-24:
|
2011-04-24:
|
||||||
- Smooth lighting with simple ambient occlusion
|
- Smooth lighting with simple ambient occlusion
|
||||||
|
@ -102,6 +102,11 @@
|
|||||||
|
|
||||||
#enable_damage = false
|
#enable_damage = false
|
||||||
|
|
||||||
|
#default_password =
|
||||||
|
|
||||||
|
# Available privileges: build, teleport, settime, privs, shout
|
||||||
|
#default_privs = build, shout
|
||||||
|
|
||||||
# Gives some stuff to players at the beginning
|
# Gives some stuff to players at the beginning
|
||||||
#give_initial_stuff = false
|
#give_initial_stuff = false
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ configure_file(
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(common_SRCS
|
set(common_SRCS
|
||||||
|
auth.cpp
|
||||||
collision.cpp
|
collision.cpp
|
||||||
nodemetadata.cpp
|
nodemetadata.cpp
|
||||||
serverobject.cpp
|
serverobject.cpp
|
||||||
|
244
src/auth.cpp
Normal file
244
src/auth.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.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 "auth.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <jmutexautolock.h>
|
||||||
|
//#include "main.h" // for g_settings
|
||||||
|
#include <sstream>
|
||||||
|
#include "strfnd.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
// Convert a privileges value into a human-readable string,
|
||||||
|
// with each component separated by a comma.
|
||||||
|
std::string privsToString(u64 privs)
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
if(privs & PRIV_BUILD)
|
||||||
|
os<<"build,";
|
||||||
|
if(privs & PRIV_TELEPORT)
|
||||||
|
os<<"teleport,";
|
||||||
|
if(privs & PRIV_SETTIME)
|
||||||
|
os<<"settime,";
|
||||||
|
if(privs & PRIV_PRIVS)
|
||||||
|
os<<"privs,";
|
||||||
|
if(privs & PRIV_SHOUT)
|
||||||
|
os<<"shout,";
|
||||||
|
if(os.tellp())
|
||||||
|
{
|
||||||
|
// Drop the trailing comma. (Why on earth can't
|
||||||
|
// you truncate a C++ stream anyway???)
|
||||||
|
std::string 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::string str)
|
||||||
|
{
|
||||||
|
u64 privs=0;
|
||||||
|
Strfnd f(str);
|
||||||
|
while(f.atend() == false)
|
||||||
|
{
|
||||||
|
std::string s = trim(f.next(","));
|
||||||
|
if(s == "build")
|
||||||
|
privs |= PRIV_BUILD;
|
||||||
|
else if(s == "teleport")
|
||||||
|
privs |= PRIV_TELEPORT;
|
||||||
|
else if(s == "settime")
|
||||||
|
privs |= PRIV_SETTIME;
|
||||||
|
else if(s == "privs")
|
||||||
|
privs |= PRIV_PRIVS;
|
||||||
|
else if(s == "shout")
|
||||||
|
privs |= PRIV_SHOUT;
|
||||||
|
else
|
||||||
|
return PRIV_INVALID;
|
||||||
|
}
|
||||||
|
return privs;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthManager::AuthManager(const std::string &authfilepath):
|
||||||
|
m_authfilepath(authfilepath)
|
||||||
|
{
|
||||||
|
m_mutex.Init();
|
||||||
|
|
||||||
|
try{
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
catch(SerializationError &e)
|
||||||
|
{
|
||||||
|
dstream<<"WARNING: AuthManager: creating "
|
||||||
|
<<m_authfilepath<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthManager::~AuthManager()
|
||||||
|
{
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::load()
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
dstream<<"AuthManager: loading from "<<m_authfilepath<<std::endl;
|
||||||
|
std::ifstream is(m_authfilepath.c_str(), std::ios::binary);
|
||||||
|
if(is.good() == false)
|
||||||
|
{
|
||||||
|
dstream<<"AuthManager: failed loading from "<<m_authfilepath<<std::endl;
|
||||||
|
throw SerializationError("AuthManager::load(): Couldn't open file");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(is.eof() || is.good() == false)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Read a line
|
||||||
|
std::string line;
|
||||||
|
std::getline(is, line, '\n');
|
||||||
|
|
||||||
|
std::istringstream iss(line);
|
||||||
|
|
||||||
|
// Read name
|
||||||
|
std::string name;
|
||||||
|
std::getline(iss, name, ':');
|
||||||
|
|
||||||
|
// Read password
|
||||||
|
std::string pwd;
|
||||||
|
std::getline(iss, pwd, ':');
|
||||||
|
|
||||||
|
// Read privileges
|
||||||
|
std::string stringprivs;
|
||||||
|
std::getline(iss, stringprivs, ':');
|
||||||
|
u64 privs = stringToPrivs(stringprivs);
|
||||||
|
|
||||||
|
// Store it
|
||||||
|
AuthData ad;
|
||||||
|
ad.pwd = pwd;
|
||||||
|
ad.privs = privs;
|
||||||
|
m_authdata[name] = ad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::save()
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
dstream<<"AuthManager: saving to "<<m_authfilepath<<std::endl;
|
||||||
|
std::ofstream os(m_authfilepath.c_str(), std::ios::binary);
|
||||||
|
if(os.good() == false)
|
||||||
|
{
|
||||||
|
dstream<<"AuthManager: failed saving to "<<m_authfilepath<<std::endl;
|
||||||
|
throw SerializationError("AuthManager::save(): Couldn't open file");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(core::map<std::string, AuthData>::Iterator
|
||||||
|
i = m_authdata.getIterator();
|
||||||
|
i.atEnd()==false; i++)
|
||||||
|
{
|
||||||
|
std::string name = i.getNode()->getKey();
|
||||||
|
if(name == "")
|
||||||
|
continue;
|
||||||
|
AuthData ad = i.getNode()->getValue();
|
||||||
|
os<<name<<":"<<ad.pwd<<":"<<privsToString(ad.privs)<<"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthManager::exists(const std::string &username)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
core::map<std::string, AuthData>::Node *n;
|
||||||
|
n = m_authdata.find(username);
|
||||||
|
if(n == NULL)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::set(const std::string &username, AuthData ad)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
m_authdata[username] = ad;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::add(const std::string &username)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
m_authdata[username] = AuthData();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AuthManager::getPassword(const std::string &username)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
core::map<std::string, AuthData>::Node *n;
|
||||||
|
n = m_authdata.find(username);
|
||||||
|
if(n == NULL)
|
||||||
|
throw AuthNotFoundException("");
|
||||||
|
|
||||||
|
return n->getValue().pwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::setPassword(const std::string &username,
|
||||||
|
const std::string &password)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
core::map<std::string, AuthData>::Node *n;
|
||||||
|
n = m_authdata.find(username);
|
||||||
|
if(n == NULL)
|
||||||
|
throw AuthNotFoundException("");
|
||||||
|
|
||||||
|
AuthData ad = n->getValue();
|
||||||
|
ad.pwd = password;
|
||||||
|
n->setValue(ad);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 AuthManager::getPrivs(const std::string &username)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
core::map<std::string, AuthData>::Node *n;
|
||||||
|
n = m_authdata.find(username);
|
||||||
|
if(n == NULL)
|
||||||
|
throw AuthNotFoundException("");
|
||||||
|
|
||||||
|
return n->getValue().privs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::setPrivs(const std::string &username, u64 privs)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
core::map<std::string, AuthData>::Node *n;
|
||||||
|
n = m_authdata.find(username);
|
||||||
|
if(n == NULL)
|
||||||
|
throw AuthNotFoundException("");
|
||||||
|
|
||||||
|
AuthData ad = n->getValue();
|
||||||
|
ad.privs = privs;
|
||||||
|
n->setValue(ad);
|
||||||
|
}
|
||||||
|
|
99
src/auth.h
Normal file
99
src/auth.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.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 AUTH_HEADER
|
||||||
|
#define AUTH_HEADER
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <jthread.h>
|
||||||
|
#include <jmutex.h>
|
||||||
|
#include "common_irrlicht.h"
|
||||||
|
#include "exceptions.h"
|
||||||
|
|
||||||
|
// 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
|
||||||
|
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_SHOUT = 32; // Can broadcast chat messages to all
|
||||||
|
// players
|
||||||
|
|
||||||
|
// Default privileges - these can be overriden for new players using the
|
||||||
|
// config option "default_privs" - however, this value still applies for
|
||||||
|
// players that existed before the privileges system was added.
|
||||||
|
const u64 PRIV_DEFAULT = PRIV_BUILD|PRIV_SHOUT;
|
||||||
|
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::string 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::string str);
|
||||||
|
|
||||||
|
struct AuthData
|
||||||
|
{
|
||||||
|
std::string pwd;
|
||||||
|
u64 privs;
|
||||||
|
|
||||||
|
AuthData():
|
||||||
|
privs(PRIV_DEFAULT)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AuthNotFoundException : public BaseException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AuthNotFoundException(const char *s):
|
||||||
|
BaseException(s)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AuthManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AuthManager(const std::string &authfilepath);
|
||||||
|
~AuthManager();
|
||||||
|
void load();
|
||||||
|
void save();
|
||||||
|
bool exists(const std::string &username);
|
||||||
|
void set(const std::string &username, AuthData ad);
|
||||||
|
void add(const std::string &username);
|
||||||
|
std::string getPassword(const std::string &username);
|
||||||
|
void setPassword(const std::string &username,
|
||||||
|
const std::string &password);
|
||||||
|
u64 getPrivs(const std::string &username);
|
||||||
|
void setPrivs(const std::string &username, u64 privs);
|
||||||
|
private:
|
||||||
|
JMutex m_mutex;
|
||||||
|
std::string m_authfilepath;
|
||||||
|
core::map<std::string, AuthData> m_authdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -610,6 +610,13 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
// to be processed even if the serialisation format has
|
// to be processed even if the serialisation format has
|
||||||
// not been agreed yet, the same as TOCLIENT_INIT.
|
// not been agreed yet, the same as TOCLIENT_INIT.
|
||||||
m_access_denied = true;
|
m_access_denied = true;
|
||||||
|
m_access_denied_reason = L"Unknown";
|
||||||
|
if(datasize >= 4)
|
||||||
|
{
|
||||||
|
std::string datastring((char*)&data[2], datasize-2);
|
||||||
|
std::istringstream is(datastring, std::ios_base::binary);
|
||||||
|
m_access_denied_reason = deSerializeWideString(is);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,6 +385,11 @@ public:
|
|||||||
return m_access_denied;
|
return m_access_denied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::wstring accessDeniedReason()
|
||||||
|
{
|
||||||
|
return m_access_denied_reason;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Virtual methods from con::PeerHandler
|
// Virtual methods from con::PeerHandler
|
||||||
@ -440,6 +445,7 @@ private:
|
|||||||
|
|
||||||
std::string m_password;
|
std::string m_password;
|
||||||
bool m_access_denied;
|
bool m_access_denied;
|
||||||
|
std::wstring m_access_denied_reason;
|
||||||
|
|
||||||
InventoryContext m_inventory_context;
|
InventoryContext m_inventory_context;
|
||||||
|
|
||||||
|
@ -24,6 +24,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#define PROTOCOL_ID 0x4f457403
|
#define PROTOCOL_ID 0x4f457403
|
||||||
|
|
||||||
|
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
|
||||||
|
// base64-encoded SHA-1 (27+\0).
|
||||||
|
|
||||||
enum ToClientCommand
|
enum ToClientCommand
|
||||||
{
|
{
|
||||||
TOCLIENT_INIT = 0x10,
|
TOCLIENT_INIT = 0x10,
|
||||||
@ -154,6 +157,8 @@ enum ToClientCommand
|
|||||||
TOCLIENT_ACCESS_DENIED = 0x35,
|
TOCLIENT_ACCESS_DENIED = 0x35,
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
|
u16 reason_length
|
||||||
|
wstring reason
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,8 +69,10 @@ void set_default_settings()
|
|||||||
// Server stuff
|
// Server stuff
|
||||||
g_settings.setDefault("enable_experimental", "false");
|
g_settings.setDefault("enable_experimental", "false");
|
||||||
g_settings.setDefault("creative_mode", "false");
|
g_settings.setDefault("creative_mode", "false");
|
||||||
g_settings.setDefault("enable_damage", "false"); //TODO: Set to true
|
g_settings.setDefault("enable_damage", "false"); //TODO: Set to true when healing is possible
|
||||||
g_settings.setDefault("give_initial_stuff", "false");
|
g_settings.setDefault("give_initial_stuff", "false");
|
||||||
|
g_settings.setDefault("default_password", "");
|
||||||
|
g_settings.setDefault("default_privs", "build, shout");
|
||||||
|
|
||||||
g_settings.setDefault("objectdata_interval", "0.2");
|
g_settings.setDefault("objectdata_interval", "0.2");
|
||||||
g_settings.setDefault("active_object_range", "2");
|
g_settings.setDefault("active_object_range", "2");
|
||||||
|
@ -426,7 +426,14 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
|||||||
testplayer.deSerialize(is);
|
testplayer.deSerialize(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
dstream<<"Loaded test player with name "<<testplayer.getName()<<std::endl;
|
if(!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS))
|
||||||
|
{
|
||||||
|
dstream<<"Not loading player with invalid name: "
|
||||||
|
<<testplayer.getName()<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
dstream<<"Loaded test player with name "<<testplayer.getName()
|
||||||
|
<<std::endl;
|
||||||
|
|
||||||
// Search for the player
|
// Search for the player
|
||||||
std::string playername = testplayer.getName();
|
std::string playername = testplayer.getName();
|
||||||
@ -723,6 +730,7 @@ void ServerEnvironment::step(float dtime)
|
|||||||
activateObjects(block);
|
activateObjects(block);
|
||||||
|
|
||||||
// TODO: Do something
|
// TODO: Do something
|
||||||
|
// TODO: Implement usage of ActiveBlockModifier
|
||||||
|
|
||||||
// Here's a quick demonstration
|
// Here's a quick demonstration
|
||||||
v3s16 p0;
|
v3s16 p0;
|
||||||
@ -784,6 +792,7 @@ void ServerEnvironment::step(float dtime)
|
|||||||
Everything should bind to inside this single content
|
Everything should bind to inside this single content
|
||||||
searching loop to keep things fast.
|
searching loop to keep things fast.
|
||||||
*/
|
*/
|
||||||
|
// TODO: Implement usage of ActiveBlockModifier
|
||||||
|
|
||||||
v3s16 p0;
|
v3s16 p0;
|
||||||
for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
|
for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
|
||||||
|
@ -112,25 +112,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
Active block modifier interface
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ServerEnvironment;
|
|
||||||
|
|
||||||
class ActiveBlockModifier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ActiveBlockModifier(){};
|
|
||||||
virtual ~ActiveBlockModifier(){};
|
|
||||||
|
|
||||||
virtual u32 getTriggerContentCount(){ return 1;}
|
|
||||||
virtual u8 getTriggerContent(u32 i) = 0;
|
|
||||||
virtual float getActiveInterval() = 0;
|
|
||||||
virtual u32 getActiveChance() = 0;
|
|
||||||
virtual void triggerEvent(ServerEnvironment *env, v3s16 p) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The server-side environment.
|
The server-side environment.
|
||||||
|
|
||||||
@ -140,6 +121,7 @@ public:
|
|||||||
#include "serverobject.h"
|
#include "serverobject.h"
|
||||||
|
|
||||||
class Server;
|
class Server;
|
||||||
|
class ActiveBlockModifier;
|
||||||
|
|
||||||
class ServerEnvironment : public Environment
|
class ServerEnvironment : public Environment
|
||||||
{
|
{
|
||||||
@ -178,6 +160,7 @@ public:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
ActiveObjects
|
ActiveObjects
|
||||||
|
-------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ServerActiveObject* getActiveObject(u16 id);
|
ServerActiveObject* getActiveObject(u16 id);
|
||||||
@ -214,6 +197,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
ActiveObjectMessage getActiveObjectMessage();
|
ActiveObjectMessage getActiveObjectMessage();
|
||||||
|
|
||||||
|
/*
|
||||||
|
ActiveBlockModifiers
|
||||||
|
-------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void addActiveBlockModifier(ActiveBlockModifier *abm);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
Remove all objects that satisfy (m_removed && m_known_by_count==0)
|
Remove all objects that satisfy (m_removed && m_known_by_count==0)
|
||||||
@ -263,6 +253,29 @@ private:
|
|||||||
float m_game_time_fraction_counter;
|
float m_game_time_fraction_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Active block modifier interface.
|
||||||
|
|
||||||
|
These are fed into ServerEnvironment at initialization time;
|
||||||
|
ServerEnvironment handles deleting them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ActiveBlockModifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActiveBlockModifier(){};
|
||||||
|
virtual ~ActiveBlockModifier(){};
|
||||||
|
|
||||||
|
//virtual core::list<u8> update(ServerEnvironment *env) = 0;
|
||||||
|
virtual u32 getTriggerContentCount(){ return 1;}
|
||||||
|
virtual u8 getTriggerContent(u32 i) = 0;
|
||||||
|
virtual float getActiveInterval() = 0;
|
||||||
|
// chance of (1 / return value), 0 is disallowed
|
||||||
|
virtual u32 getActiveChance() = 0;
|
||||||
|
// This is called usually at interval for 1/chance of the nodes
|
||||||
|
virtual void triggerEvent(ServerEnvironment *env, v3s16 p) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
|
|
||||||
#include "clientobject.h"
|
#include "clientobject.h"
|
||||||
|
@ -764,8 +764,9 @@ void the_game(
|
|||||||
{
|
{
|
||||||
if(client.accessDenied())
|
if(client.accessDenied())
|
||||||
{
|
{
|
||||||
error_message = L"Access denied. Check your password and try again.";
|
error_message = L"Access denied. Reason: "
|
||||||
std::cout<<DTIME<<"Access denied."<<std::endl;
|
+client.accessDeniedReason();
|
||||||
|
std::cout<<DTIME<<wide_to_narrow(error_message)<<std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -266,7 +266,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
|
|||||||
core::rect<s32> rect(0, 0, 130, 30);
|
core::rect<s32> rect(0, 0, 130, 30);
|
||||||
//rect += topleft_server + v2s32(size_server.X-40-130, 100+25);
|
//rect += topleft_server + v2s32(size_server.X-40-130, 100+25);
|
||||||
rect += topleft_server + v2s32(40, 100+25);
|
rect += topleft_server + v2s32(40, 100+25);
|
||||||
Environment->addButton(rect, this, 260, L"Delete map");
|
Environment->addButton(rect, this, 260, L"Delete world");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
src/main.cpp
34
src/main.cpp
@ -260,6 +260,9 @@ SUGG: MovingObject::move and Player::move are basically the same.
|
|||||||
- NOTE: There is a simple move implementation now in collision.{h,cpp}
|
- NOTE: There is a simple move implementation now in collision.{h,cpp}
|
||||||
- NOTE: MovingObject will be deleted (MapBlockObject)
|
- NOTE: MovingObject will be deleted (MapBlockObject)
|
||||||
|
|
||||||
|
TODO: Add a long step function to objects that is called with the time
|
||||||
|
difference when block activates
|
||||||
|
|
||||||
Map:
|
Map:
|
||||||
----
|
----
|
||||||
|
|
||||||
@ -304,14 +307,22 @@ Making it more portable:
|
|||||||
|
|
||||||
Stuff to do before release:
|
Stuff to do before release:
|
||||||
---------------------------
|
---------------------------
|
||||||
- Player default privileges and default password
|
- Make grass grow slower; utilize timestamp difference
|
||||||
- Chat privilege
|
|
||||||
- Some simple block-based dynamic stuff in the world (finish the
|
|
||||||
ActiveBlockModifier stuff)
|
|
||||||
- Protocol version field
|
- Protocol version field
|
||||||
- Consider getting some textures from cisoun's texture pack
|
- Consider getting some textures from cisoun's texture pack
|
||||||
- Add a long step function to objects that is called with the time
|
- Ask from Cisoun
|
||||||
difference when block activates
|
- Make sure the fence implementation and data format is good
|
||||||
|
- Think about using same bits for material for fences and doors, for
|
||||||
|
example
|
||||||
|
- Make sure server handles removing grass when a block is placed (etc)
|
||||||
|
- The client should not do it by itself
|
||||||
|
- Add mouse inversion in config
|
||||||
|
- Block cube placement around player's head
|
||||||
|
- Move mineral to param2, increment map serialization version, add conversion
|
||||||
|
|
||||||
|
Stuff to do after release:
|
||||||
|
---------------------------
|
||||||
|
- Finish the ActiveBlockModifier stuff and use it for something
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
@ -1188,7 +1199,7 @@ int main(int argc, char *argv[])
|
|||||||
port = 30000;
|
port = 30000;
|
||||||
|
|
||||||
// Map directory
|
// Map directory
|
||||||
std::string map_dir = porting::path_userdata+"/map";
|
std::string map_dir = porting::path_userdata+"/world";
|
||||||
if(cmd_args.exists("map-dir"))
|
if(cmd_args.exists("map-dir"))
|
||||||
map_dir = cmd_args.get("map-dir");
|
map_dir = cmd_args.get("map-dir");
|
||||||
else if(g_settings.exists("map-dir"))
|
else if(g_settings.exists("map-dir"))
|
||||||
@ -1488,12 +1499,19 @@ int main(int argc, char *argv[])
|
|||||||
g_settings.set("creative_mode", itos(menudata.creative_mode));
|
g_settings.set("creative_mode", itos(menudata.creative_mode));
|
||||||
g_settings.set("enable_damage", itos(menudata.enable_damage));
|
g_settings.set("enable_damage", itos(menudata.enable_damage));
|
||||||
|
|
||||||
// Check for valid parameters, restart menu if invalid.
|
/*// Check for valid parameters, restart menu if invalid.
|
||||||
if(playername == "")
|
if(playername == "")
|
||||||
{
|
{
|
||||||
error_message = L"Name required.";
|
error_message = L"Name required.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// Check that name has only valid chars
|
||||||
|
if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false)
|
||||||
|
{
|
||||||
|
error_message = L"Characters allowed: "
|
||||||
|
+narrow_to_wide(PLAYERNAME_ALLOWED_CHARS);
|
||||||
|
continue;
|
||||||
|
}*/
|
||||||
|
|
||||||
// Save settings
|
// Save settings
|
||||||
g_settings.set("name", playername);
|
g_settings.set("name", playername);
|
||||||
|
@ -23,58 +23,6 @@ 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(privs & PRIV_SHOUT)
|
|
||||||
os<<L"shout,";
|
|
||||||
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 if(*i == L"shout")
|
|
||||||
privs |= PRIV_SHOUT;
|
|
||||||
else
|
|
||||||
return PRIV_INVALID;
|
|
||||||
}
|
|
||||||
return privs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Player::Player():
|
Player::Player():
|
||||||
touching_ground(false),
|
touching_ground(false),
|
||||||
@ -83,7 +31,6 @@ Player::Player():
|
|||||||
swimming_up(false),
|
swimming_up(false),
|
||||||
craftresult_is_preview(true),
|
craftresult_is_preview(true),
|
||||||
hp(20),
|
hp(20),
|
||||||
privs(PRIV_DEFAULT),
|
|
||||||
peer_id(PEER_ID_INEXISTENT),
|
peer_id(PEER_ID_INEXISTENT),
|
||||||
m_pitch(0),
|
m_pitch(0),
|
||||||
m_yaw(0),
|
m_yaw(0),
|
||||||
@ -91,7 +38,6 @@ Player::Player():
|
|||||||
m_position(0,0,0)
|
m_position(0,0,0)
|
||||||
{
|
{
|
||||||
updateName("<not set>");
|
updateName("<not set>");
|
||||||
updatePassword("");
|
|
||||||
resetInventory();
|
resetInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +96,7 @@ void Player::serialize(std::ostream &os)
|
|||||||
Settings args;
|
Settings args;
|
||||||
args.setS32("version", 1);
|
args.setS32("version", 1);
|
||||||
args.set("name", m_name);
|
args.set("name", m_name);
|
||||||
args.set("password", m_password);
|
//args.set("password", m_password);
|
||||||
args.setFloat("pitch", m_pitch);
|
args.setFloat("pitch", m_pitch);
|
||||||
args.setFloat("yaw", m_yaw);
|
args.setFloat("yaw", m_yaw);
|
||||||
args.setV3F("position", m_position);
|
args.setV3F("position", m_position);
|
||||||
@ -185,10 +131,10 @@ void Player::deSerialize(std::istream &is)
|
|||||||
//args.getS32("version");
|
//args.getS32("version");
|
||||||
std::string name = args.get("name");
|
std::string name = args.get("name");
|
||||||
updateName(name.c_str());
|
updateName(name.c_str());
|
||||||
std::string password = "";
|
/*std::string password = "";
|
||||||
if(args.exists("password"))
|
if(args.exists("password"))
|
||||||
password = args.get("password");
|
password = args.get("password");
|
||||||
updatePassword(password.c_str());
|
updatePassword(password.c_str());*/
|
||||||
m_pitch = args.getFloat("pitch");
|
m_pitch = args.getFloat("pitch");
|
||||||
m_yaw = args.getFloat("yaw");
|
m_yaw = args.getFloat("yaw");
|
||||||
m_position = args.getV3F("position");
|
m_position = args.getV3F("position");
|
||||||
@ -202,7 +148,7 @@ void Player::deSerialize(std::istream &is)
|
|||||||
}catch(SettingNotFoundException &e){
|
}catch(SettingNotFoundException &e){
|
||||||
hp = 20;
|
hp = 20;
|
||||||
}
|
}
|
||||||
try{
|
/*try{
|
||||||
std::string sprivs = args.get("privs");
|
std::string sprivs = args.get("privs");
|
||||||
if(sprivs == "all")
|
if(sprivs == "all")
|
||||||
{
|
{
|
||||||
@ -215,7 +161,7 @@ void Player::deSerialize(std::istream &is)
|
|||||||
}
|
}
|
||||||
}catch(SettingNotFoundException &e){
|
}catch(SettingNotFoundException &e){
|
||||||
privs = PRIV_DEFAULT;
|
privs = PRIV_DEFAULT;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
inventory.deSerialize(is);
|
inventory.deSerialize(is);
|
||||||
}
|
}
|
||||||
|
44
src/player.h
44
src/player.h
@ -25,39 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
|
|
||||||
#define PLAYERNAME_SIZE 20
|
#define PLAYERNAME_SIZE 20
|
||||||
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
|
|
||||||
// base64-encoded SHA-1.
|
|
||||||
|
|
||||||
#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
|
|
||||||
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_SHOUT = 32; // Can broadcast chat messages to all
|
|
||||||
// players
|
|
||||||
|
|
||||||
// Default privileges - these can be overriden for new players using the
|
|
||||||
// config option "default_privs" - however, this value still applies for
|
|
||||||
// players that existed before the privileges system was added.
|
|
||||||
const u64 PRIV_DEFAULT = PRIV_BUILD|PRIV_SHOUT;
|
|
||||||
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;
|
||||||
@ -128,16 +97,6 @@ public:
|
|||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void updatePassword(const char *password)
|
|
||||||
{
|
|
||||||
snprintf(m_password, PASSWORD_SIZE, "%s", password);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * getPassword()
|
|
||||||
{
|
|
||||||
return m_password;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isLocal() const = 0;
|
virtual bool isLocal() const = 0;
|
||||||
|
|
||||||
virtual void updateLight(u8 light_at_pos) {};
|
virtual void updateLight(u8 light_at_pos) {};
|
||||||
@ -174,7 +133,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
char m_name[PLAYERNAME_SIZE];
|
char m_name[PLAYERNAME_SIZE];
|
||||||
char m_password[PASSWORD_SIZE];
|
|
||||||
f32 m_pitch;
|
f32 m_pitch;
|
||||||
f32 m_yaw;
|
f32 m_yaw;
|
||||||
v3f m_speed;
|
v3f m_speed;
|
||||||
|
105
src/server.cpp
105
src/server.cpp
@ -967,6 +967,7 @@ Server::Server(
|
|||||||
):
|
):
|
||||||
m_env(new ServerMap(mapsavedir), this),
|
m_env(new ServerMap(mapsavedir), this),
|
||||||
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
||||||
|
m_authmanager(mapsavedir+"/auth.txt"),
|
||||||
m_thread(this),
|
m_thread(this),
|
||||||
m_emergethread(this),
|
m_emergethread(this),
|
||||||
m_time_counter(0),
|
m_time_counter(0),
|
||||||
@ -1646,7 +1647,7 @@ void Server::AsyncRunStep()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save map
|
// Save map, players and auth stuff
|
||||||
{
|
{
|
||||||
float &counter = m_savemap_timer;
|
float &counter = m_savemap_timer;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
@ -1654,8 +1655,11 @@ void Server::AsyncRunStep()
|
|||||||
{
|
{
|
||||||
counter = 0.0;
|
counter = 0.0;
|
||||||
|
|
||||||
JMutexAutoLock lock(m_env_mutex);
|
// Auth stuff
|
||||||
|
m_authmanager.save();
|
||||||
|
|
||||||
|
// Map
|
||||||
|
JMutexAutoLock lock(m_env_mutex);
|
||||||
if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == true)
|
if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == true)
|
||||||
{
|
{
|
||||||
// Save only changed parts
|
// Save only changed parts
|
||||||
@ -1796,6 +1800,22 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
}
|
}
|
||||||
playername[PLAYERNAME_SIZE-1] = 0;
|
playername[PLAYERNAME_SIZE-1] = 0;
|
||||||
|
|
||||||
|
if(playername[0]=='\0')
|
||||||
|
{
|
||||||
|
derr_server<<DTIME<<"Server: Player has empty name"<<std::endl;
|
||||||
|
SendAccessDenied(m_con, peer_id,
|
||||||
|
L"Empty name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false)
|
||||||
|
{
|
||||||
|
derr_server<<DTIME<<"Server: Player has invalid name"<<std::endl;
|
||||||
|
SendAccessDenied(m_con, peer_id,
|
||||||
|
L"Name contains unallowed characters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get password
|
// Get password
|
||||||
char password[PASSWORD_SIZE];
|
char password[PASSWORD_SIZE];
|
||||||
if(datasize == 2+1+PLAYERNAME_SIZE)
|
if(datasize == 2+1+PLAYERNAME_SIZE)
|
||||||
@ -1811,16 +1831,38 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
}
|
}
|
||||||
password[PASSWORD_SIZE-1] = 0;
|
password[PASSWORD_SIZE-1] = 0;
|
||||||
}
|
}
|
||||||
Player *checkplayer = m_env.getPlayer(playername);
|
|
||||||
if(checkplayer != NULL && strcmp(checkplayer->getPassword(),password))
|
std::string checkpwd;
|
||||||
|
if(m_authmanager.exists(playername))
|
||||||
|
{
|
||||||
|
checkpwd = m_authmanager.getPassword(playername);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkpwd = g_settings.get("default_password");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(password != checkpwd)
|
||||||
{
|
{
|
||||||
derr_server<<DTIME<<"Server: peer_id="<<peer_id
|
derr_server<<DTIME<<"Server: peer_id="<<peer_id
|
||||||
<<": supplied invalid password for "
|
<<": supplied invalid password for "
|
||||||
<<playername<<std::endl;
|
<<playername<<std::endl;
|
||||||
SendAccessDenied(m_con, peer_id);
|
SendAccessDenied(m_con, peer_id, L"Invalid password");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add player to auth manager
|
||||||
|
if(m_authmanager.exists(playername) == false)
|
||||||
|
{
|
||||||
|
derr_server<<DTIME<<"Server: adding player "<<playername
|
||||||
|
<<" to auth manager"<<std::endl;
|
||||||
|
m_authmanager.add(playername);
|
||||||
|
m_authmanager.setPassword(playername, checkpwd);
|
||||||
|
m_authmanager.setPrivs(playername,
|
||||||
|
stringToPrivs(g_settings.get("default_privs")));
|
||||||
|
m_authmanager.save();
|
||||||
|
}
|
||||||
|
|
||||||
// Get player
|
// Get player
|
||||||
Player *player = emergePlayer(playername, password, peer_id);
|
Player *player = emergePlayer(playername, password, peer_id);
|
||||||
|
|
||||||
@ -3020,19 +3062,51 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
|
|
||||||
if(datasize != 2+PASSWORD_SIZE*2)
|
if(datasize != 2+PASSWORD_SIZE*2)
|
||||||
return;
|
return;
|
||||||
char password[PASSWORD_SIZE];
|
/*char password[PASSWORD_SIZE];
|
||||||
for(u32 i=0; i<PASSWORD_SIZE-1; i++)
|
for(u32 i=0; i<PASSWORD_SIZE-1; i++)
|
||||||
password[i] = data[2+i];
|
password[i] = data[2+i];
|
||||||
password[PASSWORD_SIZE-1] = 0;
|
password[PASSWORD_SIZE-1] = 0;*/
|
||||||
if(strcmp(player->getPassword(),password))
|
std::string oldpwd;
|
||||||
|
for(u32 i=0; i<PASSWORD_SIZE-1; i++)
|
||||||
{
|
{
|
||||||
|
char c = data[2+i];
|
||||||
|
if(c == 0)
|
||||||
|
break;
|
||||||
|
oldpwd += c;
|
||||||
|
}
|
||||||
|
std::string newpwd;
|
||||||
|
for(u32 i=0; i<PASSWORD_SIZE-1; i++)
|
||||||
|
{
|
||||||
|
char c = data[2+PASSWORD_SIZE+i];
|
||||||
|
if(c == 0)
|
||||||
|
break;
|
||||||
|
newpwd += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string playername = player->getName();
|
||||||
|
|
||||||
|
if(m_authmanager.exists(playername) == false)
|
||||||
|
{
|
||||||
|
dstream<<"Server: playername not found in authmanager"<<std::endl;
|
||||||
|
// Wrong old password supplied!!
|
||||||
|
SendChatMessage(peer_id, L"playername not found in authmanager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string checkpwd = m_authmanager.getPassword(playername);
|
||||||
|
|
||||||
|
if(oldpwd != checkpwd)
|
||||||
|
{
|
||||||
|
dstream<<"Server: invalid old password"<<std::endl;
|
||||||
// Wrong old password supplied!!
|
// Wrong old password supplied!!
|
||||||
SendChatMessage(peer_id, L"Invalid old password supplied. Password NOT changed.");
|
SendChatMessage(peer_id, L"Invalid old password supplied. Password NOT changed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(u32 i=0; i<PASSWORD_SIZE-1; i++)
|
|
||||||
password[i] = data[30+i];
|
m_authmanager.setPassword(playername, newpwd);
|
||||||
player->updatePassword(password);
|
|
||||||
|
dstream<<"Server: password change successful for "<<playername
|
||||||
|
<<std::endl;
|
||||||
SendChatMessage(peer_id, L"Password change successful");
|
SendChatMessage(peer_id, L"Password change successful");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3215,12 +3289,14 @@ void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp)
|
|||||||
con.Send(peer_id, 0, data, true);
|
con.Send(peer_id, 0, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::SendAccessDenied(con::Connection &con, u16 peer_id)
|
void Server::SendAccessDenied(con::Connection &con, u16 peer_id,
|
||||||
|
const std::wstring &reason)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
std::ostringstream os(std::ios_base::binary);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
|
||||||
writeU16(os, TOCLIENT_ACCESS_DENIED);
|
writeU16(os, TOCLIENT_ACCESS_DENIED);
|
||||||
|
os<<serializeWideString(reason);
|
||||||
|
|
||||||
// Make data buffer
|
// Make data buffer
|
||||||
std::string s = os.str();
|
std::string s = os.str();
|
||||||
@ -4207,7 +4283,10 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
|
|||||||
//player->peer_id = PEER_ID_INEXISTENT;
|
//player->peer_id = PEER_ID_INEXISTENT;
|
||||||
player->peer_id = peer_id;
|
player->peer_id = peer_id;
|
||||||
player->updateName(name);
|
player->updateName(name);
|
||||||
player->updatePassword(password);
|
m_authmanager.add(name);
|
||||||
|
m_authmanager.setPassword(name, password);
|
||||||
|
m_authmanager.setPrivs(name,
|
||||||
|
stringToPrivs(g_settings.get("default_privs")));
|
||||||
|
|
||||||
if(g_settings.exists("default_privs"))
|
if(g_settings.exists("default_privs"))
|
||||||
player->privs = g_settings.getU64("default_privs");
|
player->privs = g_settings.getU64("default_privs");
|
||||||
|
@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
|
#include "auth.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some random functions
|
Some random functions
|
||||||
@ -438,7 +439,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
|
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
|
||||||
static void SendAccessDenied(con::Connection &con, u16 peer_id);
|
static void SendAccessDenied(con::Connection &con, u16 peer_id,
|
||||||
|
const std::wstring &reason);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Non-static send methods
|
Non-static send methods
|
||||||
@ -515,6 +517,9 @@ private:
|
|||||||
// Connected clients (behind the con mutex)
|
// Connected clients (behind the con mutex)
|
||||||
core::map<u16, RemoteClient*> m_clients;
|
core::map<u16, RemoteClient*> m_clients;
|
||||||
|
|
||||||
|
// User authentication
|
||||||
|
AuthManager m_authmanager;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Threads
|
Threads
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +35,7 @@ void cmd_privs(std::wostringstream &os,
|
|||||||
{
|
{
|
||||||
// Show our own real privs, without any adjustments
|
// Show our own real privs, without any adjustments
|
||||||
// made for admin status
|
// made for admin status
|
||||||
os<<L"-!- " + privsToString(ctx->player->privs);
|
os<<L"-!- " + narrow_to_wide(privsToString(ctx->player->privs));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ void cmd_privs(std::wostringstream &os,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
os<<L"-!- " + privsToString(tp->privs);
|
os<<L"-!- " + narrow_to_wide(privsToString(tp->privs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_grantrevoke(std::wostringstream &os,
|
void cmd_grantrevoke(std::wostringstream &os,
|
||||||
@ -70,7 +70,7 @@ void cmd_grantrevoke(std::wostringstream &os,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 newprivs = stringToPrivs(ctx->parms[2]);
|
u64 newprivs = stringToPrivs(wide_to_narrow(ctx->parms[2]));
|
||||||
if(newprivs == PRIV_INVALID)
|
if(newprivs == PRIV_INVALID)
|
||||||
{
|
{
|
||||||
os<<L"-!- Invalid privileges specified";
|
os<<L"-!- Invalid privileges specified";
|
||||||
@ -90,7 +90,7 @@ void cmd_grantrevoke(std::wostringstream &os,
|
|||||||
tp->privs &= ~newprivs;
|
tp->privs &= ~newprivs;
|
||||||
|
|
||||||
os<<L"-!- Privileges change to ";
|
os<<L"-!- Privileges change to ";
|
||||||
os<<privsToString(tp->privs);
|
os<<narrow_to_wide(privsToString(tp->privs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_time(std::wostringstream &os,
|
void cmd_time(std::wostringstream &os,
|
||||||
|
@ -301,7 +301,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Figure out path to map
|
// Figure out path to map
|
||||||
std::string map_dir = porting::path_userdata+"/map";
|
std::string map_dir = porting::path_userdata+"/world";
|
||||||
if(cmd_args.exists("map-dir"))
|
if(cmd_args.exists("map-dir"))
|
||||||
map_dir = cmd_args.get("map-dir");
|
map_dir = cmd_args.get("map-dir");
|
||||||
else if(g_settings.exists("map-dir"))
|
else if(g_settings.exists("map-dir"))
|
||||||
|
@ -1984,17 +1984,23 @@ inline std::string serializeString(const std::string &plain)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// Reads a string with the length as the first two bytes
|
// Creates a string with the length as the first two bytes from wide string
|
||||||
inline std::string deSerializeString(const std::string encoded)
|
inline std::string serializeWideString(const std::wstring &plain)
|
||||||
{
|
{
|
||||||
u16 s_size = readU16((u8*)&encoded.c_str()[0]);
|
//assert(plain.size() <= 65535);
|
||||||
if(s_size > encoded.length() - 2)
|
if(plain.size() > 65535)
|
||||||
return "";
|
throw SerializationError("String too long for serializeString");
|
||||||
|
char buf[2];
|
||||||
|
writeU16((u8*)buf, plain.size());
|
||||||
std::string s;
|
std::string s;
|
||||||
s.reserve(s_size);
|
s.append(buf, 2);
|
||||||
s.append(&encoded.c_str()[2], s_size);
|
for(u32 i=0; i<plain.size(); i++)
|
||||||
|
{
|
||||||
|
writeU16((u8*)buf, plain[i]);
|
||||||
|
s.append(buf, 2);
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// Reads a string with the length as the first two bytes
|
// Reads a string with the length as the first two bytes
|
||||||
inline std::string deSerializeString(std::istream &is)
|
inline std::string deSerializeString(std::istream &is)
|
||||||
@ -2014,6 +2020,27 @@ inline std::string deSerializeString(std::istream &is)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reads a wide string with the length as the first two bytes
|
||||||
|
inline std::wstring deSerializeWideString(std::istream &is)
|
||||||
|
{
|
||||||
|
char buf[2];
|
||||||
|
is.read(buf, 2);
|
||||||
|
if(is.gcount() != 2)
|
||||||
|
throw SerializationError("deSerializeString: size not read");
|
||||||
|
u16 s_size = readU16((u8*)buf);
|
||||||
|
if(s_size == 0)
|
||||||
|
return L"";
|
||||||
|
std::wstring s;
|
||||||
|
s.reserve(s_size);
|
||||||
|
for(u32 i=0; i<s_size; i++)
|
||||||
|
{
|
||||||
|
is.read(&buf[0], 2);
|
||||||
|
wchar_t c16 = readU16((u8*)buf);
|
||||||
|
s.append(&c16, 1);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a string with the length as the first four bytes
|
// Creates a string with the length as the first four bytes
|
||||||
inline std::string serializeLongString(const std::string &plain)
|
inline std::string serializeLongString(const std::string &plain)
|
||||||
{
|
{
|
||||||
@ -2025,18 +2052,6 @@ inline std::string serializeLongString(const std::string &plain)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// Reads a string with the length as the first four bytes
|
|
||||||
inline std::string deSerializeLongString(const std::string encoded)
|
|
||||||
{
|
|
||||||
u32 s_size = readU32((u8*)&encoded.c_str()[0]);
|
|
||||||
if(s_size > encoded.length() - 4)
|
|
||||||
return "";
|
|
||||||
std::string s;
|
|
||||||
s.reserve(s_size);
|
|
||||||
s.append(&encoded.c_str()[4], s_size);
|
|
||||||
return s;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Reads a string with the length as the first four bytes
|
// Reads a string with the length as the first four bytes
|
||||||
inline std::string deSerializeLongString(std::istream &is)
|
inline std::string deSerializeLongString(std::istream &is)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user