diff --git a/Source/Client/Session.h b/Source/Client/Session.h index f43440bf..144a02fc 100644 --- a/Source/Client/Session.h +++ b/Source/Client/Session.h @@ -728,6 +728,7 @@ public: std::uint32_t ReadReplayItems(const std::vector& data); std::uint32_t ReadReplayShops(const std::vector& data); std::uint32_t ReadReplayExtra(const std::vector& data); + std::uint32_t ReadReplayShortcuts(const std::vector& data); std::uint32_t ReadReplayReserved(const std::vector& data); std::uint32_t ReadReplayEntryQueue(const std::vector& data); std::vector BuildShortcutReplayRecords(); diff --git a/Source/Contents/ClientState.cpp b/Source/Contents/ClientState.cpp index 4e5451d5..b06c60a0 100644 --- a/Source/Contents/ClientState.cpp +++ b/Source/Contents/ClientState.cpp @@ -912,6 +912,46 @@ std::uint32_t CSession::ReadReplayQuests(const std::vector& data) return offset; } +// OFFSET: 0x00E482B0 +// FUNCTION: fn_24218 +std::uint32_t CSession::ReadReplayShortcuts(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 != 7000) { + return 0xFFFFFFFF; + } + + while (offset < data.size()) { + header = {}; + std::memcpy(&header, data.data() + offset, sizeof(header)); + offset += 6; + switch (header.id) { + case 7001: + return offset; + case 7100: + g_session.ClearShortcutSlots(); + std::memcpy(this->m_shortcutSlots, data.data() + offset, header.bytes); + offset += header.bytes; + break; + case 7101: + g_session.ClearSlots06EB(); + std::memcpy(&this->unknown_06EB, data.data() + offset, 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) {