diff options
Diffstat (limited to 'Minecraft.Client/Common')
| -rw-r--r-- | Minecraft.Client/Common/Console_Utils.cpp | 36 | ||||
| -rw-r--r-- | Minecraft.Client/Common/Consoles_App.cpp | 117 | ||||
| -rw-r--r-- | Minecraft.Client/Common/Network/GameNetworkManager.cpp | 53 | ||||
| -rw-r--r-- | Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp | 50 |
4 files changed, 172 insertions, 84 deletions
diff --git a/Minecraft.Client/Common/Console_Utils.cpp b/Minecraft.Client/Common/Console_Utils.cpp index cb0f1b58..9a64dbea 100644 --- a/Minecraft.Client/Common/Console_Utils.cpp +++ b/Minecraft.Client/Common/Console_Utils.cpp @@ -1,21 +1,32 @@ #include "stdafx.h" +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) +#include "..\..\Minecraft.Server\ServerLogManager.h" +#endif //-------------------------------------------------------------------------------------- // Name: DebugSpewV() // Desc: Internal helper function //-------------------------------------------------------------------------------------- #ifndef _CONTENT_PACKAGE -static VOID DebugSpewV( const CHAR* strFormat, const va_list pArgList ) +static VOID DebugSpewV( const CHAR* strFormat, va_list pArgList ) { #if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ - assert(0); + assert(0); #else - CHAR str[2048]; - // Use the secure CRT to avoid buffer overruns. Specify a count of - // _TRUNCATE so that too long strings will be silently truncated - // rather than triggering an error. - _vsnprintf_s( str, _TRUNCATE, strFormat, pArgList ); - OutputDebugStringA( str ); +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + // Dedicated server routes legacy debug spew through ServerLogger to preserve CLI prompt handling. + if (ServerRuntime::ServerLogManager::ShouldForwardClientDebugLogs()) + { + ServerRuntime::ServerLogManager::ForwardClientDebugSpewLogV(strFormat, pArgList); + return; + } +#endif + CHAR str[2048]; + // Use the secure CRT to avoid buffer overruns. Specify a count of + // _TRUNCATE so that too long strings will be silently truncated + // rather than triggering an error. + _vsnprintf_s( str, _TRUNCATE, strFormat, pArgList ); + OutputDebugStringA( str ); #endif } #endif @@ -31,10 +42,9 @@ VOID CDECL DebugPrintf( const CHAR* strFormat, ... ) #endif { #ifndef _CONTENT_PACKAGE - va_list pArgList; - va_start( pArgList, strFormat ); - DebugSpewV( strFormat, pArgList ); - va_end( pArgList ); + va_list pArgList; + va_start( pArgList, strFormat ); + DebugSpewV( strFormat, pArgList ); + va_end( pArgList ); #endif } - diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index c3a623d5..0a2fd159 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -38,6 +38,9 @@ #include "GameRules\ConsoleSchematicFile.h" #include "..\User.h" #include "..\..\Minecraft.World\LevelData.h" +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) +#include "..\..\Minecraft.Server\ServerLogManager.h" +#endif #include "..\..\Minecraft.World\net.minecraft.world.entity.player.h" #include "..\EntityRenderDispatcher.h" #include "..\..\Minecraft.World\compression.h" @@ -240,12 +243,21 @@ void CMinecraftApp::DebugPrintf(const char *szFormat, ...) { #ifndef _FINAL_BUILD - char buf[1024]; - va_list ap; - va_start(ap, szFormat); - vsnprintf(buf, sizeof(buf), szFormat, ap); - va_end(ap); - OutputDebugStringA(buf); + va_list ap; + va_start(ap, szFormat); +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + // Dedicated server routes client debug spew through ServerLogger so CLI output stays prompt-safe. + if (ServerRuntime::ServerLogManager::ShouldForwardClientDebugLogs()) + { + ServerRuntime::ServerLogManager::ForwardClientAppDebugLogV(szFormat, ap); + va_end(ap); + return; + } +#endif + char buf[1024]; + vsnprintf(buf, sizeof(buf), szFormat, ap); + va_end(ap); + OutputDebugStringA(buf); #endif } @@ -253,53 +265,62 @@ void CMinecraftApp::DebugPrintf(const char *szFormat, ...) void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...) { #ifndef _FINAL_BUILD - if(user == USER_NONE) - return; - char buf[1024]; - va_list ap; - va_start(ap, szFormat); - vsnprintf(buf, sizeof(buf), szFormat, ap); - va_end(ap); + if(user == USER_NONE) + return; + va_list ap; + va_start(ap, szFormat); +#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD) + // Dedicated server routes client debug spew through ServerLogger so CLI output stays prompt-safe. + if (ServerRuntime::ServerLogManager::ShouldForwardClientDebugLogs()) + { + ServerRuntime::ServerLogManager::ForwardClientUserDebugLogV(user, szFormat, ap); + va_end(ap); + return; + } +#endif + char buf[1024]; + vsnprintf(buf, sizeof(buf), szFormat, ap); + va_end(ap); #ifdef __PS3__ - unsigned int writelen; - sys_tty_write(SYS_TTYP_USER1 + ( user - 1 ), buf, strlen(buf), &writelen ); + unsigned int writelen; + sys_tty_write(SYS_TTYP_USER1 + ( user - 1 ), buf, strlen(buf), &writelen ); #elif defined __PSVITA__ - switch(user) - { - case 0: - { - SceUID tty2 = sceIoOpen("tty2:", SCE_O_WRONLY, 0); - if(tty2>=0) - { - std::string string1(buf); - sceIoWrite(tty2, string1.c_str(), string1.length()); - sceIoClose(tty2); - } - } - break; - case 1: - { - SceUID tty3 = sceIoOpen("tty3:", SCE_O_WRONLY, 0); - if(tty3>=0) - { - std::string string1(buf); - sceIoWrite(tty3, string1.c_str(), string1.length()); - sceIoClose(tty3); - } - } - break; - default: - OutputDebugStringA(buf); - break; - } + switch(user) + { + case 0: + { + SceUID tty2 = sceIoOpen("tty2:", SCE_O_WRONLY, 0); + if(tty2>=0) + { + std::string string1(buf); + sceIoWrite(tty2, string1.c_str(), string1.length()); + sceIoClose(tty2); + } + } + break; + case 1: + { + SceUID tty3 = sceIoOpen("tty3:", SCE_O_WRONLY, 0); + if(tty3>=0) + { + std::string string1(buf); + sceIoWrite(tty3, string1.c_str(), string1.length()); + sceIoClose(tty3); + } + } + break; + default: + OutputDebugStringA(buf); + break; + } #else - OutputDebugStringA(buf); + OutputDebugStringA(buf); #endif #ifndef _XBOX - if(user == USER_UI) - { - ui.logDebugString(buf); - } + if(user == USER_UI) + { + ui.logDebugString(buf); + } #endif #endif } 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(); |
