Decompile 2 functions in Source/Client/Mode/GameModeNotices.cpp, Source/Client/Mode/CGameMode.h, ...

Batch #8785 by eAthena: 0 byte-identical, 2 confirmed by peer review.

- fn_21612 CGameMode::ReceiveTradeItemFilter: logic confirmed by peer review
- fn_21627 CGameMode::ReceiveGuildStorageLog: logic confirmed by peer review

Peer-reviewed-by: ragnarok-clanker, pedrao, dori, youko, KWDev
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
ragnarok-clanker 2026-10-31 22:47:48 +00:00
commit ff36eaf2ec
3 changed files with 177 additions and 8 deletions

View file

@ -681,6 +681,8 @@ public:
void ReceiveExchangeItemAddAck(const unsigned char* packet);
void ReceiveExchangeRequestAck2(const unsigned char* packet);
void ReceiveExchangeRequestAck(const unsigned char* packet);
void ReceiveGuildStorageLog(const unsigned char* packet);
void ReceiveTradeItemFilter(const unsigned char* packet);
void ReceiveOpenStore(const unsigned char* packet);
void ReceiveSearchStoreOpen(const unsigned char* packet);
void ReceiveStorageEquipList(const unsigned char* packet);

View file

@ -46,6 +46,7 @@
#include "UI/AdventureGuide/UIAdventureGuide.h"
#include "UI/CashShop/UICashShopWnd.h"
#include "UI/Dialogs/UISayDialogWnd.h"
#include "UI/Guild/UIGuild_Storage_Log.h"
#include "UI/Rodex/UIRodexComposeWnd.h"
#include "UI/Text/UITagTextViewer.h"
#include "UI/UICaptchaPreviewWnd.h"
@ -1240,6 +1241,7 @@ struct ClientItemLists {
void ClearItems1760();
void AddItem1758(const ITEM_INFO& item);
void AddItem1748(const ITEM_INFO& item);
void AddItem1718(const RawItemBasic& item, int mode);
};
struct AchievementStatePacket {
@ -2859,6 +2861,7 @@ struct LongParChangePacket {
struct SessionMessengerContext {
void ResetSlots();
int GetList0Size() const;
};
// OFFSET: 0x00D195D0
@ -2938,6 +2941,52 @@ void CGameMode::ReceiveBankCheck(const unsigned char* data) {
}
}
#pragma pack(push, 1)
struct TradeItemFilterPacket {
/* 0000 */ std::uint16_t opcode;
/* 0002 */ int type;
};
#pragma pack(pop)
struct SessionItemLists {
void ClearTradeItems();
};
// OFFSET: 0x00D198F0
// FUNCTION: fn_21612
void CGameMode::ReceiveTradeItemFilter(const unsigned char* data) {
const auto* packet = reinterpret_cast<const TradeItemFilterPacket*>(data);
reinterpret_cast<SessionItemLists*>(&g_session)->ClearTradeItems();
const int count = reinterpret_cast<SessionMessengerContext*>(&g_session)->GetList0Size();
for (int i = 0; i < count; ++i) {
ITEM_INFO item = g_session.GetInventoryItemAt(i);
if (item.unknown_0000[1] == 0) {
continue;
}
if (packet->type == 1 && !this->IsEffectId994Group(std::atoi(item.itemId.c_str()))) {
continue;
}
if (packet->type == 2 && !this->IsEffectId990Group(std::atoi(item.itemId.c_str()))) {
continue;
}
if (item.unknown_0000[1] == g_session.unknown_16EC) {
continue;
}
RawItemBasic raw = {};
raw.id = item.unknown_0000[1];
strcpy_s(raw.itemId, sizeof(raw.itemId), item.itemId.c_str());
raw.unknown_000C = item.unknown_0000[0];
raw.identified = item.identified;
raw.unknown_0004 = 1;
raw.unknown_0008 = 2;
reinterpret_cast<ClientItemLists*>(&g_session)->AddItem1718(raw, 1);
}
UIWindow* window = g_windowMgr.EnsureWindow(160);
window->SendMsg(nullptr, 0x24, 1, 0, 0, 0);
window->SendMsg(nullptr, 0x17, 0, 0, 0, 0);
g_windowMgr.EnsureWindow(161)->SendMsg(nullptr, 0x17, packet->type, 0, 0, 0);
}
// OFFSET: 0x00D1BE10
// FUNCTION: fn_21623
void CGameMode::ReceiveExchangeItemAddAck(const unsigned char* data) {
@ -3053,6 +3102,121 @@ void CGameMode::ReceiveExchangeRequestAck(const unsigned char* data) {
}
}
#pragma pack(push, 1)
struct GuildStorageLogPacketEntry {
/* 0000 */ int unknown_0000;
/* 0004 */ int itemId;
/* 0008 */ int unknown_0008;
/* 000C */ unsigned char unknown_000C;
/* 000D */ int refine;
/* 0011 */ unsigned char unknown_0011[8];
/* 0019 */ unsigned char identified;
/* 001A */ std::int16_t count;
/* 001C */ unsigned char cards[16];
/* 002C */ char name[24];
/* 0044 */ char date[24];
/* 005C */ unsigned char unknown_005C;
};
struct GuildStorageLogPacket {
/* 0000 */ std::uint16_t opcode;
/* 0002 */ std::uint16_t length;
/* 0004 */ std::int16_t result;
/* 0006 */ std::int16_t count;
/* 0008 */ GuildStorageLogPacketEntry entries[1];
};
#pragma pack(pop)
// OFFSET: 0x00D1C640
// FUNCTION: fn_21627
void CGameMode::ReceiveGuildStorageLog(const unsigned char* data) {
const auto* packet = reinterpret_cast<const GuildStorageLogPacket*>(data);
if (packet->result == 0) {
for (int i = 0; i < packet->count; ++i) {
const GuildStorageLogPacketEntry& source = packet->entries[i];
ITEM_INFO item;
item.unknown_00B8[0] = source.unknown_0000;
item.unknown_00B8[1] = source.unknown_0008;
item.unknown_00C0 = source.unknown_000C;
std::strcpy(reinterpret_cast<char*>(item.unknown_00C1), source.name);
std::strcpy(reinterpret_cast<char*>(item.unknown_00D9), source.date);
char number[16] = {};
item.itemId = _itoa(source.itemId, number, 10);
item.identified = source.identified;
item.unknown_0000[0] = source.count;
item.unknown_0060 = source.refine;
std::memcpy(item.unknown_001C, source.cards, sizeof(source.cards));
GuildStorageLogEntry entry;
entry.unknown_0000 = item.unknown_00B8[0];
entry.unknown_0004 = item.unknown_00B8[1];
entry.unknown_0008 = item.unknown_00C0;
std::strcpy(entry.unknown_0009, reinterpret_cast<const char*>(item.unknown_00C1));
std::strcpy(entry.unknown_0021, reinterpret_cast<const char*>(item.unknown_00D9));
entry.unknown_003C = item.DisplayName(0);
entry.unknown_0054 = item.identified;
entry.unknown_0058 = item.unknown_0000[0];
entry.unknown_005C = item.unknown_0060;
std::memcpy(entry.unknown_0060, item.unknown_001C, sizeof(entry.unknown_0060));
entry.unknown_0070 = source.unknown_005C;
g_guildStorageLogs[0].push_back(entry);
}
} else if (packet->result == 1) {
for (int i = 0; i < packet->count; ++i) {
const GuildStorageLogPacketEntry& source = packet->entries[i];
ITEM_INFO item;
item.unknown_00B8[0] = source.unknown_0000;
item.unknown_00B8[1] = source.unknown_0008;
item.unknown_00C0 = source.unknown_000C;
std::strcpy(reinterpret_cast<char*>(item.unknown_00C1), source.name);
std::strcpy(reinterpret_cast<char*>(item.unknown_00D9), source.date);
char number[16] = {};
item.itemId = _itoa(source.itemId, number, 10);
item.identified = source.identified;
item.unknown_0000[0] = source.count;
item.unknown_0060 = source.refine;
std::memcpy(item.unknown_001C, source.cards, sizeof(source.cards));
GuildStorageLogEntry entry;
entry.unknown_0000 = item.unknown_00B8[0];
entry.unknown_0004 = item.unknown_00B8[1];
entry.unknown_0008 = item.unknown_00C0;
std::strcpy(entry.unknown_0009, reinterpret_cast<const char*>(item.unknown_00C1));
std::strcpy(entry.unknown_0021, reinterpret_cast<const char*>(item.unknown_00D9));
entry.unknown_003C = item.DisplayName(0);
entry.unknown_0054 = item.identified;
entry.unknown_0058 = item.unknown_0000[0];
entry.unknown_005C = item.unknown_0060;
std::memcpy(entry.unknown_0060, item.unknown_001C, sizeof(entry.unknown_0060));
entry.unknown_0070 = source.unknown_005C;
g_guildStorageLogs[0].push_back(entry);
}
GuildStorageLogEntry pivot;
std::sort(g_guildStorageLogs[0].begin(), g_guildStorageLogs[0].end(), [&pivot](const GuildStorageLogEntry& left, const GuildStorageLogEntry& right) {
return std::strcmp(left.unknown_0021, right.unknown_0021) > 0;
});
for (auto it = g_guildStorageLogs[0].begin(); it != g_guildStorageLogs[0].end(); ++it) {
if (it->unknown_0008 == 1) {
g_guildStorageLogs[1].push_back(*it);
} else {
g_guildStorageLogs[2].push_back(*it);
}
}
g_windowMgr.EnsureWindow(253);
} else {
char text[252];
if (packet->result == 2) {
std::memset(text, 0, 250);
std::sprintf(text, LookupMessage(2543));
} else {
std::memset(text, 0, 250);
std::sprintf(text, LookupMessage(1816));
}
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(text), 0xFF, 0, 0, 0);
g_guildStorageLogs[0].clear();
g_guildStorageLogs[1].clear();
g_guildStorageLogs[2].clear();
}
}
// OFFSET: 0x00D45E90
// FUNCTION: fn_21843
void CGameMode::ReceiveStorageEquipList(const unsigned char* data) {

View file

@ -12,15 +12,18 @@ class UIStaticText;
class UITabControl;
struct GuildStorageLogEntry {
/* 0000 */ int unknown_0000;
/* 0004 */ int unknown_0004;
/* 0008 */ unsigned char unknown_0008;
/* 0009 */ char unknown_0009[24];
/* 0021 */ char unknown_0021[27];
/* 0000 */ int unknown_0000 = 0;
/* 0004 */ int unknown_0004 = 0;
/* 0008 */ unsigned char unknown_0008 = 0;
/* 0009 */ char unknown_0009[24] = {};
/* 0021 */ char unknown_0021[24] = {};
/* 003C */ std::string unknown_003C;
/* 0054 */ unsigned char unknown_0054[0x1C];
/* 0070 */ unsigned char unknown_0070;
/* 0071 */ unsigned char unknown_0071[3];
/* 0054 */ unsigned char unknown_0054 = 0;
/* 0058 */ int unknown_0058 = 0;
/* 005C */ int unknown_005C = 0;
/* 0060 */ unsigned char unknown_0060[16] = {};
/* 0070 */ unsigned char unknown_0070 = 0;
/* 0072 */ std::int16_t unknown_0072 = 0;
};
extern std::vector<GuildStorageLogEntry> g_guildStorageLogs[3];