From f8fd233fcd92365170593ca72224616fdf1ca39b Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Fri, 30 Oct 2026 10:52:50 +0000 Subject: [PATCH] Decompile 2 functions in Source/Contents/ClientItemLists.cpp, Source/Client/Mode/CGameMode.h Batch #5341 by eAthena: 0 byte-identical, 2 confirmed by peer review. - fn_21833 CGameMode::ReceiveItemListPart: logic confirmed by peer review - fn_21834 CGameMode::RefreshItemListWindow: logic confirmed by peer review Peer-reviewed-by: bigodeira, tayoba, SapitoSucio Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Mode/CGameMode.h | 2 + Source/Contents/ClientItemLists.cpp | 69 +++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/Source/Client/Mode/CGameMode.h b/Source/Client/Mode/CGameMode.h index 2c38815f..9a1cd84c 100644 --- a/Source/Client/Mode/CGameMode.h +++ b/Source/Client/Mode/CGameMode.h @@ -212,6 +212,8 @@ public: void ReceiveMessageBox(const unsigned char* packet); void NotifyCaptchaRegistered(); void ReceiveItem1784List(const unsigned char* packet); + void ReceiveItemListPart(unsigned char listType, int count, const unsigned char* data); + void RefreshItemListWindow(unsigned char listType, bool partial); }; #if defined(_WIN32) && !defined(_WIN64) diff --git a/Source/Contents/ClientItemLists.cpp b/Source/Contents/ClientItemLists.cpp index 45eeb5b4..e9d6e62d 100644 --- a/Source/Contents/ClientItemLists.cpp +++ b/Source/Contents/ClientItemLists.cpp @@ -107,6 +107,17 @@ namespace { /* 0008 */ int characterId; /* 000C */ char name[24]; }; + + struct ItemListRecord { + /* 0000 */ std::int16_t index; + /* 0002 */ int itemId; + /* 0006 */ unsigned char type; + /* 0007 */ std::int16_t amount; + /* 0009 */ int location; + /* 000D */ std::uint32_t cards[4]; + /* 001D */ int expireTime; + /* 0021 */ unsigned char flags; + }; #pragma pack(pop) bool IsSameItem(const ITEM_INFO& value, const ITEM_INFO& item) { @@ -151,6 +162,7 @@ static_assert(sizeof(ItemRandomOption) == 5); static_assert(sizeof(ItemAddPacket) == 0x20); static_assert(sizeof(ItemAddOptionsPacket) == 0x39); static_assert(sizeof(ItemAddGradePacket) == 0x3A); +static_assert(sizeof(ItemListRecord) == 0x22); #endif struct ClientItemLists { @@ -496,6 +508,63 @@ void CGameMode::ReceiveItem1738AddGrade(const unsigned char* data) { reinterpret_cast(&g_session)->AddItem1738(item, 1); } +// OFFSET: 0x00D443F0 +// FUNCTION: fn_21833 +void CGameMode::ReceiveItemListPart(unsigned char listType, int count, const unsigned char* data) { + const ItemListRecord* record = reinterpret_cast(data); + 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.unknown_005D = 0; + item.identified = record->flags & 1; + item.unknown_0068 = record->expireTime; + item.unknown_0060 = 0; + item.unknown_0074[0] = (record->flags >> 1) & 1; + switch (listType) { + case 0: + g_session.UpdateInventoryItem(item, 0); + break; + case 1: + reinterpret_cast(&g_session)->AddItem1740(item); + break; + case 2: + case 3: + reinterpret_cast(&g_session)->AddItem1738(item, 0); + break; + } + } +} + +// OFFSET: 0x00D44580 +// FUNCTION: fn_21834 +void CGameMode::RefreshItemListWindow(unsigned char listType, bool partial) { + if (partial) { + return; + } + + switch (listType) { + case 0: + RefreshItemWindows(&g_windowMgr); + break; + case 1: + g_session.RefreshItem1740Window(); + break; + case 2: + case 3: + if (UIWindow* window = g_windowMgr.window_0288) { + window->SendMsg(nullptr, 23, 0, 0, 0, 0); + reinterpret_cast(window)[0x190] = 1; + } + break; + } +} + // OFFSET: 0x00DD43A0 // FUNCTION: fn_23232 EquipSlots EquipSlotDecoder::Decode(int mask) const {