diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 1e2b6c2c..2b79c114 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -201,7 +201,7 @@ DWORD IQNetPlayer::GetCurrentRtt() { return 0; } bool IQNetPlayer::IsHost() { return m_isHostPlayer; } bool IQNetPlayer::IsGuest() { return false; } bool IQNetPlayer::IsLocal() { return !m_isRemote; } -PlayerUID IQNetPlayer::GetXuid() { return (PlayerUID)(0xe000d45248242f2e + m_smallId); } // todo: restore to INVALID_XUID once saves support this +PlayerUID IQNetPlayer::GetXuid() { return m_playerUID; } LPCWSTR IQNetPlayer::GetGamertag() { return m_gamertag; } int IQNetPlayer::GetSessionIndex() { return m_smallId; } bool IQNetPlayer::IsTalking() { return false; } @@ -292,13 +292,6 @@ IQNetPlayer* IQNet::GetPlayerByXuid(PlayerUID xuid) 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]; } diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index f38f6d4b..c72bf87d 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1039,9 +1039,6 @@ shared_ptr 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)); @@ -4299,9 +4296,6 @@ 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); @@ -4485,9 +4479,6 @@ 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) ); diff --git a/Minecraft.Client/PlayerList.cpp b/Minecraft.Client/PlayerList.cpp index 36ac0878..349bd3f8 100644 --- a/Minecraft.Client/PlayerList.cpp +++ b/Minecraft.Client/PlayerList.cpp @@ -539,18 +539,6 @@ shared_ptr PlayerList::getPlayerForLogin(PendingConnection *pendin player->gameMode->player = player; // 4J added as had to remove this assignment from ServerPlayer ctor player->setXuid( xuid ); // 4J Added player->setOnlineXuid( onlineXuid ); // 4J Added -#ifdef _WINDOWS64 - { - PlayerUID persistentXuid = Win64NameXuid::ResolvePersistentXuidFromName(userName); - player->setXuid(persistentXuid); - - INetworkPlayer* np = pendingConnection->connection->getSocket()->getPlayer(); - if (np != NULL) - { - player->setOnlineXuid(np->GetUID()); - } - } -#endif // Work out the base server player settings INetworkPlayer *networkPlayer = pendingConnection->connection->getSocket()->getPlayer(); if(networkPlayer != NULL && !networkPlayer->IsHost()) diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index d38ad442..1bdd95e1 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -4,6 +4,7 @@ #include "stdafx.h" #include +#include #include #include #include @@ -41,6 +42,7 @@ #include "..\..\Minecraft.World\compression.h" #include "..\..\Minecraft.World\OldChunkStorage.h" #include "Network\WinsockNetLayer.h" +#include "Windows64\Windows64_NameXuid.h" #include "Xbox/resource.h" @@ -92,6 +94,7 @@ float g_iAspectRatio = static_cast(g_iScreenWidth) / g_iScreenHeight; char g_Win64Username[17] = { 0 }; wchar_t g_Win64UsernameW[17] = { 0 }; +PlayerUID g_Win64PlayerUID = NULL; // Fullscreen toggle state static bool g_isFullscreen = false; @@ -1208,6 +1211,36 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, fclose(f); } + // Load PlayerUID from file + const char *uidFilePath = "uid.dat"; + PlayerUID uid = 0; + + // Try to read UID from file if it exists + std::ifstream uidReadableFile(uidFilePath, std::ios::binary); + if (uidReadableFile.is_open()) + { + uidReadableFile.read(reinterpret_cast(&uid), sizeof(PlayerUID)); + if (uidReadableFile.gcount() == sizeof(PlayerUID) && uid != (PlayerUID)INVALID_XUID) + { + uidReadableFile.close(); + return uid; + } + uidReadableFile.close(); + } + + // Doesn't exist, so let's write it + uid = Win64NameXuid::GenerateRandomPlayerUID(); + + std::ofstream uidWriteFile(filePath, std::ios::binary); + if (uidWriteFile.is_open()) + { + uidWriteFile.write(reinterpret_cast(&uid), sizeof(PlayerUID)); + uidWriteFile.close(); + } + + g_Win64PlayerUID = uid; + + // Load stuff from launch options, including username Win64LaunchOptions launchOptions = ParseLaunchOptions(); ApplyScreenMode(launchOptions.screenMode); diff --git a/Minecraft.Client/Windows64/Windows64_NameXuid.h b/Minecraft.Client/Windows64/Windows64_NameXuid.h index 5b3e8e1a..48a7df66 100644 --- a/Minecraft.Client/Windows64/Windows64_NameXuid.h +++ b/Minecraft.Client/Windows64/Windows64_NameXuid.h @@ -40,6 +40,25 @@ namespace Win64NameXuid return (PlayerUID)hash; } + + /** + * Creates a completely random PlayerUID while also keeping itself away from the legacy values + * + * @return Random PlayerUID within valid ranges + */ + inline PlayerUID GenerateRandomPlayerUID() + { + unsigned __int64 hash = ((unsigned __int64)rand() << 32) | (unsigned __int64)rand(); + + // Namespace the hash away from legacy smallId-based values. + hash ^= 0x9E3779B97F4A7C15ULL; + hash |= 0x8000000000000000ULL; + if (hash == (unsigned __int64)INVALID_XUID) + { + hash ^= 0x0100000000000001ULL; + } + return (PlayerUID)hash; + } } #endif diff --git a/Minecraft.World/x64headers/extraX64.h b/Minecraft.World/x64headers/extraX64.h index b89998ac..f75db367 100644 --- a/Minecraft.World/x64headers/extraX64.h +++ b/Minecraft.World/x64headers/extraX64.h @@ -220,6 +220,7 @@ public: bool m_isRemote; bool m_isHostPlayer; wchar_t m_gamertag[32]; + PlayerUID m_playerUID; private: ULONG_PTR m_customData; };