From 080c8188e6f226d421ab8332cc6970b3bf0cc7d6 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Sun, 1 Nov 2026 14:56:50 +0000 Subject: [PATCH] Decompile fn_21684 (CGameMode::ReceivePartyMemberLeft) Batch #9529 by secret: 0 byte-identical, 1 confirmed by peer review. - fn_21684 CGameMode::ReceivePartyMemberLeft: logic confirmed by peer review Peer-reviewed-by: gordaoprogramas, Lumen, dori 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/Client/Mode/GameModePackets.cpp | 57 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/Source/Client/Mode/CGameMode.h b/Source/Client/Mode/CGameMode.h index 49c1d32f..1662aac5 100644 --- a/Source/Client/Mode/CGameMode.h +++ b/Source/Client/Mode/CGameMode.h @@ -859,6 +859,8 @@ public: void ReceiveGuildMemberList2(const unsigned char* data); void ReceiveGuildMemberList3(const unsigned char* data); void ReceiveGuildRelationList(const unsigned char* data); + void ReceivePartyMemberLeft(const unsigned char* data); + void ReceiveBroadcast(const unsigned char* packet); void ReceiveEquipItemNotice(const unsigned char* data); void ReceiveEquipItemListFlags(const unsigned char* packet); void ReceiveParaResultList(const unsigned char* packet); diff --git a/Source/Client/Mode/GameModePackets.cpp b/Source/Client/Mode/GameModePackets.cpp index aae46deb..62271f4c 100644 --- a/Source/Client/Mode/GameModePackets.cpp +++ b/Source/Client/Mode/GameModePackets.cpp @@ -145,6 +145,8 @@ struct ClientItemLists { void RemoveItem1710(std::uint32_t id, int quantity); bool AddItem1710(const ITEM_INFO& item, unsigned char refresh); bool EquipItem6B68(const ITEM_INFO& item); + void ClearRecords0734(); + void ClearPartyMembers(); }; void __fastcall sub_DFF150(CSession* session); @@ -11847,6 +11849,61 @@ void CGameMode::ReceiveItem1748List2(const unsigned char* packet) { this->unknown_024C = 1; } +#pragma pack(push, 1) +struct PartyMemberLeftPacket { + /* 0000 */ std::uint16_t id; + /* 0002 */ std::uint32_t aid; + /* 0006 */ char name[24]; + /* 001E */ unsigned char type; +}; +#pragma pack(pop) + +static_assert(sizeof(PartyMemberLeftPacket) == 0x1F); + +// OFFSET: 0x00D26BB0 +// FUNCTION: fn_21684 +void CGameMode::ReceivePartyMemberLeft(const unsigned char* data) { + const PartyMemberLeftPacket* packet = reinterpret_cast(data); + char name[25]; + name[24] = '\0'; + std::memcpy(name, packet->name, sizeof(packet->name)); + switch (packet->type) { + case 0: + case 1: + this->SendMsg(0x40, g_session.GetPartyMemberAid(name), 0, 0, 0); + g_session.RemovePartyMemberByName(name); + break; + case 2: + g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); + g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(0x750)), 0xFF, 0, 0, 0); + return; + case 3: + g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); + g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(0x751)), 0xFF, 0, 0, 0); + return; + } + + if (std::strcmp(g_session.DecodePlayerName(), name) == 0) { + g_session.unknown_5464 = 0; + reinterpret_cast(&g_session)->ClearPartyMembers(); + g_session.unknown_54C4.assign("", 0); + g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); + g_windowMgr.SendNotice(1, reinterpret_cast(LookupMessage(0x54)), 0xFFFF00, 0, 0, 0); + g_windowMgr.CloseWindow(0x35); + this->SendMsg(0x41, 0, 0, 0, 0); + if (g_windowMgr.unknown_03F8) { + g_windowMgr.CloseWindow(0x89); + } + reinterpret_cast(&g_session)->ClearRecords0734(); + } + + sub_DFF150(&g_session); + if (CGameActor* actor = static_cast(this->scene->GetGameActorByAID(packet->aid))) { + actor->SetUnknown02E4(0); + } +} + +// OFFSET: 0x00D373C0 // OFFSET: 0x00D787E0 // FUNCTION: fn_22162 void CGameMode::ReceiveItem1758StoreList(const unsigned char* packet) {