aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/Network
diff options
context:
space:
mode:
authorSylvessa <225480449+sylvessa@users.noreply.github.com>2026-03-26 09:15:11 -0500
committerGitHub <noreply@github.com>2026-03-26 10:15:11 -0400
commit1a50770647c582c5ce194e5741e3014bb1c1e8b2 (patch)
tree8160994034f5f58b222032b73f8cda8c42e92479 /Minecraft.Client/Common/Network
parentdee559bd16e5fc4fb1d8cdd16e7e3924666b01c9 (diff)
Add asynchronous server joining (#1408)
Diffstat (limited to 'Minecraft.Client/Common/Network')
-rw-r--r--Minecraft.Client/Common/Network/GameNetworkManager.h3
-rw-r--r--Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp63
-rw-r--r--Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h6
3 files changed, 51 insertions, 21 deletions
diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.h b/Minecraft.Client/Common/Network/GameNetworkManager.h
index 3357b3cd..22d58807 100644
--- a/Minecraft.Client/Common/Network/GameNetworkManager.h
+++ b/Minecraft.Client/Common/Network/GameNetworkManager.h
@@ -47,7 +47,8 @@ public:
{
JOINGAME_SUCCESS,
JOINGAME_FAIL_GENERAL,
- JOINGAME_FAIL_SERVER_FULL
+ JOINGAME_FAIL_SERVER_FULL,
+ JOINGAME_PENDING
} eJoinGameResult;
void Initialise();
diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
index 1e625098..430f2c11 100644
--- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
+++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
@@ -173,6 +173,11 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa
m_bSearchPending = false;
m_bIsOfflineGame = false;
+#ifdef _WINDOWS64
+ m_bJoinPending = false;
+ m_joinLocalUsersMask = 0;
+ m_joinHostName[0] = 0;
+#endif
m_pSearchParam = nullptr;
m_SessionsUpdatedCallback = nullptr;
@@ -282,6 +287,38 @@ void CPlatformNetworkManagerStub::DoWork()
m_bLeaveGameOnTick = false;
}
}
+
+ if (m_bJoinPending)
+ {
+ WinsockNetLayer::eJoinState state = WinsockNetLayer::GetJoinState();
+ if (state == WinsockNetLayer::eJoinState_Success)
+ {
+ WinsockNetLayer::FinalizeJoin();
+
+ BYTE localSmallId = WinsockNetLayer::GetLocalSmallId();
+
+ IQNet::m_player[localSmallId].m_smallId = localSmallId;
+ IQNet::m_player[localSmallId].m_isRemote = false;
+ IQNet::m_player[localSmallId].m_isHostPlayer = false;
+ 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());
+ IQNet::s_playerCount = localSmallId + 1;
+
+ NotifyPlayerJoined(&IQNet::m_player[0]);
+ NotifyPlayerJoined(&IQNet::m_player[localSmallId]);
+
+ m_pGameNetworkManager->StateChange_AnyToStarting();
+ m_bJoinPending = false;
+ }
+ else if (state == WinsockNetLayer::eJoinState_Failed ||
+ state == WinsockNetLayer::eJoinState_Rejected ||
+ state == WinsockNetLayer::eJoinState_Cancelled)
+ {
+ m_bJoinPending = false;
+ }
+ }
#endif
}
@@ -511,36 +548,22 @@ 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();
- if (!WinsockNetLayer::JoinGame(hostIP, hostPort))
+ wcsncpy_s(m_joinHostName, 32, searchResult->data.hostName, _TRUNCATE);
+ m_joinLocalUsersMask = localUsersMask;
+
+ if (!WinsockNetLayer::BeginJoinGame(hostIP, hostPort))
{
app.DebugPrintf("Win64 LAN: Failed to connect to %s:%d\n", hostIP, hostPort);
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
}
- BYTE localSmallId = WinsockNetLayer::GetLocalSmallId();
-
- 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());
- IQNet::s_playerCount = localSmallId + 1;
-
- NotifyPlayerJoined(&IQNet::m_player[0]);
- NotifyPlayerJoined(&IQNet::m_player[localSmallId]);
-
- m_pGameNetworkManager->StateChange_AnyToStarting();
-
- return CGameNetworkManager::JOINGAME_SUCCESS;
+ m_bJoinPending = true;
+ return CGameNetworkManager::JOINGAME_PENDING;
#else
return CGameNetworkManager::JOINGAME_SUCCESS;
#endif
diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h
index 4a3f4068..dffa3953 100644
--- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h
+++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h
@@ -77,6 +77,12 @@ private:
bool m_bIsPrivateGame;
int m_flagIndexSize;
+#ifdef _WINDOWS64
+ bool m_bJoinPending;
+ int m_joinLocalUsersMask;
+ wchar_t m_joinHostName[32];
+#endif
+
// This is only maintained by the host, and is not valid on client machines
GameSessionData m_hostGameSessionData;
CGameNetworkManager *m_pGameNetworkManager;