diff --git a/mcpe/ExtendedCertificate.h b/mcpe/ExtendedCertificate.h new file mode 100644 index 0000000..a9e308c --- /dev/null +++ b/mcpe/ExtendedCertificate.h @@ -0,0 +1,7 @@ +#pragma once + +class ExtendedCertificate { + +public: + static mcpe::string (*ExtendedCertificate_getXuid)(ExtendedCertificate*); +}; diff --git a/mcpe/UUID.h b/mcpe/UUID.h index 5c2c7b2..16bec32 100644 --- a/mcpe/UUID.h +++ b/mcpe/UUID.h @@ -1,14 +1,51 @@ #pragma once +#include +#include +#include +#include + +namespace { + +inline uint64_t fnv1a_64(const std::string& s) { + uint64_t hash = 14695981039346656037ULL; + for (unsigned char c : s) { + hash ^= c; + hash *= 1099511628211ULL; + } + return hash; +} + +} + namespace mce { class UUID { public: - static UUID* EMPTY; + static mce::UUID (*fromString)(mcpe::string const&); + char filler[0x14]; + static inline mce::UUID fromText(const std::string& text) { + uint64_t h1 = fnv1a_64(text); + uint64_t h2 = fnv1a_64("salt:" + text); + + uint16_t version = ((h1 >> 16) & 0x0FFF) | 0x5000; // v5 + uint16_t variant = ((h2 >> 48) & 0x3FFF) | 0x8000; + + std::ostringstream oss; + oss << std::hex << std::setfill('0') + << std::setw(8) << (uint32_t)(h1 >> 32) << "-" + << std::setw(4) << (uint16_t)(h1 >> 16) << "-" + << std::setw(4) << version << "-" + << std::setw(4) << variant << "-" + << std::setw(12) << (h2 & 0xFFFFFFFFFFFFULL); + + mcpe::string uuidStr(oss.str().c_str()); + return fromString(uuidStr); + } }; -} \ No newline at end of file +} diff --git a/mcpe/types.cpp b/mcpe/types.cpp index 2bffd29..95aabc5 100644 --- a/mcpe/types.cpp +++ b/mcpe/types.cpp @@ -127,6 +127,7 @@ void (*ServerInstance::ServerInstance_update)(ServerInstance*); #include "UUID.h" mce::UUID* mce::UUID::EMPTY; +mce::UUID (*mce::UUID::fromString)(mcpe::string const&); #include "ResourcePackStack.h" @@ -148,4 +149,8 @@ MCRESULT (*MinecraftCommands::MinecraftCommands_requestCommandExecution)(Minecra #include "DedicatedServerCommandOrigin.h" -void (*DedicatedServerCommandOrigin::DedicatedServerCommandOrigin_construct)(DedicatedServerCommandOrigin*, mcpe::string const&, Minecraft&); \ No newline at end of file +void (*DedicatedServerCommandOrigin::DedicatedServerCommandOrigin_construct)(DedicatedServerCommandOrigin*, mcpe::string const&, Minecraft&); + +#include "ExtendedCertificate.h" + +mcpe::string (*ExtendedCertificate::ExtendedCertificate_getXuid)(ExtendedCertificate*); \ No newline at end of file diff --git a/src/server.cpp b/src/server.cpp index aaeb1a3..d58352a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -31,6 +31,7 @@ #include "../mcpe/UUID.h" #include "../mcpe/ResourcePackStack.h" #include "../mcpe/Scheduler.h" +#include "../mcpe/ExtendedCertificate.h" extern "C" { @@ -40,8 +41,6 @@ extern "C" { } -MinecraftEventing* g_eventingInstance = nullptr; - void stubFunc() {} void detachFromJavaStub() { @@ -65,6 +64,11 @@ void handleTextPacketStub() { std::cout << "chat message\n"; } +mce::UUID getIdentityStub(ExtendedCertificate* cert) { + mcpe::string xuid = ExtendedCertificate::ExtendedCertificate_getXuid(cert); + return mce::UUID::fromText(std::string(xuid.c_str())); +} + using namespace std; int main(int argc, char *argv[]) { @@ -145,6 +149,15 @@ int main(int argc, char *argv[]) { patchOff = (unsigned int) hybris_dlsym(handle, "_ZN20ServerNetworkHandler6handleERK17NetworkIdentifierRK10TextPacket"); patchCallInstruction((void*) patchOff, (void*) &handleTextPacketStub, true); + // murdle: this is a patch to make player data save via your username + // this makes it easy to just switch devices and have the same inventory and position + + bool onlineMode = ServerProperties::instance().getBool("online-mode", false); + if (!onlineMode) { + patchOff = (unsigned int) hybris_dlsym(handle, "_ZN19ExtendedCertificate11getIdentityERK11Certificate"); + patchCallInstruction((void*) patchOff, (void*) &getIdentityStub, true); + } + mcpe::string::empty = (mcpe::string*) hybris_dlsym(handle, "_ZN4Util12EMPTY_STRINGE"); std::cout << "patches applied!\n"; @@ -161,6 +174,7 @@ int main(int argc, char *argv[]) { // server functions ((void*&) mce::UUID::EMPTY) = hybris_dlsym(handle, "_ZN3mce4UUID5EMPTYE"); + ((void*&) mce::UUID::fromString) = hybris_dlsym(handle, "_ZN3mce4UUID10fromStringERKSs"); ((void*&) FilePathManager::FilePathManager_construct) = hybris_dlsym(handle, "_ZN15FilePathManagerC2ESsb"); ((void*&) FilePathManager::FilePathManager_getRootPath) = hybris_dlsym(handle, "_ZNK15FilePathManager11getRootPathEv"); @@ -173,6 +187,7 @@ int main(int argc, char *argv[]) { ((void*&) Social::XboxLiveUserManager::XboxLiveUserManager_construct) = hybris_dlsym(handle, "_ZN6Social19XboxLiveUserManagerC2ER11ScreenStack"); ((void*&) Social::UserManager::UserManager_construct) = hybris_dlsym(handle, "_ZN6Social11UserManagerC2Ev"); ((void*&) Social::UserManager::UserManager_addUser) = hybris_dlsym(handle, "_ZN6Social11UserManager7addUserESt10unique_ptrINS_19XboxLiveUserManagerESt14default_deleteIS2_EEi"); + ((void*&) ExtendedCertificate::ExtendedCertificate_getXuid) = hybris_dlsym(handle, "_ZN19ExtendedCertificate7getXuidERK11Certificate"); ((void*&) MinecraftEventing::MinecraftEventing_construct) = hybris_dlsym(handle, "_ZN17MinecraftEventingC2ERKSs"); ((void*&) EntitlementManager::EntitlementManager_construct) = hybris_dlsym(handle, "_ZN18EntitlementManagerC2ER17MinecraftEventingRN6Social11UserManagerE"); @@ -284,7 +299,7 @@ int main(int argc, char *argv[]) { ServerProperties::instance().getInt("server-port", 19132), ServerProperties::instance().getInt("server-port-v6", 19133), ServerProperties::instance().getInt("max-players", 20), - ServerProperties::instance().getBool("online-mode", false), + onlineMode, {}, "normal", false,