mirror of
https://github.com/moparisthebest/minetest
synced 2024-12-23 16:08:51 -05:00
Only keep players loaded while they're connected
This commit is contained in:
parent
50127510e7
commit
7e6db1b803
@ -1027,6 +1027,8 @@ void PlayerSAO::removingFromEnvironment()
|
|||||||
{
|
{
|
||||||
m_player->setPlayerSAO(NULL);
|
m_player->setPlayerSAO(NULL);
|
||||||
m_player->peer_id = 0;
|
m_player->peer_id = 0;
|
||||||
|
m_env->savePlayer(m_player->getName());
|
||||||
|
m_env->removePlayer(m_player->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +100,18 @@ void Environment::removePlayer(u16 peer_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Environment::removePlayer(const char *name)
|
||||||
|
{
|
||||||
|
for (std::list<Player*>::iterator it = m_players.begin();
|
||||||
|
it != m_players.end(); ++it) {
|
||||||
|
if (strcmp((*it)->getName(), name) == 0) {
|
||||||
|
delete *it;
|
||||||
|
m_players.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Player * Environment::getPlayer(u16 peer_id)
|
Player * Environment::getPlayer(u16 peer_id)
|
||||||
{
|
{
|
||||||
for(std::list<Player*>::iterator i = m_players.begin();
|
for(std::list<Player*>::iterator i = m_players.begin();
|
||||||
@ -332,10 +344,12 @@ void ActiveBlockList::update(std::list<v3s16> &active_positions,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ServerEnvironment::ServerEnvironment(ServerMap *map,
|
ServerEnvironment::ServerEnvironment(ServerMap *map,
|
||||||
GameScripting *scriptIface, IGameDef *gamedef):
|
GameScripting *scriptIface, IGameDef *gamedef,
|
||||||
|
const std::string &path_world) :
|
||||||
m_map(map),
|
m_map(map),
|
||||||
m_script(scriptIface),
|
m_script(scriptIface),
|
||||||
m_gamedef(gamedef),
|
m_gamedef(gamedef),
|
||||||
|
m_path_world(path_world),
|
||||||
m_send_recommended_timer(0),
|
m_send_recommended_timer(0),
|
||||||
m_active_block_interval_overload_skip(0),
|
m_active_block_interval_overload_skip(0),
|
||||||
m_game_time(0),
|
m_game_time(0),
|
||||||
@ -401,196 +415,85 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerEnvironment::serializePlayers(const std::string &savedir)
|
void ServerEnvironment::saveLoadedPlayers()
|
||||||
{
|
{
|
||||||
std::string players_path = savedir + "/players";
|
std::string players_path = m_path_world + DIR_DELIM "players";
|
||||||
fs::CreateDir(players_path);
|
fs::CreateDir(players_path);
|
||||||
|
|
||||||
std::set<Player*> saved_players;
|
for (std::list<Player*>::iterator it = m_players.begin();
|
||||||
|
it != m_players.end();
|
||||||
|
++it) {
|
||||||
|
RemotePlayer *player = static_cast<RemotePlayer*>(*it);
|
||||||
|
if (player->checkModified()) {
|
||||||
|
player->save(players_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerEnvironment::savePlayer(const std::string &playername)
|
||||||
|
{
|
||||||
|
std::string players_path = m_path_world + DIR_DELIM "players";
|
||||||
|
fs::CreateDir(players_path);
|
||||||
|
|
||||||
|
RemotePlayer *player = static_cast<RemotePlayer*>(getPlayer(playername.c_str()));
|
||||||
|
if (player) {
|
||||||
|
player->save(players_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Player *ServerEnvironment::loadPlayer(const std::string &playername)
|
||||||
|
{
|
||||||
|
std::string players_path = m_path_world + DIR_DELIM "players";
|
||||||
|
|
||||||
|
RemotePlayer *player = static_cast<RemotePlayer*>(getPlayer(playername.c_str()));
|
||||||
|
bool newplayer = false;
|
||||||
|
bool foundplayer = false;
|
||||||
|
if (!player) {
|
||||||
|
player = new RemotePlayer(m_gamedef);
|
||||||
|
newplayer = true;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
|
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
|
||||||
for(u32 i=0; i<player_files.size(); i++)
|
for (u32 i = 0; i < player_files.size(); i++) {
|
||||||
{
|
|
||||||
if(player_files[i].dir || player_files[i].name[0] == '.')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Full path to this file
|
|
||||||
std::string path = players_path + "/" + player_files[i].name;
|
|
||||||
|
|
||||||
//infostream<<"Checking player file "<<path<<std::endl;
|
|
||||||
|
|
||||||
// Load player to see what is its name
|
|
||||||
RemotePlayer testplayer(m_gamedef);
|
|
||||||
{
|
|
||||||
// Open file and deserialize
|
|
||||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
|
||||||
if(is.good() == false)
|
|
||||||
{
|
|
||||||
infostream<<"Failed to read "<<path<<std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
testplayer.deSerialize(is, player_files[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//infostream<<"Loaded test player with name "<<testplayer.getName()<<std::endl;
|
|
||||||
|
|
||||||
// Search for the player
|
|
||||||
std::string playername = testplayer.getName();
|
|
||||||
Player *player = getPlayer(playername.c_str());
|
|
||||||
if(player == NULL)
|
|
||||||
{
|
|
||||||
infostream<<"Didn't find matching player, ignoring file "<<path<<std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//infostream<<"Found matching player, overwriting."<<std::endl;
|
|
||||||
|
|
||||||
// OK, found. Save player there.
|
|
||||||
if(player->checkModified())
|
|
||||||
{
|
|
||||||
// Open file and serialize
|
|
||||||
std::ostringstream ss(std::ios_base::binary);
|
|
||||||
player->serialize(ss);
|
|
||||||
if(!fs::safeWriteToFile(path, ss.str()))
|
|
||||||
{
|
|
||||||
infostream<<"Failed to write "<<path<<std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
saved_players.insert(player);
|
|
||||||
} else {
|
|
||||||
saved_players.insert(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(std::list<Player*>::iterator i = m_players.begin();
|
|
||||||
i != m_players.end(); ++i)
|
|
||||||
{
|
|
||||||
Player *player = *i;
|
|
||||||
if(saved_players.find(player) != saved_players.end())
|
|
||||||
{
|
|
||||||
/*infostream<<"Player "<<player->getName()
|
|
||||||
<<" was already saved."<<std::endl;*/
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::string playername = player->getName();
|
|
||||||
// Don't save unnamed player
|
|
||||||
if(playername == "")
|
|
||||||
{
|
|
||||||
//infostream<<"Not saving unnamed player."<<std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Find a sane filename
|
|
||||||
*/
|
|
||||||
if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS) == false)
|
|
||||||
playername = "player";
|
|
||||||
std::string path = players_path + "/" + playername;
|
|
||||||
bool found = false;
|
|
||||||
for(u32 i=0; i<1000; i++)
|
|
||||||
{
|
|
||||||
if(fs::PathExists(path) == false)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
path = players_path + "/" + playername + itos(i);
|
|
||||||
}
|
|
||||||
if(found == false)
|
|
||||||
{
|
|
||||||
infostream<<"Didn't find free file for player"<<std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
/*infostream<<"Saving player "<<player->getName()<<" to "
|
|
||||||
<<path<<std::endl;*/
|
|
||||||
// Open file and serialize
|
|
||||||
std::ostringstream ss(std::ios_base::binary);
|
|
||||||
player->serialize(ss);
|
|
||||||
if(!fs::safeWriteToFile(path, ss.str()))
|
|
||||||
{
|
|
||||||
infostream<<"Failed to write "<<path<<std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
saved_players.insert(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//infostream<<"Saved "<<saved_players.size()<<" players."<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
|
||||||
{
|
|
||||||
std::string players_path = savedir + "/players";
|
|
||||||
|
|
||||||
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
|
|
||||||
for(u32 i=0; i<player_files.size(); i++)
|
|
||||||
{
|
|
||||||
if (player_files[i].dir)
|
if (player_files[i].dir)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Full path to this file
|
// Full path to this file
|
||||||
std::string path = players_path + "/" + player_files[i].name;
|
std::string path = players_path + "/" + player_files[i].name;
|
||||||
|
|
||||||
//infostream<<"Checking player file "<<path<<std::endl;
|
|
||||||
|
|
||||||
// Load player to see what is its name
|
// Load player to see what is its name
|
||||||
RemotePlayer testplayer(m_gamedef);
|
|
||||||
{
|
|
||||||
// Open file and deserialize
|
|
||||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||||
if(is.good() == false)
|
if (!is.good()) {
|
||||||
{
|
|
||||||
infostream<<"Failed to read "<<path<<std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
testplayer.deSerialize(is, player_files[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS))
|
|
||||||
{
|
|
||||||
infostream<<"Not loading player with invalid name: "
|
|
||||||
<<testplayer.getName()<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*infostream<<"Loaded test player with name "<<testplayer.getName()
|
|
||||||
<<std::endl;*/
|
|
||||||
|
|
||||||
// Search for the player
|
|
||||||
std::string playername = testplayer.getName();
|
|
||||||
Player *player = getPlayer(playername.c_str());
|
|
||||||
bool newplayer = false;
|
|
||||||
if(player == NULL)
|
|
||||||
{
|
|
||||||
//infostream<<"Is a new player"<<std::endl;
|
|
||||||
player = new RemotePlayer(m_gamedef);
|
|
||||||
newplayer = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load player
|
|
||||||
{
|
|
||||||
verbosestream<<"Reading player "<<testplayer.getName()<<" from "
|
|
||||||
<<path<<std::endl;
|
|
||||||
// Open file and deserialize
|
|
||||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
|
||||||
if(is.good() == false)
|
|
||||||
{
|
|
||||||
infostream << "Failed to read " << path << std::endl;
|
infostream << "Failed to read " << path << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
player->deSerialize(is, player_files[i].name);
|
player->deSerialize(is, player_files[i].name);
|
||||||
|
|
||||||
|
if (!string_allowed(player->getName(), PLAYERNAME_ALLOWED_CHARS)) {
|
||||||
|
infostream << "Not loading player with invalid name: "
|
||||||
|
<< player->getName() << std::endl;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(newplayer)
|
if (player->getName() == playername) {
|
||||||
{
|
// We found our player
|
||||||
|
foundplayer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!foundplayer) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (newplayer) {
|
||||||
addPlayer(player);
|
addPlayer(player);
|
||||||
}
|
}
|
||||||
}
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerEnvironment::saveMeta(const std::string &savedir)
|
void ServerEnvironment::saveMeta()
|
||||||
{
|
{
|
||||||
std::string path = savedir + "/env_meta.txt";
|
std::string path = m_path_world + DIR_DELIM "env_meta.txt";
|
||||||
|
|
||||||
// Open file and serialize
|
// Open file and serialize
|
||||||
std::ostringstream ss(std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
@ -609,9 +512,9 @@ void ServerEnvironment::saveMeta(const std::string &savedir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerEnvironment::loadMeta(const std::string &savedir)
|
void ServerEnvironment::loadMeta()
|
||||||
{
|
{
|
||||||
std::string path = savedir + "/env_meta.txt";
|
std::string path = m_path_world + DIR_DELIM "env_meta.txt";
|
||||||
|
|
||||||
// Open file and deserialize
|
// Open file and deserialize
|
||||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
|
|
||||||
virtual void addPlayer(Player *player);
|
virtual void addPlayer(Player *player);
|
||||||
void removePlayer(u16 peer_id);
|
void removePlayer(u16 peer_id);
|
||||||
|
void removePlayer(const char *name);
|
||||||
Player * getPlayer(u16 peer_id);
|
Player * getPlayer(u16 peer_id);
|
||||||
Player * getPlayer(const char *name);
|
Player * getPlayer(const char *name);
|
||||||
Player * getRandomConnectedPlayer();
|
Player * getRandomConnectedPlayer();
|
||||||
@ -199,7 +200,7 @@ class ServerEnvironment : public Environment
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
|
ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
|
||||||
IGameDef *gamedef);
|
IGameDef *gamedef, const std::string &path_world);
|
||||||
~ServerEnvironment();
|
~ServerEnvironment();
|
||||||
|
|
||||||
Map & getMap();
|
Map & getMap();
|
||||||
@ -216,17 +217,16 @@ public:
|
|||||||
float getSendRecommendedInterval()
|
float getSendRecommendedInterval()
|
||||||
{ return m_recommended_send_interval; }
|
{ return m_recommended_send_interval; }
|
||||||
|
|
||||||
/*
|
// Save players
|
||||||
Save players
|
void saveLoadedPlayers();
|
||||||
*/
|
void savePlayer(const std::string &playername);
|
||||||
void serializePlayers(const std::string &savedir);
|
Player *loadPlayer(const std::string &playername);
|
||||||
void deSerializePlayers(const std::string &savedir);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Save and load time of day and game timer
|
Save and load time of day and game timer
|
||||||
*/
|
*/
|
||||||
void saveMeta(const std::string &savedir);
|
void saveMeta();
|
||||||
void loadMeta(const std::string &savedir);
|
void loadMeta();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
External ActiveObject interface
|
External ActiveObject interface
|
||||||
@ -368,6 +368,8 @@ private:
|
|||||||
GameScripting* m_script;
|
GameScripting* m_script;
|
||||||
// Game definition
|
// Game definition
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
|
// World path
|
||||||
|
const std::string m_path_world;
|
||||||
// Active object list
|
// Active object list
|
||||||
std::map<u16, ServerActiveObject*> m_active_objects;
|
std::map<u16, ServerActiveObject*> m_active_objects;
|
||||||
// Outgoing network message buffer for active objects
|
// Outgoing network message buffer for active objects
|
||||||
|
@ -283,6 +283,72 @@ void Player::clearHud()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RemotePlayer::save(const std::string &savedir)
|
||||||
|
{
|
||||||
|
bool newplayer = true;
|
||||||
|
|
||||||
|
/* We have to iterate through all files in the players directory
|
||||||
|
* and check their player names because some file systems are not
|
||||||
|
* case-sensitive and player names are case-sensitive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A player to deserialize files into to check their names
|
||||||
|
RemotePlayer testplayer(m_gamedef);
|
||||||
|
|
||||||
|
std::vector<fs::DirListNode> player_files = fs::GetDirListing(savedir);
|
||||||
|
for(u32 i = 0; i < player_files.size(); i++) {
|
||||||
|
if (player_files[i].dir || player_files[i].name[0] == '.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full path to this file
|
||||||
|
std::string path = savedir + "/" + player_files[i].name;
|
||||||
|
|
||||||
|
// Open file and deserialize
|
||||||
|
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||||
|
if (!is.good()) {
|
||||||
|
infostream << "Failed to read " << path << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
testplayer.deSerialize(is, player_files[i].name);
|
||||||
|
|
||||||
|
if (strcmp(testplayer.getName(), m_name) == 0) {
|
||||||
|
// Open file and serialize
|
||||||
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
|
serialize(ss);
|
||||||
|
if (!fs::safeWriteToFile(path, ss.str())) {
|
||||||
|
infostream << "Failed to write " << path << std::endl;
|
||||||
|
}
|
||||||
|
newplayer = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newplayer) {
|
||||||
|
bool found = false;
|
||||||
|
std::string path = savedir + "/" + m_name;
|
||||||
|
for (u32 i = 0; i < 1000; i++) {
|
||||||
|
if (!fs::PathExists(path)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
path = savedir + "/" + m_name + itos(i);
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
infostream << "Didn't find free file for player " << m_name << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open file and serialize
|
||||||
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
|
serialize(ss);
|
||||||
|
if (!fs::safeWriteToFile(path, ss.str())) {
|
||||||
|
infostream << "Failed to write " << path << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
RemotePlayer
|
RemotePlayer
|
||||||
*/
|
*/
|
||||||
@ -292,3 +358,4 @@ void RemotePlayer::setPosition(const v3f &position)
|
|||||||
if(m_sao)
|
if(m_sao)
|
||||||
m_sao->setBasePosition(position);
|
m_sao->setBasePosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +335,8 @@ public:
|
|||||||
RemotePlayer(IGameDef *gamedef): Player(gamedef), m_sao(0) {}
|
RemotePlayer(IGameDef *gamedef): Player(gamedef), m_sao(0) {}
|
||||||
virtual ~RemotePlayer() {}
|
virtual ~RemotePlayer() {}
|
||||||
|
|
||||||
|
void save(const std::string &savedir);
|
||||||
|
|
||||||
PlayerSAO *getPlayerSAO()
|
PlayerSAO *getPlayerSAO()
|
||||||
{ return m_sao; }
|
{ return m_sao; }
|
||||||
void setPlayerSAO(PlayerSAO *sao)
|
void setPlayerSAO(PlayerSAO *sao)
|
||||||
|
@ -344,7 +344,7 @@ Server::Server(
|
|||||||
|
|
||||||
// Initialize Environment
|
// Initialize Environment
|
||||||
ServerMap *servermap = new ServerMap(path_world, this, m_emerge);
|
ServerMap *servermap = new ServerMap(path_world, this, m_emerge);
|
||||||
m_env = new ServerEnvironment(servermap, m_script, this);
|
m_env = new ServerEnvironment(servermap, m_script, this, m_path_world);
|
||||||
|
|
||||||
m_clients.setEnv(m_env);
|
m_clients.setEnv(m_env);
|
||||||
|
|
||||||
@ -361,19 +361,13 @@ Server::Server(
|
|||||||
servermap->addEventReceiver(this);
|
servermap->addEventReceiver(this);
|
||||||
|
|
||||||
// If file exists, load environment metadata
|
// If file exists, load environment metadata
|
||||||
if(fs::PathExists(m_path_world+DIR_DELIM+"env_meta.txt"))
|
if(fs::PathExists(m_path_world + DIR_DELIM "env_meta.txt"))
|
||||||
{
|
{
|
||||||
infostream<<"Server: Loading environment metadata"<<std::endl;
|
infostream<<"Server: Loading environment metadata"<<std::endl;
|
||||||
m_env->loadMeta(m_path_world);
|
m_env->loadMeta();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load players
|
// Add some test ActiveBlockModifiers to environment
|
||||||
infostream<<"Server: Loading players"<<std::endl;
|
|
||||||
m_env->deSerializePlayers(m_path_world);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Add some test ActiveBlockModifiers to environment
|
|
||||||
*/
|
|
||||||
add_legacy_abms(m_env, m_nodedef);
|
add_legacy_abms(m_env, m_nodedef);
|
||||||
|
|
||||||
m_liquid_transform_every = g_settings->getFloat("liquid_update");
|
m_liquid_transform_every = g_settings->getFloat("liquid_update");
|
||||||
@ -383,42 +377,23 @@ Server::~Server()
|
|||||||
{
|
{
|
||||||
infostream<<"Server destructing"<<std::endl;
|
infostream<<"Server destructing"<<std::endl;
|
||||||
|
|
||||||
/*
|
// Send shutdown message
|
||||||
Send shutdown message
|
SendChatMessage(PEER_ID_INEXISTENT, L"*** Server shutting down");
|
||||||
*/
|
|
||||||
{
|
|
||||||
std::wstring line = L"*** Server shutting down";
|
|
||||||
SendChatMessage(PEER_ID_INEXISTENT, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
|
|
||||||
/*
|
// Execute script shutdown hooks
|
||||||
Execute script shutdown hooks
|
|
||||||
*/
|
|
||||||
m_script->on_shutdown();
|
m_script->on_shutdown();
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Save players
|
|
||||||
*/
|
|
||||||
infostream<<"Server: Saving players"<<std::endl;
|
infostream<<"Server: Saving players"<<std::endl;
|
||||||
m_env->serializePlayers(m_path_world);
|
m_env->saveLoadedPlayers();
|
||||||
|
|
||||||
/*
|
|
||||||
Save environment metadata
|
|
||||||
*/
|
|
||||||
infostream<<"Server: Saving environment metadata"<<std::endl;
|
infostream<<"Server: Saving environment metadata"<<std::endl;
|
||||||
m_env->saveMeta(m_path_world);
|
m_env->saveMeta();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Stop threads
|
||||||
Stop threads
|
|
||||||
*/
|
|
||||||
stop();
|
stop();
|
||||||
delete m_thread;
|
delete m_thread;
|
||||||
|
|
||||||
@ -444,14 +419,12 @@ Server::~Server()
|
|||||||
delete m_script;
|
delete m_script;
|
||||||
|
|
||||||
// Delete detached inventories
|
// Delete detached inventories
|
||||||
{
|
|
||||||
for (std::map<std::string, Inventory*>::iterator
|
for (std::map<std::string, Inventory*>::iterator
|
||||||
i = m_detached_inventories.begin();
|
i = m_detached_inventories.begin();
|
||||||
i != m_detached_inventories.end(); i++) {
|
i != m_detached_inventories.end(); i++) {
|
||||||
delete i->second;
|
delete i->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Server::start(Address bind_addr)
|
void Server::start(Address bind_addr)
|
||||||
{
|
{
|
||||||
@ -1141,18 +1114,19 @@ void Server::AsyncRunStep(bool initial_step)
|
|||||||
|
|
||||||
ScopeProfiler sp(g_profiler, "Server: saving stuff");
|
ScopeProfiler sp(g_profiler, "Server: saving stuff");
|
||||||
|
|
||||||
//Ban stuff
|
// Save ban file
|
||||||
if(m_banmanager->isModified())
|
if (m_banmanager->isModified()) {
|
||||||
m_banmanager->save();
|
m_banmanager->save();
|
||||||
|
}
|
||||||
|
|
||||||
// Save changed parts of map
|
// Save changed parts of map
|
||||||
m_env->getMap().save(MOD_STATE_WRITE_NEEDED);
|
m_env->getMap().save(MOD_STATE_WRITE_NEEDED);
|
||||||
|
|
||||||
// Save players
|
// Save players
|
||||||
m_env->serializePlayers(m_path_world);
|
m_env->saveLoadedPlayers();
|
||||||
|
|
||||||
// Save environment metadata
|
// Save environment metadata
|
||||||
m_env->saveMeta(m_path_world);
|
m_env->saveMeta();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1178,27 +1152,16 @@ void Server::Receive()
|
|||||||
"SerializationError: what()="
|
"SerializationError: what()="
|
||||||
<<e.what()<<std::endl;
|
<<e.what()<<std::endl;
|
||||||
}
|
}
|
||||||
catch(con::PeerNotFoundException &e)
|
|
||||||
{
|
|
||||||
//NOTE: This is not needed anymore
|
|
||||||
|
|
||||||
// The peer has been disconnected.
|
|
||||||
// Find the associated player and remove it.
|
|
||||||
|
|
||||||
/*JMutexAutoLock envlock(m_env_mutex);
|
|
||||||
|
|
||||||
infostream<<"ServerThread: peer_id="<<peer_id
|
|
||||||
<<" has apparently closed connection. "
|
|
||||||
<<"Removing player."<<std::endl;
|
|
||||||
|
|
||||||
m_env->removePlayer(peer_id);*/
|
|
||||||
}
|
|
||||||
catch(ClientStateError &e)
|
catch(ClientStateError &e)
|
||||||
{
|
{
|
||||||
errorstream << "ProcessData: peer=" << peer_id << e.what() << std::endl;
|
errorstream << "ProcessData: peer=" << peer_id << e.what() << std::endl;
|
||||||
DenyAccess(peer_id, L"Your client sent something server didn't expect."
|
DenyAccess(peer_id, L"Your client sent something server didn't expect."
|
||||||
L"Try reconnecting or updating your client");
|
L"Try reconnecting or updating your client");
|
||||||
}
|
}
|
||||||
|
catch(con::PeerNotFoundException &e)
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerSAO* Server::StageTwoClientInit(u16 peer_id)
|
PlayerSAO* Server::StageTwoClientInit(u16 peer_id)
|
||||||
@ -5032,15 +4995,16 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Load player if it isn't already loaded
|
||||||
Create a new player if it doesn't exist yet
|
if (!player) {
|
||||||
*/
|
player = static_cast<RemotePlayer*>(m_env->loadPlayer(name));
|
||||||
if(player == NULL)
|
}
|
||||||
{
|
|
||||||
|
// Create player if it doesn't exist
|
||||||
|
if (!player) {
|
||||||
newplayer = true;
|
newplayer = true;
|
||||||
player = new RemotePlayer(this);
|
player = new RemotePlayer(this);
|
||||||
player->updateName(name);
|
player->updateName(name);
|
||||||
|
|
||||||
/* Set player position */
|
/* Set player position */
|
||||||
infostream<<"Server: Finding spawn place for player \""
|
infostream<<"Server: Finding spawn place for player \""
|
||||||
<<name<<"\""<<std::endl;
|
<<name<<"\""<<std::endl;
|
||||||
@ -5051,9 +5015,7 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
|
|||||||
m_env->addPlayer(player);
|
m_env->addPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Create a new player active object
|
||||||
Create a new player active object
|
|
||||||
*/
|
|
||||||
PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id,
|
PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id,
|
||||||
getPlayerEffectivePrivs(player->getName()),
|
getPlayerEffectivePrivs(player->getName()),
|
||||||
isSingleplayer());
|
isSingleplayer());
|
||||||
@ -5065,8 +5027,9 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
|
|||||||
m_env->addActiveObject(playersao);
|
m_env->addActiveObject(playersao);
|
||||||
|
|
||||||
/* Run scripts */
|
/* Run scripts */
|
||||||
if(newplayer)
|
if (newplayer) {
|
||||||
m_script->on_newplayer(playersao);
|
m_script->on_newplayer(playersao);
|
||||||
|
}
|
||||||
|
|
||||||
return playersao;
|
return playersao;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user