From e513d6b8c59a38c1af76eb98ebe6ecbb89e81ba3 Mon Sep 17 00:00:00 2001 From: Michal Schiller Date: Fri, 6 Mar 2026 18:24:35 +0100 Subject: [PATCH] Refactor player management and socket handling Call order in AddLocalPlayerByUserIndex NotifyPlayerJoined was called before AddLocalPlayerByUserIndex, so the slot was always uninitialised at the point of dereference. Swapped the order. --- .../Network/PlatformNetworkManagerStub.cpp | 105 +++++------------- 1 file changed, 25 insertions(+), 80 deletions(-) diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp index 80fbd98cf..6f5c23a62 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp @@ -1,14 +1,12 @@ -#include "stdafx.h" +#include "stdafx.h" #include "..\..\..\Minecraft.World\Socket.h" #include "..\..\..\Minecraft.World\StringHelpers.h" #include "PlatformNetworkManagerStub.h" #include "..\..\Xbox\Network\NetworkPlayerXbox.h" #ifdef _WINDOWS64 #include "..\..\Windows64\Network\WinsockNetLayer.h" -#include "..\..\Windows64\Windows64_Xuid.h" #include "..\..\Minecraft.h" #include "..\..\User.h" -#include #endif CPlatformNetworkManagerStub *g_pPlatformNetworkManager; @@ -65,8 +63,9 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer ) { // Do we already have a primary player for this system? bool systemHasPrimaryPlayer = false; - for (auto& pQNetPrimaryPlayer : m_machineQNetPrimaryPlayers) - { + for(AUTO_VAR(it, m_machineQNetPrimaryPlayers.begin()); it < m_machineQNetPrimaryPlayers.end(); ++it) + { + IQNetPlayer *pQNetPrimaryPlayer = *it; if( pQNetPlayer->IsSameSystem(pQNetPrimaryPlayer) ) { systemHasPrimaryPlayer = true; @@ -78,7 +77,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer ) } } g_NetworkManager.PlayerJoining( networkPlayer ); - + if( createFakeSocket == true && !m_bHostChanged ) { g_NetworkManager.CreateSocket( networkPlayer, localPlayer ); @@ -98,7 +97,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer ) // g_NetworkManager.UpdateAndSetGameSessionData(); SystemFlagAddPlayer( networkPlayer ); } - + for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx) { if(playerChangedCallback[idx] != NULL) @@ -162,7 +161,7 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa { playerChangedCallback[ i ] = NULL; } - + m_bLeavingGame = false; m_bLeaveGameOnTick = false; m_bHostChanged = false; @@ -235,7 +234,6 @@ void CPlatformNetworkManagerStub::DoWork() qnetPlayer->m_smallId = 0; qnetPlayer->m_isRemote = false; qnetPlayer->m_isHostPlayer = false; - qnetPlayer->m_resolvedXuid = INVALID_XUID; qnetPlayer->m_gamertag[0] = 0; qnetPlayer->SetCustomDataValue(0); WinsockNetLayer::PushFreeSmallId(disconnectedSmallId); @@ -269,8 +267,11 @@ int CPlatformNetworkManagerStub::GetLocalPlayerMask(int playerIndex) bool CPlatformNetworkManagerStub::AddLocalPlayerByUserIndex( int userIndex ) { - NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); - return ( m_pIQNet->AddLocalPlayerByUserIndex(userIndex) == S_OK ); + // Initialize the slot first so GetLocalPlayerByUserIndex never returns NULL + bool success = ( m_pIQNet->AddLocalPlayerByUserIndex(userIndex) == S_OK ); + if (success) + NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); + return success; } bool CPlatformNetworkManagerStub::RemoveLocalPlayerByUserIndex( int userIndex ) @@ -319,8 +320,8 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost) m_pIQNet->EndGame(); } - for (auto & it : currentNetworkPlayers) - delete it; + for (AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++) + delete* it; currentNetworkPlayers.clear(); m_machineQNetPrimaryPlayers.clear(); SystemFlagReset(); @@ -356,9 +357,7 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame, #ifdef _WINDOWS64 IQNet::m_player[0].m_smallId = 0; IQNet::m_player[0].m_isRemote = false; - // world host is pinned to legacy host XUID to keep old player data compatibility. IQNet::m_player[0].m_isHostPlayer = true; - IQNet::m_player[0].m_resolvedXuid = Win64Xuid::GetLegacyEmbeddedHostXuid(); IQNet::s_playerCount = 1; #endif @@ -415,8 +414,6 @@ int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo* searchResult, int l IQNet::m_player[0].m_smallId = 0; IQNet::m_player[0].m_isRemote = true; IQNet::m_player[0].m_isHostPlayer = true; - // Remote host still maps to legacy host XUID in mixed old/new sessions. - IQNet::m_player[0].m_resolvedXuid = Win64Xuid::GetLegacyEmbeddedHostXuid(); wcsncpy_s(IQNet::m_player[0].m_gamertag, 32, searchResult->data.hostName, _TRUNCATE); WinsockNetLayer::StopDiscovery(); @@ -432,8 +429,6 @@ int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo* searchResult, int l IQNet::m_player[localSmallId].m_smallId = localSmallId; IQNet::m_player[localSmallId].m_isRemote = false; IQNet::m_player[localSmallId].m_isHostPlayer = false; - // Local non-host identity is the persistent uid.dat XUID. - IQNet::m_player[localSmallId].m_resolvedXuid = Win64Xuid::ResolvePersistentXuid(); Minecraft* pMinecraft = Minecraft::GetInstance(); wcscpy_s(IQNet::m_player[localSmallId].m_gamertag, 32, pMinecraft->user->name.c_str()); @@ -480,7 +475,7 @@ void CPlatformNetworkManagerStub::UnRegisterPlayerChangedCallback(int iPad, void void CPlatformNetworkManagerStub::HandleSignInChange() { - return; + return; } bool CPlatformNetworkManagerStub::_RunNetworkGame() @@ -507,24 +502,24 @@ bool CPlatformNetworkManagerStub::_RunNetworkGame() void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) { // DWORD playerCount = m_pIQNet->GetPlayerCount(); -// +// // if( this->m_bLeavingGame ) // return; -// +// // if( GetHostPlayer() == NULL ) // return; -// +// // for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) // { // if( i < playerCount ) // { // INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i); -// +// // // We can call this from NotifyPlayerLeaving but at that point the player is still considered in the session // if( pNetworkPlayer != pNetworkPlayerLeaving ) // { // m_hostGameSessionData.players[i] = ((NetworkPlayerXbox *)pNetworkPlayer)->GetUID(); -// +// // char *temp; // temp = (char *)wstringtofilename( pNetworkPlayer->GetOnlineName() ); // memcpy(m_hostGameSessionData.szPlayers[i],temp,XUSER_NAME_SIZE); @@ -541,7 +536,7 @@ void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pN // memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE); // } // } -// +// // m_hostGameSessionData.hostPlayerUID = ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetXuid(); // m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); } @@ -708,7 +703,6 @@ void CPlatformNetworkManagerStub::SearchForGames() #ifdef _WINDOWS64 std::vector lanSessions = WinsockNetLayer::GetDiscoveredSessions(); - //THEY GET DELETED HERE DAMMIT for (size_t i = 0; i < friendsSessions[0].size(); i++) delete friendsSessions[0][i]; friendsSessions[0].clear(); @@ -739,55 +733,6 @@ void CPlatformNetworkManagerStub::SearchForGames() friendsSessions[0].push_back(info); } - std::FILE* file = std::fopen("servers.txt", "r"); - - if (file) { - wstring wline; - int phase = 0; - - string ip; - wstring port; - wstring name; - - char buffer[512]; - while (std::fgets(buffer, sizeof(buffer), file)) { - if (phase == 0) { - ip = buffer; - if (!ip.empty() && (ip.back() == '\n' || ip.back() == '\r')) - ip.pop_back(); - phase = 1; - } - else if (phase == 1) { - wline = convStringToWstring(buffer); - port = wline; - phase = 2; - } - else if (phase == 2) { - wline = convStringToWstring(buffer); - name = wline; - phase = 0; - - //THEY GET DELETED AFTER USE LIKE 30 LINES UP!! - FriendSessionInfo* info = new FriendSessionInfo(); - wchar_t label[128]; - wcsncpy_s(label, sizeof(label)/sizeof(wchar_t), name.c_str(), _TRUNCATE); - size_t nameLen = wcslen(label); - info->displayLabel = new wchar_t[nameLen+1]; - wcscpy_s(info->displayLabel, nameLen + 1, label); - info->displayLabelLength = (unsigned char)nameLen; - info->displayLabelViewableStartIndex = 0; - info->data.isReadyToJoin = true; - info->data.isJoinable = true; - strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), ip.c_str(), _TRUNCATE); - info->data.hostPort = stoi(port); - info->sessionId = (SessionID)(static_cast(inet_addr(ip.c_str())) | (static_cast(stoi(port)) << 32)); - friendsSessions[0].push_back(info); - } - } - - std::fclose(file); - } - m_searchResultsCount[0] = (int)friendsSessions[0].size(); if (m_SessionsUpdatedCallback != NULL) @@ -832,7 +777,7 @@ void CPlatformNetworkManagerStub::GetFullFriendSessionInfo( FriendSessionInfo *f void CPlatformNetworkManagerStub::ForceFriendsSessionRefresh() { app.DebugPrintf("Resetting friends session search data\n"); - + for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { m_searchResultsCount[i] = 0; @@ -853,8 +798,8 @@ INetworkPlayer *CPlatformNetworkManagerStub::addNetworkPlayer(IQNetPlayer *pQNet void CPlatformNetworkManagerStub::removeNetworkPlayer(IQNetPlayer *pQNetPlayer) { INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pQNetPlayer); - for (auto it = currentNetworkPlayers.begin(); it != currentNetworkPlayers.end(); it++) - { + for( AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++ ) + { if( *it == pNetworkPlayer ) { currentNetworkPlayers.erase(it); @@ -871,7 +816,7 @@ INetworkPlayer *CPlatformNetworkManagerStub::getNetworkPlayer(IQNetPlayer *pQNet INetworkPlayer *CPlatformNetworkManagerStub::GetLocalPlayerByUserIndex(int userIndex ) { - return getNetworkPlayer(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); + return getNetworkPlayer(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); } INetworkPlayer *CPlatformNetworkManagerStub::GetPlayerByIndex(int playerIndex)