aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client/Common')
-rw-r--r--Minecraft.Client/Common/Console_Utils.cpp36
-rw-r--r--Minecraft.Client/Common/Consoles_App.cpp117
-rw-r--r--Minecraft.Client/Common/Network/GameNetworkManager.cpp53
-rw-r--r--Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp50
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();