From 14a25fffebbb15e032178770ad9a1bba4e7fa459 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Sat, 31 Oct 2026 01:57:28 +0000 Subject: [PATCH] Decompile 3 functions in Source/Client/Mode/GameModePackets.cpp, Source/Client/Mode/CGameMode.h Batch #6830 by superintelligence: 0 byte-identical, 3 confirmed by peer review. - fn_21668 CGameMode::ReceiveItem1740BasicList: logic confirmed by peer review - fn_21669 CGameMode::ReceiveItem1740BasicListBind: logic confirmed by peer review - fn_21720 CGameMode::ReceiveItemInventoryList: logic confirmed by peer review Peer-reviewed-by: eAthena, alisonrag, willerthal Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Mode/CGameMode.h | 3 + Source/Client/Mode/GameModePackets.cpp | 117 +++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/Source/Client/Mode/CGameMode.h b/Source/Client/Mode/CGameMode.h index 95968754..3ef5aa15 100644 --- a/Source/Client/Mode/CGameMode.h +++ b/Source/Client/Mode/CGameMode.h @@ -315,6 +315,9 @@ public: void ReceiveItem1740Add(const unsigned char* packet); void ReceiveItem1740AddOptions(const unsigned char* packet); void ReceiveItem1740AddGrade(const unsigned char* packet); + void ReceiveItem1740BasicList(const unsigned char* packet); + void ReceiveItem1740BasicListBind(const unsigned char* packet); + void ReceiveItemInventoryList(const unsigned char* packet); void ReceiveUnknown05C4Result(const unsigned char* packet); void ReceiveHpSpRecovery(const unsigned char* packet, int variant); void ReceiveUnknown173A5BC(const unsigned char* packet); diff --git a/Source/Client/Mode/GameModePackets.cpp b/Source/Client/Mode/GameModePackets.cpp index 657ce0e9..777100bc 100644 --- a/Source/Client/Mode/GameModePackets.cpp +++ b/Source/Client/Mode/GameModePackets.cpp @@ -41,6 +41,7 @@ struct SessionMessengerContext { void UpdateRandomStats(); int GetList9Size() const; + void KeepEquipment(); }; struct ClientItemLists { @@ -110,6 +111,39 @@ namespace { /* 0013 */ char name[1]; }; + struct PacketLengthHeader { + /* 0000 */ std::uint16_t packetType; + /* 0002 */ std::int16_t length; + }; + + struct Item1740Record { + /* 0000 */ std::int16_t index; + /* 0002 */ int itemId; + /* 0006 */ unsigned char type; + /* 0007 */ unsigned char identified; + /* 0008 */ std::uint16_t location; + /* 000A */ std::uint16_t wearState; + /* 000C */ unsigned char unknown_000C; + /* 000D */ unsigned char refine; + /* 000E */ std::uint32_t cards[4]; + /* 001E */ std::uint32_t expireTime; + }; + + struct Item1740EquipRecord { + /* 0000 */ std::int16_t index; + /* 0002 */ int itemId; + /* 0006 */ unsigned char type; + /* 0007 */ unsigned char identified; + /* 0008 */ std::uint16_t location; + /* 000A */ std::uint16_t wearState; + /* 000C */ unsigned char unknown_000C; + /* 000D */ unsigned char refine; + /* 000E */ std::uint32_t cards[4]; + /* 001E */ std::uint32_t expireTime; + /* 0022 */ std::uint16_t bindOnEquip; + /* 0024 */ std::uint16_t sprite; + }; + struct ItemStoreListHeader { /* 0000 */ std::uint16_t packetType; /* 0002 */ std::uint16_t length; @@ -180,6 +214,9 @@ namespace { static_assert(sizeof(StoreEquipRecord) == 0x29); static_assert(sizeof(StoreEquipOptionRecord) == 0x43); static_assert(sizeof(StoreNormalRecord) == 0x22); + static_assert(sizeof(PacketLengthHeader) == 0x04); + static_assert(sizeof(Item1740Record) == 0x22); + static_assert(sizeof(Item1740EquipRecord) == 0x26); // INLINED int CountStoreItemOptions(const StoreItemOption* options) { @@ -1523,3 +1560,83 @@ void __stdcall sub_D08640(const unsigned char* packet) { *reinterpret_cast(packet + 0xC), *reinterpret_cast(packet + 0x10)); } + +// OFFSET: 0x00D246B0 +// FUNCTION: fn_21668 +void CGameMode::ReceiveItem1740BasicList(const unsigned char* data) { + const PacketLengthHeader* packet = reinterpret_cast(data); + const int count = (packet->length - sizeof(PacketLengthHeader)) / sizeof(Item1740Record); + const Item1740Record* record = reinterpret_cast(data + sizeof(PacketLengthHeader)); + for (int i = 0; i < count; ++i, ++record) { + ITEM_INFO item; + item.unknown_0000[0] = record->type; + item.unknown_0000[1] = record->index; + item.unknown_0000[2] = record->location; + item.unknown_0000[3] = record->wearState; + item.quantity = 1; + std::memcpy(item.unknown_001C, record->cards, sizeof(record->cards)); + item.SetItemId(record->itemId); + item.identified = record->identified; + item.unknown_005D = record->unknown_000C; + item.unknown_0060 = record->refine; + item.unknown_0068 = record->expireTime; + reinterpret_cast(&g_session)->AddItem1740(item); + } + + g_session.RefreshItem1740Window(); +} + +// OFFSET: 0x00D24810 +// FUNCTION: fn_21669 +void CGameMode::ReceiveItem1740BasicListBind(const unsigned char* data) { + const PacketLengthHeader* packet = reinterpret_cast(data); + const int count = (packet->length - sizeof(PacketLengthHeader)) / sizeof(Item1740EquipRecord); + const Item1740EquipRecord* record = reinterpret_cast(data + sizeof(PacketLengthHeader)); + for (int i = 0; i < count; ++i, ++record) { + ITEM_INFO item; + item.unknown_0000[0] = record->type; + item.unknown_0000[1] = record->index; + item.unknown_0000[2] = record->location; + item.unknown_0000[3] = record->wearState; + item.quantity = 1; + std::memcpy(item.unknown_001C, record->cards, sizeof(record->cards)); + item.SetItemId(record->itemId); + item.identified = record->identified; + item.unknown_005D = record->unknown_000C; + item.unknown_0060 = record->refine; + item.unknown_0068 = record->expireTime; + item.unknown_0064 = record->bindOnEquip; + item.unknown_0070 = record->sprite; + reinterpret_cast(&g_session)->AddItem1740(item); + } + + g_session.RefreshItem1740Window(); +} + +// OFFSET: 0x00D2D770 +// FUNCTION: fn_21720 +void CGameMode::ReceiveItemInventoryList(const unsigned char* data) { + reinterpret_cast(&g_session)->KeepEquipment(); + + const PacketLengthHeader* packet = reinterpret_cast(data); + const int count = (packet->length - sizeof(PacketLengthHeader)) / sizeof(StoreNormalRecord); + const StoreNormalRecord* record = reinterpret_cast(data + sizeof(PacketLengthHeader)); + for (int i = 0; i < count; ++i, ++record) { + ITEM_INFO item; + item.unknown_0000[0] = record->type; + item.unknown_0000[1] = record->index; + item.unknown_0000[3] = record->location; + item.unknown_0000[2] = 0; + item.quantity = record->amount; + std::memcpy(item.unknown_001C, record->cards, sizeof(record->cards)); + item.SetItemId(record->itemId); + item.identified = record->flags & 1; + item.unknown_005D = 0; + item.unknown_0060 = 0; + item.unknown_0068 = record->expireTime; + item.unknown_0074[0] = (record->flags >> 1) & 1; + g_session.UpdateInventoryItem(item, 0); + } + + RefreshItemWindows(&g_windowMgr); +}