diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index 425c936e7..04bcccf9b 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -1264,6 +1264,11 @@ bool CGameNetworkManager::SystemFlagGet(INetworkPlayer *pNetworkPlayer, int inde return s_pPlatformNetworkManager->SystemFlagGet( pNetworkPlayer, index ); } +void CGameNetworkManager::SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer) +{ + s_pPlatformNetworkManager->SystemFlagClearForSystem( pNetworkPlayer ); +} + wstring CGameNetworkManager::GatherStats() { return s_pPlatformNetworkManager->GatherStats(); diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.h b/Minecraft.Client/Common/Network/GameNetworkManager.h index 1bb532dab..388224b77 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.h +++ b/Minecraft.Client/Common/Network/GameNetworkManager.h @@ -133,6 +133,7 @@ public: void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index); bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index); + void SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer); // Events diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerInterface.h b/Minecraft.Client/Common/Network/PlatformNetworkManagerInterface.h index 31c415a75..acde6da7c 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerInterface.h +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerInterface.h @@ -101,6 +101,7 @@ private: public: virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index) = 0; virtual bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index) = 0; + virtual void SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer) {} virtual wstring GatherStats() = 0; virtual wstring GatherRTTStats() = 0; diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp index 636f9b908..f5c786e28 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp @@ -707,6 +707,19 @@ bool CPlatformNetworkManagerStub::SystemFlagGet(INetworkPlayer *pNetworkPlayer, return false; } +void CPlatformNetworkManagerStub::SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer) +{ + if( pNetworkPlayer == NULL ) return; + + for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) + { + if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) + { + memset(m_playerFlags[i]->flags, 0, m_playerFlags[i]->count / 8); + } + } +} + wstring CPlatformNetworkManagerStub::GatherStats() { return L""; diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h index 919efd713..2144ddd63 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h @@ -108,6 +108,7 @@ private: public: virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index); virtual bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index); + virtual void SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer); // For telemetry private: diff --git a/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.cpp b/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.cpp index 009993cb0..562f98498 100644 --- a/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.cpp +++ b/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.cpp @@ -1064,6 +1064,19 @@ bool CPlatformNetworkManagerSony::SystemFlagGet(INetworkPlayer *pNetworkPlayer, return false; } +void CPlatformNetworkManagerSony::SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer) +{ + if( pNetworkPlayer == NULL ) return; + + for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) + { + if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) + { + memset(m_playerFlags[i]->flags, 0, m_playerFlags[i]->count / 8); + } + } +} + wstring CPlatformNetworkManagerSony::GatherStats() { #if 0 diff --git a/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.h b/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.h index 258acd833..92c9f4d1a 100644 --- a/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.h +++ b/Minecraft.Client/Common/Network/Sony/PlatformNetworkManagerSony.h @@ -129,6 +129,7 @@ private: public: virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index); virtual bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index); + virtual void SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer); // For telemetry private: diff --git a/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.cpp b/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.cpp index 3efba5edb..ccc97af4b 100644 --- a/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.cpp +++ b/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.cpp @@ -744,6 +744,19 @@ bool CPlatformNetworkManagerDurango::SystemFlagGet(INetworkPlayer *pNetworkPlaye return false; } +void CPlatformNetworkManagerDurango::SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer) +{ + if( pNetworkPlayer == NULL ) return; + + for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) + { + if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) + { + memset(m_playerFlags[i]->flags, 0, m_playerFlags[i]->count / 8); + } + } +} + wstring CPlatformNetworkManagerDurango::GatherStats() { return L""; @@ -937,4 +950,4 @@ bool CPlatformNetworkManagerDurango::IsReadyToPlayOrIdle() bool CPlatformNetworkManagerDurango::IsSessionJoinable() { return m_hostGameSessionIsJoinable; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.h b/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.h index 558072275..4f9b71a9a 100644 --- a/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.h +++ b/Minecraft.Client/Durango/Network/PlatformNetworkManagerDurango.h @@ -114,6 +114,7 @@ private: public: virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index); virtual bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index); + virtual void SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer); // For telemetry private: @@ -165,4 +166,4 @@ public: virtual void HandleDisconnect(bool bLostRoomOnly); virtual void HandleInviteReceived(int playerIndex, DQRNetworkManager::SessionInfo *pInviteInfo); virtual bool IsSessionJoinable(); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/PlayerList.cpp b/Minecraft.Client/PlayerList.cpp index 7921cbf89..82893f3a8 100644 --- a/Minecraft.Client/PlayerList.cpp +++ b/Minecraft.Client/PlayerList.cpp @@ -86,6 +86,32 @@ void PlayerList::placeNewPlayer(Connection *connection, shared_ptr player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_HOST,1); } + // A reconnect from the same machine can race with platform-level leave notifications. + // If this is the first active player we can currently see for this system, clear the per-system + // chunk-sent flags so initial terrain is always resent for this login. + if( networkPlayer != NULL ) + { + bool hasActiveSameSystemPlayer = false; + for(AUTO_VAR(it, players.begin()); it < players.end(); ++it) + { + shared_ptr existingPlayer = *it; + if( existingPlayer == NULL || existingPlayer->connection == NULL ) continue; + + INetworkPlayer *existingNetworkPlayer = existingPlayer->connection->getNetworkPlayer(); + if( existingNetworkPlayer == NULL ) continue; + + if( networkPlayer->IsSameSystem(existingNetworkPlayer) ) + { + hasActiveSameSystemPlayer = true; + break; + } + } + + if( !hasActiveSameSystemPlayer ) + { + g_NetworkManager.SystemFlagClearForSystem(networkPlayer); + } + } #if defined(__PS3__) || defined(__ORBIS__) // PS3 networking library doesn't automatically assign PlayerUIDs to the network players for anything remote, so need to tell it what to set from the data in this packet now if( !g_NetworkManager.IsLocalGame() ) diff --git a/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.cpp b/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.cpp index a551725b0..6f798250f 100644 --- a/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.cpp +++ b/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.cpp @@ -1097,6 +1097,19 @@ bool CPlatformNetworkManagerXbox::SystemFlagGet(INetworkPlayer *pNetworkPlayer, return false; } +void CPlatformNetworkManagerXbox::SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer) +{ + if( pNetworkPlayer == NULL ) return; + + for( unsigned int i = 0; i < m_playerFlags.size(); i++ ) + { + if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) ) + { + memset(m_playerFlags[i]->flags, 0, m_playerFlags[i]->count / 8); + } + } +} + wstring CPlatformNetworkManagerXbox::GatherStats() { return L"Queue messages: " + _toString(((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetSendQueueSize( NULL, QNET_GETSENDQUEUESIZE_MESSAGES ) ) diff --git a/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.h b/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.h index 7c6112b4e..1885ce500 100644 --- a/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.h +++ b/Minecraft.Client/Xbox/Network/PlatformNetworkManagerXbox.h @@ -115,6 +115,7 @@ private: public: virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index); virtual bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index); + virtual void SystemFlagClearForSystem(INetworkPlayer *pNetworkPlayer); // For telemetry private: @@ -181,4 +182,4 @@ public: VOID NotifyGameInvite( __in DWORD dwUserIndex, __in const INVITE_INFO * pInviteInfo ); VOID NotifyContextChanged( __in const XUSER_CONTEXT * pContext); VOID NotifyPropertyChanged( __in const XUSER_PROPERTY * pProperty); -}; \ No newline at end of file +};