fix: fix multiplayer player data mix between different players bug

Fixes a Win64 multiplayer issue where player data (`players/*.dat`) could be mismatched because identity was effectively tied to connection-order `smallId` XUIDs.
Introduces a deterministic username-derived persistent XUID and integrates it into the existing XUID-based save pipeline.

- Added `Windows64_NameXuid` for deterministic `name -> persistent xuid` resolution
- On Win64 login (`PlayerList`), set `ServerPlayer::xuid` from username-based resolver
- Aligned local player `xuid` assignment (`Minecraft`) for create/init/respawn paths to use the same resolver
- Added Win64 local-self guard in `ClientConnection::handleAddPlayer` using name match to avoid duplicate local remote-player creation
- Kept `IQNet::GetPlayerByXuid` compatibility fallback behavior, while extending lookup to also resolve username-based XUIDs
- Moved implementation to `Minecraft.Client/Windows64/Windows64_NameXuid.h`; kept legacy `Win64NameXuid.h` as compatibility include

Rename migration is intentionally out of scope (same-name identity only).
This commit is contained in:
kuwacom
2026-03-05 12:29:15 +09:00
parent f1d477c1ec
commit f8cbd4f844
5 changed files with 88 additions and 5 deletions

View File

@@ -21,6 +21,7 @@
#include "Windows64\Social\SocialManager.h"
#include "Windows64\Sentient\DynamicConfigurations.h"
#include "Windows64\Network\WinsockNetLayer.h"
#include "Windows64\Windows64_NameXuid.h"
#elif defined __PSVITA__
#include "PSVita\Sentient\SentientManager.h"
#include "StatsCounter.h"
@@ -285,7 +286,19 @@ IQNetPlayer* IQNet::GetPlayerByXuid(PlayerUID xuid)
{
for (DWORD i = 0; i < s_playerCount; i++)
{
if (Win64_IsActivePlayer(&m_player[i], i) && m_player[i].GetXuid() == xuid) return &m_player[i];
// Conventional XUID implementation except for Windows 64.
if (!Win64_IsActivePlayer(&m_player[i], i))
continue;
if (m_player[i].GetXuid() == xuid)
return &m_player[i];
// For Windows 64, NameBase XUID is used.
#ifdef _WINDOWS64
PlayerUID nameXuid = Win64NameXuid::ResolvePersistentXuidFromName(m_player[i].GetGamertag());
if (nameXuid == xuid)
return &m_player[i];
#endif
}
return &m_player[0];
}