diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 83d3d24..3b7e6af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,7 @@ jobs: uses: actions/checkout@v2 - name: Configure - run: cmake -B build -A Win32 + run: cmake -B build -A x64 - name: Build run: cmake --build build --config Release --parallel diff --git a/CMakeLists.txt b/CMakeLists.txt index ea04c61..b2760a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ endif() project(Kanan) -set(VCPKG_TARGET_TRIPLET x86-windows-static) +set(VCPKG_TARGET_TRIPLET x64-windows-static) if(CMKR_ROOT_PROJECT AND NOT CMKR_DISABLE_VCPKG) include(FetchContent) @@ -197,16 +197,12 @@ list(APPEND Kanan_SOURCES "Kanan/LoginScreen.hpp" "Kanan/Mabinogi.hpp" "Kanan/Mabinogi/CAccount.hpp" - "Kanan/Mabinogi/CAccountPtr.hpp" "Kanan/Mabinogi/CCharacter.hpp" "Kanan/Mabinogi/CEntityList.hpp" - "Kanan/Mabinogi/CEntityListPtr.hpp" "Kanan/Mabinogi/CItem.hpp" "Kanan/Mabinogi/CRenderer.hpp" - "Kanan/Mabinogi/CRendererPtr.hpp" "Kanan/Mabinogi/CString.hpp" "Kanan/Mabinogi/CWorld.hpp" - "Kanan/Mabinogi/CWorldPtr.hpp" "Kanan/Mabinogi/Matrix4x4.hpp" "Kanan/Mabinogi/Vector3.hpp" "Kanan/Mabinogi/Vector4.hpp" @@ -257,6 +253,13 @@ set_target_properties(Kanan PROPERTIES MultiThreaded$<$:Debug> ) +# Copy Kanan/Patches.json to the output directory. +add_custom_command(TARGET Kanan POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/Kanan/Patches.json + $ +) + unset(CMKR_TARGET) unset(CMKR_SOURCES) @@ -291,7 +294,7 @@ target_link_libraries(Loader PRIVATE ) target_link_options(Loader PRIVATE - "/MANIFESTUAC:level=requireAdministrator" + "/MANIFESTUAC:level='requireAdministrator'" ) set_target_properties(Loader PROPERTIES @@ -299,6 +302,13 @@ set_target_properties(Loader PROPERTIES MultiThreaded$<$:Debug> ) +# Copy Loader/Loader.txt to the output directory +add_custom_command(TARGET Loader POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/Loader/Loader.txt + $ +) + unset(CMKR_TARGET) unset(CMKR_SOURCES) @@ -367,7 +377,7 @@ target_link_libraries(Launcher PRIVATE ) target_link_options(Launcher PRIVATE - "/MANIFESTUAC:level=requireAdministrator" + "/MANIFESTUAC:level='requireAdministrator'" ) set_target_properties(Launcher PROPERTIES diff --git a/Kanan/AutoChangeChannels.cpp b/Kanan/AutoChangeChannels.cpp index 819f613..052ab74 100644 --- a/Kanan/AutoChangeChannels.cpp +++ b/Kanan/AutoChangeChannels.cpp @@ -71,10 +71,10 @@ void AutoChangeChannels::onFrame() { } auto& characters = ents->characters; - auto node = characters.root; + auto node = *characters.root; - for (uint32_t i = 0; i <= characters.count && node != nullptr; ++i, node = node->next) { - auto character = (KCharacter*)node->entry->character; + for (uint32_t i = 0; i < characters.count && node != nullptr; ++i, node = node->next) { + auto character = (KCharacter*)node->character; if (character == nullptr) { continue; diff --git a/Kanan/CookingMod.cpp b/Kanan/CookingMod.cpp index 370147a..30942a1 100644 --- a/Kanan/CookingMod.cpp +++ b/Kanan/CookingMod.cpp @@ -29,6 +29,7 @@ namespace kanan { //the asm we want to inject +#if 0 void __declspec(naked) HookForCooking() { __asm @@ -45,8 +46,11 @@ namespace kanan { ret } - } +#else + void HookForCooking() { + } +#endif //the code i use for injecting stuff diff --git a/Kanan/EnableMultiClient.cpp b/Kanan/EnableMultiClient.cpp index bf5a756..6b92d2e 100644 --- a/Kanan/EnableMultiClient.cpp +++ b/Kanan/EnableMultiClient.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "Log.hpp" #include "EnableMultiClient.hpp" @@ -14,12 +15,12 @@ namespace kanan { { log("Entering EnableMultiClient."); - auto address = scan("client.exe", "B9 ? ? ? ? E8 ? ? ? ? 84 C0 74 ? 8B 0D ? ? ? ? 8D 45 C0"); + auto address = scan("client.exe", "48 8D 0D ? ? ? ? E8 ? ? ? ? 84 C0 74 ? 48 8B 0D ? ? ? ? E8 ? ? ? ?"); if (address) { log("Got EnableMultiClient %p", *address); - m_handlePtr = (HANDLE**)(*address + 1); + m_handlePtr = (HANDLE*)rel_to_abs(*address + 3); } else { log("Failed to find EnableMultiClient address."); @@ -72,12 +73,12 @@ namespace kanan { log("Toggling EnableMultiClient..."); - if (SetHandleInformation(**m_handlePtr, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0) == FALSE) { + if (SetHandleInformation(*m_handlePtr, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0) == FALSE) { log("Failed to SetHandleInformation on the handle %p", *m_handlePtr); return; } - if (CloseHandle(**m_handlePtr) == FALSE) { + if (CloseHandle(*m_handlePtr) == FALSE) { log("Failed to CloseHandle on the handle %p", *m_handlePtr); return; } diff --git a/Kanan/EnableMultiClient.hpp b/Kanan/EnableMultiClient.hpp index c0fa4cb..8285039 100644 --- a/Kanan/EnableMultiClient.hpp +++ b/Kanan/EnableMultiClient.hpp @@ -16,7 +16,7 @@ namespace kanan { private: bool m_isEnabled; - HANDLE** m_handlePtr; + HANDLE* m_handlePtr; void apply(); }; diff --git a/Kanan/EntityViewer.cpp b/Kanan/EntityViewer.cpp index 7fe9303..f0fa514 100644 --- a/Kanan/EntityViewer.cpp +++ b/Kanan/EntityViewer.cpp @@ -81,10 +81,10 @@ namespace kanan { auto& characters = entityList->characters; auto highestIndex = characters.count; - auto node = characters.root; + auto node = *characters.root; - for (uint32_t i = 0; i <= highestIndex && node != nullptr; ++i, node = node->next) { - auto character = (KCharacter*)node->entry->character; + for (uint32_t i = 0; i < highestIndex && node != nullptr; ++i, node = node->next) { + auto character = (KCharacter*)node->character; if (character == nullptr || !character->getID()) { continue; @@ -114,10 +114,10 @@ namespace kanan { auto& items = entityList->items; auto highestIndex = items.count; - auto node = items.root; + auto node = *items.root; - for (uint32_t i = 0; i <= highestIndex && node != nullptr; ++i, node = node->next) { - auto item = (KItem*)node->entry->item; + for (uint32_t i = 0; i < highestIndex && node != nullptr; ++i, node = node->next) { + auto item = (KItem*)node->item; if (item == nullptr || !item->getID()) { continue; diff --git a/Kanan/EquipmentOverride.cpp b/Kanan/EquipmentOverride.cpp index 20ce2f5..829f4e3 100644 --- a/Kanan/EquipmentOverride.cpp +++ b/Kanan/EquipmentOverride.cpp @@ -143,7 +143,7 @@ namespace kanan { m_equipmentOverrides[17].name = "Accessory 2"; m_equipmentOverrides[18].name = "Tail"; - if (auto call_address = scan("client.exe", "E8 ? ? ? ? C7 45 FC ? ? ? ? 8D 4D C0 E8 ? ? ? ? 8B 45 B8")) { + if (auto call_address = scan("client.exe", "E8 ? ? ? ? 90 E9 ? ? ? ? 44 39 B6 A4 1B 00 00")) { log("[EquipmentOverride] Found address of call setEquipmentInfo %p", *call_address); auto set_equip_info = rel_to_abs(*call_address + 1); @@ -247,7 +247,7 @@ namespace kanan { } } - void EquipmentOverride::hookedSetEquipmentInfo(CCharacter::CEquipment* equipment, uint32_t EDX, int inventoryID, int itemID, int a4, int a5, uint32_t* color, int a7, int * a8, int a9, int a10, int * a11) { + void EquipmentOverride::hookedSetEquipmentInfo(CCharacter::CEquipment* equipment,int inventoryID, int itemID, int a4, int a5, uint32_t* color, uint64_t a7, int * a8, int a9, int a10, int * a11) { auto orig = (decltype(hookedSetEquipmentInfo)*)g_equipmentOverride->m_setEquipmentInfoHook->getOriginal(); auto equipmentSlot = convertInventoryIDToEquipmentSlot(inventoryID); @@ -264,12 +264,12 @@ namespace kanan { auto localCharacter = game->getLocalCharacter(); if (localCharacter == nullptr || equipment != localCharacter->equipment) { - return orig(equipment, EDX, inventoryID, itemID, a4, a5, color, a7, a8, a9, a10, a11); + return orig(equipment, inventoryID, itemID, a4, a5, color, a7, a8, a9, a10, a11); } // Filter out inventoryIDs. if (equipmentSlot < 0 || equipmentSlot >= (int)g_equipmentOverride->m_equipmentOverrides.size()) { - return orig(equipment, EDX, inventoryID, itemID, a4, a5, color, a7, a8, a9, a10, a11); + return orig(equipment, inventoryID, itemID, a4, a5, color, a7, a8, a9, a10, a11); } auto& overrideInfo = g_equipmentOverride->m_equipmentOverrides[equipmentSlot]; @@ -292,6 +292,6 @@ namespace kanan { log("[EquipmentOverride] Item overwritten!"); } - return orig(equipment, EDX, inventoryID, itemID, a4, a5, color, a7, a8, a9, a10, a11); + return orig(equipment, inventoryID, itemID, a4, a5, color, a7, a8, a9, a10, a11); } } diff --git a/Kanan/EquipmentOverride.hpp b/Kanan/EquipmentOverride.hpp index 388b4d2..21947a1 100644 --- a/Kanan/EquipmentOverride.hpp +++ b/Kanan/EquipmentOverride.hpp @@ -40,6 +40,6 @@ namespace kanan { std::unique_ptr m_setEquipmentInfoHook; bool m_isNoFlashyEquipmentEnabled; - static void __fastcall hookedSetEquipmentInfo(CCharacter::CEquipment* equipment, uint32_t EDX, int inventoryID, int itemID, int a4, int a5, uint32_t* color, int a7, int* a8, int a9, int a10, int* a11); + static void hookedSetEquipmentInfo(CCharacter::CEquipment* equipment, int inventoryID, int itemID, int a4, int a5, uint32_t* color, uint64_t a7, int* a8, int a9, int a10, int* a11); }; } \ No newline at end of file diff --git a/Kanan/FreezeTimeOfDay.cpp b/Kanan/FreezeTimeOfDay.cpp index 156af8b..478f20f 100644 --- a/Kanan/FreezeTimeOfDay.cpp +++ b/Kanan/FreezeTimeOfDay.cpp @@ -19,7 +19,7 @@ namespace kanan { g_freezeTimeOfDay = this; - auto address = scan("client.exe", "55 8B EC 8B 01 F3 0F 10 45 08 F3 0F 11 40 0C"); + auto address = scan("client.exe", "48 8B 01 F3 0F 11 48 18"); if (address) { log("[FreezeTimeOfDay] Found address for setTimeOfDay %p", *address); diff --git a/Kanan/Game.cpp b/Kanan/Game.cpp index 68c4026..3c8c100 100644 --- a/Kanan/Game.cpp +++ b/Kanan/Game.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "Log.hpp" #include "Game.hpp" @@ -8,59 +9,67 @@ using namespace std; namespace kanan { Game::Game() - : m_rendererPtr{ nullptr }, - m_entityListPtr{ nullptr }, - m_worldPtr{nullptr}, - m_accountPtr{nullptr} + : m_renderer{ nullptr }, + m_entityList{ nullptr }, + m_world{nullptr}, + m_account{nullptr} { log("Entering Game constructor."); // Find the games global renderer pointer. - auto rendererAddress = scan("client.exe", "8B 0D ? ? ? ? 8D 45 DC 6A ? 6A ? 50"); + auto rendererAddress = scan("client.exe", "48 8B 0D ? ? ? ? E8 ? ? ? ? 84 C0 74 ? C7 07 ? ? ? ? 32 C0"); if (rendererAddress) { - m_rendererPtr = *(CRendererPtr**)(*rendererAddress + 2); + do { + m_renderer = (CRenderer**)rel_to_abs(*rendererAddress + 3); + } while (*m_renderer == nullptr); - log("Got CRendererPtr %p", m_rendererPtr); + log("Got CRenderer %p", *m_renderer); } else { - error("Failed to find address of CRendererPtr."); + error("Failed to find address of CRenderer."); } // Find the games global entity list pointer. - auto entityListAddress = scan("client.exe", "8B 0D ? ? ? ? 56 FF 75 08 E8 ? ? ? ? 85 C0 0F 84 ? ? ? ?"); + auto entityListAddress = scan("client.exe", "48 8B 0D ? ? ? ? E8 ? ? ? ? 48 85 C0 0F 84 ? ? ? ? 48 8B 0D ? ? ? ? 48 8B 91 60 01 00 00 E8 ? ? ? ?"); if (entityListAddress) { - m_entityListPtr = *(CEntityListPtr**)(*entityListAddress + 2); + do { + m_entityList = (CEntityList**)rel_to_abs(*entityListAddress + 3); + } while (*m_entityList == nullptr); - log("Got CEntityListPtr %p", m_entityListPtr); + log("Got CEntityList %p", *m_entityList); } else { - error("Failed to find CEntityListPtr."); + error("Failed to find CEntityList."); } // Find the games global world pointer. - auto worldAddress = scan("client.exe", "A1 ? ? ? ? 8B 48 1C E8 ? ? ? ? 0F B6 C0"); + auto worldAddress = scan("client.exe", "48 8B 0D ? ? ? ? E8 ? ? ? ? 84 C0 0F 85 ? ? ? ? 48 8B 86 A0 01 00 00"); if (worldAddress) { - m_worldPtr = *(CWorldPtr**)(*worldAddress + 1); + do { + m_world = (CWorld**)rel_to_abs(*worldAddress + 3); + } while (*m_world == nullptr); - log("Got CWorldPtr %p", m_worldPtr); + log("Got CWorld %p", *m_world); } else { - error("Failed to find CWorldPtr."); + error("Failed to find CWorld."); } // Find the games global account pointer. - auto accountAddress = scan("client.exe", "8B 0D ? ? ? ? 6A ? 6A ? 53 E8 ? ? ? ? 8B 06"); + auto accountAddress = scan("client.exe", "48 8B 0D ? ? ? ? E8 ? ? ? ? 84 C0 74 ? 49 8B CE E8 ? ? ? ? 84 C0 75 ? 49 8B 06"); if (accountAddress) { - m_accountPtr = *(CAccountPtr**)(*accountAddress + 2); + do { + m_account = (CAccount**)rel_to_abs(*accountAddress + 3); + } while (*m_account == nullptr); - log("Got CAccountPtr %p", m_accountPtr); + log("Got CAccount %p", *m_account); } else { - error("Failed to find CAccountPtr."); + error("Failed to find CAccount."); } log("Leaving Game constructor."); @@ -77,10 +86,10 @@ namespace kanan { // ID. auto& characters = entityList->characters; auto highestIndex = characters.count; - auto node = characters.root; + auto node = *characters.root; - for (uint32_t i = 0; i <= highestIndex && node != nullptr; ++i, node = node->next) { - auto character = (KCharacter*)node->entry->character; + for (uint32_t i = 0; i < highestIndex && node != nullptr; ++i, node = node->next) { + auto character = (KCharacter*)node->character; if (character == nullptr) { continue; @@ -149,36 +158,4 @@ namespace kanan { cc(account, &val2, 0, 0); } - - CRenderer* Game::getRenderer() const { - if (m_rendererPtr == nullptr || m_rendererPtr->renderer == nullptr) { - return nullptr; - } - - return m_rendererPtr->renderer; - } - - CEntityList* Game::getEntityList() const { - if (m_entityListPtr == nullptr || m_entityListPtr->entityList == nullptr) { - return nullptr; - } - - return m_entityListPtr->entityList; - } - - CWorld* Game::getWorld() const { - if (m_worldPtr == nullptr || m_worldPtr->world == nullptr) { - return nullptr; - } - - return m_worldPtr->world; - } - - CAccount* Game::getAccount() const { - if (m_accountPtr == nullptr || m_accountPtr->account == nullptr) { - return nullptr; - } - - return m_accountPtr->account; - } - } +} diff --git a/Kanan/Game.hpp b/Kanan/Game.hpp index 776f79a..f858738 100644 --- a/Kanan/Game.hpp +++ b/Kanan/Game.hpp @@ -17,15 +17,15 @@ namespace kanan { void changeChannel(int channel); - CRenderer* getRenderer() const; - CEntityList* getEntityList() const; - CWorld* getWorld() const; - CAccount* getAccount() const; + CRenderer* getRenderer() const { return *m_renderer; } + CEntityList* getEntityList() const { return *m_entityList; } + CWorld* getWorld() const { return *m_world; } + CAccount* getAccount() const { return *m_account; } private: - CRendererPtr* m_rendererPtr; - CEntityListPtr* m_entityListPtr; - CWorldPtr* m_worldPtr; - CAccountPtr* m_accountPtr; + CRenderer** m_renderer; + CEntityList** m_entityList; + CWorld** m_world; + CAccount** m_account; }; } diff --git a/Kanan/Mabinogi.hpp b/Kanan/Mabinogi.hpp index 42cc71c..5ec5e52 100644 --- a/Kanan/Mabinogi.hpp +++ b/Kanan/Mabinogi.hpp @@ -4,14 +4,10 @@ #include #include "Mabinogi/CEntityList.hpp" -#include "Mabinogi/CEntityListPtr.hpp" #include "Mabinogi/CRenderer.hpp" -#include "Mabinogi/CRendererPtr.hpp" #include "Mabinogi/CString.hpp" #include "Mabinogi/CCharacter.hpp" #include "Mabinogi/CItem.hpp" #include "Mabinogi/CWorld.hpp" -#include "Mabinogi/CWorldPtr.hpp" #include "Mabinogi/CAccount.hpp" -#include "Mabinogi/CAccountPtr.hpp" diff --git a/Kanan/Mabinogi/CAccountPtr.hpp b/Kanan/Mabinogi/CAccountPtr.hpp deleted file mode 100644 index da3c38d..0000000 --- a/Kanan/Mabinogi/CAccountPtr.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -class CAccount; -#pragma pack(push, 1) -class CAccountPtr { -public: - CAccount* account; // 0x0 -}; // Size: 0x4 -#pragma pack(pop) diff --git a/Kanan/Mabinogi/CCharacter.hpp b/Kanan/Mabinogi/CCharacter.hpp index e9eed77..e3aa149 100644 --- a/Kanan/Mabinogi/CCharacter.hpp +++ b/Kanan/Mabinogi/CCharacter.hpp @@ -8,107 +8,107 @@ class CCharacter { public: class CMemberString { public: - char pad_0[0x4]; - CString* value; // 0x4 - char pad_8[0x8]; - }; // Size: 0x10 + char pad_0[0x8]; + CString* value; // 0x8 + char pad_10[0x10]; + }; // Size: 0x20 class CMemberChar { public: - char pad_0[0x4]; - int8_t value; // 0x4 - char pad_5[0x7]; - }; // Size: 0xc + char pad_0[0x8]; + int8_t value; // 0x8 + char pad_9[0xf]; + }; // Size: 0x18 class CMemberUChar { public: - char pad_0[0x4]; - uint8_t value; // 0x4 - char pad_5[0x7]; - }; // Size: 0xc + char pad_0[0x8]; + uint8_t value; // 0x8 + char pad_9[0xf]; + }; // Size: 0x18 class CMemberUShort { public: - char pad_0[0x4]; - uint16_t value; // 0x4 - char pad_6[0x6]; - }; // Size: 0xc + char pad_0[0x8]; + uint16_t value; // 0x8 + char pad_a[0xe]; + }; // Size: 0x18 class CMemberULong { public: - char pad_0[0x4]; - uint32_t value; // 0x4 - char pad_8[0x8]; - }; // Size: 0x10 + char pad_0[0x8]; + uint32_t value; // 0x8 + char pad_c[0xc]; + }; // Size: 0x18 class CMemberUInt64 { public: - char pad_0[0x4]; - uint64_t value; // 0x4 - char pad_c[0xc]; - }; // Size: 0x18 + char pad_0[0x8]; + uint64_t value; // 0x8 + char pad_10[0x10]; + }; // Size: 0x20 class CMemberFloat { public: - char pad_0[0x4]; - float value; // 0x4 - char pad_8[0x8]; - }; // Size: 0x10 + char pad_0[0x8]; + float value; // 0x8 + char pad_c[0xc]; + }; // Size: 0x18 - char pad_0[0x20]; - CMemberString name; // 0x20 - CMemberString title; // 0x30 - CMemberString engTitle; // 0x40 - CMemberULong type; // 0x50 - CMemberUChar skinColor; // 0x60 - CMemberUShort eyeType; // 0x6c - CMemberUChar eyeColor; // 0x78 - CMemberUChar mouthType; // 0x84 - CMemberULong status; // 0x90 - CMemberULong statusEx; // 0xa0 - CMemberULong statusEx2; // 0xb0 - CMemberFloat scaleHeight; // 0xc0 - CMemberFloat scaleFatness; // 0xd0 - CMemberFloat scaleUpper; // 0xe0 - CMemberFloat scaleLower; // 0xf0 - CMemberULong regionID; // 0x100 - CMemberULong positionX; // 0x110 - CMemberULong positionY; // 0x120 - CMemberChar direction; // 0x130 - CMemberULong battleState; // 0x13c - CMemberUChar weaponSet; // 0x14c - CMemberULong extra1; // 0x158 - CMemberULong extra2; // 0x168 - CMemberULong extra3; // 0x178 - CMemberFloat combatPower; // 0x188 - CMemberString motionType; // 0x198 - CMemberUChar oddEyeLeftColor; // 0x1a8 - CMemberUChar oddEyeRightColor; // 0x1b4 - CMemberFloat life; // 0x1c0 - CMemberFloat lifeMaxBase; // 0x1d0 - CMemberFloat lifeDamaged; // 0x1e0 - CMemberFloat lifeMaxMod; // 0x1f0 - CMemberFloat mana; // 0x200 - CMemberFloat manaMaxBase; // 0x210 - CMemberFloat manaMaxMod; // 0x220 - CMemberFloat stamina; // 0x230 - CMemberFloat staminaMaxBase; // 0x240 - CMemberFloat staminaMaxMod; // 0x250 - CMemberFloat food; // 0x260 - CMemberFloat foodMinRatio; // 0x270 - CMemberUShort level; // 0x280 - CMemberULong cumulatedLevel; // 0x28c - CMemberUShort maxLevel; // 0x29c - CMemberUShort rebirthCount; // 0x2a8 - CMemberUShort lifeTimeSkill; // 0x2b4 - CMemberUInt64 experienceInt; // 0x2c0 - CMemberUShort age; // 0x2d8 - char pad_2e4[0x798]; - CMemberFloat dorcha; // 0xa7c - CMemberFloat dorchaMaxBase; // 0xa8c - CMemberFloat tuairim; // 0xa9c - CMemberFloat tuairimMaxBase; // 0xaac - }; // Size: 0xabc + char pad_0[0x30]; + CMemberString name; // 0x30 + CMemberString title; // 0x50 + CMemberString engTitle; // 0x70 + CMemberULong type; // 0x90 + CMemberUChar skinColor; // 0xa8 + CMemberUShort eyeType; // 0xc0 + CMemberUChar eyeColor; // 0xd8 + CMemberUChar mouthType; // 0xf0 + CMemberULong status; // 0x108 + CMemberULong statusEx; // 0x120 + CMemberULong statusEx2; // 0x138 + CMemberFloat scaleHeight; // 0x150 + CMemberFloat scaleFatness; // 0x168 + CMemberFloat scaleUpper; // 0x180 + CMemberFloat scaleLower; // 0x198 + CMemberULong regionID; // 0x1b0 + CMemberULong positionX; // 0x1c8 + CMemberULong positionY; // 0x1e0 + CMemberChar direction; // 0x1f8 + CMemberULong battleState; // 0x210 + CMemberUChar weaponSet; // 0x228 + CMemberULong extra1; // 0x240 + CMemberULong extra2; // 0x258 + CMemberULong extra3; // 0x270 + CMemberFloat combatPower; // 0x288 + CMemberString motionType; // 0x2a0 + CMemberUChar oddEyeLeftColor; // 0x2c0 + CMemberUChar oddEyeRightColor; // 0x2d8 + CMemberFloat life; // 0x2f0 + CMemberFloat lifeMaxBase; // 0x308 + CMemberFloat lifeDamaged; // 0x320 + CMemberFloat lifeMaxMod; // 0x338 + CMemberFloat mana; // 0x350 + CMemberFloat manaMaxBase; // 0x368 + CMemberFloat manaMaxMod; // 0x380 + CMemberFloat stamina; // 0x398 + CMemberFloat staminaMaxBase; // 0x3b0 + CMemberFloat staminaMaxMod; // 0x3c8 + CMemberFloat food; // 0x3e0 + CMemberFloat foodMinRatio; // 0x3f8 + CMemberUShort level; // 0x410 + CMemberULong cumulatedLevel; // 0x428 + CMemberUShort maxLevel; // 0x440 + CMemberUShort rebirthCount; // 0x458 + CMemberUShort lifeTimeSkill; // 0x470 + CMemberUInt64 experienceInt; // 0x488 + CMemberUShort age; // 0x4a8 + char pad_4c0[0xd60]; + CMemberFloat dorcha; // 0x1220 + CMemberFloat dorchaMaxBase; // 0x1238 + CMemberFloat tuairim; // 0x1250 + CMemberFloat tuairimMaxBase; // 0x1268 + }; // Size: 0x1280 class CAction { public: @@ -116,33 +116,34 @@ class CCharacter { public: class CFramework { public: - char pad_0[0xa0]; - Vector3 position; // 0xa0 - }; // Size: 0xac + char pad_0[0xd0]; + Vector3 position; // 0xd0 + char pad_dc[0x124]; + }; // Size: 0x200 - char pad_0[0x4]; - CFramework* framework; // 0x4 - }; // Size: 0x8 + char pad_0[0x8]; + CFramework* framework; // 0x8 + }; // Size: 0x10 - char pad_0[0x40]; - CCharacter* character; // 0x40 - CAnimatorContext* animatorContext; // 0x44 - }; // Size: 0x48 + char pad_0[0x48]; + CCharacter* character; // 0x48 + CAnimatorContext* animatorContext; // 0x50 + }; // Size: 0x58 class CSkillMgr { public: class CActiveSkill { public: - char pad_0[0x10]; - uint16_t skillID; // 0x10 - uint8_t charges; // 0x12 - char pad_13[0x9]; - uint8_t state; // 0x1c - }; // Size: 0x1d + char pad_0[0x18]; + uint16_t skillID; // 0x18 + uint8_t charges; // 0x1a + char pad_1b[0x9]; + uint8_t state; // 0x24 + }; // Size: 0x25 - char pad_0[0x4]; - CActiveSkill* skillInfo; // 0x4 - }; // Size: 0x8 + char pad_0[0x8]; + CActiveSkill* skillInfo; // 0x8 + }; // Size: 0x10 class CConditionMgr { public: @@ -153,44 +154,44 @@ class CCharacter { char pad_8[0x1d]; }; // Size: 0x25 - char pad_0[0x8]; - CCondition* condition; // 0x8 - char pad_c[0x44]; + char pad_0[0x10]; + CCondition* condition; // 0x10 + char pad_18[0x38]; }; // Size: 0x50 class CEquipmentItemInfo { public: - char pad_0[0xc]; - uint32_t classID; // 0xc - char pad_10[0xc]; - uint32_t color1; // 0x1c - uint32_t color2; // 0x20 - uint32_t color3; // 0x24 - char pad_28[0x4]; - uint32_t color4; // 0x2c - uint32_t color5; // 0x30 - uint32_t color6; // 0x34 - char pad_38[0x18]; - }; // Size: 0x50 + uint32_t classID; // 0x0 + char pad_4[0xc]; + uint32_t color1; // 0x10 + uint32_t color2; // 0x14 + uint32_t color3; // 0x18 + char pad_1c[0x14]; + uint32_t color4; // 0x30 + uint32_t color5; // 0x34 + uint32_t color6; // 0x38 + char pad_3c[0x1c]; + }; // Size: 0x58 class CEquipment { public: - CCharacter::CEquipmentItemInfo itemInfo[20]; // 0x0 - }; // Size: 0x640 - - char pad_0[0x4]; - uint64_t* entityID; // 0x4 - char pad_8[0xa0]; - CParameter* parameter; // 0xa8 - CAction* action; // 0xac - CSkillMgr* skill; // 0xb0 - char pad_b4[0x10]; - CConditionMgr* condition; // 0xc4 - char pad_c8[0x1b8]; - CEquipment* equipment; // 0x280 - char pad_284[0x54]; - uint64_t targetID; // 0x2d8 - char pad_2e0[0x8]; - uint64_t mouseTarget; // 0x2e8 -}; // Size: 0x2f0 + char pad_0[0x6c]; + CCharacter::CEquipmentItemInfo itemInfo[20]; // 0x6c + }; // Size: 0x74c + + char pad_0[0x8]; + uint64_t* entityID; // 0x8 + char pad_10[0xc8]; + CParameter* parameter; // 0xd8 + CAction* action; // 0xe0 + CSkillMgr* skill; // 0xe8 + char pad_f0[0x20]; + CConditionMgr* condition; // 0x110 + char pad_118[0x370]; + CEquipment* equipment; // 0x488 + char pad_490[0xa8]; + uint64_t targetID; // 0x538 + char pad_540[0x8]; + uint64_t mouseTarget; // 0x548 +}; // Size: 0x550 #pragma pack(pop) diff --git a/Kanan/Mabinogi/CEntityList.hpp b/Kanan/Mabinogi/CEntityList.hpp index 629dd73..c1c1c15 100644 --- a/Kanan/Mabinogi/CEntityList.hpp +++ b/Kanan/Mabinogi/CEntityList.hpp @@ -6,48 +6,37 @@ class CEntityList { public: class CItemList { public: - class CCItemListNode { - }; // Size: 0x0 - class CItemListNode { public: - class CItemListNodeEntry { - public: - char pad_0[0x10]; - CItem* item; // 0x10 - }; // Size: 0x14 - - CItemListNodeEntry* entry; // 0x0 - CEntityList::CItemList::CItemListNode* next; // 0x4 - }; // Size: 0x8 + CEntityList::CItemList::CItemListNode* next; // 0x0 + char pad_8[0x10]; + CItem* item; // 0x18 + }; // Size: 0x20 - char pad_0[0x4]; - CItemListNode* root; // 0x4 - uint32_t count; // 0x8 - }; // Size: 0xc + char pad_0[0x10]; + CItemListNode** root; // 0x10 + uint32_t count; // 0x18 + }; // Size: 0x1c class CCharacterList { public: class CCharacterListNode { public: - class CCharacterListNodeEntry { - public: - char pad_0[0x10]; - CCharacter* character; // 0x10 - }; // Size: 0x14 - - CCharacterListNodeEntry* entry; // 0x0 - CEntityList::CCharacterList::CCharacterListNode* next; // 0x4 - }; // Size: 0x8 + CEntityList::CCharacterList::CCharacterListNode* next; // 0x0 + char pad_8[0x10]; + CCharacter* character; // 0x18 + char pad_20[0x8]; + }; // Size: 0x28 - char pad_0[0x4]; - CCharacterListNode* root; // 0x4 - uint32_t count; // 0x8 - }; // Size: 0xc + char pad_0[0x10]; + CCharacterListNode** root; // 0x10 + uint32_t count; // 0x18 + }; // Size: 0x1c char pad_0[0x8]; CItemList items; // 0x8 - char pad_14[0x14]; - CCharacterList characters; // 0x28 -}; // Size: 0x34 + char pad_24[0x24]; + CCharacterList characters; // 0x48 + char pad_64[0x9c]; +}; // Size: 0x100 #pragma pack(pop) diff --git a/Kanan/Mabinogi/CEntityListPtr.hpp b/Kanan/Mabinogi/CEntityListPtr.hpp deleted file mode 100644 index ec4e6ce..0000000 --- a/Kanan/Mabinogi/CEntityListPtr.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -class CEntityList; -#pragma pack(push, 1) -class CEntityListPtr { -public: - CEntityList* entityList; // 0x0 -}; // Size: 0x4 -#pragma pack(pop) diff --git a/Kanan/Mabinogi/CItem.hpp b/Kanan/Mabinogi/CItem.hpp index f105475..be2a6cf 100644 --- a/Kanan/Mabinogi/CItem.hpp +++ b/Kanan/Mabinogi/CItem.hpp @@ -4,44 +4,46 @@ class CString; class CItem { public: struct SItemDBDesc { - char pad_0[0x4]; - CString* type; // 0x4 - char pad_8[0x2c]; - CString* displayName; // 0x34 - char pad_38[0x4]; - CString* name; // 0x3c - CString* description; // 0x40 - char pad_44[0x88]; + char pad_0[0x8]; + CString* type; // 0x8 + char pad_10[0x28]; + CString* displayName; // 0x38 + char pad_40[0x10]; + CString* name; // 0x50 + char pad_58[0x8]; + CString* description; // 0x60 + CString* longDescription; // 0x68 + char pad_70[0x5c]; uint16_t maxStackCount; // 0xcc }; // Size: 0xce - char pad_0[0x4]; - uint64_t* entityID; // 0x4 - uint32_t inventoryID; // 0x8 - uint32_t itemID; // 0xc - uint32_t color1; // 0x10 - uint32_t color2; // 0x14 - uint32_t color3; // 0x18 - char pad_1c[0x4]; - uint32_t color4; // 0x20 - uint32_t color5; // 0x24 - uint32_t color6; // 0x28 - uint32_t stackCount; // 0x2c - char pad_30[0x4]; - uint32_t positionX; // 0x34 - uint32_t positionY; // 0x38 - char pad_3c[0x28]; - uint32_t price; // 0x64 - uint32_t sellPrice; // 0x68 - char pad_6c[0x4]; - uint32_t durability; // 0x70 - uint32_t maxDurability; // 0x74 - uint32_t originalDurability; // 0x78 - char pad_7c[0x5c]; - SItemDBDesc* dbDesc; // 0xd8 - char pad_dc[0x1c]; - uint64_t ownerID; // 0xf8 - char pad_100[0x24]; - CString* name; // 0x124 -}; // Size: 0x128 + char pad_0[0x8]; + uint64_t* entityID; // 0x8 + uint32_t inventoryID; // 0x10 + uint32_t itemID; // 0x14 + uint32_t color1; // 0x18 + uint32_t color2; // 0x1c + uint32_t color3; // 0x20 + char pad_24[0x4]; + uint32_t color4; // 0x28 + uint32_t color5; // 0x2c + uint32_t color6; // 0x30 + uint32_t stackCount; // 0x34 + char pad_38[0x4]; + uint32_t positionX; // 0x3c + uint32_t positionY; // 0x40 + char pad_44[0x30]; + uint32_t price; // 0x74 + uint32_t sellPrice; // 0x78 + char pad_7c[0x4]; + uint32_t durability; // 0x80 + uint32_t maxDurability; // 0x84 + uint32_t originalDurability; // 0x88 + char pad_8c[0x74]; + SItemDBDesc* dbDesc; // 0x100 + char pad_108[0x28]; + uint64_t ownerID; // 0x130 + char pad_138[0x38]; + CString* name; // 0x170 +}; // Size: 0x178 #pragma pack(pop) diff --git a/Kanan/Mabinogi/CRenderer.hpp b/Kanan/Mabinogi/CRenderer.hpp index 4e28c5f..bca99a2 100644 --- a/Kanan/Mabinogi/CRenderer.hpp +++ b/Kanan/Mabinogi/CRenderer.hpp @@ -9,28 +9,29 @@ class CRenderer { public: class CCameraState { public: - char pad_0[0xc]; - Vector3 target; // 0xc - char pad_18[0x4]; - Vector3 position; // 0x1c - char pad_28[0x8]; - Vector4 forward; // 0x30 - float drawDistance; // 0x40 - float zNear; // 0x44 - float zFar; // 0x48 - float fov; // 0x4c - float screenWidth; // 0x50 - float screenHeight; // 0x54 - char pad_58[0x1c]; - float aspectRatio; // 0x74 - char pad_78[0xd4]; + char pad_0[0x10]; + Vector3 target; // 0x10 + char pad_1c[0x4]; + Vector3 position; // 0x20 + char pad_2c[0x8]; + Vector4 forward; // 0x34 + float drawDistance; // 0x44 + float zNear; // 0x48 + float zFar; // 0x4c + float fov; // 0x50 + float screenWidth; // 0x54 + float screenHeight; // 0x58 + char pad_5c[0x1c]; + float aspectRatio; // 0x78 + char pad_7c[0xd0]; Matrix4x4 transformMatrix; // 0x14c }; // Size: 0x18c CCameraState* state; // 0x0 - }; // Size: 0x4 + }; // Size: 0x8 - char pad_0[0x24]; - CCamera* camera; // 0x24 -}; // Size: 0x28 + char pad_0[0x38]; + CCamera* camera; // 0x38 + char pad_40[0xc0]; +}; // Size: 0x100 #pragma pack(pop) diff --git a/Kanan/Mabinogi/CRendererPtr.hpp b/Kanan/Mabinogi/CRendererPtr.hpp deleted file mode 100644 index a5e1432..0000000 --- a/Kanan/Mabinogi/CRendererPtr.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -class CRenderer; -#pragma pack(push, 1) -class CRendererPtr { -public: - CRenderer* renderer; // 0x0 -}; // Size: 0x4 -#pragma pack(pop) diff --git a/Kanan/Mabinogi/CString.hpp b/Kanan/Mabinogi/CString.hpp index a1bf250..0a7bca5 100644 --- a/Kanan/Mabinogi/CString.hpp +++ b/Kanan/Mabinogi/CString.hpp @@ -2,13 +2,13 @@ #pragma pack(push, 1) class CString { public: - char pad_0[0x4]; - int32_t referenceCount; // 0x4 - char pad_8[0x4]; - uint32_t length; // 0xc - uint32_t capacity; // 0x10 - char pad_14[0x8]; + char pad_0[0x8]; + int32_t referenceCount; // 0x8 + char pad_c[0x4]; + uint32_t length; // 0x10 + uint32_t capacity; // 0x14 + char pad_18[0x8]; // Metadata: utf16* - char16_t buffer[70]; // 0x1c -}; // Size: 0xa8 + char16_t buffer[70]; // 0x20 +}; // Size: 0xac #pragma pack(pop) diff --git a/Kanan/Mabinogi/CWorld.hpp b/Kanan/Mabinogi/CWorld.hpp index 2c4d02f..df49853 100644 --- a/Kanan/Mabinogi/CWorld.hpp +++ b/Kanan/Mabinogi/CWorld.hpp @@ -2,7 +2,8 @@ #pragma pack(push, 1) class CWorld { public: - char pad_0[0xb8]; - uint64_t localPlayerID; // 0xb8 -}; // Size: 0xc0 + char pad_0[0x160]; + uint64_t localPlayerID; // 0x160 + char pad_168[0x98]; +}; // Size: 0x200 #pragma pack(pop) diff --git a/Kanan/Mabinogi/CWorldPtr.hpp b/Kanan/Mabinogi/CWorldPtr.hpp deleted file mode 100644 index a7fe4c3..0000000 --- a/Kanan/Mabinogi/CWorldPtr.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -class CWorld; -#pragma pack(push, 1) -class CWorldPtr { -public: - CWorld* world; // 0x0 -}; // Size: 0x4 -#pragma pack(pop) diff --git a/Kanan/Mods.cpp b/Kanan/Mods.cpp index 4c43306..603f3fa 100644 --- a/Kanan/Mods.cpp +++ b/Kanan/Mods.cpp @@ -123,15 +123,15 @@ namespace kanan { addMod(make_unique()); addMod(make_unique()); addMod(make_unique()); - addMod(make_unique()); + // addMod(make_unique()); addMod(make_unique()); addMod(make_unique()); addMod(make_unique()); - addMod(make_unique()); + /* addMod(make_unique()); addMod(make_unique()); - addMod(make_unique()); + addMod(make_unique());*/ addMod(make_unique()); - addMod(make_unique()); + //addMod(make_unique()); log("[Mods] Finished loading mods."); } diff --git a/Kanan/Patches.json b/Kanan/Patches.json index 3c0f694..777a524 100644 --- a/Kanan/Patches.json +++ b/Kanan/Patches.json @@ -23,10 +23,11 @@ "desc": "Shows the combat power of players and enemies.\nCredits: Rydian", "category": "Information", "patches": [ - { - "pattern": "0F 85 ? ? ? ? FF B3 14 01 00 00", - "patch": "90 90 90 90 90 90" - } + { + "pattern": "3D ? ? ? ? 0F 85 ? ? ? ? 49 8B ? ? ? ? ? 48 8B ? ? ? ? ? E8", + "offset": 5, + "patch": "90 90 90 90 90 90" + } ] }, { @@ -94,10 +95,10 @@ "desc": "Lets you mount/dismount your pet as fast as you want.\nCredits: Licat", "category": "Speedup", "patches": [ - { - "pattern": "89 88 78 02 00 00 B0 ?", - "patch": "90 90 90 90 90 90" - } + { + "pattern": "45 89 ? ? ? ? ? B0 ? 4C 8D", + "patch": "90 90 90 90 90 90 90" + } ] }, { @@ -116,11 +117,10 @@ "desc": "Allows you to logout in the middle of a conversation with an NPC.", "category": "Fixes", "patches": [ - { - "pattern": "84 C0 74 ? B8 ? ? ? ? 8B 4D F4 64 89 0D ? ? ? ? 59 5F 5E 5B 8B E5 5D C2 ? ? 8B 0D ? ? ? ?", - "offset": 2, - "patch": "EB" - } + { + "pattern": "E8 ? ? ? ? 84 C0 74 ? 41 8D ? ? E9", + "patch": "B8 00 FF FF FF" + } ] }, { @@ -128,10 +128,10 @@ "desc": "Allows you to move to the same channel you're currently on.", "category": "Speedup", "patches": [ - { - "pattern": "0F 84 ? ? ? ? 68 ? ? ? ? 8D 4D E8 E8 ? ? ? ? C6 45 FC ? 8D 45 E8 50 8D 45 CC 50 E8 ? ? ? ? 8B C8 E8 ? ? ? ? C6 45 FC ? 8D 4D EC 51 8B C8 E8 ? ? ? ? C6 45 FC ? C7 45 F0 ? ? ? ?", - "patch": "90 E9" - } + { + "pattern": "74 ? 48 83 C1 ? EB ? 49 8B ? E8 ? ? ? ? 85 C0 0F 85 ? ? ? ? 4C 89 ? ? 48 8D ? ? ? ? ? E8 ? ? ? ? 8B F8 8D 48 ? E8 ? ? ? ? 48 89 ? ? 48 8D ? ? 4C 8D ? ? ? ? ? 8D 57 ? E8 ? ? ? ? 48 8B ? ? 89 79 ? E8 ? ? ? ? 48 8B ? 4C 8D ? ? 48 8D ? ? E8 ? ? ? ? 90 48 8D ? ? 48 8B ? E8 ? ? ? ? 90 4C 89 ? ? 4C 89 ? ? C6 44 24 60 ? 48 8D ? ? 48 89 ? ? ? C6 44 24 50 ? C6 44 24 48 ? C6 44 24 40 ? C6 44 24 38 ? C6 44 24 30 ? C6 44 24 28 ? C7 44 24 20 ? ? ? ? 4D 8B ? 4C 8D ? ? 48 8D ? ? 48 8B ? ? ? ? ? E8 ? ? ? ? 90 48 8B ? ? 48 85 ? 74 ? E8 ? ? ? ? 4C 89 ? ? 48 8B ? ? 48 85 ? 74 ? E8 ? ? ? ? 4C 89 ? ? 48 8B ? ? 48 85 ? 74 ? E8 ? ? ? ? 4C 89 ? ? 48 8D ? ? E8 ? ? ? ? 90 48 8B ? ? 48 85 ? 0F 84", + "patch": "EB" + } ] }, { @@ -145,17 +145,6 @@ } ] }, - { - "name": "Disable Channel Move Denial", - "desc": "Allows you change channel while in conversation with an NPC.", - "category": "Speedup", - "patches": [ - { - "pattern": "0F 84 ? ? ? ? C7 45 F0 ? ? ? ? C7 45 FC ? ? ? ? 8B CB E8 ? ? ? ? 8D 4D E4", - "patch": "90 E9" - } - ] - }, { "name": "Disable Channel Move Description", "desc": "Hides the warning when selecting which channel to change to.", @@ -308,7 +297,7 @@ "category": "Information", "patches": [ { - "pattern": "74 ? 8B 06 8B CE FF 90 94 00 00 00 8B C8 E8 ? ? ? ? 3D ? ? ? ? 74 04", + "pattern": "74 ? 48 8B ? 48 8B ? FF 90 ? ? ? ? 48 8B ? E8 ? ? ? ? 3D ? ? ? ? 74 ? 32 C0", "patch": "EB" } ] @@ -796,8 +785,8 @@ "category": "Speedup", "patches": [ { - "pattern": "8B C8 C7 45 E8 98 3A", - "offset": 6, + "pattern": "BF 98 3A 00 00", + "offset": 1, "patch": "00 00" } ] @@ -1130,8 +1119,8 @@ "category": "Speedup", "patches": [ { - "pattern": "0F 84 ? ? ? ? 83 BE 04 01 00 00", - "patch": "0F 85" + "pattern": "0F 84 ? ? ? ? 49 83 BE 40 01 00 00 ? 0F 85", + "patch": "90 E9" } ] }, @@ -1141,8 +1130,8 @@ "category": "Graphics", "patches": [ { - "pattern": "FF D2 84 C0 0F 84 ? ? ? ? 6A ? 68 ? ? ? ?", - "offset": 4, + "pattern": "FF 52 ? 84 C0 0F 84 ? ? ? ? 45 33", + "offset": 5, "patch": "90 E9" } ] @@ -1187,11 +1176,11 @@ }, { "name": "Disable WaitProcess Skill Locks", - "desc": "Allows the use of changing skills without needing to first cancel the skill for cetain skills (Windmill, Deathmark, Anchor Rush, etc) \nMay interact with some skills in strange ways.", + "desc": "Allows the ability to load a new skill without needing to first cancel the currently loaded skill for cetain skills with waitprocess locks enabled (Windmill, Deathmark, Anchor Rush, etc) \nMay interact with some skills in strange ways.", "category": "Speedup", "patches": [ { - "pattern": "OF85 ? ? ? ? 8B B3 ? ? ? ? 85 F6 74 29", + "pattern": "0F 85 ? ? ? ? 48 8B ? ? ? ? ? 48 85 ? 74 ? 48 8D", "patch": "90 90 90 90 90 90" } ] @@ -1231,7 +1220,7 @@ "category": "Quality of Life", "patches": [ { - "pattern": "74 ? 2B BD 7C FF FF FF 83 EF 1C D1 FF EB 03 83 CF FF C6 45 FC 00 85 F6 74 11", + "pattern": "74 ? 48 2B ? ? ? 48 83 EF ? 48 D1 ? EB ? 83 CF ? 48 8B ? E8 ? ? ? ? 33 F6 48 89 ? ? ? 48 8D", "patch": "90 90" } ] @@ -1255,13 +1244,36 @@ }, { "name": "Don't Close Title Window", - "desc": "Disables the automatic closing of the title window when switching titles.", + "desc": "Disables the automatic closing of the title window when switching titles. \n(Use the X in top right to close title window as this disables cancel button too)", "category": "Quality of Life", "patches": [ { - "pattern": "FF 50 ? E9 ? ? ? ? 8B 86 ? ? ? ? 3B 48 ? 75 ? 8B CE", + "pattern": "FF 50 ? B0 ? 48 8B ? ? ? 48 83 C4 ? 5F C3 CC CC CC CC 40 ? 48 83 EC", "patch": "90 90 90" } ] + }, + { + "name": "Enable Mounted Prop Attack", + "desc": "Enables ability to attack props with all mounts (tuann, horses, etc)", + "category": "Quality of Life", + "patches": [ + { + "pattern": "B0 01 EB ? 48 8B ? ? ? 48 85 ? 74 ? 4C 8B ? ? ? 4C 2B ? 49 C1 F8 ? 48 8D ? ? ? E8 ? ? ? ? 0F 57 ? F3 0F ? ? ? ? 48 C7 44 24 38 ? ? ? ? 32 C0 48 8B ? ? ? 48 8B", + "offset": 1, + "patch": "00" + } + ] + }, + { + "name": "Enable Hidden Mob attack (Mimic-Unhide)", + "desc": "Enables targetting of hidden mobs such as mimics and golems", + "category": "Quality of Life", + "patches": [ + { + "pattern": "0F 84 ? ? ? ? 48 8B ? FF 90 ? ? ? ? 48 8B ? E8 ? ? ? ? 48 8B ? 48 85 ? 0F 84 ? ? ? ? 49 8B", + "patch": "90 E9" + } + ] } ] diff --git a/Kanan/RangedAttackSwap.cpp b/Kanan/RangedAttackSwap.cpp index 02fad0d..5e43ef7 100644 --- a/Kanan/RangedAttackSwap.cpp +++ b/Kanan/RangedAttackSwap.cpp @@ -13,16 +13,16 @@ namespace kanan { m_choice{ 0 }, m_patch{} { - auto address = scan("client.exe", "B8 09 52 00 00 5F"); + auto address = scan("client.exe", "B8 09 52 00 00 48"); if (address) { - log("Got RangedAttackSwap %p", *address); + log("[RangedAttackSwap]Got Address %p", *address); m_patch.address = *address + 1; m_patch.bytes = { 0x09, 0x52 }; } else { - log("Failed to find RangedAttackSwap address."); + log("[RangedAttackSwap]Failed to find address."); } } diff --git a/Kanan/TTFFontSize.cpp b/Kanan/TTFFontSize.cpp index dcb23c3..276d0f4 100644 --- a/Kanan/TTFFontSize.cpp +++ b/Kanan/TTFFontSize.cpp @@ -12,150 +12,20 @@ namespace kanan { : PatchMod{ "TTF Font Size", "" }, m_choice{ 0 }, m_patch{}, - m_originalByte{}, - foundNPCFix{ false }, - code_address{ NULL } + m_originalByte{} { - auto address = scan("client.exe", "C7 86 C4 00 00 00 0B 00 00 00 C7"); // Pattern for locating location of the byte that controls text font size - auto npctextaddress1 = scan("client.exe", "E8 ? ? ? ? 56 53 8D 8D ? ? ? ? E8 ? ? ? ? 8B F0"); // Pattern that locates the function that calls the text sizing function when speaking with an NPC - Used for redirection. - auto npctextmidcall = scan("client.exe", "8B 01 8B 40 08 48 83 F8 07 77 19"); //Start of a function that is called in the middle of our modified NPC text function + // Pattern for locating location of the byte that controls text font size + auto address = scan("client.exe", "C7 86 D0 00 00 00 ? ? ? ? C7 86 D4 00 00 00 ? ? ? ? C7 86 E8 00 00 00 ? ? ? ? C7 86 EC 00 00 00 ? ? ? ? 88 86 ? ? ? ? C6 86 B0 00 00 00 ? 83 46 10 ? 4C 8B"); if (address) { log("[TTF Font Size] Found address TTF Font Size %p", *address); m_patch.address = *address + 6; m_originalByte = { *reinterpret_cast(m_patch.address) }; - - if (npctextaddress1 && npctextmidcall) { //Create patches for redirecting function calls made when speaking to an NPC. NPC text boxes crash when using a trext size larger than 13. We create a copy to allow rest of the client to use larger values and redirect the NPC calls to our copy. - log("[TTF Font Size] Found address TTFFontSize NPC Caller %p", *npctextaddress1); - log("[TTF Font Size] Found address TTFFontSize NPC Call %p", *npctextmidcall); - foundNPCFix = true; - - m_patchNPC1.address = *npctextaddress1; - m_patchNPCCall.address = *npctextmidcall; - // Array of bytes that make up the function called when drawing text. We define a copy, allocate our own memory for it and redirect NPC calls to this function instead of the client's. - // With a text size > 13 When an NPC is spoken to - the NPC dialogue box uses this function instead - using a size value of 13 as sizes higher will crash the game. - code = vector{ - 0x55, //- 1 push ebp - 0x8B, 0xEC, //- 2 mov ebp, esp - 0x80, 0xB9, 0x09, 0x09, 0x00, 0x00, 0x00, //- 3 cmp byte ptr[ecx + 00000909], 00 - 0x74, 0x60, //- 4 je Client.exe + C9E3CC - 0x56, //- 5 push esi - 0x8B, 0x75, 0x08, //- 6 mov esi,[ebp + 08] - 0x80, 0xBE, 0xA8, 0x00, 0x00, 0x00, 0x00, //- 7 cmp byte ptr[esi + 000000A8], 00 - 0x74, 0x52, //- 8 je Client.exe + C9E3CB - 0xB9, 0x44, 0x03, 0x6A, 0x03, //- 9 mov ecx, Client.exe + 329B254 This changes from client to client patch. We patch this before redirecting - 0xE8, 0xED, 0x50, 0x4F, 0xFF, //- 10 call Client.exe + 193470 -- This is a call to another function. We update this call location as we enable this patch - 0x83, 0xF8, 0x01, //- 11 cmp eax, 01 - 0x75, 0x43, //- 12 jne Client.exe + C9E3CB - 0x83, 0xBE, 0xB0, 0x00, 0x00, 0x00, 0x02, //- 13 cmp dword ptr[esi + 000000B0], 02 - 0x75, 0x0B, //- 14 jne Client.exe + C9E39C - 0x8B, 0x45, 0x0C, //- 15 mov eax,[ebp + 0C] - 0x5E, //- 16 pop esi - 0x83, 0x00, 0x03, //- 17 add dword ptr[eax], 03 - 0x5D, //- 18 pop ebp - 0xC2, 0x08, 0x00, //- 19 ret 0008 - 0x80, 0xBE, 0x83, 0x00, 0x00, 0x00, 0x00, //- 20 cmp byte ptr[esi + kanan.dtor_list_head + 63], 00 - 0x75, 0x26, //- 21 jne Client.exe + C9E3CB - 0xC7, 0x86, 0xC4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, //- 22 mov[esi + 000000C4], kanan._Init_thread_epoch + 2 -- This influences the text size. Currently set to max stable text size for NPC text, 0x0D (13) - 0xC7, 0x86, 0xC8, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, //- 23 mov[esi + 000000C8], kanan.kanan::g_pages + B - 0x83, 0x46, 0x10, 0xFC, //- 24 add dword ptr[esi + 10], -04 - 0xC6, 0x86, 0x85, 0x00, 0x00, 0x00, 0x01, //- 25 mov byte ptr[esi + kanan.dtor_list_head + 65], 01 - 0xC6, 0x86, 0xA8, 0x00, 0x00, 0x00, 0x00, //- 26 mov byte ptr[esi + 000000A8], 00 - 0x5E, //- 27 pop esi - 0x5D, //- 28 pop ebp - 0xC2, 0x08, 0x00 //- 29 ret 0008 - }; - - - } - else { - log("[TTF Font Size] Failed to find TTFFontSize NPC Fix addresses."); - } - - } - else { - log("[TTF Font Size] Failed to find TTFFontSize address."); - } - } - - - //Apply NPC function redirection. Passing in true will enable the patch and allocate memory to store the patch if it hasn't been done alresady. Passing in False will disable and de-allocate the patch. Returns false if we are unable to allocate memory for any reason. - - bool TTFFontSize::applyNPCFix(bool npcFixEnable) { - //Enabling NPC Fix. Make copy of the function with max stable text size set for when an NPC text box is drawn. - if (npcFixEnable == true) { - //First check to see if we already allocated and constructed our redircted NPC function. - if (code_address == NULL) { - // Allocate memory to store our copied function - code_address = VirtualAlloc(nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - if (code_address == NULL) { - log("[TTF Font Size] Failed to allocate memory for TTFFontSize NPC Fix."); - return false; - } - else { - log("[TTF Font Size] Successfully allocated memory for TTFFontSize NPC Fix %p", (uintptr_t)code_address); - - // Create patch to replace calls to text size function made by NPC text draws. We calculate relative call address and create our patch. - //Find relative offset amount between our allocated code and the call we need to make - uintptr_t callToBytesNPC1 = (uintptr_t)code_address - (m_patchNPC1.address + 5); - //create array of bytes containing our relative address offset - unsigned char callToArrayNPC1[sizeof(void*)]; // - memcpy(callToArrayNPC1, &callToBytesNPC1, sizeof(void*)); - //patch call code_address - m_patchNPC1.bytes = { 0xE8, callToArrayNPC1[0], callToArrayNPC1[1], callToArrayNPC1[2], callToArrayNPC1[3] }; - - // Calculate relative location of the call to another function in the middle of our function copy (Asm code Line 10) so we can update the call to point to the correct address in memory should it be needed. - uintptr_t midCallToBytes = (m_patchNPCCall.address - 0x23) - (uintptr_t)code_address; - unsigned char midCallTextArray[sizeof(void*)]; - memcpy(midCallTextArray, &midCallToBytes, sizeof(void*)); - //Patch relative call to the function in the middle of our copied function. - code[31] = midCallTextArray[0]; - code[32] = midCallTextArray[1]; - code[33] = midCallTextArray[2]; - code[34] = midCallTextArray[3]; - - - //Patch mov reference in original function (Asm code Line 11) - this changes from client build to build. - uintptr_t movRefToBytes = m_patch.address - 0x31; - unsigned char movRefArray[5]; - memcpy(movRefArray, &movRefToBytes, 5); - code[26] = movRefArray[0]; - code[27] = movRefArray[1]; - code[28] = movRefArray[2]; - code[29] = movRefArray[3]; - - // Copy our modified function that NPC text calls will use to memory and apply the patch to have NPC text call this copied function. - memcpy(code_address, code.data(), code.size()); - - patch(m_patchNPC1); - return true; - } - } - //Memory is already allocated, just apply the patch - else { - patch(m_patchNPC1); - return true; - } - - } - //Disable NPC Fix. Check to see if memory for NPC is allocated. If it is, deallocate the memory. - else { - if (code_address != NULL) { - log("[TTF Font Size] Disabling TTFont Size NPCFix..."); - undoPatch(m_patchNPC1); - VirtualFree(code_address, 0, MEM_RELEASE); - code_address = NULL; - return true; - } - //NPC Text fix wasn't in use. Nothing to do. - else { - return true; - } - } + } else { + log("[TTF Font Size] Failed to find TTFFontSize address."); + } } - - void TTFFontSize::onPatchUI() { if (m_patch.address == 0) { return; @@ -199,43 +69,12 @@ namespace kanan { short choice = m_choice; m_patch.bytes = { choice }; patch(m_patch); - applyNPCFix(false); } - // If our size is less than 14 we don't need to patch NPC functions - else if (m_choice < 14) { + else{ log("[TTF Font Size] Applying TTFFontSize..."); short choice = m_choice; m_patch.bytes = { choice }; patch(m_patch); - applyNPCFix(false); - } - // Selected font size is greater than 13 - In order to speak with NPCs we must redirect them to a copy of the function with a font size lower than 14 to prevent a crash - else if (m_choice >= 14) { - //First check if we were able to find the addresses needed for the NPC fix - if (foundNPCFix == true) { - log("[TTF Font Size] Applying TTFFontSize with NPC Fix..."); - short choice = m_choice; - m_patch.bytes = { choice }; - patch(m_patch); - //attempt NPC fix, if the memory to hold the patch fails to allocate fall back to setting the text size to max stable (13) - if (applyNPCFix(true) == false) { - log("[TTF Font Size] Applying TTFFontSize - NPC fix failed, setting size to 13..."); - short choice = 13; - m_patch.bytes = { choice }; - patch(m_patch); - } - - ; - } - //Addresses necesarry to make the NPC fix patch were not found. Set text size to max stable size (13) instead - else { - log("[TTF Font Size] Applying TTFFontSize - NPC fix addresses were not found, setting size to 13..."); - short choice = 13; - m_patch.bytes = { choice }; - patch(m_patch); - - } - } } } \ No newline at end of file diff --git a/Kanan/TTFFontSize.hpp b/Kanan/TTFFontSize.hpp index 19ca3cc..9342ae6 100644 --- a/Kanan/TTFFontSize.hpp +++ b/Kanan/TTFFontSize.hpp @@ -8,21 +8,14 @@ namespace kanan { class TTFFontSize : public PatchMod { public: TTFFontSize(); - - bool applyNPCFix(bool npcFixEnable); void onPatchUI() override; void onConfigLoad(const Config& cfg) override; void onConfigSave(Config& cfg) override; private: Patch m_patch; - Patch m_patchNPC1; - Patch m_patchNPCCall; int m_choice; unsigned char m_originalByte; - std::vector code; - LPVOID code_address; - bool foundNPCFix; void apply(); }; } \ No newline at end of file diff --git a/Kanan/UseDataFolder.cpp b/Kanan/UseDataFolder.cpp index 75868eb..2bd8d1b 100644 --- a/Kanan/UseDataFolder.cpp +++ b/Kanan/UseDataFolder.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "Log.hpp" #include "UseDataFolder.hpp" @@ -15,10 +16,10 @@ namespace kanan { { log("[UseDataFolder] Entering constructor..."); - auto address = scan("client.exe", "B9 ? ? ? ? E8 ? ? ? ? 80 7B 13 ?"); + auto address = scan("client.exe", "48 8D 0D ? ? ? ? E8 ? ? ? ? 84 C0 74 ? 48 8B 0D ? ? ? ? 4C 8B C3"); if (address) { - m_fileSystem = *(uintptr_t*)(*address + 1); + m_fileSystem = (uintptr_t)rel_to_abs(*address + 3); log("[UseDataFolder] Got address of CFileSystem %p", m_fileSystem); } @@ -26,10 +27,10 @@ namespace kanan { log("[UseDataFolder] Failed to get address of CFileSystem"); } - address = scan("client.exe", "55 8B EC 6A ? 68 ? ? ? ? 64 A1 ? ? ? ? 50 83 EC ? 53 56 57 A1 ? ? ? ? 33 C5 50 8D 45 F4 64 A3 ? ? ? ? 8B D9 89 5D F0 E8 ? ? ? ? 84 C0 0F 84 ? ? ? ? 8B 53 04"); + address = scan("client.exe", "E8 ? ? ? ? 48 8B 4E 08 E8 ? ? ? ? 48 8B 5C 24 58"); if (address) { - m_setLookUpOrder = (decltype(m_setLookUpOrder))*address; + m_setLookUpOrder = (decltype(m_setLookUpOrder))rel_to_abs(*address + 1); log("[UseDataFolder] Got address of SetLookUpOrder %p", m_setLookUpOrder); } diff --git a/Loader/Main.cpp b/Loader/Main.cpp index ba29023..4eaf0e7 100644 --- a/Loader/Main.cpp +++ b/Loader/Main.cpp @@ -37,7 +37,11 @@ bool inject(DWORD clientID) { string dllConfigLine{}; while (getline(dllConfig, dllConfigLine)) { - dllNames.push_back(move(dllConfigLine)); + dllNames.emplace_back(move(dllConfigLine)); + } + + if (dllNames.empty()) { + dllNames.emplace_back("Kanan.dll"); } for (auto& dllName : dllNames) { diff --git a/README.md b/README.md index 30522ec..074ceb4 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Downloads for the latest _official_ releases are located [here](https://github.c ## Build steps From the command line you must generate a project using CMake: ``` -> cmake -B build -G "Visual Studio 17 2022" -A Win32 +> cmake -B build -G "Visual Studio 17 2022" -A x64 ``` At this point you can now open `/build/Kanan.sln` with visual studio, or continue the build from the command line with: diff --git a/cmake.toml b/cmake.toml index ee62022..792ce21 100644 --- a/cmake.toml +++ b/cmake.toml @@ -2,7 +2,7 @@ [project] name = "Kanan" cmake-after = """ -set(VCPKG_TARGET_TRIPLET x86-windows-static) +set(VCPKG_TARGET_TRIPLET x64-windows-static) """ [vcpkg] @@ -39,13 +39,29 @@ include-directories = ["Kanan/"] compile-definitions = ["IMGUI_DISABLE_INCLUDE_IMCONFIG_H"] link-libraries = ["Core", "imgui::imgui", "nlohmann_json::nlohmann_json", "ws2_32"] properties.MSVC_RUNTIME_LIBRARY = "MultiThreaded$<$:Debug>" +cmake-after = """ +# Copy Kanan/Patches.json to the output directory. +add_custom_command(TARGET Kanan POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/Kanan/Patches.json + $ +) +""" [target.Loader] type = "executable" sources = ["Loader/Main.cpp"] link-libraries = ["Core"] -link-options = ["/MANIFESTUAC:level=requireAdministrator"] +link-options = ["/MANIFESTUAC:level='requireAdministrator'"] properties.MSVC_RUNTIME_LIBRARY = "MultiThreaded$<$:Debug>" +cmake-after = """ +# Copy Loader/Loader.txt to the output directory +add_custom_command(TARGET Loader POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/Loader/Loader.txt + $ +) +""" [target.Launcher] type = "executable" @@ -54,7 +70,7 @@ headers = ["Launcher/**.hpp"] include-directories = ["Kanan/"] # For FontData.hpp compile-definitions = ["IMGUI_DISABLE_INCLUDE_IMCONFIG_H"] link-libraries = ["Core", "imgui::imgui", "nlohmann_json::nlohmann_json", "Bcrypt", "Crypt32", "Winhttp", "Rpcrt4", "D3d9", "Wbemuuid"] -link-options = ["/MANIFESTUAC:level=requireAdministrator"] +link-options = ["/MANIFESTUAC:level='requireAdministrator'"] properties.MSVC_RUNTIME_LIBRARY = "MultiThreaded$<$:Debug>" properties.WIN32_EXECUTABLE = true diff --git a/mabinogi.genny b/mabinogi.genny index 2d2095e..e28644c 100644 --- a/mabinogi.genny +++ b/mabinogi.genny @@ -29,116 +29,116 @@ struct Matrix4x4 { } class CString { - int32_t referenceCount @ 0x4 - uint32_t length @ 0xC - uint32_t capacity @ 0x10 - char16_t buffer[70] @ 0x1C [[utf16*]] + int32_t referenceCount @ 0x8 + uint32_t length @ 0x10 + uint32_t capacity @ 0x14 + char16_t buffer[70] @ 0x20 [[utf16*]] } class CCharacter { class CParameter { - class CMemberString 0x10 { - CString* value @ 0x4 + class CMemberString 0x20 { + CString* value @ 0x8 } - class CMemberChar 0xC { - int8_t value @ 0x4 + class CMemberChar 0x18 { + int8_t value @ 0x8 } - class CMemberUChar 0xC { - uint8_t value @ 0x4 + class CMemberUChar 0x18 { + uint8_t value @ 0x8 } - class CMemberUShort 0xC { - uint16_t value @ 0x4 + class CMemberUShort 0x18 { + uint16_t value @ 0x8 } - class CMemberULong 0x10 { - uint32_t value @ 0x4 + class CMemberULong 0x18 { + uint32_t value @ 0x8 } - class CMemberUInt64 0x18 { - uint64_t value @ 0x4 + class CMemberUInt64 0x20 { + uint64_t value @ 0x8 } - class CMemberFloat 0x10 { - float value @ 0x4 + class CMemberFloat 0x18 { + float value @ 0x8 } - CMemberString name @ 0x20 - CMemberString title; //0x0030 - CMemberString engTitle; //0x0040 - CMemberULong type; //0x0050 - CMemberUChar skinColor; //0x0060 - CMemberUShort eyeType; //0x006C - CMemberUChar eyeColor; //0x0078 - CMemberUChar mouthType; //0x0084 - CMemberULong status; //0x0090 - CMemberULong statusEx; //0x00A0 - CMemberULong statusEx2; //0x00B0 - CMemberFloat scaleHeight; //0x00C0 - CMemberFloat scaleFatness; //0x00D0 - CMemberFloat scaleUpper; //0x00E0 - CMemberFloat scaleLower; //0x00F0 - CMemberULong regionID; //0x0100 - CMemberULong positionX; //0x0110 - CMemberULong positionY; //0x0120 - CMemberChar direction; //0x0130 - CMemberULong battleState; //0x013C - CMemberUChar weaponSet; //0x014C - CMemberULong extra1; //0x0158 - CMemberULong extra2; //0x0168 - CMemberULong extra3; //0x0178 - CMemberFloat combatPower; //0x0188 - CMemberString motionType; //0x0198 - CMemberUChar oddEyeLeftColor; //0x01A8 - CMemberUChar oddEyeRightColor; //0x01B4 - CMemberFloat life; //0x01C0 - CMemberFloat lifeMaxBase; //0x01D0 - CMemberFloat lifeDamaged; //0x01E0 - CMemberFloat lifeMaxMod; //0x01F0 - CMemberFloat mana; //0x0200 - CMemberFloat manaMaxBase; //0x0210 - CMemberFloat manaMaxMod; //0x0220 - CMemberFloat stamina; //0x0230 - CMemberFloat staminaMaxBase; //0x0240 - CMemberFloat staminaMaxMod; //0x0250 - CMemberFloat food; //0x0260 - CMemberFloat foodMinRatio; //0x0270 - CMemberUShort level; //0x0280 - CMemberULong cumulatedLevel; //0x028C - CMemberUShort maxLevel; //0x029C - CMemberUShort rebirthCount; //0x02A8 - CMemberUShort lifeTimeSkill; //0x02B4 - CMemberUInt64 experienceInt; //0x02C0 - CMemberUShort age; //0x02D8 - CMemberFloat dorcha @ 0xA7C; //0x0A7C - CMemberFloat dorchaMaxBase; //0x0A8C - CMemberFloat tuairim; //0x0A9C For Bachram Boost - CMemberFloat tuairimMaxBase; //0x0AAC For Bachram Boost + CMemberString name @ 0x30 + CMemberString title; + CMemberString engTitle; + CMemberULong type; + CMemberUChar skinColor; + CMemberUShort eyeType; + CMemberUChar eyeColor; + CMemberUChar mouthType; + CMemberULong status; + CMemberULong statusEx; + CMemberULong statusEx2; + CMemberFloat scaleHeight; + CMemberFloat scaleFatness; + CMemberFloat scaleUpper; + CMemberFloat scaleLower; + CMemberULong regionID; + CMemberULong positionX; + CMemberULong positionY; + CMemberChar direction; + CMemberULong battleState; + CMemberUChar weaponSet; + CMemberULong extra1; + CMemberULong extra2; + CMemberULong extra3; + CMemberFloat combatPower; + CMemberString motionType; + CMemberUChar oddEyeLeftColor; + CMemberUChar oddEyeRightColor; + CMemberFloat life; + CMemberFloat lifeMaxBase; + CMemberFloat lifeDamaged; + CMemberFloat lifeMaxMod; + CMemberFloat mana; + CMemberFloat manaMaxBase; + CMemberFloat manaMaxMod; + CMemberFloat stamina; + CMemberFloat staminaMaxBase; + CMemberFloat staminaMaxMod; + CMemberFloat food; + CMemberFloat foodMinRatio; + CMemberUShort level; + CMemberULong cumulatedLevel; + CMemberUShort maxLevel; + CMemberUShort rebirthCount; + CMemberUShort lifeTimeSkill; + CMemberUInt64 experienceInt; + CMemberUShort age; + CMemberFloat dorcha @ 0x1220; + CMemberFloat dorchaMaxBase; + CMemberFloat tuairim; // For Bachram Boost + CMemberFloat tuairimMaxBase; // For Bachram Boost } class CAction { class CAnimatorContext { - class CFramework { - Vector3 position @ 0xA0 + class CFramework 0x200 { + Vector3 position @ 0xD0 } - CFramework* framework @ 0x4 + CFramework* framework @ 0x8 } - CCharacter* character @ 0x40 + CCharacter* character @ 0x48 CAnimatorContext* animatorContext } class CSkillMgr { class CActiveSkill { - uint16_t skillID @ 0x10 + uint16_t skillID @ 0x18 uint8_t charges uint8_t state +9 } - CActiveSkill* skillInfo @ 0x4 + CActiveSkill* skillInfo @ 0x8 } class CConditionMgr 0x50 { @@ -146,108 +146,94 @@ class CCharacter { int32_t statusCount @ 0x4 } - CCondition* condition @ 0x8 + CCondition* condition @ 0x10 } - class CEquipmentItemInfo 0x50 { - uint32_t classID @ 0xC - uint32_t color1 @ 0x1C + class CEquipmentItemInfo 0x58 { + uint32_t classID + uint32_t color1 + 0xC uint32_t color2 uint32_t color3 - uint32_t color4 @ 0x2c + uint32_t color4 + 0x14 uint32_t color5 uint32_t color6 } class CEquipment { - CEquipmentItemInfo itemInfo[20] + CEquipmentItemInfo itemInfo[20] @ 0x6C } - uint64_t* entityID @ 0x4 - CParameter* parameter @ 0xA8 + uint64_t* entityID @ 0x8 + CParameter* parameter @ 0xD8 CAction* action CSkillMgr* skill - CConditionMgr* condition +16 - CEquipment* equipment @ 0x280 - uint64_t targetID @ 0x2D8 + CConditionMgr* condition +32 + CEquipment* equipment @ 0x488 + uint64_t targetID @ 0x538 uint64_t mouseTarget +8 } class CItem { struct SItemDBDesc { - CString* type @ 0x4 - CString* displayName @ 0x34 - CString* name @ 0x3C - CString* description @ 0x40 + CString* type @ 0x8 + CString* displayName @ 0x38 + CString* name +16 + CString* description +8 + CString* longDescription uint16_t maxStackCount @ 0xcc } - uint64_t* entityID @ 0x4 - uint32_t inventoryID; //0x0008 - uint32_t itemID; //0x000C - uint32_t color1; //0x0010 - uint32_t color2; //0x0014 - uint32_t color3; //0x0018 - uint32_t color4 +4; //0x0020 - uint32_t color5; //0x0024 - uint32_t color6; //0x0028 - uint32_t stackCount; //0x002C - uint32_t positionX + 4; //0x0034 - uint32_t positionY; //0x0038 - uint32_t price +40; //0x0064 - uint32_t sellPrice; //0x0068 - uint32_t durability +4; //0x0070 - uint32_t maxDurability; //0x0074 - uint32_t originalDurability; //0x0078 - SItemDBDesc* dbDesc +92; //0x00D8 - uint64_t ownerID +28; //0x00F8 - CString* name +36; //0x0124 + uint64_t* entityID @ 0x8 + uint32_t inventoryID + uint32_t itemID + uint32_t color1 + uint32_t color2 + uint32_t color3 + uint32_t color4 +4 + uint32_t color5 + uint32_t color6 + uint32_t stackCount + uint32_t positionX + 4 + uint32_t positionY + uint32_t price + 48 + uint32_t sellPrice + uint32_t durability +4 + uint32_t maxDurability + uint32_t originalDurability + SItemDBDesc* dbDesc @ 0x100 + uint64_t ownerID @ 0x130 + CString* name @ 0x170 } -// 0x4a04410 -class CEntityList { +class CEntityList 0x100 { class CItemList { - class CCItemListNode {} class CItemListNode { - class CItemListNodeEntry { - CItem* item @ 0x10; - } - - CItemListNodeEntry* entry CItemListNode* next + CItem* item @ 0x18 } - CItemListNode* root @ 0x4 + CItemListNode** root @ 0x10 uint32_t count } class CCharacterList { - class CCharacterListNode {} - class CCharacterListNode { - class CCharacterListNodeEntry { - CCharacter* character @ 0x10; - } - - CCharacterListNodeEntry* entry + class CCharacterListNode 0x28 { CCharacterListNode* next + CCharacter* character @ 0x18 } - CCharacterListNode* root @ 0x4 + CCharacterListNode** root @ 0x10 uint32_t count } CItemList items @ 0x8 - CCharacterList characters @ 0x28 -} - -class CEntityListPtr { - CEntityList* entityList + CCharacterList characters @ 0x48 } -class CRenderer { +class CRenderer 0x100 { class CCamera { class CCameraState { - Vector3 target @ 0xC + Vector3 target @ 0x10 Vector3 position +4 Vector4 forward +8 float drawDistance @@ -263,24 +249,12 @@ class CRenderer { CCameraState* state; } - CCamera* camera @ 0x24 + CCamera* camera @ 0x38 } -class CRendererPtr { - CRenderer* renderer -} - -class CWorld { - uint64_t localPlayerID @ 0xB8 -} - -class CWorldPtr { - CWorld* world +class CWorld 0x200 { + uint64_t localPlayerID @ 0x160 } class CAccount 0x50 { } - -class CAccountPtr { - CAccount* account -} \ No newline at end of file diff --git a/mabinogi.json b/mabinogi.json index ad7b90b..bcd0745 100644 --- a/mabinogi.json +++ b/mabinogi.json @@ -5,7 +5,7 @@ }, "process": { "filter": "client", - "id": 301532, + "id": 21460, "name": "Client.exe" }, "props": { @@ -101,34 +101,6 @@ "parameter": { "parameter": { "__collapsed": false, - "age": {}, - "battleState": {}, - "combatPower": {}, - "cumulatedLevel": {}, - "direction": {}, - "dorcha": {}, - "dorchaMaxBase": {}, - "engTitle": {}, - "experienceInt": {}, - "extra1": {}, - "extra2": {}, - "extra3": {}, - "eyeColor": {}, - "eyeType": {}, - "food": {}, - "foodMinRatio": {}, - "level": {}, - "life": {}, - "lifeDamaged": {}, - "lifeMaxBase": {}, - "lifeMaxMod": {}, - "lifeTimeSkill": {}, - "mana": {}, - "manaMaxBase": {}, - "manaMaxMod": {}, - "maxLevel": {}, - "motionType": {}, - "mouthType": {}, "name": { "__collapsed": false, "value": { @@ -137,29 +109,7 @@ "__collapsed": false } } - }, - "oddEyeLeftColor": {}, - "oddEyeRightColor": {}, - "positionX": {}, - "positionY": {}, - "rebirthCount": {}, - "regionID": {}, - "scaleFatness": {}, - "scaleHeight": {}, - "scaleLower": {}, - "scaleUpper": {}, - "skinColor": {}, - "stamina": {}, - "staminaMaxBase": {}, - "staminaMaxMod": {}, - "status": {}, - "statusEx": {}, - "statusEx2": {}, - "title": {}, - "tuairim": {}, - "tuairimMaxBase": {}, - "type": {}, - "weaponSet": {} + } } }, "skill": { @@ -178,7 +128,69 @@ "CEntityList": { "__collapsed": false, "root": { - "__collapsed": false + "__collapsed": false, + "characters": {}, + "items": { + "__collapsed": false, + "root": { + "__collapsed": false, + "root": { + "__collapsed": false, + "entry": { + "__collapsed": false, + "entry": { + "__collapsed": false, + "item": { + "__collapsed": false, + "item": { + "__collapsed": false, + "dbDesc": { + "dbDesc": { + "__collapsed": false, + "description": { + "description": { + "__collapsed": false + } + }, + "displayName": { + "displayName": { + "__collapsed": false + } + }, + "longDescription": { + "longDescription": { + "__collapsed": false + } + }, + "name": { + "name": { + "__collapsed": false + } + }, + "type": { + "type": { + "__collapsed": false + } + } + } + }, + "name": { + "name": { + "__collapsed": false + } + } + } + } + } + }, + "next": { + "next": { + "__collapsed": false + } + } + } + } + } } }, "CEntityListPtr": { @@ -281,22 +293,25 @@ "state": { "__collapsed": false, "state": { - "__collapsed": false, - "forward": { - "__collapsed": false - }, - "position": { - "__collapsed": false - }, - "target": { - "__collapsed": false - } + "__collapsed": false } } } } } }, + "CRenderer.CCamera": { + "__collapsed": false, + "root": { + "__collapsed": false + } + }, + "CWorld": { + "__collapsed": false, + "root": { + "__collapsed": false + } + }, "CWorldPtr": { "__collapsed": false, "root": { @@ -314,12 +329,14 @@ "addresses": { "CAccountPtr": "0x3a4ef3c", "CCharacter": "0x88d20eb8", - "CEntityList": "0x4a04410", + "CEntityList": "0x4ee9ee0", "CEntityListPtr": "0x3ceef74", "CItem": "0x7cb223c8", - "CRenderer": "0xa9d0998", - "CWorldPtr": "0x3c2c080" + "CRenderer": "0x4ec0180", + "CRenderer.CCamera": "", + "CWorld": "0x4ef05d0", + "CWorldPtr": "0x4ef05d0" }, - "chosen": "CCharacter" + "chosen": "CWorld" } } \ No newline at end of file