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

@@ -52,6 +52,7 @@
#include "..\Minecraft.World\net.minecraft.world.level.dimension.h"
#include "..\Minecraft.World\net.minecraft.world.item.h"
#include "..\Minecraft.World\Minecraft.World.h"
#include "Windows64\Windows64_NameXuid.h"
#include "ClientConnection.h"
#include "..\Minecraft.World\HellRandomLevelSource.h"
#include "..\Minecraft.World\net.minecraft.world.entity.animal.h"
@@ -1038,6 +1039,9 @@ shared_ptr<MultiplayerLocalPlayer> Minecraft::createExtraLocalPlayer(int idx, co
PlayerUID playerXUIDOnline = INVALID_XUID;
ProfileManager.GetXUID(idx,&playerXUIDOffline,false);
ProfileManager.GetXUID(idx,&playerXUIDOnline,true);
#ifdef _WINDOWS64
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(localplayers[idx]->name);
#endif
localplayers[idx]->setXuid(playerXUIDOffline);
localplayers[idx]->setOnlineXuid(playerXUIDOnline);
localplayers[idx]->setIsGuest(ProfileManager.IsGuest(idx));
@@ -4295,6 +4299,9 @@ void Minecraft::setLevel(MultiPlayerLevel *level, int message /*=-1*/, shared_pt
// player doesn't have an online UID, set it from the player name
playerXUIDOnline.setForAdhoc();
}
#endif
#ifdef _WINDOWS64
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(player->name);
#endif
player->setXuid(playerXUIDOffline);
player->setOnlineXuid(playerXUIDOnline);
@@ -4478,6 +4485,9 @@ void Minecraft::respawnPlayer(int iPad, int dimension, int newEntityId)
PlayerUID playerXUIDOnline = INVALID_XUID;
ProfileManager.GetXUID(iTempPad,&playerXUIDOffline,false);
ProfileManager.GetXUID(iTempPad,&playerXUIDOnline,true);
#ifdef _WINDOWS64
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(player->name);
#endif
player->setXuid(playerXUIDOffline);
player->setOnlineXuid(playerXUIDOnline);
player->setIsGuest( ProfileManager.IsGuest(iTempPad) );