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.
This commit is contained in:
Michal Schiller 2026-03-06 18:24:35 +01:00 committed by GitHub
parent fbba14eda5
commit e513d6b8c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,14 +1,12 @@
#include "stdafx.h" #include "stdafx.h"
#include "..\..\..\Minecraft.World\Socket.h" #include "..\..\..\Minecraft.World\Socket.h"
#include "..\..\..\Minecraft.World\StringHelpers.h" #include "..\..\..\Minecraft.World\StringHelpers.h"
#include "PlatformNetworkManagerStub.h" #include "PlatformNetworkManagerStub.h"
#include "..\..\Xbox\Network\NetworkPlayerXbox.h" #include "..\..\Xbox\Network\NetworkPlayerXbox.h"
#ifdef _WINDOWS64 #ifdef _WINDOWS64
#include "..\..\Windows64\Network\WinsockNetLayer.h" #include "..\..\Windows64\Network\WinsockNetLayer.h"
#include "..\..\Windows64\Windows64_Xuid.h"
#include "..\..\Minecraft.h" #include "..\..\Minecraft.h"
#include "..\..\User.h" #include "..\..\User.h"
#include <iostream>
#endif #endif
CPlatformNetworkManagerStub *g_pPlatformNetworkManager; CPlatformNetworkManagerStub *g_pPlatformNetworkManager;
@ -65,8 +63,9 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
{ {
// Do we already have a primary player for this system? // Do we already have a primary player for this system?
bool systemHasPrimaryPlayer = false; 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) ) if( pQNetPlayer->IsSameSystem(pQNetPrimaryPlayer) )
{ {
systemHasPrimaryPlayer = true; systemHasPrimaryPlayer = true;
@ -78,7 +77,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
} }
} }
g_NetworkManager.PlayerJoining( networkPlayer ); g_NetworkManager.PlayerJoining( networkPlayer );
if( createFakeSocket == true && !m_bHostChanged ) if( createFakeSocket == true && !m_bHostChanged )
{ {
g_NetworkManager.CreateSocket( networkPlayer, localPlayer ); g_NetworkManager.CreateSocket( networkPlayer, localPlayer );
@ -98,7 +97,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
// g_NetworkManager.UpdateAndSetGameSessionData(); // g_NetworkManager.UpdateAndSetGameSessionData();
SystemFlagAddPlayer( networkPlayer ); SystemFlagAddPlayer( networkPlayer );
} }
for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx) for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{ {
if(playerChangedCallback[idx] != NULL) if(playerChangedCallback[idx] != NULL)
@ -162,7 +161,7 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa
{ {
playerChangedCallback[ i ] = NULL; playerChangedCallback[ i ] = NULL;
} }
m_bLeavingGame = false; m_bLeavingGame = false;
m_bLeaveGameOnTick = false; m_bLeaveGameOnTick = false;
m_bHostChanged = false; m_bHostChanged = false;
@ -235,7 +234,6 @@ void CPlatformNetworkManagerStub::DoWork()
qnetPlayer->m_smallId = 0; qnetPlayer->m_smallId = 0;
qnetPlayer->m_isRemote = false; qnetPlayer->m_isRemote = false;
qnetPlayer->m_isHostPlayer = false; qnetPlayer->m_isHostPlayer = false;
qnetPlayer->m_resolvedXuid = INVALID_XUID;
qnetPlayer->m_gamertag[0] = 0; qnetPlayer->m_gamertag[0] = 0;
qnetPlayer->SetCustomDataValue(0); qnetPlayer->SetCustomDataValue(0);
WinsockNetLayer::PushFreeSmallId(disconnectedSmallId); WinsockNetLayer::PushFreeSmallId(disconnectedSmallId);
@ -269,8 +267,11 @@ int CPlatformNetworkManagerStub::GetLocalPlayerMask(int playerIndex)
bool CPlatformNetworkManagerStub::AddLocalPlayerByUserIndex( int userIndex ) bool CPlatformNetworkManagerStub::AddLocalPlayerByUserIndex( int userIndex )
{ {
NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); // Initialize the slot first so GetLocalPlayerByUserIndex never returns NULL
return ( m_pIQNet->AddLocalPlayerByUserIndex(userIndex) == S_OK ); bool success = ( m_pIQNet->AddLocalPlayerByUserIndex(userIndex) == S_OK );
if (success)
NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(userIndex));
return success;
} }
bool CPlatformNetworkManagerStub::RemoveLocalPlayerByUserIndex( int userIndex ) bool CPlatformNetworkManagerStub::RemoveLocalPlayerByUserIndex( int userIndex )
@ -319,8 +320,8 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost)
m_pIQNet->EndGame(); m_pIQNet->EndGame();
} }
for (auto & it : currentNetworkPlayers) for (AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++)
delete it; delete* it;
currentNetworkPlayers.clear(); currentNetworkPlayers.clear();
m_machineQNetPrimaryPlayers.clear(); m_machineQNetPrimaryPlayers.clear();
SystemFlagReset(); SystemFlagReset();
@ -356,9 +357,7 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,
#ifdef _WINDOWS64 #ifdef _WINDOWS64
IQNet::m_player[0].m_smallId = 0; IQNet::m_player[0].m_smallId = 0;
IQNet::m_player[0].m_isRemote = false; 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_isHostPlayer = true;
IQNet::m_player[0].m_resolvedXuid = Win64Xuid::GetLegacyEmbeddedHostXuid();
IQNet::s_playerCount = 1; IQNet::s_playerCount = 1;
#endif #endif
@ -415,8 +414,6 @@ int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo* searchResult, int l
IQNet::m_player[0].m_smallId = 0; IQNet::m_player[0].m_smallId = 0;
IQNet::m_player[0].m_isRemote = true; IQNet::m_player[0].m_isRemote = true;
IQNet::m_player[0].m_isHostPlayer = 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); wcsncpy_s(IQNet::m_player[0].m_gamertag, 32, searchResult->data.hostName, _TRUNCATE);
WinsockNetLayer::StopDiscovery(); 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_smallId = localSmallId;
IQNet::m_player[localSmallId].m_isRemote = false; IQNet::m_player[localSmallId].m_isRemote = false;
IQNet::m_player[localSmallId].m_isHostPlayer = 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(); Minecraft* pMinecraft = Minecraft::GetInstance();
wcscpy_s(IQNet::m_player[localSmallId].m_gamertag, 32, pMinecraft->user->name.c_str()); 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() void CPlatformNetworkManagerStub::HandleSignInChange()
{ {
return; return;
} }
bool CPlatformNetworkManagerStub::_RunNetworkGame() bool CPlatformNetworkManagerStub::_RunNetworkGame()
@ -507,24 +502,24 @@ bool CPlatformNetworkManagerStub::_RunNetworkGame()
void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/) void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/)
{ {
// DWORD playerCount = m_pIQNet->GetPlayerCount(); // DWORD playerCount = m_pIQNet->GetPlayerCount();
// //
// if( this->m_bLeavingGame ) // if( this->m_bLeavingGame )
// return; // return;
// //
// if( GetHostPlayer() == NULL ) // if( GetHostPlayer() == NULL )
// return; // return;
// //
// for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i) // for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
// { // {
// if( i < playerCount ) // if( i < playerCount )
// { // {
// INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i); // INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i);
// //
// // We can call this from NotifyPlayerLeaving but at that point the player is still considered in the session // // We can call this from NotifyPlayerLeaving but at that point the player is still considered in the session
// if( pNetworkPlayer != pNetworkPlayerLeaving ) // if( pNetworkPlayer != pNetworkPlayerLeaving )
// { // {
// m_hostGameSessionData.players[i] = ((NetworkPlayerXbox *)pNetworkPlayer)->GetUID(); // m_hostGameSessionData.players[i] = ((NetworkPlayerXbox *)pNetworkPlayer)->GetUID();
// //
// char *temp; // char *temp;
// temp = (char *)wstringtofilename( pNetworkPlayer->GetOnlineName() ); // temp = (char *)wstringtofilename( pNetworkPlayer->GetOnlineName() );
// memcpy(m_hostGameSessionData.szPlayers[i],temp,XUSER_NAME_SIZE); // 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); // memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE);
// } // }
// } // }
// //
// m_hostGameSessionData.hostPlayerUID = ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetXuid(); // m_hostGameSessionData.hostPlayerUID = ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetXuid();
// m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All); // m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All);
} }
@ -708,7 +703,6 @@ void CPlatformNetworkManagerStub::SearchForGames()
#ifdef _WINDOWS64 #ifdef _WINDOWS64
std::vector<Win64LANSession> lanSessions = WinsockNetLayer::GetDiscoveredSessions(); std::vector<Win64LANSession> lanSessions = WinsockNetLayer::GetDiscoveredSessions();
//THEY GET DELETED HERE DAMMIT
for (size_t i = 0; i < friendsSessions[0].size(); i++) for (size_t i = 0; i < friendsSessions[0].size(); i++)
delete friendsSessions[0][i]; delete friendsSessions[0][i];
friendsSessions[0].clear(); friendsSessions[0].clear();
@ -739,55 +733,6 @@ void CPlatformNetworkManagerStub::SearchForGames()
friendsSessions[0].push_back(info); 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<uint64_t>(inet_addr(ip.c_str())) | (static_cast<uint64_t>(stoi(port)) << 32));
friendsSessions[0].push_back(info);
}
}
std::fclose(file);
}
m_searchResultsCount[0] = (int)friendsSessions[0].size(); m_searchResultsCount[0] = (int)friendsSessions[0].size();
if (m_SessionsUpdatedCallback != NULL) if (m_SessionsUpdatedCallback != NULL)
@ -832,7 +777,7 @@ void CPlatformNetworkManagerStub::GetFullFriendSessionInfo( FriendSessionInfo *f
void CPlatformNetworkManagerStub::ForceFriendsSessionRefresh() void CPlatformNetworkManagerStub::ForceFriendsSessionRefresh()
{ {
app.DebugPrintf("Resetting friends session search data\n"); app.DebugPrintf("Resetting friends session search data\n");
for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
{ {
m_searchResultsCount[i] = 0; m_searchResultsCount[i] = 0;
@ -853,8 +798,8 @@ INetworkPlayer *CPlatformNetworkManagerStub::addNetworkPlayer(IQNetPlayer *pQNet
void CPlatformNetworkManagerStub::removeNetworkPlayer(IQNetPlayer *pQNetPlayer) void CPlatformNetworkManagerStub::removeNetworkPlayer(IQNetPlayer *pQNetPlayer)
{ {
INetworkPlayer *pNetworkPlayer = getNetworkPlayer(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 ) if( *it == pNetworkPlayer )
{ {
currentNetworkPlayers.erase(it); currentNetworkPlayers.erase(it);
@ -871,7 +816,7 @@ INetworkPlayer *CPlatformNetworkManagerStub::getNetworkPlayer(IQNetPlayer *pQNet
INetworkPlayer *CPlatformNetworkManagerStub::GetLocalPlayerByUserIndex(int userIndex ) INetworkPlayer *CPlatformNetworkManagerStub::GetLocalPlayerByUserIndex(int userIndex )
{ {
return getNetworkPlayer(m_pIQNet->GetLocalPlayerByUserIndex(userIndex)); return getNetworkPlayer(m_pIQNet->GetLocalPlayerByUserIndex(userIndex));
} }
INetworkPlayer *CPlatformNetworkManagerStub::GetPlayerByIndex(int playerIndex) INetworkPlayer *CPlatformNetworkManagerStub::GetPlayerByIndex(int playerIndex)