From 8125ad1ce177e284db63d425590692e78feaa0d4 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Wed, 28 Oct 2026 20:43:04 +0000 Subject: [PATCH] Decompile fn_06623 (BuildReplayTaggedRecord) Batch #1714 by ragnarok-clanker: 0 byte-identical, 1 confirmed by peer review. - fn_06623 BuildReplayTaggedRecord: logic confirmed by peer review (annotation added to existing code) Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Replay.cpp | 2 +- Source/Client/Replay.h | 2 ++ Source/Client/Session.h | 23 +++++++++++++++++++---- Source/Contents/ClientItemLists.cpp | 5 +++-- Source/Contents/Items/ItemDescription.h | 4 ++++ Source/Contents/Items/ItemInfo.cpp | 3 +++ Source/Contents/Items/ItemInfo.h | 25 ++++++++++++++++++++++++- Source/Contents/Items/ItemNaming.cpp | 11 ++++++++++- Source/Contents/Items/ItemNaming.h | 4 ++++ Source/Contents/Jobs/JobInheritance.cpp | 17 +++++++++++++++++ Source/Contents/Jobs/JobInheritance.h | 6 ++++++ 11 files changed, 93 insertions(+), 9 deletions(-) diff --git a/Source/Client/Replay.cpp b/Source/Client/Replay.cpp index 2a97ee3..0f3458c 100644 --- a/Source/Client/Replay.cpp +++ b/Source/Client/Replay.cpp @@ -26,7 +26,7 @@ static_assert(sizeof(ReplayTaggedRecordHeader) == 6); // OFFSET: 0x006DA340 // FUNCTION: fn_06623 -static std::vector BuildReplayTaggedRecord(std::uint16_t id, const void* data, std::uint32_t bytes) { +std::vector BuildReplayTaggedRecord(std::uint16_t id, const void* data, std::uint32_t bytes) { std::vector record(bytes + 6u, 0); const ReplayTaggedRecordHeader header{id, bytes}; std::memcpy(record.data(), &header, sizeof(header)); diff --git a/Source/Client/Replay.h b/Source/Client/Replay.h index ea19ca6..68b9717 100644 --- a/Source/Client/Replay.h +++ b/Source/Client/Replay.h @@ -121,6 +121,8 @@ public: bool RecordPacket(const std::vector& packet, int event, std::uint32_t delay); }; +std::vector BuildReplayTaggedRecord(std::uint16_t id, const void* data, std::uint32_t bytes); + extern int g_replayAnimationScaling; static_assert(sizeof(ReplayCachedPacket) == 0x10); diff --git a/Source/Client/Session.h b/Source/Client/Session.h index 6f3484c..73e315e 100644 --- a/Source/Client/Session.h +++ b/Source/Client/Session.h @@ -67,7 +67,9 @@ public: /* 0798 */ int m_serverTimeAdjustCount; /* 079C */ unsigned char unknown_079C[0x04]; /* 07A0 */ std::uint32_t m_averagePing; - /* 07A4 */ unsigned char unknown_07A4[0x6F4]; + /* 07A4 */ unsigned char unknown_07A4[0x10]; + /* 07B4 */ unsigned char m_playerNameKey[0x40]; + /* 07F4 */ unsigned char unknown_07F4[0x6A4]; /* 0E98 */ int unknown_0E98; /* 0E9C */ unsigned char unknown_0E9C[0x64]; /* 0F00 */ int m_robe; @@ -95,14 +97,18 @@ public: /* 1628 */ int m_job; /* 162C */ unsigned char unknown_162C[0x24]; /* 1650 */ int m_level; - /* 1654 */ unsigned char unknown_1654[0x9C]; + /* 1654 */ unsigned char unknown_1654[0x98]; + /* 16EC */ std::uint32_t unknown_16EC; /* 16F0 */ int m_zeny; /* 16F4 */ unsigned char unknown_16F4[0x1C]; /* 1710 */ std::list m_inventoryItems; - /* 1718 */ unsigned char unknown_1718[0x20]; + /* 1718 */ unsigned char unknown_1718[0x18]; + /* 1730 */ std::list unknown_1730; /* 1738 */ std::list unknown_1738; /* 1740 */ std::list unknown_1740; - /* 1748 */ unsigned char unknown_1748[0x1408]; + /* 1748 */ unsigned char unknown_1748[0xA8]; + /* 17F0 */ ItemInfo unknown_17F0[10]; + /* 21A0 */ unsigned char unknown_21A0[0x9B0]; /* 2B50 */ ItemInfo unknown_2B50[10]; /* 3500 */ ItemInfo unknown_3500[10]; /* 3EB0 */ unsigned char unknown_3EB0[0x9B0]; @@ -177,6 +183,7 @@ public: int SetPairValue(int value, int slot); int SetHotkeyEntry(char enabled, int id, int value, int slot); int SetFlag(char value); + void SetPlayerNameKey(const unsigned char* key); // INLINED NormalItemSlot& SkillHotkey(int index) { return reinterpret_cast(reinterpret_cast(this) + offsetof(CSession, unknown_06EB))[index]; @@ -240,6 +247,11 @@ public: float GetNpcLocationRadius(int job, bool riding); int GetRidingJob(int job); int GetSpriteJob(int job, int costumeJob, bool spriteIndex); + bool HasRequiredItems() const; + bool IsSlotItemIdentity(std::uint32_t id) const; + bool HasInventoryItem(std::uint32_t id) const; + bool HasItemId(int itemId) const; + bool HasItemCount(int itemId, int count) const; }; extern CSession g_session; @@ -295,6 +307,9 @@ static_assert(offsetof(CSession, unknown_0E98) == 0xE98); static_assert(offsetof(CSession, m_petActionTable) == 0x1058); static_assert(offsetof(CSession, m_job) == 0x1628); static_assert(offsetof(CSession, m_inventoryItems) == 0x1710); +static_assert(offsetof(CSession, unknown_16EC) == 0x16EC); +static_assert(offsetof(CSession, unknown_1730) == 0x1730); +static_assert(offsetof(CSession, unknown_17F0) == 0x17F0); static_assert(offsetof(CSession, unknown_2B50) == 0x2B50); static_assert(offsetof(CSession, unknown_3500) == 0x3500); static_assert(offsetof(CSession, m_accessoryNames) == 0x52B8); diff --git a/Source/Contents/ClientItemLists.cpp b/Source/Contents/ClientItemLists.cpp index aff30d5..8bffc37 100644 --- a/Source/Contents/ClientItemLists.cpp +++ b/Source/Contents/ClientItemLists.cpp @@ -4,6 +4,7 @@ #include "UI/Window/UIWindowMgr.h" #include +#include #include #include @@ -35,8 +36,8 @@ struct ClientItemLists { /* 21A0 */ ItemInfo equipped[10]; bool AddItem1710(const ItemInfo& item, unsigned char refresh); - void AddItem1718(const ItemInfo& item, int quantity, std::uint16_t unknown_006C); - void AddItem1718(const ItemInfo& item, int mode); + void AddItem1718(const RawItemBasic& item, int quantity, std::uint16_t unknown_006C); + void AddItem1718(const RawItemBasic& item, int mode); bool AddItem1768(const ItemInfo& item, unsigned char alternate, unsigned char refresh); bool AddItem1740(const ItemInfo& item); bool AddItem1750(const ItemInfo& item, int type, unsigned char refresh); diff --git a/Source/Contents/Items/ItemDescription.h b/Source/Contents/Items/ItemDescription.h index a8ce94d..94df02c 100644 --- a/Source/Contents/Items/ItemDescription.h +++ b/Source/Contents/Items/ItemDescription.h @@ -34,9 +34,13 @@ struct ItemDescriptions { int Name(const ItemInfo& item, char* output, int& capacity, unsigned char consume); }; +extern std::map g_itemDescriptions; +extern std::map> g_metalProcessItems; + ITEM_DESC& FindItemDescription(int id); ItemCardName& EnsureItemCardName(int id, std::map& values); std::vector& EnsureItemDescriptionLines(int id, std::map>& values); +const std::vector& FindMetalProcessItems(int id); #if defined(_WIN32) && !defined(_WIN64) static_assert(sizeof(ITEM_DESC) == 68); diff --git a/Source/Contents/Items/ItemInfo.cpp b/Source/Contents/Items/ItemInfo.cpp index 5db5eff..1dea338 100644 --- a/Source/Contents/Items/ItemInfo.cpp +++ b/Source/Contents/Items/ItemInfo.cpp @@ -1,4 +1,7 @@ #include "Contents/Items/ItemInfo.h" +#include "Client/Session.h" +#include "Contents/Items/ItemDescription.h" +#include "Contents/Items/ItemNaming.h" #include #include diff --git a/Source/Contents/Items/ItemInfo.h b/Source/Contents/Items/ItemInfo.h index dd65e7f..1781d37 100644 --- a/Source/Contents/Items/ItemInfo.h +++ b/Source/Contents/Items/ItemInfo.h @@ -1,9 +1,11 @@ #ifndef RAGNAROK_SOURCE_CONTENTS_ITEMS_ITEMINFO_H #define RAGNAROK_SOURCE_CONTENTS_ITEMS_ITEMINFO_H +#include #include #include #include +#include struct RawItemData { /* 0000 */ std::uint32_t unknown_0000; @@ -35,6 +37,23 @@ struct RawItemData { static_assert(sizeof(RawItemData) == 188); #endif +struct RawItemBasic { + /* 0000 */ std::int32_t id; + /* 0004 */ std::uint32_t unknown_0004; + /* 0008 */ std::uint32_t unknown_0008; + /* 000C */ std::uint32_t unknown_000C; + /* 0010 */ unsigned char identified; + /* 0011 */ char itemId[33]; + /* 0034 */ std::uint32_t unknown_0034; + /* 0038 */ std::int32_t unknown_0038; +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(offsetof(RawItemBasic, itemId) == 0x11); +static_assert(offsetof(RawItemBasic, unknown_0034) == 0x34); +static_assert(offsetof(RawItemBasic, unknown_0038) == 0x38); +#endif + struct alignas(8) ItemInfo { ItemInfo(); explicit ItemInfo(int unused); @@ -42,7 +61,7 @@ struct alignas(8) ItemInfo { ItemInfo& operator=(const ItemInfo& other); void Reset(); std::uint32_t Assign(const RawItemData& item); - ItemInfo& AssignBasic(const RawItemData& item); + ItemInfo& AssignBasic(const RawItemBasic& item); bool operator<(const ItemInfo& other) const; bool SetName(const char* name); void SetItemId(int value); @@ -52,6 +71,7 @@ struct alignas(8) ItemInfo { bool IsElementalStone() const; bool IsAboveItemId600() const; int Refine(char* output, int& capacity, unsigned char consume) const; + std::vector Serialize() const; /* 0000 */ std::uint32_t unknown_0000[4]; /* 0010 */ std::int32_t quantity; /* 0014 */ std::uint32_t unknown_0014[2]; @@ -81,6 +101,9 @@ struct alignas(8) ItemInfo { ItemInfo LookupClientItem(const std::list& values, int id, unsigned char requireIdentified); ItemInfo LookupClientItemByIdentity(const std::list& values, std::uint32_t id); bool IsNumericText(const char* text); +bool MatchItemName(std::string name, std::string query, unsigned char partial, std::list* result, int id); +std::list SearchItemIds(std::string query, unsigned char cardsOnly, unsigned char partial); + #if defined(_WIN32) && !defined(_WIN64) static_assert(sizeof(ItemInfo) == 248); diff --git a/Source/Contents/Items/ItemNaming.cpp b/Source/Contents/Items/ItemNaming.cpp index 26ee223..4552328 100644 --- a/Source/Contents/Items/ItemNaming.cpp +++ b/Source/Contents/Items/ItemNaming.cpp @@ -1,3 +1,4 @@ +#include "Client/Replay.h" #include "Contents/Items/ItemInfo.h" #include "Contents/Items/ItemNaming.h" #include "Utility/Text/FormatString.h" @@ -6,6 +7,13 @@ #include #include +#include + +// GLOBAL: gl_24726 +std::map> g_metalProcessItems; + +// GLOBAL: gl_24675 +std::map g_itemCardNames; namespace { // OFFSET: 0x006D8810 @@ -356,7 +364,6 @@ std::string ItemNaming::DisplayName(const ItemInfo& item, unsigned char detailed return result; } - // OFFSET: 0x005E11E0 // OFFSET: 0x006D69C0 @@ -389,6 +396,8 @@ int ItemUnidentifiedName(const ItemInfo& item, char* output, int& capacity, unsi return written; } +// OFFSET: 0x006D3770 + // OFFSET: 0x006D78C0 struct ItemNamingContext : public ItemNaming { diff --git a/Source/Contents/Items/ItemNaming.h b/Source/Contents/Items/ItemNaming.h index 784993c..393a189 100644 --- a/Source/Contents/Items/ItemNaming.h +++ b/Source/Contents/Items/ItemNaming.h @@ -34,6 +34,10 @@ struct ItemNaming { const char* Message(int id) const; }; +extern std::map g_itemCardNames; + +ItemCardName& FindItemCardName(int id, std::map& values); + #if defined(_WIN32) && !defined(_WIN64) static_assert(sizeof(ItemCardName) == 12); static_assert(offsetof(ItemCardName, name) == 0x0000); diff --git a/Source/Contents/Jobs/JobInheritance.cpp b/Source/Contents/Jobs/JobInheritance.cpp index 6dfd18c..613d49d 100644 --- a/Source/Contents/Jobs/JobInheritance.cpp +++ b/Source/Contents/Jobs/JobInheritance.cpp @@ -9,6 +9,19 @@ #include "Script/LuaScript.h" #include +#include + +// GLOBAL: gl_24496 +int g_screenShakeDuration; + +// GLOBAL: gl_24497 +char g_screenShakeMode; + +// GLOBAL: gl_24702 +const char g_playerNameKeyData[] = "가나다라마바사아자차카타파하가나다라마바사아자차카타파하"; + +// GLOBAL: gl_24649 +const char* g_playerNameKey = g_playerNameKeyData; namespace { // OFFSET: 0x00DFBC00 @@ -581,3 +594,7 @@ int CSession::SetFlag(char value) { this->unknown_5558 = result; return result; } + +// OFFSET: 0x00DFB490 + +// OFFSET: 0x00E25DD0 diff --git a/Source/Contents/Jobs/JobInheritance.h b/Source/Contents/Jobs/JobInheritance.h index 8382a6f..653f245 100644 --- a/Source/Contents/Jobs/JobInheritance.h +++ b/Source/Contents/Jobs/JobInheritance.h @@ -22,5 +22,11 @@ bool __stdcall IsJobWeaponAllowed(int job, int slot, std::int64_t weapon); int __stdcall GetRealWeaponId(int weapon); std::string GetJobTitleString(int job); bool ResetHotkeySlots(); +bool IsScreenShakeActive(); + +extern int g_screenShakeDuration; +extern char g_screenShakeMode; +extern const char g_playerNameKeyData[]; +extern const char* g_playerNameKey; #endif