Skip to content

Commit 7e6db1b

Browse files
committedJun 23, 2014
Only keep players loaded while they're connected
1 parent 5012751 commit 7e6db1b

File tree

6 files changed

+181
-242
lines changed

6 files changed

+181
-242
lines changed
 

‎src/content_sao.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,8 @@ void PlayerSAO::removingFromEnvironment()
10271027
{
10281028
m_player->setPlayerSAO(NULL);
10291029
m_player->peer_id = 0;
1030+
m_env->savePlayer(m_player->getName());
1031+
m_env->removePlayer(m_player->getName());
10301032
}
10311033
}
10321034

‎src/environment.cpp

+67-164
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ void Environment::removePlayer(u16 peer_id)
100100
}
101101
}
102102

103+
void Environment::removePlayer(const char *name)
104+
{
105+
for (std::list<Player*>::iterator it = m_players.begin();
106+
it != m_players.end(); ++it) {
107+
if (strcmp((*it)->getName(), name) == 0) {
108+
delete *it;
109+
m_players.erase(it);
110+
return;
111+
}
112+
}
113+
}
114+
103115
Player * Environment::getPlayer(u16 peer_id)
104116
{
105117
for(std::list<Player*>::iterator i = m_players.begin();
@@ -332,10 +344,12 @@ void ActiveBlockList::update(std::list<v3s16> &active_positions,
332344
*/
333345

334346
ServerEnvironment::ServerEnvironment(ServerMap *map,
335-
GameScripting *scriptIface, IGameDef *gamedef):
347+
GameScripting *scriptIface, IGameDef *gamedef,
348+
const std::string &path_world) :
336349
m_map(map),
337350
m_script(scriptIface),
338351
m_gamedef(gamedef),
352+
m_path_world(path_world),
339353
m_send_recommended_timer(0),
340354
m_active_block_interval_overload_skip(0),
341355
m_game_time(0),
@@ -401,196 +415,85 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16
401415
return true;
402416
}
403417

404-
void ServerEnvironment::serializePlayers(const std::string &savedir)
418+
void ServerEnvironment::saveLoadedPlayers()
405419
{
406-
std::string players_path = savedir + "/players";
420+
std::string players_path = m_path_world + DIR_DELIM "players";
407421
fs::CreateDir(players_path);
408422

409-
std::set<Player*> saved_players;
410-
411-
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
412-
for(u32 i=0; i<player_files.size(); i++)
413-
{
414-
if(player_files[i].dir || player_files[i].name[0] == '.')
415-
continue;
416-
417-
// Full path to this file
418-
std::string path = players_path + "/" + player_files[i].name;
419-
420-
//infostream<<"Checking player file "<<path<<std::endl;
421-
422-
// Load player to see what is its name
423-
RemotePlayer testplayer(m_gamedef);
424-
{
425-
// Open file and deserialize
426-
std::ifstream is(path.c_str(), std::ios_base::binary);
427-
if(is.good() == false)
428-
{
429-
infostream<<"Failed to read "<<path<<std::endl;
430-
continue;
431-
}
432-
testplayer.deSerialize(is, player_files[i].name);
433-
}
434-
435-
//infostream<<"Loaded test player with name "<<testplayer.getName()<<std::endl;
436-
437-
// Search for the player
438-
std::string playername = testplayer.getName();
439-
Player *player = getPlayer(playername.c_str());
440-
if(player == NULL)
441-
{
442-
infostream<<"Didn't find matching player, ignoring file "<<path<<std::endl;
443-
continue;
444-
}
445-
446-
//infostream<<"Found matching player, overwriting."<<std::endl;
447-
448-
// OK, found. Save player there.
449-
if(player->checkModified())
450-
{
451-
// Open file and serialize
452-
std::ostringstream ss(std::ios_base::binary);
453-
player->serialize(ss);
454-
if(!fs::safeWriteToFile(path, ss.str()))
455-
{
456-
infostream<<"Failed to write "<<path<<std::endl;
457-
continue;
458-
}
459-
saved_players.insert(player);
460-
} else {
461-
saved_players.insert(player);
423+
for (std::list<Player*>::iterator it = m_players.begin();
424+
it != m_players.end();
425+
++it) {
426+
RemotePlayer *player = static_cast<RemotePlayer*>(*it);
427+
if (player->checkModified()) {
428+
player->save(players_path);
462429
}
463430
}
431+
}
464432

465-
for(std::list<Player*>::iterator i = m_players.begin();
466-
i != m_players.end(); ++i)
467-
{
468-
Player *player = *i;
469-
if(saved_players.find(player) != saved_players.end())
470-
{
471-
/*infostream<<"Player "<<player->getName()
472-
<<" was already saved."<<std::endl;*/
473-
continue;
474-
}
475-
std::string playername = player->getName();
476-
// Don't save unnamed player
477-
if(playername == "")
478-
{
479-
//infostream<<"Not saving unnamed player."<<std::endl;
480-
continue;
481-
}
482-
/*
483-
Find a sane filename
484-
*/
485-
if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS) == false)
486-
playername = "player";
487-
std::string path = players_path + "/" + playername;
488-
bool found = false;
489-
for(u32 i=0; i<1000; i++)
490-
{
491-
if(fs::PathExists(path) == false)
492-
{
493-
found = true;
494-
break;
495-
}
496-
path = players_path + "/" + playername + itos(i);
497-
}
498-
if(found == false)
499-
{
500-
infostream<<"Didn't find free file for player"<<std::endl;
501-
continue;
502-
}
433+
void ServerEnvironment::savePlayer(const std::string &playername)
434+
{
435+
std::string players_path = m_path_world + DIR_DELIM "players";
436+
fs::CreateDir(players_path);
503437

504-
{
505-
/*infostream<<"Saving player "<<player->getName()<<" to "
506-
<<path<<std::endl;*/
507-
// Open file and serialize
508-
std::ostringstream ss(std::ios_base::binary);
509-
player->serialize(ss);
510-
if(!fs::safeWriteToFile(path, ss.str()))
511-
{
512-
infostream<<"Failed to write "<<path<<std::endl;
513-
continue;
514-
}
515-
saved_players.insert(player);
516-
}
438+
RemotePlayer *player = static_cast<RemotePlayer*>(getPlayer(playername.c_str()));
439+
if (player) {
440+
player->save(players_path);
517441
}
518-
519-
//infostream<<"Saved "<<saved_players.size()<<" players."<<std::endl;
520442
}
521443

522-
void ServerEnvironment::deSerializePlayers(const std::string &savedir)
444+
Player *ServerEnvironment::loadPlayer(const std::string &playername)
523445
{
524-
std::string players_path = savedir + "/players";
446+
std::string players_path = m_path_world + DIR_DELIM "players";
447+
448+
RemotePlayer *player = static_cast<RemotePlayer*>(getPlayer(playername.c_str()));
449+
bool newplayer = false;
450+
bool foundplayer = false;
451+
if (!player) {
452+
player = new RemotePlayer(m_gamedef);
453+
newplayer = true;
454+
}
525455

526456
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
527-
for(u32 i=0; i<player_files.size(); i++)
528-
{
529-
if(player_files[i].dir)
457+
for (u32 i = 0; i < player_files.size(); i++) {
458+
if (player_files[i].dir)
530459
continue;
531460

532461
// Full path to this file
533462
std::string path = players_path + "/" + player_files[i].name;
534463

535-
//infostream<<"Checking player file "<<path<<std::endl;
536-
537464
// Load player to see what is its name
538-
RemotePlayer testplayer(m_gamedef);
539-
{
540-
// Open file and deserialize
541-
std::ifstream is(path.c_str(), std::ios_base::binary);
542-
if(is.good() == false)
543-
{
544-
infostream<<"Failed to read "<<path<<std::endl;
545-
continue;
546-
}
547-
testplayer.deSerialize(is, player_files[i].name);
548-
}
549-
550-
if(!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS))
551-
{
552-
infostream<<"Not loading player with invalid name: "
553-
<<testplayer.getName()<<std::endl;
465+
std::ifstream is(path.c_str(), std::ios_base::binary);
466+
if (!is.good()) {
467+
infostream << "Failed to read " << path << std::endl;
468+
continue;
554469
}
470+
player->deSerialize(is, player_files[i].name);
555471

556-
/*infostream<<"Loaded test player with name "<<testplayer.getName()
557-
<<std::endl;*/
558-
559-
// Search for the player
560-
std::string playername = testplayer.getName();
561-
Player *player = getPlayer(playername.c_str());
562-
bool newplayer = false;
563-
if(player == NULL)
564-
{
565-
//infostream<<"Is a new player"<<std::endl;
566-
player = new RemotePlayer(m_gamedef);
567-
newplayer = true;
472+
if (!string_allowed(player->getName(), PLAYERNAME_ALLOWED_CHARS)) {
473+
infostream << "Not loading player with invalid name: "
474+
<< player->getName() << std::endl;
475+
continue;
568476
}
569477

570-
// Load player
571-
{
572-
verbosestream<<"Reading player "<<testplayer.getName()<<" from "
573-
<<path<<std::endl;
574-
// Open file and deserialize
575-
std::ifstream is(path.c_str(), std::ios_base::binary);
576-
if(is.good() == false)
577-
{
578-
infostream<<"Failed to read "<<path<<std::endl;
579-
continue;
580-
}
581-
player->deSerialize(is, player_files[i].name);
478+
if (player->getName() == playername) {
479+
// We found our player
480+
foundplayer = true;
481+
break;
582482
}
583483

584-
if(newplayer)
585-
{
586-
addPlayer(player);
587-
}
588484
}
485+
if (!foundplayer) {
486+
return NULL;
487+
}
488+
if (newplayer) {
489+
addPlayer(player);
490+
}
491+
return player;
589492
}
590493

591-
void ServerEnvironment::saveMeta(const std::string &savedir)
494+
void ServerEnvironment::saveMeta()
592495
{
593-
std::string path = savedir + "/env_meta.txt";
496+
std::string path = m_path_world + DIR_DELIM "env_meta.txt";
594497

595498
// Open file and serialize
596499
std::ostringstream ss(std::ios_base::binary);
@@ -609,9 +512,9 @@ void ServerEnvironment::saveMeta(const std::string &savedir)
609512
}
610513
}
611514

612-
void ServerEnvironment::loadMeta(const std::string &savedir)
515+
void ServerEnvironment::loadMeta()
613516
{
614-
std::string path = savedir + "/env_meta.txt";
517+
std::string path = m_path_world + DIR_DELIM "env_meta.txt";
615518

616519
// Open file and deserialize
617520
std::ifstream is(path.c_str(), std::ios_base::binary);

‎src/environment.h

+10-8
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class Environment
7070

7171
virtual void addPlayer(Player *player);
7272
void removePlayer(u16 peer_id);
73+
void removePlayer(const char *name);
7374
Player * getPlayer(u16 peer_id);
7475
Player * getPlayer(const char *name);
7576
Player * getRandomConnectedPlayer();
@@ -199,7 +200,7 @@ class ServerEnvironment : public Environment
199200
{
200201
public:
201202
ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
202-
IGameDef *gamedef);
203+
IGameDef *gamedef, const std::string &path_world);
203204
~ServerEnvironment();
204205

205206
Map & getMap();
@@ -216,17 +217,16 @@ class ServerEnvironment : public Environment
216217
float getSendRecommendedInterval()
217218
{ return m_recommended_send_interval; }
218219

219-
/*
220-
Save players
221-
*/
222-
void serializePlayers(const std::string &savedir);
223-
void deSerializePlayers(const std::string &savedir);
220+
// Save players
221+
void saveLoadedPlayers();
222+
void savePlayer(const std::string &playername);
223+
Player *loadPlayer(const std::string &playername);
224224

225225
/*
226226
Save and load time of day and game timer
227227
*/
228-
void saveMeta(const std::string &savedir);
229-
void loadMeta(const std::string &savedir);
228+
void saveMeta();
229+
void loadMeta();
230230

231231
/*
232232
External ActiveObject interface
@@ -368,6 +368,8 @@ class ServerEnvironment : public Environment
368368
GameScripting* m_script;
369369
// Game definition
370370
IGameDef *m_gamedef;
371+
// World path
372+
const std::string m_path_world;
371373
// Active object list
372374
std::map<u16, ServerActiveObject*> m_active_objects;
373375
// Outgoing network message buffer for active objects

0 commit comments

Comments
 (0)
Please sign in to comment.