PlayerSAO saving fix (#4734)

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...
This commit is contained in:
Ner'zhul 2016-11-05 10:25:30 +01:00 committed by GitHub
parent b5c84c34ce
commit 66bb295436
4 changed files with 20 additions and 17 deletions

View 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()

View File

@ -318,6 +318,7 @@ public:
private:
std::string getPropertyPacket();
void unlinkPlayerSessionAndSave();
RemotePlayer *m_player;
u16 m_peer_id;

View 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);

View 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);