aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
diff options
context:
space:
mode:
authorqwasdrizzel <145519042+qwasdrizzel@users.noreply.github.com>2026-03-16 21:44:26 -0500
committerGitHub <noreply@github.com>2026-03-16 21:44:26 -0500
commitce739f6045ec72127491286ea3f3f21e537c1b55 (patch)
treef33bd42a47c1b4a7b2153a7fb77127ee3b407db9 /Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
parent255a18fe8e9b57377975f82e2b227afe2a12eda0 (diff)
parent5a59f5d146b43811dde6a5a0245ee9875d7b5cd1 (diff)
Merge branch 'smartcmd:main' into main
Diffstat (limited to 'Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp')
-rw-r--r--Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp301
1 files changed, 212 insertions, 89 deletions
diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
index 85531e47..1e625098 100644
--- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
+++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
@@ -5,8 +5,11 @@
#include "..\..\Xbox\Network\NetworkPlayerXbox.h"
#ifdef _WINDOWS64
#include "..\..\Windows64\Network\WinsockNetLayer.h"
+#include "..\..\Windows64\Windows64_Xuid.h"
#include "..\..\Minecraft.h"
#include "..\..\User.h"
+#include "..\..\MinecraftServer.h"
+#include "..\..\PlayerList.h"
#include <iostream>
#endif
@@ -23,7 +26,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
bool createFakeSocket = false;
bool localPlayer = false;
- NetworkPlayerXbox *networkPlayer = (NetworkPlayerXbox *)addNetworkPlayer(pQNetPlayer);
+ NetworkPlayerXbox *networkPlayer = static_cast<NetworkPlayerXbox *>(addNetworkPlayer(pQNetPlayer));
if( pQNetPlayer->IsLocal() )
{
@@ -87,8 +90,8 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
pQNetPlayer,
pQNetPlayer->GetGamertag(),
pszDescription,
- (int) pQNetPlayer->HasVoice(),
- (int) pQNetPlayer->HasCamera() );
+ pQNetPlayer->HasVoice(),
+ pQNetPlayer->HasCamera() );
if( m_pIQNet->IsHost() )
@@ -100,7 +103,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{
- if(playerChangedCallback[idx] != NULL)
+ if(playerChangedCallback[idx] != nullptr)
playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, false );
}
@@ -109,7 +112,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
int localPlayerCount = 0;
for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{
- if( m_pIQNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount;
+ if( m_pIQNet->GetLocalPlayerByUserIndex(idx) != nullptr ) ++localPlayerCount;
}
float appTime = app.getAppTime();
@@ -124,11 +127,11 @@ void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer* pQNetPlayer)
app.DebugPrintf("Player 0x%p \"%ls\" leaving.\n", pQNetPlayer, pQNetPlayer->GetGamertag());
INetworkPlayer* networkPlayer = getNetworkPlayer(pQNetPlayer);
- if (networkPlayer == NULL)
+ if (networkPlayer == nullptr)
return;
Socket* socket = networkPlayer->GetSocket();
- if (socket != NULL)
+ if (socket != nullptr)
{
if (m_pIQNet->IsHost())
g_NetworkManager.CloseConnection(networkPlayer);
@@ -143,7 +146,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer* pQNetPlayer)
for (int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{
- if (playerChangedCallback[idx] != NULL)
+ if (playerChangedCallback[idx] != nullptr)
playerChangedCallback[idx](playerChangedCallbackParam[idx], networkPlayer, true);
}
@@ -159,7 +162,7 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa
g_pPlatformNetworkManager = this;
for( int i = 0; i < XUSER_MAX_COUNT; i++ )
{
- playerChangedCallback[ i ] = NULL;
+ playerChangedCallback[ i ] = nullptr;
}
m_bLeavingGame = false;
@@ -170,8 +173,8 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa
m_bSearchPending = false;
m_bIsOfflineGame = false;
- m_pSearchParam = NULL;
- m_SessionsUpdatedCallback = NULL;
+ m_pSearchParam = nullptr;
+ m_SessionsUpdatedCallback = nullptr;
for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
{
@@ -179,10 +182,10 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa
m_lastSearchStartTime[i] = 0;
// The results that will be filled in with the current search
- m_pSearchResults[i] = NULL;
- m_pQoSResult[i] = NULL;
- m_pCurrentSearchResults[i] = NULL;
- m_pCurrentQoSResult[i] = NULL;
+ m_pSearchResults[i] = nullptr;
+ m_pQoSResult[i] = nullptr;
+ m_pCurrentSearchResults[i] = nullptr;
+ m_pCurrentQoSResult[i] = nullptr;
m_currentSearchResultsCount[i] = 0;
}
@@ -228,23 +231,73 @@ void CPlatformNetworkManagerStub::DoWork()
while (WinsockNetLayer::PopDisconnectedSmallId(&disconnectedSmallId))
{
IQNetPlayer* qnetPlayer = m_pIQNet->GetPlayerBySmallId(disconnectedSmallId);
- if (qnetPlayer != NULL && qnetPlayer->m_smallId == disconnectedSmallId)
+ if (qnetPlayer != nullptr && qnetPlayer->m_smallId == disconnectedSmallId)
{
NotifyPlayerLeaving(qnetPlayer);
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);
- if (IQNet::s_playerCount > 1)
+ // Recalculate s_playerCount as the highest active slot + 1.
+ // A blind decrement would hide players at higher-indexed slots when a
+ // lower-indexed player disconnects first: GetPlayerBySmallId scans
+ // [0, s_playerCount) so any slot at or above the decremented count
+ // becomes invisible, causing its disconnect to be missed (ghost player).
+ while (IQNet::s_playerCount > 1 &&
+ IQNet::m_player[IQNet::s_playerCount - 1].GetCustomDataValue() == 0)
IQNet::s_playerCount--;
}
+ // NOTE: Do NOT call PushFreeSmallId here. The old PlayerConnection's
+ // write thread may still be alive (it dies in PlayerList::tick when
+ // m_smallIdsToClose is processed). If we recycle the smallId now,
+ // AcceptThread can reuse it for a new connection, and the old write
+ // thread's getPlayer() lookup will resolve to the NEW player, sending
+ // stale game packets to the new client's TCP socket — corrupting its
+ // login handshake (bad packet id crash). PushFreeSmallId and
+ // ClearSocketForSmallId are called from PlayerList::tick after the
+ // old Connection threads are dead.
+ //
+ // Clear chunk visibility flags for this system so rejoin gets fresh chunk state.
+ SystemFlagRemoveBySmallId(disconnectedSmallId);
+ }
+ }
+
+ // Client-side host disconnect detection:
+ // if TCP is gone, propagate through normal network-disconnect flow so UI returns to menus.
+ // The processing from the Xbox version will be reused.
+ if (_iQNetStubState == QNET_STATE_GAME_PLAY && !m_pIQNet->IsHost() && !m_bLeavingGame)
+ {
+ if (!WinsockNetLayer::IsConnected())
+ {
+ if (!m_bLeaveGameOnTick)
+ {
+ m_bLeaveGameOnTick = true;
+ g_NetworkManager.HandleDisconnect(false);
+ }
+ }
+ else
+ {
+ m_bLeaveGameOnTick = false;
}
}
#endif
}
+bool CPlatformNetworkManagerStub::CanAcceptMoreConnections()
+{
+#ifdef _WINDOWS64
+ MinecraftServer* server = MinecraftServer::getInstance();
+ if (server == NULL) return true;
+ PlayerList* list = server->getPlayerList();
+ if (list == NULL) return true;
+ return static_cast<unsigned int>(list->players.size()) < static_cast<unsigned int>(list->getMaxPlayers());
+#else
+ return true;
+#endif
+}
+
int CPlatformNetworkManagerStub::GetPlayerCount()
{
return m_pIQNet->GetPlayerCount();
@@ -267,12 +320,40 @@ int CPlatformNetworkManagerStub::GetLocalPlayerMask(int playerIndex)
bool CPlatformNetworkManagerStub::AddLocalPlayerByUserIndex( int userIndex )
{
- NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(userIndex));
- return ( m_pIQNet->AddLocalPlayerByUserIndex(userIndex) == S_OK );
+ if ( m_pIQNet->AddLocalPlayerByUserIndex(userIndex) != S_OK )
+ return false;
+ // Player is now registered in IQNet — get a pointer and notify the network layer.
+ // Use the static array directly: GetLocalPlayerByUserIndex checks customData which
+ // isn't set until addNetworkPlayer runs inside NotifyPlayerJoined.
+ NotifyPlayerJoined(&IQNet::m_player[userIndex]);
+ return true;
}
bool CPlatformNetworkManagerStub::RemoveLocalPlayerByUserIndex( int userIndex )
{
+#ifdef _WINDOWS64
+ if (userIndex > 0 && userIndex < XUSER_MAX_COUNT && !m_pIQNet->IsHost())
+ {
+ IQNetPlayer* qp = &IQNet::m_player[userIndex];
+
+ // Notify the network layer before clearing the slot
+ if (qp->GetCustomDataValue() != 0)
+ {
+ NotifyPlayerLeaving(qp);
+ }
+
+ // Close the split-screen TCP connection and reset WinsockNetLayer state
+ WinsockNetLayer::CloseSplitScreenConnection(userIndex);
+
+ // Clear the IQNet slot so it can be reused on rejoin
+ qp->m_smallId = 0;
+ qp->m_isRemote = false;
+ qp->m_isHostPlayer = false;
+ qp->m_resolvedXuid = INVALID_XUID;
+ qp->m_gamertag[0] = 0;
+ qp->SetCustomDataValue(0);
+ }
+#endif
return true;
}
@@ -300,6 +381,7 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost)
if( m_bLeavingGame ) return true;
m_bLeavingGame = true;
+ m_bLeaveGameOnTick = false;
#ifdef _WINDOWS64
WinsockNetLayer::StopAdvertising();
@@ -348,13 +430,16 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,
localUsersMask |= GetLocalPlayerMask( g_NetworkManager.GetPrimaryPad() );
m_bLeavingGame = false;
+ m_bLeaveGameOnTick = false;
m_pIQNet->HostGame();
#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
@@ -362,7 +447,7 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,
#ifdef _WINDOWS64
int port = WIN64_NET_DEFAULT_PORT;
- const char* bindIp = NULL;
+ const char* bindIp = nullptr;
if (g_Win64DedicatedServer)
{
if (g_Win64DedicatedServerPort > 0)
@@ -375,9 +460,23 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,
if (WinsockNetLayer::IsActive())
{
- const wchar_t* hostName = IQNet::m_player[0].m_gamertag;
- unsigned int settings = app.GetGameHostOption(eGameHostOption_All);
- WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION);
+ // For Dedicated Server, refer to `lan-advertise` in `server.properties`
+ bool enableLanAdvertising = true;
+ if (g_Win64DedicatedServer)
+ {
+ enableLanAdvertising = g_Win64DedicatedServerLanAdvertise;
+ }
+
+ if (enableLanAdvertising)
+ {
+ const wchar_t* hostName = IQNet::m_player[0].m_gamertag;
+ unsigned int settings = app.GetGameHostOption(eGameHostOption_All);
+ WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION);
+ }
+ else
+ {
+ WinsockNetLayer::StopAdvertising();
+ }
}
#endif
//#endif
@@ -395,7 +494,7 @@ bool CPlatformNetworkManagerStub::_StartGame()
int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo* searchResult, int localUsersMask, int primaryUserIndex)
{
#ifdef _WINDOWS64
- if (searchResult == NULL)
+ if (searchResult == nullptr)
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
const char* hostIP = searchResult->data.hostIP;
@@ -405,12 +504,15 @@ int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo* searchResult, int l
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
m_bLeavingGame = false;
+ m_bLeaveGameOnTick = false;
IQNet::s_isHosting = false;
m_pIQNet->ClientJoinGame();
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();
@@ -426,6 +528,8 @@ 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());
@@ -465,8 +569,8 @@ void CPlatformNetworkManagerStub::UnRegisterPlayerChangedCallback(int iPad, void
{
if(playerChangedCallbackParam[iPad] == callbackParam)
{
- playerChangedCallback[iPad] = NULL;
- playerChangedCallbackParam[iPad] = NULL;
+ playerChangedCallback[iPad] = nullptr;
+ playerChangedCallbackParam[iPad] = nullptr;
}
}
@@ -486,7 +590,7 @@ bool CPlatformNetworkManagerStub::_RunNetworkGame()
if (IQNet::m_player[i].m_isRemote)
{
INetworkPlayer* pNetworkPlayer = getNetworkPlayer(&IQNet::m_player[i]);
- if (pNetworkPlayer != NULL && pNetworkPlayer->GetSocket() != NULL)
+ if (pNetworkPlayer != nullptr && pNetworkPlayer->GetSocket() != nullptr)
{
Socket::addIncomingSocket(pNetworkPlayer->GetSocket());
}
@@ -496,14 +600,14 @@ bool CPlatformNetworkManagerStub::_RunNetworkGame()
return true;
}
-void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/)
+void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= nullptr*/)
{
// DWORD playerCount = m_pIQNet->GetPlayerCount();
//
// if( this->m_bLeavingGame )
// return;
//
-// if( GetHostPlayer() == NULL )
+// if( GetHostPlayer() == nullptr )
// return;
//
// for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
@@ -523,13 +627,13 @@ void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pN
// }
// else
// {
-// m_hostGameSessionData.players[i] = NULL;
+// m_hostGameSessionData.players[i] = nullptr;
// memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE);
// }
// }
// else
// {
-// m_hostGameSessionData.players[i] = NULL;
+// m_hostGameSessionData.players[i] = nullptr;
// memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE);
// }
// }
@@ -540,18 +644,18 @@ void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pN
int CPlatformNetworkManagerStub::RemovePlayerOnSocketClosedThreadProc( void* lpParam )
{
- INetworkPlayer *pNetworkPlayer = (INetworkPlayer *)lpParam;
+ INetworkPlayer *pNetworkPlayer = static_cast<INetworkPlayer *>(lpParam);
Socket *socket = pNetworkPlayer->GetSocket();
- if( socket != NULL )
+ if( socket != nullptr )
{
//printf("Waiting for socket closed event\n");
socket->m_socketClosedEvent->WaitForSignal(INFINITE);
//printf("Socket closed event has fired\n");
// 4J Stu - Clear our reference to this socket
- pNetworkPlayer->SetSocket( NULL );
+ pNetworkPlayer->SetSocket( nullptr );
delete socket;
}
@@ -573,6 +677,7 @@ CPlatformNetworkManagerStub::PlayerFlags::PlayerFlags(INetworkPlayer *pNetworkPl
this->flags = new unsigned char [ count / 8 ];
memset( this->flags, 0, count / 8 );
this->count = count;
+ this->m_smallId = (pNetworkPlayer && pNetworkPlayer->IsLocal()) ? 256 : (pNetworkPlayer ? static_cast<int>(pNetworkPlayer->GetSmallId()) : -1);
}
CPlatformNetworkManagerStub::PlayerFlags::~PlayerFlags()
{
@@ -610,6 +715,23 @@ void CPlatformNetworkManagerStub::SystemFlagRemovePlayer(INetworkPlayer *pNetwor
}
}
+// Clear chunk flags for a system when they disconnect (by smallId). Call even when we don't find the player,
+// so we always clear and the smallId can be reused without stale "chunk seen" state.
+void CPlatformNetworkManagerStub::SystemFlagRemoveBySmallId(int smallId)
+{
+ if (smallId < 0) return;
+ for (unsigned int i = 0; i < m_playerFlags.size(); i++)
+ {
+ if (m_playerFlags[i]->m_smallId == smallId)
+ {
+ delete m_playerFlags[i];
+ m_playerFlags[i] = m_playerFlags.back();
+ m_playerFlags.pop_back();
+ return;
+ }
+ }
+}
+
void CPlatformNetworkManagerStub::SystemFlagReset()
{
for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
@@ -623,7 +745,7 @@ void CPlatformNetworkManagerStub::SystemFlagReset()
void CPlatformNetworkManagerStub::SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index)
{
if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return;
- if( pNetworkPlayer == NULL ) return;
+ if( pNetworkPlayer == nullptr ) return;
for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
{
@@ -639,7 +761,7 @@ void CPlatformNetworkManagerStub::SystemFlagSet(INetworkPlayer *pNetworkPlayer,
bool CPlatformNetworkManagerStub::SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index)
{
if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return false;
- if( pNetworkPlayer == NULL )
+ if( pNetworkPlayer == nullptr )
{
return false;
}
@@ -667,7 +789,7 @@ wstring CPlatformNetworkManagerStub::GatherRTTStats()
for(unsigned int i = 0; i < GetPlayerCount(); ++i)
{
- IQNetPlayer *pQNetPlayer = ((NetworkPlayerXbox *)GetPlayerByIndex( i ))->GetQNetPlayer();
+ IQNetPlayer *pQNetPlayer = static_cast<NetworkPlayerXbox *>(GetPlayerByIndex(i))->GetQNetPlayer();
if(!pQNetPlayer->IsLocal())
{
@@ -682,7 +804,7 @@ wstring CPlatformNetworkManagerStub::GatherRTTStats()
void CPlatformNetworkManagerStub::TickSearch()
{
#ifdef _WINDOWS64
- if (m_SessionsUpdatedCallback == NULL)
+ if (m_SessionsUpdatedCallback == nullptr)
return;
static DWORD lastSearchTime = 0;
@@ -711,7 +833,7 @@ void CPlatformNetworkManagerStub::SearchForGames()
size_t nameLen = wcslen(lanSessions[i].hostName);
info->displayLabel = new wchar_t[nameLen + 1];
wcscpy_s(info->displayLabel, nameLen + 1, lanSessions[i].hostName);
- info->displayLabelLength = (unsigned char)nameLen;
+ info->displayLabelLength = static_cast<unsigned char>(nameLen);
info->displayLabelViewableStartIndex = 0;
info->data.netVersion = lanSessions[i].netVersion;
@@ -726,63 +848,64 @@ void CPlatformNetworkManagerStub::SearchForGames()
info->data.playerCount = lanSessions[i].playerCount;
info->data.maxPlayers = lanSessions[i].maxPlayers;
- info->sessionId = (SessionID)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32));
+ info->sessionId = static_cast<uint64_t>(inet_addr(lanSessions[i].hostIP)) |
+ static_cast<uint64_t>(lanSessions[i].hostPort) << 32;
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;
+ if (std::FILE* file = std::fopen("servers.db", "rb")) {
+ char magic[4] = {};
+ if (std::fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
+ {
+ uint32_t version = 0, count = 0;
+ std::fread(&version, sizeof(uint32_t), 1, file);
+ std::fread(&count, sizeof(uint32_t), 1, file);
- 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);
+ if (version == 1)
+ {
+ for (uint32_t s = 0; s < count; s++)
+ {
+ uint16_t ipLen = 0, port = 0, nameLen = 0;
+ if (std::fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
+ if (ipLen == 0 || ipLen > 256) break;
+
+ char ipBuf[257] = {};
+ if (std::fread(ipBuf, 1, ipLen, file) != ipLen) break;
+ if (std::fread(&port, sizeof(uint16_t), 1, file) != 1) break;
+
+ if (std::fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
+ if (nameLen > 256) break;
+
+ char nameBuf[257] = {};
+ if (nameLen > 0)
+ {
+ if (std::fread(nameBuf, 1, nameLen, file) != nameLen) break;
+ }
+
+ wstring wName = convStringToWstring(nameBuf);
+
+ FriendSessionInfo* info = new FriendSessionInfo();
+ size_t nLen = wName.length();
+ info->displayLabel = new wchar_t[nLen + 1];
+ wcscpy_s(info->displayLabel, nLen + 1, wName.c_str());
+ info->displayLabelLength = static_cast<unsigned char>(nLen);
+ info->displayLabelViewableStartIndex = 0;
+ info->data.isReadyToJoin = true;
+ info->data.isJoinable = true;
+ strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), ipBuf, _TRUNCATE);
+ info->data.hostPort = port;
+ info->sessionId = static_cast<uint64_t>(inet_addr(ipBuf)) | static_cast<uint64_t>(port) << 32;
+ friendsSessions[0].push_back(info);
+ }
}
}
-
std::fclose(file);
}
- m_searchResultsCount[0] = (int)friendsSessions[0].size();
+ m_searchResultsCount[0] = static_cast<int>(friendsSessions[0].size());
- if (m_SessionsUpdatedCallback != NULL)
+ if (m_SessionsUpdatedCallback != nullptr)
m_SessionsUpdatedCallback(m_pSearchParam);
#endif
}
@@ -802,7 +925,7 @@ vector<FriendSessionInfo *> *CPlatformNetworkManagerStub::GetSessionList(int iPa
{
vector<FriendSessionInfo*>* filteredList = new vector<FriendSessionInfo*>();
for (size_t i = 0; i < friendsSessions[0].size(); i++)
- filteredList->push_back(friendsSessions[0][i]);
+ filteredList->push_back(new FriendSessionInfo(*friendsSessions[0][i]));
return filteredList;
}
@@ -830,7 +953,7 @@ void CPlatformNetworkManagerStub::ForceFriendsSessionRefresh()
m_searchResultsCount[i] = 0;
m_lastSearchStartTime[i] = 0;
delete m_pSearchResults[i];
- m_pSearchResults[i] = NULL;
+ m_pSearchResults[i] = nullptr;
}
}
@@ -857,7 +980,7 @@ void CPlatformNetworkManagerStub::removeNetworkPlayer(IQNetPlayer *pQNetPlayer)
INetworkPlayer *CPlatformNetworkManagerStub::getNetworkPlayer(IQNetPlayer *pQNetPlayer)
{
- return pQNetPlayer ? (INetworkPlayer *)(pQNetPlayer->GetCustomDataValue()) : NULL;
+ return pQNetPlayer ? (INetworkPlayer *)(pQNetPlayer->GetCustomDataValue()) : nullptr;
}