apply smallId leak fixes

This commit is contained in:
bytesizedfox 2026-03-03 01:29:46 -05:00
parent 60f8613efb
commit 0667907862

View file

@ -168,7 +168,7 @@ void PIXSetMarkerDeprecated(int a, char *b, ...) {}
bool IsEqualXUID(PlayerUID a, PlayerUID b) bool IsEqualXUID(PlayerUID a, PlayerUID b)
{ {
#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO) #if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO) || defined(_WINDOWS64)
return (a == b); return (a == b);
#else #else
return false; return false;
@ -232,13 +232,17 @@ void Win64_SetupRemoteQNetPlayer(IQNetPlayer *player, BYTE smallId, bool isHost,
IQNet::s_playerCount = smallId + 1; IQNet::s_playerCount = smallId + 1;
} }
static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index);
HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; } HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; }
IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; } IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; }
IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex) IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
{ {
if (s_isHosting) if (s_isHosting)
{ {
if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS && !m_player[dwUserIndex].m_isRemote) if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS &&
!m_player[dwUserIndex].m_isRemote &&
Win64_IsActivePlayer(&m_player[dwUserIndex], dwUserIndex))
return &m_player[dwUserIndex]; return &m_player[dwUserIndex];
return NULL; return NULL;
} }
@ -246,22 +250,15 @@ IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
return NULL; return NULL;
for (DWORD i = 0; i < s_playerCount; i++) for (DWORD i = 0; i < s_playerCount; i++)
{ {
if (!m_player[i].m_isRemote) if (!m_player[i].m_isRemote && Win64_IsActivePlayer(&m_player[i], i))
{ return &m_player[i];
// 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; return NULL;
} }
static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index) static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index)
{ {
if (index == 0) return true; if (index == 0) return true;
// Use smallId as the source of truth for activity; custom data can be cleared return (p->GetCustomDataValue() != 0);
// while the socket still needs to resolve the player.
return (p->m_smallId == index);
} }
IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex) IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex)
@ -279,21 +276,21 @@ IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex)
} }
IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId) IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId)
{ {
if (SmallId < MINECRAFT_NET_MAX_PLAYERS && m_player[SmallId].m_smallId == SmallId) if (SmallId >= MINECRAFT_NET_MAX_PLAYERS)
return &m_player[SmallId]; return NULL;
for (DWORD i = 0; i < s_playerCount; i++)
{ m_player[SmallId].m_smallId = SmallId;
if (m_player[i].m_smallId == SmallId && Win64_IsActivePlayer(&m_player[i], i)) return &m_player[i]; if (SmallId >= s_playerCount)
} s_playerCount = SmallId + 1;
return NULL; return &m_player[SmallId];
} }
IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid) IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid)
{ {
for (DWORD i = 0; i < s_playerCount; i++) for (DWORD i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
{ {
if (Win64_IsActivePlayer(&m_player[i], i) && m_player[i].GetXuid() == xuid) return &m_player[i]; if (Win64_IsActivePlayer(&m_player[i], i) && m_player[i].GetXuid() == xuid) return &m_player[i];
} }
return &m_player[0]; return NULL;
} }
DWORD IQNet::GetPlayerCount() DWORD IQNet::GetPlayerCount()
{ {
@ -308,15 +305,28 @@ QNET_STATE IQNet::GetState() { return _iQNetStubState; }
bool IQNet::IsHost() { return s_isHosting; } bool IQNet::IsHost() { return s_isHosting; }
HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; } 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::HostGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = true; }
void IQNet::ClientJoinGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = false; } 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::EndGame() void IQNet::EndGame()
{ {
_iQNetStubState = QNET_STATE_IDLE; _iQNetStubState = QNET_STATE_IDLE;
s_isHosting = false; s_isHosting = false;
s_playerCount = 1; s_playerCount = 1;
for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++) for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
{ {
m_player[i].m_smallId = 0; m_player[i].m_smallId = (BYTE)i;
m_player[i].m_isRemote = false; m_player[i].m_isRemote = false;
m_player[i].m_isHostPlayer = false; m_player[i].m_isHostPlayer = false;
m_player[i].m_gamertag[0] = 0; m_player[i].m_gamertag[0] = 0;