diff --git a/AmethystAPI/CMakeLists.txt b/AmethystAPI/CMakeLists.txt index beedafdd..73ebdb36 100644 --- a/AmethystAPI/CMakeLists.txt +++ b/AmethystAPI/CMakeLists.txt @@ -6,7 +6,7 @@ FetchContent_Declare( GIT_REPOSITORY https://github.com/BasedInc/libhat.git GIT_TAG 9ef05d6961ce37a4c801f11159de895aa21878a9 ) -FetchContent_MakeAvailable(libhat) +FetchContent_MakeAvailable(libhat) file(GLOB_RECURSE AmethystAPI_All "src/*.cpp" diff --git a/AmethystAPI/src/amethyst/Config.cpp b/AmethystAPI/src/amethyst/Config.cpp index a6ace4f9..3ce14daf 100644 --- a/AmethystAPI/src/amethyst/Config.cpp +++ b/AmethystAPI/src/amethyst/Config.cpp @@ -1,9 +1,5 @@ #include "amethyst/Config.hpp" -Config::Config() -{ -} - Config::Config(std::string& text) { // Parse config.json into json @@ -13,26 +9,25 @@ Config::Config(std::string& text) data = json::parse(text); } catch (std::exception e) { - Log::Error("Failed to parse config.json"); - throw e; + Assert("Failed to parse config file 'launcher_config.json'"); } // Verify all fields are correct in config.json if (!data["runtime"].is_string()) { - throw std::exception("Required field \"runtime\" should be of type \"string\" in config.json"); + Assert("Required field \"runtime\" should be of type \"string\" in config.json"); } if (!data["mods"].is_array()) { - throw std::exception("Required field \"mods\" should be of type \"string[]\" in config.json"); + Assert("Required field \"mods\" should be of type \"string[]\" in config.json"); } if (!data["developer_mode"].is_boolean()) { - throw std::exception("Required field \"developer_mode\" should be of type \"boolean\" in config.json"); + Assert("Required field \"developer_mode\" should be of type \"boolean\" in config.json"); } for (const auto& element : data["mods"]) { if (!element.is_string()) { - throw std::exception("Array \"mods\" in config.json should only contain strings"); + Assert("Array \"mods\" in config.json should only contain strings"); } } diff --git a/AmethystAPI/src/amethyst/Config.hpp b/AmethystAPI/src/amethyst/Config.hpp index 86a44711..291bb026 100644 --- a/AmethystAPI/src/amethyst/Config.hpp +++ b/AmethystAPI/src/amethyst/Config.hpp @@ -13,6 +13,6 @@ class Config { bool promptDebugger; public: - Config(); + Config() = default; Config(std::string& text); }; \ No newline at end of file diff --git a/AmethystAPI/src/amethyst/Log.cpp b/AmethystAPI/src/amethyst/Log.cpp index 88397326..ef84cd53 100644 --- a/AmethystAPI/src/amethyst/Log.cpp +++ b/AmethystAPI/src/amethyst/Log.cpp @@ -1,28 +1,34 @@ #include "amethyst/Log.hpp" namespace Log { -FILE* fp; + FILE* fp; -void InitializeConsole() -{ - // Initialize console with stdout/stderr - AllocConsole(); - freopen_s(&fp, "CONOUT$", "w", stdout); - freopen_s(&fp, "CONOUT$", "w", stderr); + void InitializeConsole() + { + // Initialize console with stdout/stderr + AllocConsole(); + freopen_s(&fp, "CONOUT$", "w", stdout); + freopen_s(&fp, "CONOUT$", "w", stderr); - // Enable ANSI-Escape codes for colours - HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD consoleMode; + // Enable ANSI-Escape codes for colours + HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD consoleMode; - GetConsoleMode(consoleHandle, &consoleMode); - consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - SetConsoleMode(consoleHandle, consoleMode); - SetConsoleTitle("AmethystAPI"); -} + GetConsoleMode(consoleHandle, &consoleMode); + consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(consoleHandle, consoleMode); + SetConsoleTitle("AmethystAPI"); + } -void DestroyConsole() -{ - fclose(fp); - FreeConsole(); -} + void DestroyConsole() + { + fclose(fp); + FreeConsole(); + } + + void HideConsole() + { + HWND consoleWindow = GetConsoleWindow(); + ShowWindow(consoleWindow, SW_HIDE); + } } // namespace Log \ No newline at end of file diff --git a/AmethystAPI/src/amethyst/Log.hpp b/AmethystAPI/src/amethyst/Log.hpp index 2d9ac27f..271cb28a 100644 --- a/AmethystAPI/src/amethyst/Log.hpp +++ b/AmethystAPI/src/amethyst/Log.hpp @@ -10,6 +10,7 @@ namespace Log { void InitializeConsole(); void DestroyConsole(); + void HideConsole(); template void Info(fmt::format_string fmt, T&&... args) { diff --git a/AmethystAPI/src/amethyst/MinecraftVtables.cpp b/AmethystAPI/src/amethyst/MinecraftVtables.cpp index 20ee5e51..f37309c1 100644 --- a/AmethystAPI/src/amethyst/MinecraftVtables.cpp +++ b/AmethystAPI/src/amethyst/MinecraftVtables.cpp @@ -71,7 +71,7 @@ void InitializeVtablePtrs() { InitializeVtbl(BlockActorRenderer_vtable, "48 8D 05 ? ? ? ? 48 89 06 48 8D 05 ? ? ? ? 48 89 46 ? 40 88 BE"); - Packet_vtable = (void*)SlideAddress(0x5389A20); + Packet_vtable = (void*)SlideAddress(0x4CB18D0); // 1.21.0.3 ChestBlock_vtable = (void*)SlideAddress(0x4E37018); InitializeCtor(ChestBlock_ctor, "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B 05 ? ? ? ? 48 8B D9 4C 8B 15"); diff --git a/AmethystAPI/src/amethyst/Utility.cpp b/AmethystAPI/src/amethyst/Utility.cpp index 39f6ec73..d5c2a49a 100644 --- a/AmethystAPI/src/amethyst/Utility.cpp +++ b/AmethystAPI/src/amethyst/Utility.cpp @@ -1,25 +1,15 @@ #include "amethyst/Utility.hpp" -#include -std::string GetAmethystFolder() +fs::path GetComMojangPath() { - static std::string amethystFolder; - - if (amethystFolder.empty()) { - char* path; - size_t path_length; - errno_t err = _dupenv_s(&path, &path_length, "LocalAppData"); - - if (err) throw std::exception("Failed to get environment variable %LocalAppData%"); - if (path == nullptr) throw std::exception("%LocalAppData% was null"); - - std::string localAppDataFolder(path); - free(path); - - amethystFolder = localAppDataFolder + "/Amethyst/"; - } + StorageFolder localFolder = ApplicationData::Current().LocalFolder(); + fs::path localPath = localFolder.Path().c_str(); + return localPath / L"games" / L"com.mojang"; +} - return amethystFolder; +fs::path GetAmethystFolder() +{ + return GetComMojangPath() / L"amethyst"; } std::string StringFromWstring(std::wstring wstring) diff --git a/AmethystAPI/src/amethyst/Utility.hpp b/AmethystAPI/src/amethyst/Utility.hpp index 89b17065..451ffc19 100644 --- a/AmethystAPI/src/amethyst/Utility.hpp +++ b/AmethystAPI/src/amethyst/Utility.hpp @@ -1,10 +1,25 @@ #pragma once #include +#include +#include +#include +#include +#include "windows.h" + +namespace fs = std::filesystem; +using namespace winrt; +using namespace Windows::Storage; + +/* +Returns a path to Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang +*/ +fs::path GetComMojangPath(); + +/* +Returns a path to com.mojang/amethyst +*/ +fs::path GetAmethystFolder(); -/** - * Returns the path to the amethyst UWP folder - */ -std::string GetAmethystFolder(); std::string StringFromWstring(std::wstring wstring); std::wstring WstringFromString(std::string string); \ No newline at end of file diff --git a/AmethystAPI/src/amethyst/runtime/mod/Mod.cpp b/AmethystAPI/src/amethyst/runtime/mod/Mod.cpp index 91f70e0f..375d83da 100644 --- a/AmethystAPI/src/amethyst/runtime/mod/Mod.cpp +++ b/AmethystAPI/src/amethyst/runtime/mod/Mod.cpp @@ -38,7 +38,7 @@ void Mod::Shutdown() Mod::Metadata Mod::GetMetadata(std::string modName) { // Ensure the mod exists - std::string modConfigPath = GetAmethystFolder() + "mods/" + modName + "/" + "mod.json"; + fs::path modConfigPath = GetAmethystFolder() / L"mods" / modName / L"mod.json"; if (!fs::exists(modConfigPath)) { Assert("[AmethystRuntime] mod.json could not be found, for {}!", modName); @@ -121,10 +121,10 @@ fs::path Mod::GetTempDll() } // Ensure temp directory exists - fs::path tempDir = GetAmethystFolder() + "temp/" + modName + "/"; + fs::path tempDir = GetAmethystFolder() / L"Temp" / modName; if (!fs::exists(tempDir)) fs::create_directories(tempDir); - fs::path originalDll = GetAmethystFolder() + "mods/" + modName + "/" + modShortened + ".dll"; + fs::path originalDll = GetAmethystFolder() / L"Mods" / modName / std::string(modShortened + ".dll"); if (!fs::exists(originalDll)) { Assert("[AmethystRuntime] Could not find '{}.dll'", modShortened); } diff --git a/AmethystAPI/src/minecraft/src/common/network/IPacketHandlerDispatcher.hpp b/AmethystAPI/src/minecraft/src/common/network/IPacketHandlerDispatcher.hpp new file mode 100644 index 00000000..e69de29b diff --git a/AmethystAPI/src/minecraft/src/common/world/actor/Actor.hpp b/AmethystAPI/src/minecraft/src/common/world/actor/Actor.hpp index 77d55729..14e81219 100644 --- a/AmethystAPI/src/minecraft/src/common/world/actor/Actor.hpp +++ b/AmethystAPI/src/minecraft/src/common/world/actor/Actor.hpp @@ -23,9 +23,9 @@ class Actor { public: /* this + 0 */ uintptr_t** vtable; /* this + 8 */ EntityContext mEntityContext; - /* this + 32 */ std::byte padding32[552]; - /* this + 584 */ std::weak_ptr mDimension; // moved -8 in 1.21 - /* this + 600 */ std::byte padding600[56]; + /* this + 32 */ std::byte padding32[544]; + /* this + 576 */ std::weak_ptr mDimension; // moved -16 in 1.21 + /* this + 592 */ std::byte padding592[64]; /* this + 656 */ BuiltInActorComponents mBuiltInComponents; // 1.21 /* this + 688 */ std::byte padding688[536]; diff --git a/AmethystAPI/src/minecraft/src/common/world/level/Level.hpp b/AmethystAPI/src/minecraft/src/common/world/level/Level.hpp index 8c4a7991..abc54b2f 100644 --- a/AmethystAPI/src/minecraft/src/common/world/level/Level.hpp +++ b/AmethystAPI/src/minecraft/src/common/world/level/Level.hpp @@ -11,8 +11,12 @@ class Level { public: /* this + 0 */ std::byte padding0[840]; /* this + 840 */ const ItemRegistryRef mItemRegistry; - /* this + 856 */ std::byte padding856[1976]; - /* this + 2832 */ PacketSender* mPacketSender; - /* this + 2840 */ std::byte padding2840[2680]; - /* this + 5520 */ bool isClientSide; // -81 in 1.21 -}; \ No newline at end of file + /* this + 856 */ std::byte padding856[2008]; + /* this + 2864 */ PacketSender* mPacketSender; + /* this + 2872 */ std::byte padding2872[2648]; + /* this + 5520 */ bool isClientSide; +}; + +// 1.21.0.3 +static_assert(offsetof(Level, mPacketSender) == 2864); +static_assert(offsetof(Level, isClientSide) == 5520); \ No newline at end of file diff --git a/AmethystRuntime/CMakeLists.txt b/AmethystRuntime/CMakeLists.txt index 5aec697e..9c471856 100644 --- a/AmethystRuntime/CMakeLists.txt +++ b/AmethystRuntime/CMakeLists.txt @@ -7,13 +7,13 @@ set(MOD_TARGET_VERSION_MINOR 21) set(MOD_TARGET_VERSION_PATCH 3) # Amethyst Minecraft Folder -set(AmethystFolder "$ENV{localappdata}/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/AC/Amethyst/") +set(AmethystFolder "$ENV{localappdata}/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/amethyst/") # Configure to build within the Amethyst Folder configure_file(mod.json.in "${AmethystFolder}/mods/AmethystRuntime@${MOD_VERSION}/mod.json" @ONLY) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${AmethystFolder}/mods/AmethystRuntime@${MOD_VERSION}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${AmethystFolder}/mods/AmethystRuntime@${MOD_VERSION}") -# Create AmethystRuntime +# Create AmethystRuntime file(GLOB_RECURSE AmethystRuntime_All "src/*.cpp" "src/*.c" diff --git a/AmethystRuntime/src/AmethystDebugging.hpp b/AmethystRuntime/src/AmethystDebugging.hpp index 1399757b..6baa37ff 100644 --- a/AmethystRuntime/src/AmethystDebugging.hpp +++ b/AmethystRuntime/src/AmethystDebugging.hpp @@ -5,7 +5,7 @@ #include #include -static void LogAssemblyOfExceptionCause(uintptr_t address) +static void LogAssemblyOfExceptionCause(uintptr_t address) { ZydisDecoder decoder; ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); diff --git a/AmethystRuntime/src/AmethystRuntime.cpp b/AmethystRuntime/src/AmethystRuntime.cpp index dc07c8fd..6af328f8 100644 --- a/AmethystRuntime/src/AmethystRuntime.cpp +++ b/AmethystRuntime/src/AmethystRuntime.cpp @@ -39,7 +39,7 @@ void AmethystRuntime::Start() void AmethystRuntime::ReadLauncherConfig() { // Ensure it exists - std::string launcherConfigPath = GetAmethystFolder() + "launcher_config.json"; + fs::path launcherConfigPath = GetAmethystFolder() / "launcher_config.json"; if (!fs::exists(launcherConfigPath)) { throw std::exception("launcher_config.json could not be found!");