fix: preserve legacy host xuid (base xuid + 0) for existing world compatibility

- Add legacy embedded host XUID helper (base + 0).
- When Minecraft.Client is hosting, force only the first host player to use legacy host XUID.
- Keep name-based XUID for non-host players.
- Prevent old singleplayer/hosted worlds from losing/mismatching host player data.
This commit is contained in:
kuwacom 2026-03-06 10:17:13 +09:00
parent f8cbd4f844
commit a0f75679c1
3 changed files with 45 additions and 3 deletions

View file

@ -1040,7 +1040,15 @@ shared_ptr<MultiplayerLocalPlayer> Minecraft::createExtraLocalPlayer(int idx, co
ProfileManager.GetXUID(idx,&playerXUIDOffline,false); ProfileManager.GetXUID(idx,&playerXUIDOffline,false);
ProfileManager.GetXUID(idx,&playerXUIDOnline,true); ProfileManager.GetXUID(idx,&playerXUIDOnline,true);
#ifdef _WINDOWS64 #ifdef _WINDOWS64
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(localplayers[idx]->name); INetworkPlayer *localNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(idx);
if(localNetworkPlayer != NULL && localNetworkPlayer->IsHost())
{
playerXUIDOffline = Win64NameXuid::GetLegacyEmbeddedHostXuid();
}
else
{
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(localplayers[idx]->name);
}
#endif #endif
localplayers[idx]->setXuid(playerXUIDOffline); localplayers[idx]->setXuid(playerXUIDOffline);
localplayers[idx]->setOnlineXuid(playerXUIDOnline); localplayers[idx]->setOnlineXuid(playerXUIDOnline);
@ -4301,7 +4309,15 @@ void Minecraft::setLevel(MultiPlayerLevel *level, int message /*=-1*/, shared_pt
} }
#endif #endif
#ifdef _WINDOWS64 #ifdef _WINDOWS64
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(player->name); INetworkPlayer *localNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(iPrimaryPlayer);
if(localNetworkPlayer != NULL && localNetworkPlayer->IsHost())
{
playerXUIDOffline = Win64NameXuid::GetLegacyEmbeddedHostXuid();
}
else
{
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(player->name);
}
#endif #endif
player->setXuid(playerXUIDOffline); player->setXuid(playerXUIDOffline);
player->setOnlineXuid(playerXUIDOnline); player->setOnlineXuid(playerXUIDOnline);
@ -4486,7 +4502,15 @@ void Minecraft::respawnPlayer(int iPad, int dimension, int newEntityId)
ProfileManager.GetXUID(iTempPad,&playerXUIDOffline,false); ProfileManager.GetXUID(iTempPad,&playerXUIDOffline,false);
ProfileManager.GetXUID(iTempPad,&playerXUIDOnline,true); ProfileManager.GetXUID(iTempPad,&playerXUIDOnline,true);
#ifdef _WINDOWS64 #ifdef _WINDOWS64
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(player->name); INetworkPlayer *localNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(iTempPad);
if(localNetworkPlayer != NULL && localNetworkPlayer->IsHost())
{
playerXUIDOffline = Win64NameXuid::GetLegacyEmbeddedHostXuid();
}
else
{
playerXUIDOffline = Win64NameXuid::ResolvePersistentXuidFromName(player->name);
}
#endif #endif
player->setXuid(playerXUIDOffline); player->setXuid(playerXUIDOffline);
player->setOnlineXuid(playerXUIDOnline); player->setOnlineXuid(playerXUIDOnline);

View file

@ -528,6 +528,13 @@ shared_ptr<ServerPlayer> PlayerList::getPlayerForLogin(PendingConnection *pendin
if (np != NULL) if (np != NULL)
{ {
player->setOnlineXuid(np->GetUID()); player->setOnlineXuid(np->GetUID());
// Backward compatibility: when Minecraft.Client is hosting, keep the first
// host player on the legacy embedded host XUID (base + 0).
if (np->IsHost())
{
player->setXuid(Win64NameXuid::GetLegacyEmbeddedHostXuid());
}
} }
} }
#endif #endif

View file

@ -6,6 +6,17 @@
namespace Win64NameXuid namespace Win64NameXuid
{ {
inline PlayerUID GetLegacyEmbeddedBaseXuid()
{
return (PlayerUID)0xe000d45248242f2eULL;
}
inline PlayerUID GetLegacyEmbeddedHostXuid()
{
// Legacy behavior used "embedded base + smallId"; host was always smallId 0.
return GetLegacyEmbeddedBaseXuid();
}
/** /**
* ## Resolves a persistent 64-bit player ID from the player's username. * ## Resolves a persistent 64-bit player ID from the player's username.
* *