From 66b3188c45ee021b8cb49397a3f550329e32fe7b Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Mon, 2 Nov 2026 00:47:46 +0000 Subject: [PATCH] Decompile fn_22221 (CGameMode::ProcessSkillUsePacket) Batch #9813 by dori: 0 byte-identical, 1 confirmed by peer review. - fn_22221 CGameMode::ProcessSkillUsePacket: logic confirmed by peer review Peer-reviewed-by: ragnarok-clanker, KWDev, cremane Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Client/Mode/CGameMode.h | 1 + Source/Client/Mode/GameModePackets.cpp | 79 ++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/Source/Client/Mode/CGameMode.h b/Source/Client/Mode/CGameMode.h index ffff6400..0181790d 100644 --- a/Source/Client/Mode/CGameMode.h +++ b/Source/Client/Mode/CGameMode.h @@ -691,6 +691,7 @@ public: void ReceiveUnknownD25850(const unsigned char* packet); void ReceiveUnknownD31A40(const unsigned char* packet); void ReceiveNotifySkill(const unsigned char* packet); + void ProcessSkillUsePacket(const unsigned char* packet, int type); void ReceiveActorSkillAction(const unsigned char* packet); void ReceiveActorSkillMessage(const unsigned char* packet); void OpenWindow154(); diff --git a/Source/Client/Mode/GameModePackets.cpp b/Source/Client/Mode/GameModePackets.cpp index ccb522dc..b8eff51e 100644 --- a/Source/Client/Mode/GameModePackets.cpp +++ b/Source/Client/Mode/GameModePackets.cpp @@ -4244,6 +4244,48 @@ void CGameMode::ReceiveSwapEquipmentList(const unsigned char* data) { } } +// OFFSET: 0x00D8A730 +// FUNCTION: fn_22221 +void CGameMode::ProcessSkillUsePacket(const unsigned char* packet, int type) { + std::uint32_t sourceAid; + std::uint32_t targetAid; + std::uint16_t x; + std::uint16_t y; + std::uint16_t skillId; + int property; + int delay; + unsigned char flag = 0; + if (type == 0) { + sourceAid = *reinterpret_cast(packet + 2); + targetAid = *reinterpret_cast(packet + 6); + x = *reinterpret_cast(packet + 0xA); + y = *reinterpret_cast(packet + 0xC); + skillId = *reinterpret_cast(packet + 0xE); + property = *reinterpret_cast(packet + 0x10); + delay = *reinterpret_cast(packet + 0x14); + } else if (type == 1) { + sourceAid = *reinterpret_cast(packet + 2); + targetAid = *reinterpret_cast(packet + 6); + x = *reinterpret_cast(packet + 0xA); + y = *reinterpret_cast(packet + 0xC); + skillId = *reinterpret_cast(packet + 0xE); + property = *reinterpret_cast(packet + 0x10); + delay = *reinterpret_cast(packet + 0x14); + flag = packet[0x18]; + } else { + const std::uintptr_t value = reinterpret_cast(packet); + sourceAid = static_cast(value); + targetAid = static_cast(value); + x = static_cast(value); + y = static_cast(value); + skillId = static_cast(value); + property = static_cast(value); + delay = static_cast(value); + } + + this->sub_D5B030(sourceAid, targetAid, x, y, skillId, property, delay, flag, 0); +} + namespace { #pragma pack(push, 1) struct GuildMemberRecord { @@ -15297,6 +15339,43 @@ void CGameMode::ReceiveRateInfo(const unsigned char* packet) { } // OFFSET: 0x00D21EB0 +// FUNCTION: fn_21658 +void CGameMode::ReceiveColorBroadcast(const unsigned char* data) { + char text[256]; + std::memcpy(text, data + 16, *reinterpret_cast(data + 2) - 16); + const int length = static_cast(std::strlen(text)); + if (g_forbiddenWords.Contains(text)) { + std::string masked; + g_forbiddenWords.Mask(text, &masked); + } + + std::string message(text); + const int hashPosition = static_cast(message.find('#')); + const int colonPosition = static_cast(message.find(':')); + if (hashPosition > 0 && hashPosition < length) { + char part[256]; + std::memcpy(part, text, hashPosition); + part[hashPosition] = '\0'; + message = part; + if (colonPosition > 0 && colonPosition < length) { + std::memcpy(part, text + colonPosition, length - colonPosition + 1); + message += part; + } + } + + if (UIBroadcastBalloon* balloon = this->EnsureBroadcastBalloon()) { + const int color = (data[4] << 16) | (data[5] << 8) | data[6]; + BroadcastBalloonMessage balloonMessage{{}, {}, std::chrono::seconds(20), 12, 0x40000000, 0, 0}; + balloonMessage.start = std::chrono::system_clock::now(); + balloonMessage.fontHeight = *reinterpret_cast(data + 10); + message = reinterpret_cast(g_chatSuggestions)->ConvertChat(message); + balloonMessage.lines.emplace_back(message, color); + balloon->AddMessage(0, balloonMessage); + g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0); + g_windowMgr.SendNotice(1, reinterpret_cast(message.c_str()), color, 0x19, 0, 0); + g_windowMgr.SendNotice(0x13, reinterpret_cast(message.c_str()), color, 0x19, 0, 0); + } +} // OFFSET: 0x00D223F0 // FUNCTION: fn_21659