Only try to load from possible player files
authorShadowNinja <shadowninja@minetest.net>
Sun, 1 Jun 2014 17:11:37 +0000 (13:11 -0400)
committerShadowNinja <shadowninja@minetest.net>
Mon, 23 Jun 2014 19:45:59 +0000 (15:45 -0400)
src/environment.cpp
src/player.cpp
src/player.h

index 91f5ea2b6fe045c1a06c438f491cc3ebeb725389..d068aa788a43100ae433ae69e8b59a13336ccac4 100644 (file)
@@ -443,46 +443,35 @@ void ServerEnvironment::savePlayer(const std::string &playername)
 
 Player *ServerEnvironment::loadPlayer(const std::string &playername)
 {
-       std::string players_path = m_path_world + DIR_DELIM "players";
+       std::string players_path = m_path_world + DIR_DELIM "players" DIR_DELIM;
 
        RemotePlayer *player = static_cast<RemotePlayer*>(getPlayer(playername.c_str()));
        bool newplayer = false;
-       bool foundplayer = false;
+       bool found = 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)
-                       continue;
-               
-               // Full path to this file
-               std::string path = players_path + "/" + player_files[i].name;
-
-               // Load player to see what is its name
+       RemotePlayer testplayer(m_gamedef);
+       std::string path = players_path + playername;
+       for (u32 i = 0; i < 1000; i++) {
+               // 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;
+                       return NULL;
                }
-               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 (player->getName() == playername) {
-                       // We found our player
-                       foundplayer = true;
+               testplayer.deSerialize(is, path);
+               if (testplayer.getName() == playername) {
+                       *player = testplayer;
+                       found = true;
                        break;
                }
-
+               path = players_path + playername + itos(i);
        }
-       if (!foundplayer) {
+       if (!found) {
+               infostream << "Player file for player " << playername
+                               << " not found" << std::endl;
                return NULL;
        }
        if (newplayer) {
index 78ba17e8992ef9e1986d6b7613c40d2c02340d63..a52385f20c936e5d08a6d5266d5c8624ea5a881b 100644 (file)
@@ -284,11 +284,10 @@ void Player::clearHud()
 }
 
 
-void RemotePlayer::save(const std::string &savedir)
+void RemotePlayer::save(std::string savedir)
 {
-       bool newplayer = true;
-
-       /* We have to iterate through all files in the players directory
+       /*
+        * We have to open all possible player files in the players directory
         * and check their player names because some file systems are not
         * case-sensitive and player names are case-sensitive.
         */
@@ -296,23 +295,25 @@ void RemotePlayer::save(const std::string &savedir)
        // 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;
+       savedir += DIR_DELIM;
+       std::string path = savedir + m_name;
+       for (u32 i = 0; i < 1000; i++) {
+               if (!fs::PathExists(path)) {
+                       // 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;
+                       }
+                       return;
                }
-
-               // 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;
+                       infostream << "Failed to open " << path << std::endl;
+                       return;
                }
-               testplayer.deSerialize(is, player_files[i].name);
-
+               testplayer.deSerialize(is, path);
                if (strcmp(testplayer.getName(), m_name) == 0) {
                        // Open file and serialize
                        std::ostringstream ss(std::ios_base::binary);
@@ -320,33 +321,13 @@ void RemotePlayer::save(const std::string &savedir)
                        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;
-               }
+               path = savedir + m_name + itos(i);
        }
+
+       infostream << "Didn't find free file for player " << m_name << std::endl;
+       return;
 }
 
 /*
index 098a4d1537d017fb951e1dc0b6f3311aab41f9ce..93197d374a5ecff3573e2c3d2d115024fcdae503 100644 (file)
@@ -335,7 +335,7 @@ public:
        RemotePlayer(IGameDef *gamedef): Player(gamedef), m_sao(0) {}
        virtual ~RemotePlayer() {}
 
-       void save(const std::string &savedir);
+       void save(std::string savedir);
 
        PlayerSAO *getPlayerSAO()
        { return m_sao; }