From eef095a19592bb9db816ca5cf133cbd148b2ba98 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Fri, 30 Oct 2026 17:47:26 +0000 Subject: [PATCH] Decompile 2 functions in Source/Contents/ClientState.cpp, Source/Client/Session.h Batch #5904 by ragnarok-clanker: 0 byte-identical, 2 confirmed by peer review. - fn_24210 CSession::ReadReplayStats: logic confirmed by peer review - fn_24216 CSession::ReadReplayCompanions: logic confirmed by peer review Peer-reviewed-by: ntrl, Snow, SapitoSucio Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Session.h | 72 ++++- Source/Contents/ClientState.cpp | 516 ++++++++++++++++++++++++++++++++ 2 files changed, 577 insertions(+), 11 deletions(-) diff --git a/Source/Client/Session.h b/Source/Client/Session.h index bbb8a29a..b35b3bcb 100644 --- a/Source/Client/Session.h +++ b/Source/Client/Session.h @@ -154,7 +154,8 @@ public: /* 0F38 */ int cartMaxCount; /* 0F3C */ int cartWeight; /* 0F40 */ int cartMaxWeight; - /* 0F44 */ unsigned char unknown_0F44[0x0C]; + /* 0F44 */ unsigned char unknown_0F44[8]; + /* 0F4C */ int unknown_0F4C; /* 0F50 */ int unknown_0F50; /* 0F54 */ unsigned char unknown_0F54[0x18]; /* 0F6C */ const char* const* m_humanMaleHeadNames; @@ -172,11 +173,15 @@ public: /* 0FF8 */ unsigned char unknown_0FF8[0x18]; /* 1010 */ std::uint32_t unknown_1010; /* 1014 */ unsigned char unknown_1014[4]; - /* 1018 */ char unknown_1018[0x24]; + /* 1018 */ char unknown_1018[0x20]; + /* 1038 */ int unknown_1038; /* 103C */ int unknown_103C; - /* 1040 */ unsigned char unknown_1040[0x0C]; + /* 1040 */ int unknown_1040; + /* 1044 */ int unknown_1044; + /* 1048 */ unsigned char unknown_1048[4]; /* 104C */ int m_petFriendly; - /* 1050 */ unsigned char unknown_1050[0x08]; + /* 1050 */ int unknown_1050; + /* 1054 */ int unknown_1054; /* 1058 */ int m_petActionTable[5][5][7]; /* 1314 */ unsigned char unknown_1314[0x258]; /* 156C */ XmlDocument m_petTalkTable; @@ -193,7 +198,13 @@ public: /* 1658 */ int m_jobLevel; /* 165C */ unsigned char unknown_165C[0x04]; /* 1660 */ int m_guildSkillPoint; - /* 1664 */ unsigned char unknown_1664[0x20]; + /* 1664 */ unsigned char unknown_1664[8]; + /* 166C */ int unknown_166C; + /* 1670 */ int unknown_1670; + /* 1674 */ int unknown_1674; + /* 1678 */ int unknown_1678; + /* 167C */ int unknown_167C; + /* 1680 */ int unknown_1680; /* 1684 */ int m_standardStats[6]; /* 169C */ unsigned char unknown_169C[0x50]; /* 16EC */ std::uint32_t unknown_16EC; @@ -247,7 +258,17 @@ public: /* 52C4 */ std::vector m_robeNames; /* 52D0 */ std::vector m_navigationForbiddenMaps; /* 52DC */ std::vector> m_commandOptions; - /* 52E8 */ unsigned char unknown_52E8[0x160]; + /* 52E8 */ unsigned char unknown_52E8[0x44]; + /* 532C */ int unknown_532C; + /* 5330 */ int unknown_5330; + /* 5334 */ int unknown_5334; + /* 5338 */ int unknown_5338; + /* 533C */ int unknown_533C; + /* 5340 */ unsigned char unknown_5340[0x30]; + /* 5370 */ unsigned char unknown_5370[0x30]; + /* 53A0 */ unsigned char unknown_53A0[0x30]; + /* 53D0 */ unsigned char unknown_53D0[0x30]; + /* 5400 */ unsigned char unknown_5400[0x48]; /* 5448 */ int unknown_5448; /* 544C */ unsigned char unknown_544C[0x04]; /* 5450 */ int unknown_5450; @@ -258,7 +279,12 @@ public: /* 546C */ unsigned char unknown_546C[0x04]; /* 5470 */ int unknown_5470; /* 5474 */ int unknown_5474; - /* 5478 */ unsigned char unknown_5478[0x28]; + /* 5478 */ unsigned char unknown_5478[8]; + /* 5480 */ int unknown_5480; + /* 5484 */ int unknown_5484; + /* 5488 */ int unknown_5488; + /* 548C */ int unknown_548C; + /* 5490 */ unsigned char unknown_5490[0x10]; /* 54A0 */ int unknown_54A0; /* 54A4 */ int unknown_54A4; /* 54A8 */ int unknown_54A8; @@ -277,10 +303,22 @@ public: /* 55C4 */ int m_homunHp; /* 55C8 */ unsigned char unknown_55C8[0x04]; /* 55CC */ int m_homunSp; - /* 55D0 */ unsigned char unknown_55D0[0x10]; + /* 55D0 */ int unknown_55D0; + /* 55D4 */ int unknown_55D4; + /* 55D8 */ int unknown_55D8; + /* 55DC */ unsigned char unknown_55DC[4]; /* 55E0 */ std::int64_t m_homunExp; /* 55E8 */ std::int64_t m_homunMaxExp; - /* 55F0 */ unsigned char unknown_55F0[0x28]; + /* 55F0 */ int unknown_55F0; + /* 55F4 */ int unknown_55F4; + /* 55F8 */ int unknown_55F8; + /* 55FC */ int unknown_55FC; + /* 5600 */ int unknown_5600; + /* 5604 */ int unknown_5604; + /* 5608 */ int unknown_5608; + /* 560C */ int unknown_560C; + /* 5610 */ int unknown_5610; + /* 5614 */ int unknown_5614; /* 5618 */ int m_traceAi; /* 561C */ int m_homunActionState; /* 5620 */ unsigned char unknown_5620[0xC]; @@ -297,7 +335,13 @@ public: /* 568C */ int m_mercenaryKills; /* 5690 */ unsigned char unknown_5690[4]; /* 5694 */ __time32_t m_mercenaryExpiration; - /* 5698 */ unsigned char unknown_5698[0x1C]; + /* 5698 */ int unknown_5698; + /* 569C */ int unknown_569C; + /* 56A0 */ int unknown_56A0; + /* 56A4 */ int unknown_56A4; + /* 56A8 */ int unknown_56A8; + /* 56AC */ int unknown_56AC; + /* 56B0 */ int unknown_56B0; /* 56B4 */ int m_mercenaryActionState; /* 56B8 */ unsigned char unknown_56B8[0x242]; /* 58FA */ char unknown_58FA[0x18]; @@ -326,7 +370,11 @@ public: /* 5B78 */ PartyBookingMgr m_partyBooking; /* 5BBC */ unsigned char unknown_5BBC[0x04]; /* 5BC0 */ int unknown_5BC0; - /* 5BC4 */ unsigned char unknown_5BC4[0x2C]; + /* 5BC4 */ int unknown_5BC4; + /* 5BC8 */ int unknown_5BC8; + /* 5BCC */ int unknown_5BCC; + /* 5BD0 */ int unknown_5BD0; + /* 5BD4 */ unsigned char unknown_5BD4[0x1C]; /* 5BF0 */ std::uint32_t unknown_5BF0; /* 5BF4 */ int m_pairValues[3]; /* 5C00 */ unsigned char unknown_5C00[0x1C]; @@ -594,6 +642,8 @@ public: std::string GetWeaponEffectActName(int job, int sex, int weapon, int weaponItem, int effect, int costume); std::string GetWeaponEffectSprName(int job, int sex, int weapon, int weaponItem, int effect, int costume); void CollectCardItems(); + std::uint32_t ReadReplayStats(const std::vector& data); + std::uint32_t ReadReplayCompanions(const std::vector& data); std::uint32_t ReadReplayMessenger(const std::vector& data); std::uint32_t ReadReplayItems(const std::vector& data); std::uint32_t ReadReplayShops(const std::vector& data); diff --git a/Source/Contents/ClientState.cpp b/Source/Contents/ClientState.cpp index d8e2f2e7..a24fb27c 100644 --- a/Source/Contents/ClientState.cpp +++ b/Source/Contents/ClientState.cpp @@ -1,7 +1,11 @@ #include "Contents/ClientState.h" +#include "Client/Mode/CGameMode.h" +#include "Client/Mode/ModeMgr.h" #include "Client/Session.h" +#include "Contents/Actors/Pc.h" #include "Contents/MessageTable.h" +#include "Contents/World/World.h" #include "UI/Window/UIWindow.h" #include "UI/Window/UIWindowMgr.h" @@ -43,6 +47,175 @@ bool g_homunculusAutoFeed; // GLOBAL: gl_24493 bool g_petAutoFeed; +// OFFSET: 0x00E46040 +// FUNCTION: fn_24210 +std::uint32_t CSession::ReadReplayStats(const std::vector& data) { + if (data.begin() == data.end()) { + return 0xFFFFFFFF; + } + + std::uint32_t offset = 6; + ReplayBlockHeader header{}; + std::memcpy(&header, data.data(), sizeof(header)); + if (header.id != 2000) { + return 0xFFFFFFFF; + } + + while (offset < data.size()) { + header = {}; + std::memcpy(&header, data.data() + offset, sizeof(header)); + offset += 6; + const unsigned char* source = data.data() + offset; + if (header.id == 2001) { + break; + } + + switch (header.id) { + case 2010: + std::memcpy(&this->unknown_166C, source, header.bytes); + offset += header.bytes; + break; + case 2011: + std::memcpy(&this->unknown_1670, source, header.bytes); + offset += header.bytes; + break; + case 2012: + std::memcpy(&this->unknown_1674, source, header.bytes); + offset += header.bytes; + break; + case 2013: + std::memcpy(&this->unknown_1678, source, header.bytes); + offset += header.bytes; + break; + case 2014: + std::memcpy(&this->unknown_167C, source, header.bytes); + offset += header.bytes; + break; + case 2015: + std::memcpy(&this->unknown_1680, source, header.bytes); + offset += header.bytes; + break; + case 2016: + std::memcpy(&this->unknown_0F4C, source, header.bytes); + offset += header.bytes; + break; + case 2017: + std::memcpy(&this->m_weight, source, header.bytes); + offset += header.bytes; + break; + case 2018: + std::memcpy(&this->m_maxWeight, source, header.bytes); + offset += header.bytes; + break; + case 2019: + std::memcpy(&this->unknown_532C, source, header.bytes); + offset += header.bytes; + break; + case 2020: + std::memcpy(&this->unknown_5330, source, header.bytes); + offset += header.bytes; + break; + case 2021: + std::memcpy(&this->unknown_5334, source, header.bytes); + offset += header.bytes; + break; + case 2022: + std::memcpy(&this->unknown_5338, source, header.bytes); + offset += header.bytes; + break; + case 2023: + std::memcpy(&this->unknown_533C, source, header.bytes); + offset += header.bytes; + break; + case 2024: + std::memcpy(this->unknown_5340, source, header.bytes); + offset += header.bytes; + break; + case 2025: + std::memcpy(this->unknown_5370, source, header.bytes); + offset += header.bytes; + break; + case 2026: + std::memcpy(this->unknown_53A0, source, header.bytes); + offset += header.bytes; + break; + case 2027: + std::memcpy(this->unknown_53D0, source, header.bytes); + offset += header.bytes; + break; + case 2028: + std::memcpy(this->unknown_5400, source, header.bytes); + offset += header.bytes; + break; + case 2029: + std::memcpy(&this->unknown_5568, source, header.bytes); + offset += header.bytes; + break; + case 2030: + std::memcpy(&this->unknown_556C, source, header.bytes); + offset += header.bytes; + break; + case 2031: + std::memcpy(&this->unknown_5570[0], source, header.bytes); + offset += header.bytes; + break; + case 2032: + std::memcpy(&this->unknown_5570[4], source, header.bytes); + offset += header.bytes; + break; + case 2033: + std::memcpy(&this->m_prohibitionTarget, source, header.bytes); + offset += header.bytes; + break; + case 2034: + std::memcpy(&this->unknown_5480, source, header.bytes); + offset += header.bytes; + break; + case 2035: + std::memcpy(&this->unknown_5484, source, header.bytes); + offset += header.bytes; + break; + case 2036: + std::memcpy(&this->unknown_5488, source, header.bytes); + offset += header.bytes; + break; + case 2037: + std::memcpy(&this->unknown_548C, source, header.bytes); + offset += header.bytes; + break; + case 2038: + this->m_accountName.resize(header.bytes); + std::memcpy(this->m_accountName.data(), data.data() + offset, header.bytes); + offset += header.bytes; + break; + case 2052: { + std::memcpy(&this->unknown_8074, source, header.bytes); + offset += header.bytes; + CPlayer* player = static_cast(g_modeMgr.GetGameMode())->scene->player; + if (player) { + player->Slot57(this->unknown_8074); + player->SendMsg(nullptr, this->unknown_8074 ? 105 : 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + break; + } + default: + offset += header.bytes; + break; + } + } + + if (g_windowMgr.unknown_04FC == 0) { + g_windowMgr.unknown_04FC = 1; + for (UIWindow* window : g_windowMgr.rendered) { + if (window->Slot03()) { + window->InvalidateChildren(); + } + } + } + + return offset; +} + // OFFSET: 0x00E46620 // FUNCTION: fn_24211 std::uint32_t CSession::ReadReplayMessenger(const std::vector& data) { @@ -345,6 +518,349 @@ std::uint32_t CSession::ReadReplayReserved(const std::vector&) { return 0; } +// OFFSET: 0x00E47420 +// FUNCTION: fn_24216 +std::uint32_t CSession::ReadReplayCompanions(const std::vector& data) { + if (data.begin() == data.end()) { + return 0xFFFFFFFF; + } + + std::uint32_t offset = 6; + ReplayBlockHeader header{}; + std::memcpy(&header, data.data(), sizeof(header)); + if (header.id != 5000) { + return 0xFFFFFFFF; + } + + while (offset < data.size()) { + header = {}; + std::memcpy(&header, data.data() + offset, sizeof(header)); + offset += 6; + const unsigned char* source = data.data() + offset; + switch (header.id) { + case 5001: + return offset; + case 5101: + std::memcpy(&this->unknown_5570[8], source, header.bytes); + offset += header.bytes; + break; + case 5102: + std::memcpy(&this->unknown_5570[0xC], source, header.bytes); + offset += header.bytes; + break; + case 5103: + std::memcpy(&this->unknown_5570[0x2C], source, header.bytes); + offset += header.bytes; + break; + case 5104: + std::memcpy(&this->unknown_5570[0x30], source, header.bytes); + offset += header.bytes; + break; + case 5105: + std::memcpy(&this->unknown_5570[0x34], source, header.bytes); + offset += header.bytes; + break; + case 5106: + std::memcpy(&this->unknown_5570[0x38], source, header.bytes); + offset += header.bytes; + break; + case 5107: + std::memcpy(&this->unknown_5570[0x3C], source, header.bytes); + offset += header.bytes; + break; + case 5108: + std::memcpy(&this->unknown_5570[0x40], source, header.bytes); + offset += header.bytes; + break; + case 5109: + std::memcpy(&this->unknown_5570[0x44], source, header.bytes); + offset += header.bytes; + break; + case 5110: + std::memcpy(&this->unknown_5570[0x48], source, header.bytes); + offset += header.bytes; + break; + case 5111: + std::memcpy(&this->m_homunJob, source, header.bytes); + offset += header.bytes; + break; + case 5112: + std::memcpy(this->unknown_55C0, source, header.bytes); + offset += header.bytes; + break; + case 5113: + std::memcpy(&this->m_homunHp, source, header.bytes); + offset += header.bytes; + break; + case 5114: + std::memcpy(this->unknown_55C8, source, header.bytes); + offset += header.bytes; + break; + case 5115: + std::memcpy(&this->m_homunSp, source, header.bytes); + offset += header.bytes; + break; + case 5116: + std::memcpy(&this->unknown_55D0, source, header.bytes); + offset += header.bytes; + break; + case 5117: + std::memcpy(&this->unknown_55D4, source, header.bytes); + offset += header.bytes; + break; + case 5118: + std::memcpy(&this->unknown_55D8, source, header.bytes); + offset += header.bytes; + break; + case 5119: + std::memcpy(&this->m_homunExp, source, header.bytes); + offset += header.bytes; + break; + case 5120: + std::memcpy(&this->m_homunMaxExp, source, header.bytes); + offset += header.bytes; + break; + case 5121: + std::memcpy(&this->unknown_55F0, source, header.bytes); + offset += header.bytes; + break; + case 5122: + std::memcpy(&this->unknown_55F4, source, header.bytes); + offset += header.bytes; + break; + case 5123: + std::memcpy(&this->unknown_55F8, source, header.bytes); + offset += header.bytes; + break; + case 5124: + std::memcpy(&this->unknown_55FC, source, header.bytes); + offset += header.bytes; + break; + case 5125: + std::memcpy(&this->unknown_5600, source, header.bytes); + offset += header.bytes; + break; + case 5126: + std::memcpy(&this->unknown_5604, source, header.bytes); + offset += header.bytes; + break; + case 5127: + std::memcpy(&this->unknown_5608, source, header.bytes); + offset += header.bytes; + break; + case 5128: + std::memcpy(&this->unknown_560C, source, header.bytes); + offset += header.bytes; + break; + case 5129: + std::memcpy(&this->unknown_5610, source, header.bytes); + offset += header.bytes; + break; + case 5130: + std::memcpy(&this->unknown_5614, source, header.bytes); + offset += header.bytes; + break; + case 5131: + std::memcpy(&this->m_traceAi, source, header.bytes); + offset += header.bytes; + break; + case 5132: + std::memcpy(&this->m_homunActionState, source, header.bytes); + offset += header.bytes; + break; + case 5133: + std::memcpy(&this->unknown_5620[0], source, header.bytes); + offset += header.bytes; + break; + case 5134: + std::memcpy(&this->unknown_5620[4], source, header.bytes); + offset += header.bytes; + break; + case 5201: + std::memcpy(&this->unknown_5620[8], source, header.bytes); + offset += header.bytes; + break; + case 5202: + std::memcpy(this->m_mercenaryName, source, header.bytes); + offset += header.bytes; + break; + case 5203: + std::memcpy(&this->m_mercenaryStats[0], source, header.bytes); + offset += header.bytes; + break; + case 5204: + std::memcpy(&this->m_mercenaryStats[1], source, header.bytes); + offset += header.bytes; + break; + case 5205: + std::memcpy(&this->m_mercenaryStats[2], source, header.bytes); + offset += header.bytes; + break; + case 5206: + std::memcpy(&this->m_mercenaryStats[3], source, header.bytes); + offset += header.bytes; + break; + case 5207: + std::memcpy(&this->m_mercenaryStats[4], source, header.bytes); + offset += header.bytes; + break; + case 5208: + std::memcpy(&this->m_mercenaryStats[5], source, header.bytes); + offset += header.bytes; + break; + case 5209: + std::memcpy(&this->m_mercenaryStats[6], source, header.bytes); + offset += header.bytes; + break; + case 5210: + std::memcpy(&this->m_mercenaryStats[7], source, header.bytes); + offset += header.bytes; + break; + case 5211: + std::memcpy(&this->m_mercenaryHp, source, header.bytes); + offset += header.bytes; + break; + case 5212: + std::memcpy(&this->m_mercenaryMaxHp, source, header.bytes); + offset += header.bytes; + break; + case 5213: + std::memcpy(&this->m_mercenaryClass, source, header.bytes); + offset += header.bytes; + break; + case 5214: + std::memcpy(&this->m_mercenaryLevel, source, header.bytes); + offset += header.bytes; + break; + case 5215: + std::memcpy(&this->m_mercenarySp, source, header.bytes); + offset += header.bytes; + break; + case 5216: + std::memcpy(&this->m_mercenaryMaxSp, source, header.bytes); + offset += header.bytes; + break; + case 5217: + std::memcpy(&this->m_mercenaryLoyalty, source, header.bytes); + offset += header.bytes; + break; + case 5218: + std::memcpy(&this->m_mercenarySummons, source, header.bytes); + offset += header.bytes; + break; + case 5219: + std::memcpy(&this->m_mercenaryKills, source, header.bytes); + offset += header.bytes; + break; + case 5220: + std::memcpy(this->unknown_5690, source, header.bytes); + offset += header.bytes; + break; + case 5221: + std::memcpy(&this->m_mercenaryExpiration, source, header.bytes); + offset += header.bytes; + break; + case 5222: + std::memcpy(&this->unknown_5698, source, header.bytes); + offset += header.bytes; + break; + case 5223: + std::memcpy(&this->unknown_569C, source, header.bytes); + offset += header.bytes; + break; + case 5224: + std::memcpy(&this->unknown_56A0, source, header.bytes); + offset += header.bytes; + break; + case 5225: + std::memcpy(&this->unknown_56A4, source, header.bytes); + offset += header.bytes; + break; + case 5226: + std::memcpy(&this->unknown_56A8, source, header.bytes); + offset += header.bytes; + break; + case 5227: + std::memcpy(&this->unknown_56AC, source, header.bytes); + offset += header.bytes; + break; + case 5228: + std::memcpy(&this->unknown_56B0, source, header.bytes); + offset += header.bytes; + break; + case 5229: + std::memcpy(&this->m_mercenaryActionState, source, header.bytes); + offset += header.bytes; + break; + case 5301: + std::memcpy(&this->unknown_1010, source, header.bytes); + offset += header.bytes; + break; + case 5302: + std::memcpy(this->unknown_1014, source, header.bytes); + offset += header.bytes; + break; + case 5303: + std::memcpy(this->unknown_1018, source, header.bytes); + offset += header.bytes; + break; + case 5304: + std::memcpy(&this->unknown_1038, source, header.bytes); + offset += header.bytes; + break; + case 5305: + std::memcpy(&this->unknown_103C, source, header.bytes); + offset += header.bytes; + break; + case 5306: + std::memcpy(&this->unknown_1040, source, header.bytes); + offset += header.bytes; + break; + case 5307: + std::memcpy(&this->unknown_1044, source, header.bytes); + offset += header.bytes; + break; + case 5308: + std::memcpy(&this->m_petFriendly, source, header.bytes); + offset += header.bytes; + break; + case 5309: + std::memcpy(&this->unknown_1050, source, header.bytes); + offset += header.bytes; + break; + case 5310: + std::memcpy(&this->unknown_1054, source, header.bytes); + offset += header.bytes; + break; + case 5401: + std::memcpy(&this->unknown_5BC0, source, header.bytes); + offset += header.bytes; + break; + case 5402: + std::memcpy(&this->unknown_5BC4, source, header.bytes); + offset += header.bytes; + break; + case 5403: + std::memcpy(&this->unknown_5BC8, source, header.bytes); + offset += header.bytes; + break; + case 5404: + std::memcpy(&this->unknown_5BCC, source, header.bytes); + offset += header.bytes; + break; + case 5405: + std::memcpy(&this->unknown_5BD0, source, header.bytes); + offset += header.bytes; + break; + default: + offset += header.bytes; + break; + } + } + + return offset; +} + // OFFSET: 0x00E488C0 // FUNCTION: fn_24221 void CSession::UpdateBodyStyle(int job, int style, int renderJob) {