diff options
Diffstat (limited to 'Minecraft.Client/Common/Network')
| -rw-r--r-- | Minecraft.Client/Common/Network/GameNetworkManager.cpp | 53 | ||||
| -rw-r--r-- | Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp | 50 |
2 files changed, 80 insertions, 23 deletions
diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index a502dbfb..50aeae68 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -200,10 +200,12 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame #endif int64_t seed = 0; + bool dedicatedNoLocalHostPlayer = false; if (lpParameter != nullptr) { NetworkGameInitData *param = static_cast<NetworkGameInitData *>(lpParameter); seed = param->seed; + dedicatedNoLocalHostPlayer = param->dedicatedNoLocalHostPlayer; app.setLevelGenerationOptions(param->levelGen); if(param->levelGen != nullptr) @@ -359,9 +361,19 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame // PRIMARY PLAYER vector<ClientConnection *> createdConnections; - ClientConnection *connection; + ClientConnection *connection = nullptr; - if( g_NetworkManager.IsHost() ) + if( g_NetworkManager.IsHost() && dedicatedNoLocalHostPlayer ) + { + app.DebugPrintf("Dedicated server mode: skipping local host client connection\n"); + + // Keep telemetry behavior consistent with the host path. + INT multiplayerInstanceId = TelemetryManager->GenerateMultiplayerInstanceId(); + TelemetryManager->SetMultiplayerInstanceId(multiplayerInstanceId); + + app.SetGameMode( eMode_Multiplayer ); + } + else if( g_NetworkManager.IsHost() ) { connection = new ClientConnection(minecraft, nullptr); } @@ -390,16 +402,18 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame connection = new ClientConnection(minecraft, socket); } - if( !connection->createdOk ) + if (connection != nullptr) { - assert(false); - delete connection; - connection = nullptr; - MinecraftServer::HaltServer(); - return false; - } + if( !connection->createdOk ) + { + assert(false); + delete connection; + connection = nullptr; + MinecraftServer::HaltServer(); + return false; + } - connection->send(std::make_shared<PreLoginPacket>(minecraft->user->name)); + connection->send(std::make_shared<PreLoginPacket>(minecraft->user->name)); // Tick connection until we're ready to go. The stages involved in this are: // (1) Creating the ClientConnection sends a prelogin packet to the server @@ -434,9 +448,9 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame connection->close(); } - if( connection->isStarted() && !connection->isClosed() ) - { - createdConnections.push_back( connection ); + if( connection->isStarted() && !connection->isClosed() ) + { + createdConnections.push_back( connection ); int primaryPad = ProfileManager.GetPrimaryPad(); app.SetRichPresenceContext(primaryPad,CONTEXT_GAME_STATE_BLANK); @@ -533,13 +547,14 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame } } - app.SetGameMode( eMode_Multiplayer ); - } - else if ( connection->isClosed() || !IsInSession()) - { + app.SetGameMode( eMode_Multiplayer ); + } + else if ( connection->isClosed() || !IsInSession()) + { // assert(false); - MinecraftServer::HaltServer(); - return false; + MinecraftServer::HaltServer(); + return false; + } } diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp index 7340a7e0..1e625098 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp @@ -240,7 +240,13 @@ void CPlatformNetworkManagerStub::DoWork() qnetPlayer->m_resolvedXuid = INVALID_XUID; qnetPlayer->m_gamertag[0] = 0; qnetPlayer->SetCustomDataValue(0); - while (IQNet::s_playerCount > 1 && IQNet::m_player[IQNet::s_playerCount - 1].GetCustomDataValue() == 0) + // 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 @@ -257,6 +263,25 @@ void CPlatformNetworkManagerStub::DoWork() 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 } @@ -356,6 +381,7 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost) if( m_bLeavingGame ) return true; m_bLeavingGame = true; + m_bLeaveGameOnTick = false; #ifdef _WINDOWS64 WinsockNetLayer::StopAdvertising(); @@ -404,6 +430,7 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame, localUsersMask |= GetLocalPlayerMask( g_NetworkManager.GetPrimaryPad() ); m_bLeavingGame = false; + m_bLeaveGameOnTick = false; m_pIQNet->HostGame(); @@ -433,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 @@ -463,6 +504,7 @@ 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(); |
