aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client/Common')
-rw-r--r--Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp40
-rw-r--r--Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h5
-rw-r--r--Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp42
3 files changed, 86 insertions, 1 deletions
diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
index a898c136..970dfd24 100644
--- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
+++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.cpp
@@ -8,6 +8,8 @@
#include "..\..\Windows64\Windows64_Xuid.h"
#include "..\..\Minecraft.h"
#include "..\..\User.h"
+#include "..\..\MinecraftServer.h"
+#include "..\..\PlayerList.h"
#include <iostream>
#endif
@@ -238,15 +240,33 @@ void CPlatformNetworkManagerStub::DoWork()
qnetPlayer->m_resolvedXuid = INVALID_XUID;
qnetPlayer->m_gamertag[0] = 0;
qnetPlayer->SetCustomDataValue(0);
- WinsockNetLayer::PushFreeSmallId(disconnectedSmallId);
if (IQNet::s_playerCount > 1)
IQNet::s_playerCount--;
}
+ // Always return smallId to the free pool so it can be reused (game may have already cleared the slot).
+ WinsockNetLayer::PushFreeSmallId(disconnectedSmallId);
+ // Clear O(1) socket lookup so GetSocketForSmallId stays fast (s_connections never shrinks).
+ WinsockNetLayer::ClearSocketForSmallId(disconnectedSmallId);
+ // Clear chunk visibility flags for this system so rejoin gets fresh chunk state.
+ SystemFlagRemoveBySmallId((int)disconnectedSmallId);
}
}
#endif
}
+bool CPlatformNetworkManagerStub::CanAcceptMoreConnections()
+{
+#ifdef _WINDOWS64
+ MinecraftServer* server = MinecraftServer::getInstance();
+ if (server == NULL) return true;
+ PlayerList* list = server->getPlayerList();
+ if (list == NULL) return true;
+ return (unsigned int)list->players.size() < (unsigned int)list->getMaxPlayers();
+#else
+ return true;
+#endif
+}
+
int CPlatformNetworkManagerStub::GetPlayerCount()
{
return m_pIQNet->GetPlayerCount();
@@ -581,6 +601,7 @@ CPlatformNetworkManagerStub::PlayerFlags::PlayerFlags(INetworkPlayer *pNetworkPl
this->flags = new unsigned char [ count / 8 ];
memset( this->flags, 0, count / 8 );
this->count = count;
+ this->m_smallId = (pNetworkPlayer && pNetworkPlayer->IsLocal()) ? 256 : (pNetworkPlayer ? (int)pNetworkPlayer->GetSmallId() : -1);
}
CPlatformNetworkManagerStub::PlayerFlags::~PlayerFlags()
{
@@ -618,6 +639,23 @@ void CPlatformNetworkManagerStub::SystemFlagRemovePlayer(INetworkPlayer *pNetwor
}
}
+// Clear chunk flags for a system when they disconnect (by smallId). Call even when we don't find the player,
+// so we always clear and the smallId can be reused without stale "chunk seen" state.
+void CPlatformNetworkManagerStub::SystemFlagRemoveBySmallId(int smallId)
+{
+ if (smallId < 0) return;
+ for (unsigned int i = 0; i < m_playerFlags.size(); i++)
+ {
+ if (m_playerFlags[i]->m_smallId == smallId)
+ {
+ delete m_playerFlags[i];
+ m_playerFlags[i] = m_playerFlags.back();
+ m_playerFlags.pop_back();
+ return;
+ }
+ }
+}
+
void CPlatformNetworkManagerStub::SystemFlagReset()
{
for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
diff --git a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h
index 28953cec..261639f2 100644
--- a/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h
+++ b/Minecraft.Client/Common/Network/PlatformNetworkManagerStub.h
@@ -98,12 +98,14 @@ private:
INetworkPlayer *m_pNetworkPlayer;
unsigned char *flags;
unsigned int count;
+ int m_smallId;
PlayerFlags(INetworkPlayer *pNetworkPlayer, unsigned int count);
~PlayerFlags();
};
vector<PlayerFlags *> m_playerFlags;
void SystemFlagAddPlayer(INetworkPlayer *pNetworkPlayer);
void SystemFlagRemovePlayer(INetworkPlayer *pNetworkPlayer);
+ void SystemFlagRemoveBySmallId(int smallId);
void SystemFlagReset();
public:
virtual void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index);
@@ -161,6 +163,9 @@ public:
virtual void GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam );
virtual void ForceFriendsSessionRefresh();
+ // Win64: used by accept thread to reject connections when server is at max players (so we don't assign smallId > max).
+ bool CanAcceptMoreConnections();
+
public:
void NotifyPlayerJoined( IQNetPlayer *pQNetPlayer );
void NotifyPlayerLeaving(IQNetPlayer* pQNetPlayer);
diff --git a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp
index c036f7bf..6e354922 100644
--- a/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp
+++ b/Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp
@@ -534,6 +534,48 @@ void UIScene_JoinMenu::JoinGame(UIScene_JoinMenu* pClass)
if( exitReasonStringId == -1 )
{
+ Minecraft* pMinecraft = Minecraft::GetInstance();
+ int primaryPad = ProfileManager.GetPrimaryPad();
+ if( pMinecraft->m_connectionFailed[primaryPad] )
+ {
+ switch( pMinecraft->m_connectionFailedReason[primaryPad] )
+ {
+ case DisconnectPacket::eDisconnect_LoginTooLong:
+ exitReasonStringId = IDS_DISCONNECTED_LOGIN_TOO_LONG;
+ break;
+ case DisconnectPacket::eDisconnect_ServerFull:
+ exitReasonStringId = IDS_DISCONNECTED_SERVER_FULL;
+ break;
+ case DisconnectPacket::eDisconnect_Kicked:
+ exitReasonStringId = IDS_DISCONNECTED_KICKED;
+ break;
+ case DisconnectPacket::eDisconnect_NoUGC_AllLocal:
+ exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL;
+ break;
+ case DisconnectPacket::eDisconnect_NoUGC_Single_Local:
+ exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL;
+ break;
+ case DisconnectPacket::eDisconnect_NoFlying:
+ exitReasonStringId = IDS_DISCONNECTED_FLYING;
+ break;
+ case DisconnectPacket::eDisconnect_Quitting:
+ exitReasonStringId = IDS_DISCONNECTED_SERVER_QUIT;
+ break;
+ case DisconnectPacket::eDisconnect_OutdatedServer:
+ exitReasonStringId = IDS_DISCONNECTED_SERVER_OLD;
+ break;
+ case DisconnectPacket::eDisconnect_OutdatedClient:
+ exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD;
+ break;
+ default:
+ exitReasonStringId = IDS_CONNECTION_LOST_SERVER;
+ break;
+ }
+ }
+ }
+
+ if( exitReasonStringId == -1 )
+ {
ui.NavigateBack(pClass->m_iPad);
}
else