Decompile 4 functions in Source/Contents/Jobs/JobInheritance.cpp, Source/Client/Session.h, ...

Batch #6406 by eAthena: 0 byte-identical, 4 confirmed by peer review.

- fn_23793 CSession::GetPetTargetAid: logic confirmed by peer review
- fn_24365 ApplyAiPatch: logic confirmed by peer review
- fn_21743 CGameMode::ReceiveEquipWindowMicroscope: logic confirmed by peer review
- fn_21919 UIItemStoreWnd::SetTitle: logic confirmed by peer review

Peer-reviewed-by: ragnarok-clanker, willerthal
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
Adds to the build: Source/Client/Mode/GameModeEquipWindow.cpp, Source/UI/Item/UIItemStoreWnd.cpp
This commit is contained in:
ragnarok-clanker 2026-10-31 00:51:56 +00:00
commit fa26ae4cf5
9 changed files with 192 additions and 0 deletions

View file

@ -4,9 +4,12 @@
#include "Contents/Configuration/ServiceConfiguration.h"
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <io.h>
#include <string>
#include <windows.h>
#include <shellapi.h>
// STATIC: 0x0173ad64
// GLOBAL: gl_24472
@ -652,6 +655,56 @@ bool RestartFromCommandLine(char* commandLine) {
return true;
}
// OFFSET: 0x00E58A60
// FUNCTION: fn_24365
void ApplyAiPatch() {
const std::uint8_t patchSource[] = {0xAE, 0x6A, 0x8A, 0x9F, 0x78, 0x25, 0xF2, 0x53, 0xEF};
thread_local EncryptedName<sizeof(patchSource), 0x3B915119EFD523EFULL> patchName(patchSource);
if (_access(patchName.Text(), 0) != 0) {
return;
}
const std::uint8_t aiSource[] = {0x5A, 0x44, 0x39};
thread_local EncryptedName<sizeof(aiSource), 0x5B8F49AF09390D1BULL> aiName(aiSource);
if (_access(aiName.Text(), 0) != 0) {
return;
}
const std::uint8_t backupSource[] = {0x80, 0x9A, 0x84, 0x15, 0xFA, 0x16, 0xA8, 0x3C, 0xB1, 0xD3};
thread_local EncryptedName<sizeof(backupSource), 0x49C3759B77DBD3C1ULL> backupName(backupSource);
if (_access(backupName.Text(), 0) == 0) {
const std::uint8_t deleteSource[] = {0xDA, 0xE4, 0x2A, 0xAD, 0xB0, 0x5E, 0x86, 0x18, 0xEB, 0xAD};
char path[16] = {};
thread_local EncryptedName<sizeof(deleteSource), 0x6DED3DD1CF75AD9BULL> deleteName(deleteSource);
std::strcpy(path, deleteName.Text());
SHFILEOPSTRUCTA operation;
operation.hwnd = nullptr;
operation.wFunc = FO_DELETE;
operation.pFrom = path;
operation.pTo = nullptr;
operation.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
operation.fAnyOperationsAborted = FALSE;
operation.hNameMappings = nullptr;
operation.lpszProgressTitle = nullptr;
SHFileOperationA(&operation);
}
const std::uint8_t backupTargetSource[] = {0xBC, 0xB4, 0x22, 0x91, 0x80, 0x76, 0x92, 0x6E, 0x8D, 0xFD};
thread_local EncryptedName<sizeof(backupTargetSource), 0x1BF915E1F37DFDFDULL> backupTarget(backupTargetSource);
const char* backup = backupTarget.Text();
const std::uint8_t currentSource[] = {0x9E, 0x90, 0x5D};
thread_local EncryptedName<sizeof(currentSource), 0x01FF9313695DD9DFULL> current(currentSource);
std::rename(current.Text(), backup);
const std::uint8_t installTargetSource[] = {0x52, 0x8E, 0x03};
thread_local EncryptedName<sizeof(installTargetSource), 0x4F1791FB1503C713ULL> installTarget(installTargetSource);
const char* install = installTarget.Text();
const std::uint8_t patchedSource[] = {0x92, 0xA4, 0xC8, 0x65, 0x2C, 0x2F, 0xC6, 0xC9, 0xD3};
thread_local EncryptedName<sizeof(patchedSource), 0xA1A55B4D1597EDD3ULL> patched(patchedSource);
std::rename(patched.Text(), install);
}
// INLINED
void ExitForProtectionCheck(const char* commandLine) {
if (std::strstr(commandLine, "/check_themida")) {

View file

@ -144,6 +144,7 @@ public:
void ReceiveStatDump(const unsigned char* packet);
void ReceiveActorText(const unsigned char* packet);
void ReceiveRentalItemTime(const unsigned char* packet);
void ReceiveEquipWindowMicroscope(const unsigned char* packet);
void ReceiveMemorialDungeonInfo(const unsigned char* packet);
void ReceiveMemorialDungeonNotify(const unsigned char* packet);
void ReceiveMemorialDungeonSubscriptionInfo(const unsigned char* packet);

View file

@ -0,0 +1,27 @@
#ifndef RAGNAROK_SOURCE_CLIENT_MODE_EQUIPWINDOWLOOK_H
#define RAGNAROK_SOURCE_CLIENT_MODE_EQUIPWINDOWLOOK_H
#include <cstddef>
struct EquipWindowLook {
/* 0000 */ int job;
/* 0004 */ int sex;
/* 0008 */ int head;
/* 000C */ int accessory;
/* 0010 */ int accessory2;
/* 0014 */ int accessory3;
/* 0018 */ int bodyPalette;
/* 001C */ int headPalette;
/* 0020 */ int robe;
/* 0024 */ int unknown_0024;
/* 0028 */ char name[24];
};
extern EquipWindowLook g_equipWindowLook;
#if defined(_WIN32) && !defined(_WIN64)
static_assert(sizeof(EquipWindowLook) == 0x40);
static_assert(offsetof(EquipWindowLook, name) == 0x28);
#endif
#endif

View file

@ -0,0 +1,69 @@
#include "Client/Mode/CGameMode.h"
#include "Client/Mode/EquipWindowLook.h"
#include "Client/Session.h"
#include "Contents/Items/ItemInfo.h"
#include "UI/Window/UIWindowMgr.h"
#include <cstdint>
#include <cstring>
struct ClientItemLists {
bool Equip(const ITEM_INFO& item);
void ResetEquipped();
};
// GLOBAL: gl_25085
EquipWindowLook g_equipWindowLook;
// OFFSET: 0x00D325F0
// FUNCTION: fn_21743
void CGameMode::ReceiveEquipWindowMicroscope(const unsigned char* packet) {
reinterpret_cast<ClientItemLists*>(&g_session)->ResetEquipped();
g_session.ResetItems3500();
const int length = *reinterpret_cast<const std::int16_t*>(packet + 2);
const int count = static_cast<unsigned>(length - 45) / 37u;
const unsigned char* entry = packet + 45;
for (int index = 0; index < count; ++index, entry += 37) {
ITEM_INFO item;
item.unknown_0000[0] = entry[6];
item.unknown_0000[2] = *reinterpret_cast<const std::uint16_t*>(entry + 7);
item.unknown_0000[1] = *reinterpret_cast<const std::int16_t*>(entry);
item.unknown_0000[3] = *reinterpret_cast<const std::uint16_t*>(entry + 9);
item.quantity = 1;
std::memcpy(item.unknown_001C, entry + 12, sizeof(item.unknown_001C));
item.SetItemId(*reinterpret_cast<const int*>(entry + 2));
const unsigned char flags = entry[36];
item.identified = flags & 1;
item.unknown_005D = (flags >> 1) & 1;
item.unknown_0060 = entry[11];
item.unknown_0068 = *reinterpret_cast<const std::uint32_t*>(entry + 28);
item.unknown_0064 = *reinterpret_cast<const std::uint16_t*>(entry + 32);
item.unknown_0070 = *reinterpret_cast<const std::uint16_t*>(entry + 34);
item.unknown_0074[0] = (flags >> 2) & 1;
if (item.unknown_0000[3] != 0) {
if (g_session.IsCostumeLocation(item.unknown_0000[3])) {
g_session.EquipItem3500(item);
} else {
reinterpret_cast<ClientItemLists*>(&g_session)->Equip(item);
}
}
}
g_equipWindowLook.job = *reinterpret_cast<const std::int16_t*>(packet + 0x1C);
g_equipWindowLook.sex = packet[0x2C];
g_equipWindowLook.head = *reinterpret_cast<const std::int16_t*>(packet + 0x1E);
g_equipWindowLook.accessory = *reinterpret_cast<const std::int16_t*>(packet + 0x20);
g_equipWindowLook.accessory2 = *reinterpret_cast<const std::int16_t*>(packet + 0x22);
g_equipWindowLook.accessory3 = *reinterpret_cast<const std::int16_t*>(packet + 0x24);
g_equipWindowLook.bodyPalette = *reinterpret_cast<const std::int16_t*>(packet + 0x2A);
g_equipWindowLook.headPalette = *reinterpret_cast<const std::int16_t*>(packet + 0x28);
std::memcpy(g_equipWindowLook.name, packet + 4, sizeof(g_equipWindowLook.name));
g_equipWindowLook.robe = *reinterpret_cast<const std::int16_t*>(packet + 0x26);
if (!g_windowMgr.CloseWindow(0x8B)) {
g_windowMgr.EnsureWindow(0x8B);
}
}

View file

@ -652,6 +652,7 @@ public:
int MercSkillLevel(int skillId) const;
int HomunSkillLevel(int skillId) const;
CRenderObject* FindGameActor(std::uint32_t aid) const;
int GetPetTargetAid() const;
bool sub_E1DE30(std::uint32_t aid);
int sub_DDD2C0(const ITEM_INFO& item);
const char* GetJobName(unsigned job, int sex);

View file

@ -1212,6 +1212,33 @@ int CSession::GetPairValue() const {
return third == -1 ? second : third;
}
// OFFSET: 0x00E0A220
// FUNCTION: fn_23793
int CSession::GetPetTargetAid() const {
int target = 0;
std::uint32_t aid = *reinterpret_cast<const std::uint32_t*>(&this->unknown_5570[8]);
CGameMode* mode;
CRenderObject* actor;
if (aid != 0 && (mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode())) != nullptr &&
(actor = mode->scene->GetGameActorByAID(aid)) != nullptr) {
target = static_cast<CGameActor*>(actor)->hitTargetAid;
}
aid = *reinterpret_cast<const std::uint32_t*>(&this->unknown_5620[8]);
if (aid != 0 && (mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode())) != nullptr &&
(actor = mode->scene->GetGameActorByAID(aid)) != nullptr) {
target = static_cast<CGameActor*>(actor)->hitTargetAid;
}
if (target > 0) {
mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
if (mode == nullptr || mode->scene->GetGameActorByAID(target) == nullptr) {
return 0;
}
}
return target;
}
// OFFSET: 0x00E1D950
// FUNCTION: fn_23854
int CSession::WorldUnknown0050() const {

View file

@ -0,0 +1,10 @@
#include "UI/Item/UIItemStoreWnd.h"
#include "UI/Text/UIStaticText.h"
#include <string>
// OFFSET: 0x00D532D0
// FUNCTION: fn_21919
void UIItemStoreWnd::SetTitle(std::string title) {
this->title->SetTextFitted(title.c_str());
}

View file

@ -5,6 +5,7 @@
#include "UI/Item/UIItemBaseWnd.h"
#include <cstddef>
#include <string>
class UICheckBox;
class UIStaticText;
@ -17,6 +18,7 @@ public:
void Slot25(int x, int y) override;
__declspec(noinline) ITEM_INFO GetItemAt(int x, int y);
void SetTabChecked(int index, bool checked);
void SetTitle(std::string title);
/* 00F0 */ int unknown_00F0;
/* 00F4 */ unsigned char unknown_00F4[0x04];

View file

@ -259,6 +259,7 @@
"Source/Client/Input/Mouse.cpp": 0,
"Source/Client/Input/VietnameseInput.cpp": 0,
"Source/Client/Mode/GameMode.cpp": 0,
"Source/Client/Mode/GameModeEquipWindow.cpp": 0,
"Source/Client/Mode/GameModeHandlers.cpp": 0,
"Source/Client/Mode/GameModeMiniMap.cpp": 0,
"Source/Client/Mode/GameModeNames.cpp": 0,
@ -865,6 +866,7 @@
"Source/UI/Guild/UIGuildWnd.cpp": 2,
"Source/UI/Guild/UIGuild_Storage_Log.cpp": 2,
"Source/UI/Item/UIEquipmentPropertiesWnd.cpp": 2,
"Source/UI/Item/UIItemStoreWnd.cpp": 2,
"Source/UI/Item/UIMerchantItemLogWnd.cpp": 2,
"Source/UI/Item/UIParaItemShopWnd.cpp": 2,
"Source/UI/Items/MergeItemWnd.cpp": 2,