From 60f8613efbd0a6df547be887d8a10fa9963bffee Mon Sep 17 00:00:00 2001 From: bytesizedfox Date: Tue, 3 Mar 2026 00:21:06 -0500 Subject: [PATCH] apply networking patches related to s Fix Win64 LAN join failures and slot leaks, more than two players can join --- .../Common/Network/GameNetworkManager.cpp | 17 +- .../Network/PlatformNetworkManagerStub.cpp | 55 ++---- Minecraft.Client/Extrax64Stubs.cpp | 58 +++--- Minecraft.Client/PendingConnection.cpp | 23 ++- Minecraft.Client/PendingConnection.h | 6 +- .../Windows64/Network/WinsockNetLayer.cpp | 177 ++++++++---------- .../Windows64/Network/WinsockNetLayer.h | 3 +- 7 files changed, 165 insertions(+), 174 deletions(-) diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index a633359..fb86f08 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -289,11 +289,24 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame } else { - INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(ProfileManager.GetLockedProfile()); + int lockedProfile = ProfileManager.GetLockedProfile(); + if (lockedProfile < 0 || lockedProfile >= XUSER_MAX_COUNT) + lockedProfile = ProfileManager.GetPrimaryPad(); + if (lockedProfile < 0 || lockedProfile >= XUSER_MAX_COUNT) + lockedProfile = 0; + + INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(lockedProfile); + if(pNetworkPlayer == NULL) + { + // Fallback to primary pad if the locked profile didn't resolve. + int primary = ProfileManager.GetPrimaryPad(); + if (primary >= 0 && primary < XUSER_MAX_COUNT) + pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(primary); + } if(pNetworkPlayer == NULL) { MinecraftServer::HaltServer(); - app.DebugPrintf("%d\n",ProfileManager.GetLockedProfile()); + app.DebugPrintf("Join failed: no local player for locked=%d primary=%d\n", lockedProfile, ProfileManager.GetPrimaryPad()); // If the player is NULL here then something went wrong in the session setup, and continuing will end up in a crash return false; } diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp index 0a69cd6..aad360f 100644 --- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp +++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp @@ -226,7 +226,14 @@ void CPlatformNetworkManagerStub::DoWork() BYTE disconnectedSmallId; while (WinsockNetLayer::PopDisconnectedSmallId(&disconnectedSmallId)) { + // Always free the smallId so a failed/aborted join doesn't permanently consume a slot. + if (disconnectedSmallId != 0) + WinsockNetLayer::PushFreeSmallId(disconnectedSmallId); + IQNetPlayer *qnetPlayer = m_pIQNet->GetPlayerBySmallId(disconnectedSmallId); + if (qnetPlayer == NULL && disconnectedSmallId < MINECRAFT_NET_MAX_PLAYERS) + qnetPlayer = &IQNet::m_player[disconnectedSmallId]; + if (qnetPlayer != NULL && qnetPlayer->m_smallId == disconnectedSmallId) { NotifyPlayerLeaving(qnetPlayer); @@ -235,32 +242,19 @@ void CPlatformNetworkManagerStub::DoWork() qnetPlayer->m_isHostPlayer = false; qnetPlayer->m_gamertag[0] = 0; qnetPlayer->SetCustomDataValue(0); - WinsockNetLayer::PushFreeSmallId(disconnectedSmallId); - if (IQNet::s_playerCount > 1) - IQNet::s_playerCount--; } - } - for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++) - { - IQNetPlayer *qp = &IQNet::m_player[i]; - if (qp->GetCustomDataValue() == 0) - continue; - INetworkPlayer *np = (INetworkPlayer *)qp->GetCustomDataValue(); - Socket *sock = np->GetSocket(); - if (sock != NULL && sock->isClosing()) + // Recompute high-water mark so GetPlayerBySmallId doesn't miss active players. + DWORD newCount = 1; + for (int i = MINECRAFT_NET_MAX_PLAYERS - 1; i >= 1; --i) { - WinsockNetLayer::CloseConnectionBySmallId((BYTE)i); + if (IQNet::m_player[i].m_smallId == i) + { + newCount = i + 1; + break; + } } - } - } - if (_iQNetStubState == QNET_STATE_GAME_PLAY && !m_pIQNet->IsHost()) - { - if (!WinsockNetLayer::IsConnected() && !g_NetworkManager.IsLeavingGame()) - { - if (app.GetDisconnectReason() == DisconnectPacket::eDisconnect_None) - app.SetDisconnectReason(DisconnectPacket::eDisconnect_Quitting); - app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ExitWorld, (void *)TRUE); + IQNet::s_playerCount = newCount; } } #endif @@ -834,20 +828,9 @@ INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerByXuid(PlayerUID xuid) INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerBySmallId(unsigned char smallId) { IQNetPlayer *qnetPlayer = m_pIQNet->GetPlayerBySmallId(smallId); - if (qnetPlayer == NULL) - return NULL; - - INetworkPlayer *networkPlayer = getNetworkPlayer(qnetPlayer); -#ifdef _WINDOWS64 - if (networkPlayer == NULL && smallId != 0 && !m_pIQNet->IsHost()) - { - qnetPlayer->m_isRemote = true; - qnetPlayer->m_isHostPlayer = false; - NotifyPlayerJoined(qnetPlayer); - networkPlayer = getNetworkPlayer(qnetPlayer); - } -#endif - return networkPlayer; + if (qnetPlayer == NULL && smallId < MINECRAFT_NET_MAX_PLAYERS) + qnetPlayer = &IQNet::m_player[smallId]; + return getNetworkPlayer(qnetPlayer); } INetworkPlayer *CPlatformNetworkManagerStub::GetHostPlayer() diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 9db5776..1124b60 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -168,7 +168,7 @@ void PIXSetMarkerDeprecated(int a, char *b, ...) {} bool IsEqualXUID(PlayerUID a, PlayerUID b) { -#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO) || defined(_WINDOWS64) +#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO) return (a == b); #else return false; @@ -232,17 +232,13 @@ void Win64_SetupRemoteQNetPlayer(IQNetPlayer *player, BYTE smallId, bool isHost, IQNet::s_playerCount = smallId + 1; } -static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index); - HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; } IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; } IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex) { if (s_isHosting) { - if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS && - !m_player[dwUserIndex].m_isRemote && - Win64_IsActivePlayer(&m_player[dwUserIndex], dwUserIndex)) + if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS && !m_player[dwUserIndex].m_isRemote) return &m_player[dwUserIndex]; return NULL; } @@ -250,15 +246,22 @@ IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex) return NULL; for (DWORD i = 0; i < s_playerCount; i++) { - if (!m_player[i].m_isRemote && Win64_IsActivePlayer(&m_player[i], i)) - return &m_player[i]; + if (!m_player[i].m_isRemote) + { + // Require a valid smallId and attached network player to avoid + // returning unused slots on the client. + if (m_player[i].m_smallId == i && m_player[i].GetCustomDataValue() != 0) + return &m_player[i]; + } } return NULL; } static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index) { if (index == 0) return true; - return (p->GetCustomDataValue() != 0); + // Use smallId as the source of truth for activity; custom data can be cleared + // while the socket still needs to resolve the player. + return (p->m_smallId == index); } IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex) @@ -276,21 +279,21 @@ IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex) } IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId) { - if (SmallId >= MINECRAFT_NET_MAX_PLAYERS) - return NULL; - - m_player[SmallId].m_smallId = SmallId; - if (SmallId >= s_playerCount) - s_playerCount = SmallId + 1; - return &m_player[SmallId]; + if (SmallId < MINECRAFT_NET_MAX_PLAYERS && m_player[SmallId].m_smallId == SmallId) + return &m_player[SmallId]; + for (DWORD i = 0; i < s_playerCount; i++) + { + if (m_player[i].m_smallId == SmallId && Win64_IsActivePlayer(&m_player[i], i)) return &m_player[i]; + } + return NULL; } IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid) { - for (DWORD i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++) + for (DWORD i = 0; i < s_playerCount; i++) { if (Win64_IsActivePlayer(&m_player[i], i) && m_player[i].GetXuid() == xuid) return &m_player[i]; } - return NULL; + return &m_player[0]; } DWORD IQNet::GetPlayerCount() { @@ -305,28 +308,15 @@ QNET_STATE IQNet::GetState() { return _iQNetStubState; } bool IQNet::IsHost() { return s_isHosting; } HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; } void IQNet::HostGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = true; } -void IQNet::ClientJoinGame() -{ - _iQNetStubState = QNET_STATE_SESSION_STARTING; - s_isHosting = false; - - for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++) - { - m_player[i].m_smallId = (BYTE)i; - m_player[i].m_isRemote = true; - m_player[i].m_isHostPlayer = false; - m_player[i].m_gamertag[0] = 0; - m_player[i].SetCustomDataValue(0); - } -} +void IQNet::ClientJoinGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = false; } void IQNet::EndGame() { _iQNetStubState = QNET_STATE_IDLE; s_isHosting = false; s_playerCount = 1; - for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++) + for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++) { - m_player[i].m_smallId = (BYTE)i; + m_player[i].m_smallId = 0; m_player[i].m_isRemote = false; m_player[i].m_isHostPlayer = false; m_player[i].m_gamertag[0] = 0; diff --git a/Minecraft.Client/PendingConnection.cpp b/Minecraft.Client/PendingConnection.cpp index 2bb5106..b013557 100644 --- a/Minecraft.Client/PendingConnection.cpp +++ b/Minecraft.Client/PendingConnection.cpp @@ -14,6 +14,9 @@ #include "..\Minecraft.World\net.minecraft.world.item.h" #include "..\Minecraft.World\SharedConstants.h" #include "Settings.h" +#ifdef _WINDOWS64 +#include "Windows64\\Network\\WinsockNetLayer.h" +#endif // #ifdef __PS3__ // #include "PS3\Network\NetworkPlayerSony.h" // #endif @@ -65,6 +68,24 @@ void PendingConnection::disconnect(DisconnectPacket::eDisconnectReason reason) // try { // 4J - removed try/catch // logger.info("Disconnecting " + getName() + ": " + reason); app.DebugPrintf("Pending connection disconnect: %d\n", reason ); +#ifdef _WINDOWS64 + // Ensure the underlying Win64 TCP connection is closed so the slot is freed. + if (connection != NULL) + { + Socket *sock = connection->getSocket(); + INetworkPlayer *np = sock ? sock->getPlayer() : NULL; + if (np != NULL && !np->IsLocal()) + { + WinsockNetLayer::DisconnectSmallId(np->GetSmallId()); + } + else if (sock != NULL) + { + BYTE sid = sock->getSmallId(); + if (sid != 0) + WinsockNetLayer::DisconnectSmallId(sid); + } + } +#endif connection->send( shared_ptr( new DisconnectPacket(reason) ) ); connection->sendAndQuit(); done = true; @@ -294,4 +315,4 @@ wstring PendingConnection::getName() bool PendingConnection::isServerPacketListener() { return true; -} \ No newline at end of file +} diff --git a/Minecraft.Client/PendingConnection.h b/Minecraft.Client/PendingConnection.h index 02d706f..cfd75fd 100644 --- a/Minecraft.Client/PendingConnection.h +++ b/Minecraft.Client/PendingConnection.h @@ -11,7 +11,11 @@ class PendingConnection : public PacketListener { private: static const int FAKE_LAG = 0; +#ifdef _WINDOWS64 + static const int MAX_TICKS_BEFORE_LOGIN = 20 * 5; +#else static const int MAX_TICKS_BEFORE_LOGIN = 20 * 30; +#endif // public static Logger logger = Logger.getLogger("Minecraft"); static Random *random; @@ -45,4 +49,4 @@ public: private: void sendPreLoginResponse(); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp b/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp index 7e7c6ae..9ab1ae8 100644 --- a/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp +++ b/Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp @@ -213,14 +213,6 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port) s_isHost = false; s_hostSmallId = 0; - s_connected = false; - s_active = false; - - if (s_hostConnectionSocket != INVALID_SOCKET) - { - closesocket(s_hostConnectionSocket); - s_hostConnectionSocket = INVALID_SOCKET; - } struct addrinfo hints = {}; struct addrinfo *result = NULL; @@ -239,55 +231,37 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port) return false; } - bool connected = false; - BYTE assignedSmallId = 0; - const int maxAttempts = 12; - - for (int attempt = 0; attempt < maxAttempts; ++attempt) - { - s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - if (s_hostConnectionSocket == INVALID_SOCKET) - { - app.DebugPrintf("socket() failed: %d\n", WSAGetLastError()); - break; - } - - int noDelay = 1; - setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay)); - - iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen); - if (iResult == SOCKET_ERROR) - { - int err = WSAGetLastError(); - app.DebugPrintf("connect() to %s:%d failed (attempt %d/%d): %d\n", ip, port, attempt + 1, maxAttempts, err); - closesocket(s_hostConnectionSocket); - s_hostConnectionSocket = INVALID_SOCKET; - Sleep(200); - continue; - } - - BYTE assignBuf[1]; - int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0); - if (bytesRecv != 1) - { - app.DebugPrintf("Failed to receive small ID assignment from host (attempt %d/%d)\n", attempt + 1, maxAttempts); - closesocket(s_hostConnectionSocket); - s_hostConnectionSocket = INVALID_SOCKET; - Sleep(200); - continue; - } - - assignedSmallId = assignBuf[0]; - connected = true; - break; - } - freeaddrinfo(result); - - if (!connected) + s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); + if (s_hostConnectionSocket == INVALID_SOCKET) { + app.DebugPrintf("socket() failed: %d\n", WSAGetLastError()); + freeaddrinfo(result); return false; } - s_localSmallId = assignedSmallId; + + int noDelay = 1; + setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay)); + + iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen); + freeaddrinfo(result); + if (iResult == SOCKET_ERROR) + { + app.DebugPrintf("connect() to %s:%d failed: %d\n", ip, port, WSAGetLastError()); + closesocket(s_hostConnectionSocket); + s_hostConnectionSocket = INVALID_SOCKET; + return false; + } + + BYTE assignBuf[1]; + int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0); + if (bytesRecv != 1) + { + app.DebugPrintf("Failed to receive small ID assignment from host\n"); + closesocket(s_hostConnectionSocket); + s_hostConnectionSocket = INVALID_SOCKET; + return false; + } + s_localSmallId = assignBuf[0]; app.DebugPrintf("Win64 LAN: Connected to %s:%d, assigned smallId=%d\n", ip, port, s_localSmallId); @@ -447,6 +421,8 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param) continue; } LeaveCriticalSection(&s_freeSmallIdLock); + app.DebugPrintf("Win64 LAN: Allocated smallId=%d (next=%d, free=%u)\n", + assignedSmallId, s_nextSmallId, (unsigned int)s_freeSmallIds.size()); BYTE assignBuf[1] = { assignedSmallId }; int sent = send(clientSocket, (const char *)assignBuf, 1, 0); @@ -454,6 +430,7 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param) { app.DebugPrintf("Failed to send small ID to client\n"); closesocket(clientSocket); + PushFreeSmallId(assignedSmallId); continue; } @@ -505,8 +482,7 @@ DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param) BYTE clientSmallId = s_connections[connIdx].smallId; LeaveCriticalSection(&s_connectionsLock); - std::vector recvBuf; - recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE); + BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE]; while (s_active) { @@ -517,47 +493,34 @@ DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param) break; } - int packetSize = - ((uint32_t)header[0] << 24) | - ((uint32_t)header[1] << 16) | - ((uint32_t)header[2] << 8) | - ((uint32_t)header[3]); + int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3]; - if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE) + if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE) { - app.DebugPrintf("Win64 LAN: Invalid packet size %d from client smallId=%d (max=%d)\n", - packetSize, - clientSmallId, - (int)WIN64_NET_MAX_PACKET_SIZE); + app.DebugPrintf("Win64 LAN: Invalid packet size %d from client smallId=%d\n", packetSize, clientSmallId); break; } - if ((int)recvBuf.size() < packetSize) - { - recvBuf.resize(packetSize); - app.DebugPrintf("Win64 LAN: Resized host recv buffer to %d bytes for client smallId=%d\n", packetSize, clientSmallId); - } - - if (!RecvExact(sock, &recvBuf[0], packetSize)) + if (!RecvExact(sock, recvBuf, packetSize)) { app.DebugPrintf("Win64 LAN: Client smallId=%d disconnected (body)\n", clientSmallId); break; } - HandleDataReceived(clientSmallId, s_hostSmallId, &recvBuf[0], packetSize); + HandleDataReceived(clientSmallId, s_hostSmallId, recvBuf, packetSize); } + delete[] recvBuf; + app.DebugPrintf("Win64 LAN: RecvThread ending for smallId=%d\n", clientSmallId); + EnterCriticalSection(&s_connectionsLock); for (size_t i = 0; i < s_connections.size(); i++) { if (s_connections[i].smallId == clientSmallId) { s_connections[i].active = false; - if (s_connections[i].tcpSocket != INVALID_SOCKET) - { - closesocket(s_connections[i].tcpSocket); - s_connections[i].tcpSocket = INVALID_SOCKET; - } + closesocket(s_connections[i].tcpSocket); + s_connections[i].tcpSocket = INVALID_SOCKET; break; } } @@ -581,6 +544,8 @@ bool WinsockNetLayer::PopDisconnectedSmallId(BYTE *outSmallId) found = true; } LeaveCriticalSection(&s_disconnectLock); + if (found) + app.DebugPrintf("Win64 LAN: Popped disconnected smallId=%d\n", *outSmallId); return found; } @@ -589,28 +554,50 @@ void WinsockNetLayer::PushFreeSmallId(BYTE smallId) EnterCriticalSection(&s_freeSmallIdLock); s_freeSmallIds.push_back(smallId); LeaveCriticalSection(&s_freeSmallIdLock); + app.DebugPrintf("Win64 LAN: Freed smallId=%d (free=%u)\n", smallId, (unsigned int)s_freeSmallIds.size()); } -void WinsockNetLayer::CloseConnectionBySmallId(BYTE smallId) +void WinsockNetLayer::DisconnectSmallId(BYTE smallId) { + if (!s_active) return; + + HANDLE recvThread = NULL; + bool closed = false; + EnterCriticalSection(&s_connectionsLock); for (size_t i = 0; i < s_connections.size(); i++) { - if (s_connections[i].smallId == smallId && s_connections[i].active && s_connections[i].tcpSocket != INVALID_SOCKET) + if (s_connections[i].smallId == smallId && s_connections[i].active) { - closesocket(s_connections[i].tcpSocket); - s_connections[i].tcpSocket = INVALID_SOCKET; - app.DebugPrintf("Win64 LAN: Force-closed TCP connection for smallId=%d\n", smallId); + s_connections[i].active = false; + recvThread = s_connections[i].recvThread; + if (s_connections[i].tcpSocket != INVALID_SOCKET) + { + closesocket(s_connections[i].tcpSocket); + s_connections[i].tcpSocket = INVALID_SOCKET; + closed = true; + } break; } } LeaveCriticalSection(&s_connectionsLock); + + if (closed) + { + app.DebugPrintf("Win64 LAN: Forced disconnect smallId=%d\n", smallId); + // If there's no recv thread to report this, queue it now. + if (recvThread == NULL) + { + EnterCriticalSection(&s_disconnectLock); + s_disconnectedSmallIds.push_back(smallId); + LeaveCriticalSection(&s_disconnectLock); + } + } } DWORD WINAPI WinsockNetLayer::ClientRecvThreadProc(LPVOID param) { - std::vector recvBuf; - recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE); + BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE]; while (s_active && s_hostConnectionSocket != INVALID_SOCKET) { @@ -623,29 +610,23 @@ DWORD WINAPI WinsockNetLayer::ClientRecvThreadProc(LPVOID param) int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3]; - if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE) + if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE) { - app.DebugPrintf("Win64 LAN: Invalid packet size %d from host (max=%d)\n", - packetSize, - (int)WIN64_NET_MAX_PACKET_SIZE); + app.DebugPrintf("Win64 LAN: Invalid packet size %d from host\n", packetSize); break; } - if ((int)recvBuf.size() < packetSize) - { - recvBuf.resize(packetSize); - app.DebugPrintf("Win64 LAN: Resized client recv buffer to %d bytes\n", packetSize); - } - - if (!RecvExact(s_hostConnectionSocket, &recvBuf[0], packetSize)) + if (!RecvExact(s_hostConnectionSocket, recvBuf, packetSize)) { app.DebugPrintf("Win64 LAN: Disconnected from host (body)\n"); break; } - HandleDataReceived(s_hostSmallId, s_localSmallId, &recvBuf[0], packetSize); + HandleDataReceived(s_hostSmallId, s_localSmallId, recvBuf, packetSize); } + delete[] recvBuf; + s_connected = false; return 0; } diff --git a/Minecraft.Client/Windows64/Network/WinsockNetLayer.h b/Minecraft.Client/Windows64/Network/WinsockNetLayer.h index e6ace42..842110a 100644 --- a/Minecraft.Client/Windows64/Network/WinsockNetLayer.h +++ b/Minecraft.Client/Windows64/Network/WinsockNetLayer.h @@ -12,7 +12,6 @@ #define WIN64_NET_DEFAULT_PORT 25565 #define WIN64_NET_MAX_CLIENTS 7 #define WIN64_NET_RECV_BUFFER_SIZE 65536 -#define WIN64_NET_MAX_PACKET_SIZE (4 * 1024 * 1024) #define WIN64_LAN_DISCOVERY_PORT 25566 #define WIN64_LAN_BROADCAST_MAGIC 0x4D434C4E @@ -82,7 +81,7 @@ public: static bool PopDisconnectedSmallId(BYTE *outSmallId); static void PushFreeSmallId(BYTE smallId); - static void CloseConnectionBySmallId(BYTE smallId); + static void DisconnectSmallId(BYTE smallId); static bool StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer); static void StopAdvertising();