mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Only keep players loaded while they're connected
This commit is contained in:
		@@ -1027,6 +1027,8 @@ void PlayerSAO::removingFromEnvironment()
 | 
			
		||||
	{
 | 
			
		||||
		m_player->setPlayerSAO(NULL);
 | 
			
		||||
		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)
 | 
			
		||||
{
 | 
			
		||||
	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,
 | 
			
		||||
		GameScripting *scriptIface, IGameDef *gamedef):
 | 
			
		||||
		GameScripting *scriptIface, IGameDef *gamedef,
 | 
			
		||||
		const std::string &path_world) :
 | 
			
		||||
	m_map(map),
 | 
			
		||||
	m_script(scriptIface),
 | 
			
		||||
	m_gamedef(gamedef),
 | 
			
		||||
	m_path_world(path_world),
 | 
			
		||||
	m_send_recommended_timer(0),
 | 
			
		||||
	m_active_block_interval_overload_skip(0),
 | 
			
		||||
	m_game_time(0),
 | 
			
		||||
@@ -401,196 +415,85 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
	for(u32 i=0; i<player_files.size(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		if(player_files[i].dir || player_files[i].name[0] == '.')
 | 
			
		||||
	for (u32 i = 0; i < player_files.size(); i++) {
 | 
			
		||||
		if (player_files[i].dir)
 | 
			
		||||
			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);
 | 
			
		||||
		std::ifstream is(path.c_str(), std::ios_base::binary);
 | 
			
		||||
		if (!is.good()) {
 | 
			
		||||
			infostream << "Failed to read " << path << std::endl;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		player->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;
 | 
			
		||||
		if (!string_allowed(player->getName(), PLAYERNAME_ALLOWED_CHARS)) {
 | 
			
		||||
			infostream << "Not loading player with invalid name: "
 | 
			
		||||
					<< player->getName() << 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);
 | 
			
		||||
		if (player->getName() == playername) {
 | 
			
		||||
			// We found our player
 | 
			
		||||
			foundplayer = true;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
		}
 | 
			
		||||
	if (!foundplayer) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//infostream<<"Saved "<<saved_players.size()<<" players."<<std::endl;
 | 
			
		||||
	if (newplayer) {
 | 
			
		||||
		addPlayer(player);
 | 
			
		||||
	}
 | 
			
		||||
	return player;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ServerEnvironment::deSerializePlayers(const std::string &savedir)
 | 
			
		||||
void ServerEnvironment::saveMeta()
 | 
			
		||||
{
 | 
			
		||||
	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)
 | 
			
		||||
			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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			player->deSerialize(is, player_files[i].name);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(newplayer)
 | 
			
		||||
		{
 | 
			
		||||
			addPlayer(player);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ServerEnvironment::saveMeta(const std::string &savedir)
 | 
			
		||||
{
 | 
			
		||||
	std::string path = savedir + "/env_meta.txt";
 | 
			
		||||
	std::string path = m_path_world + DIR_DELIM "env_meta.txt";
 | 
			
		||||
 | 
			
		||||
	// Open file and serialize
 | 
			
		||||
	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
 | 
			
		||||
	std::ifstream is(path.c_str(), std::ios_base::binary);
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	virtual void addPlayer(Player *player);
 | 
			
		||||
	void removePlayer(u16 peer_id);
 | 
			
		||||
	void removePlayer(const char *name);
 | 
			
		||||
	Player * getPlayer(u16 peer_id);
 | 
			
		||||
	Player * getPlayer(const char *name);
 | 
			
		||||
	Player * getRandomConnectedPlayer();
 | 
			
		||||
@@ -199,7 +200,7 @@ class ServerEnvironment : public Environment
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
 | 
			
		||||
			IGameDef *gamedef);
 | 
			
		||||
			IGameDef *gamedef, const std::string &path_world);
 | 
			
		||||
	~ServerEnvironment();
 | 
			
		||||
 | 
			
		||||
	Map & getMap();
 | 
			
		||||
@@ -216,17 +217,16 @@ public:
 | 
			
		||||
	float getSendRecommendedInterval()
 | 
			
		||||
		{ return m_recommended_send_interval; }
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Save players
 | 
			
		||||
	*/
 | 
			
		||||
	void serializePlayers(const std::string &savedir);
 | 
			
		||||
	void deSerializePlayers(const std::string &savedir);
 | 
			
		||||
	// Save players
 | 
			
		||||
	void saveLoadedPlayers();
 | 
			
		||||
	void savePlayer(const std::string &playername);
 | 
			
		||||
	Player *loadPlayer(const std::string &playername);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Save and load time of day and game timer
 | 
			
		||||
	*/
 | 
			
		||||
	void saveMeta(const std::string &savedir);
 | 
			
		||||
	void loadMeta(const std::string &savedir);
 | 
			
		||||
	void saveMeta();
 | 
			
		||||
	void loadMeta();
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		External ActiveObject interface
 | 
			
		||||
@@ -368,6 +368,8 @@ private:
 | 
			
		||||
	GameScripting* m_script;
 | 
			
		||||
	// Game definition
 | 
			
		||||
	IGameDef *m_gamedef;
 | 
			
		||||
	// World path
 | 
			
		||||
	const std::string m_path_world;
 | 
			
		||||
	// Active object list
 | 
			
		||||
	std::map<u16, ServerActiveObject*> m_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
 | 
			
		||||
*/
 | 
			
		||||
@@ -292,3 +358,4 @@ void RemotePlayer::setPosition(const v3f &position)
 | 
			
		||||
	if(m_sao)
 | 
			
		||||
		m_sao->setBasePosition(position);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -335,6 +335,8 @@ public:
 | 
			
		||||
	RemotePlayer(IGameDef *gamedef): Player(gamedef), m_sao(0) {}
 | 
			
		||||
	virtual ~RemotePlayer() {}
 | 
			
		||||
 | 
			
		||||
	void save(const std::string &savedir);
 | 
			
		||||
 | 
			
		||||
	PlayerSAO *getPlayerSAO()
 | 
			
		||||
	{ return m_sao; }
 | 
			
		||||
	void setPlayerSAO(PlayerSAO *sao)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										103
									
								
								src/server.cpp
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								src/server.cpp
									
									
									
									
									
								
							@@ -344,7 +344,7 @@ Server::Server(
 | 
			
		||||
 | 
			
		||||
	// Initialize Environment
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
@@ -361,19 +361,13 @@ Server::Server(
 | 
			
		||||
	servermap->addEventReceiver(this);
 | 
			
		||||
 | 
			
		||||
	// 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;
 | 
			
		||||
		m_env->loadMeta(m_path_world);
 | 
			
		||||
		m_env->loadMeta();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Load players
 | 
			
		||||
	infostream<<"Server: Loading players"<<std::endl;
 | 
			
		||||
	m_env->deSerializePlayers(m_path_world);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Add some test ActiveBlockModifiers to environment
 | 
			
		||||
	*/
 | 
			
		||||
	// Add some test ActiveBlockModifiers to environment
 | 
			
		||||
	add_legacy_abms(m_env, m_nodedef);
 | 
			
		||||
 | 
			
		||||
	m_liquid_transform_every = g_settings->getFloat("liquid_update");
 | 
			
		||||
@@ -383,42 +377,23 @@ Server::~Server()
 | 
			
		||||
{
 | 
			
		||||
	infostream<<"Server destructing"<<std::endl;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Send shutdown message
 | 
			
		||||
	*/
 | 
			
		||||
	{
 | 
			
		||||
		std::wstring line = L"*** Server shutting down";
 | 
			
		||||
		SendChatMessage(PEER_ID_INEXISTENT, line);
 | 
			
		||||
	}
 | 
			
		||||
	// Send shutdown message
 | 
			
		||||
	SendChatMessage(PEER_ID_INEXISTENT, L"*** Server shutting down");
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		JMutexAutoLock envlock(m_env_mutex);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
			Execute script shutdown hooks
 | 
			
		||||
		*/
 | 
			
		||||
		// Execute script shutdown hooks
 | 
			
		||||
		m_script->on_shutdown();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		JMutexAutoLock envlock(m_env_mutex);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
			Save players
 | 
			
		||||
		*/
 | 
			
		||||
		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;
 | 
			
		||||
		m_env->saveMeta(m_path_world);
 | 
			
		||||
		m_env->saveMeta();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Stop threads
 | 
			
		||||
	*/
 | 
			
		||||
	// Stop threads
 | 
			
		||||
	stop();
 | 
			
		||||
	delete m_thread;
 | 
			
		||||
 | 
			
		||||
@@ -444,12 +419,10 @@ Server::~Server()
 | 
			
		||||
	delete m_script;
 | 
			
		||||
 | 
			
		||||
	// Delete detached inventories
 | 
			
		||||
	{
 | 
			
		||||
		for(std::map<std::string, Inventory*>::iterator
 | 
			
		||||
				i = m_detached_inventories.begin();
 | 
			
		||||
				i != m_detached_inventories.end(); i++){
 | 
			
		||||
			delete i->second;
 | 
			
		||||
		}
 | 
			
		||||
	for (std::map<std::string, Inventory*>::iterator
 | 
			
		||||
			i = m_detached_inventories.begin();
 | 
			
		||||
			i != m_detached_inventories.end(); i++) {
 | 
			
		||||
		delete i->second;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1141,18 +1114,19 @@ void Server::AsyncRunStep(bool initial_step)
 | 
			
		||||
 | 
			
		||||
			ScopeProfiler sp(g_profiler, "Server: saving stuff");
 | 
			
		||||
 | 
			
		||||
			//Ban stuff
 | 
			
		||||
			if(m_banmanager->isModified())
 | 
			
		||||
			// Save ban file
 | 
			
		||||
			if (m_banmanager->isModified()) {
 | 
			
		||||
				m_banmanager->save();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Save changed parts of map
 | 
			
		||||
			m_env->getMap().save(MOD_STATE_WRITE_NEEDED);
 | 
			
		||||
 | 
			
		||||
			// Save players
 | 
			
		||||
			m_env->serializePlayers(m_path_world);
 | 
			
		||||
			m_env->saveLoadedPlayers();
 | 
			
		||||
 | 
			
		||||
			// Save environment metadata
 | 
			
		||||
			m_env->saveMeta(m_path_world);
 | 
			
		||||
			m_env->saveMeta();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1178,27 +1152,16 @@ void Server::Receive()
 | 
			
		||||
				"SerializationError: what()="
 | 
			
		||||
				<<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)
 | 
			
		||||
	{
 | 
			
		||||
		errorstream << "ProcessData: peer=" << peer_id  << e.what() << std::endl;
 | 
			
		||||
		DenyAccess(peer_id, L"Your client sent something server didn't expect."
 | 
			
		||||
				L"Try reconnecting or updating your client");
 | 
			
		||||
	}
 | 
			
		||||
	catch(con::PeerNotFoundException &e)
 | 
			
		||||
	{
 | 
			
		||||
		// Do nothing
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PlayerSAO* Server::StageTwoClientInit(u16 peer_id)
 | 
			
		||||
@@ -5032,15 +4995,16 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Create a new player if it doesn't exist yet
 | 
			
		||||
	*/
 | 
			
		||||
	if(player == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	// Load player if it isn't already loaded
 | 
			
		||||
	if (!player) {
 | 
			
		||||
		player = static_cast<RemotePlayer*>(m_env->loadPlayer(name));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create player if it doesn't exist
 | 
			
		||||
	if (!player) {
 | 
			
		||||
		newplayer = true;
 | 
			
		||||
		player = new RemotePlayer(this);
 | 
			
		||||
		player->updateName(name);
 | 
			
		||||
 | 
			
		||||
		/* Set player position */
 | 
			
		||||
		infostream<<"Server: Finding spawn place for player \""
 | 
			
		||||
				<<name<<"\""<<std::endl;
 | 
			
		||||
@@ -5051,9 +5015,7 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
 | 
			
		||||
		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,
 | 
			
		||||
			getPlayerEffectivePrivs(player->getName()),
 | 
			
		||||
			isSingleplayer());
 | 
			
		||||
@@ -5065,8 +5027,9 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
 | 
			
		||||
	m_env->addActiveObject(playersao);
 | 
			
		||||
 | 
			
		||||
	/* Run scripts */
 | 
			
		||||
	if(newplayer)
 | 
			
		||||
	if (newplayer) {
 | 
			
		||||
		m_script->on_newplayer(playersao);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return playersao;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user