PlayerSAO saving fix (#4734)
authorNer'zhul <nerzhul@users.noreply.github.com>
Sat, 5 Nov 2016 09:25:30 +0000 (10:25 +0100)
committerGitHub <noreply@github.com>
Sat, 5 Nov 2016 09:25:30 +0000 (10:25 +0100)
PlayerSAO::disconnected() function was historical and remove the link between SAO and RemotePlayer session. With previous attributes linked to RemotePlayer saving was working. But now attributes are read from SAO not RemotePlayer and the current serialize function verify SAO exists to save the player attributes.

Because PlayerSAO::disconnected marks playersao for removal, only mark playerSAO for removal and let PlayerSAO::removingFromEnvironment do the correct saving behaviour and all the disconnection process instead of doing a partial removal and let the server loop doing the RemotePlayer cleanup and remove some saved attributes...

src/content_sao.cpp
src/content_sao.h
src/remoteplayer.cpp
src/server.cpp

index 5fb8f936e58acfe04325db3fb58ba5a5eb69e0db..dff222f42a16cdf3ed2aa1a7edf4b3211e408c15 100644 (file)
@@ -838,10 +838,7 @@ void PlayerSAO::removingFromEnvironment()
 {
        ServerActiveObject::removingFromEnvironment();
        if (m_player->getPlayerSAO() == this) {
-               m_player->peer_id = 0;
-               m_env->savePlayer(m_player);
-               m_player->setPlayerSAO(NULL);
-               m_env->removePlayer(m_player);
+               unlinkPlayerSessionAndSave();
                for (UNORDERED_SET<u32>::iterator it = m_attached_particle_spawners.begin();
                        it != m_attached_particle_spawners.end(); ++it) {
                        m_env->deleteParticleSpawner(*it, false);
@@ -1340,15 +1337,20 @@ void PlayerSAO::setWieldIndex(int i)
        }
 }
 
+// Erase the peer id and make the object for removal
 void PlayerSAO::disconnected()
 {
        m_peer_id = 0;
        m_removed = true;
-       if(m_player->getPlayerSAO() == this)
-       {
-               m_player->setPlayerSAO(NULL);
-               m_player->peer_id = 0;
-       }
+}
+
+void PlayerSAO::unlinkPlayerSessionAndSave()
+{
+       assert(m_player->getPlayerSAO() == this);
+       m_player->peer_id = 0;
+       m_env->savePlayer(m_player);
+       m_player->setPlayerSAO(NULL);
+       m_env->removePlayer(m_player);
 }
 
 std::string PlayerSAO::getPropertyPacket()
index 5d837a4663f6b661581d8a2919e98ed79e8b4756..f58c7dadbf7447ca35c0475723e8a48cec663e86 100644 (file)
@@ -318,6 +318,7 @@ public:
 
 private:
        std::string getPropertyPacket();
+       void unlinkPlayerSessionAndSave();
 
        RemotePlayer *m_player;
        u16 m_peer_id;
index f4a79dd081515f136cffe747ddaa892d2ac37235..67ab89113aa73a88fd83aac701cedea10fe97798 100644 (file)
@@ -177,13 +177,13 @@ void RemotePlayer::serialize(std::ostream &os)
        args.set("name", m_name);
        //args.set("password", m_password);
 
-       if (m_sao) {
-               args.setS32("hp", m_sao->getHP());
-               args.setV3F("position", m_sao->getBasePosition());
-               args.setFloat("pitch", m_sao->getPitch());
-               args.setFloat("yaw", m_sao->getYaw());
-               args.setS32("breath", m_sao->getBreath());
-       }
+       // This should not happen
+       assert(m_sao);
+       args.setS32("hp", m_sao->getHP());
+       args.setV3F("position", m_sao->getBasePosition());
+       args.setFloat("pitch", m_sao->getPitch());
+       args.setFloat("yaw", m_sao->getYaw());
+       args.setS32("breath", m_sao->getBreath());
 
        args.writeLines(os);
 
index cd526ad77aed35d47400fc9664cc4eb1919ad436..48331e4f84b2dad4eaf56c6815d6319468b224e9 100644 (file)
@@ -2654,7 +2654,7 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason)
                RemotePlayer *player = m_env->getPlayer(peer_id);
 
                /* Run scripts and remove from environment */
-               if(player != NULL) {
+               if (player != NULL) {
                        PlayerSAO *playersao = player->getPlayerSAO();
                        assert(playersao);