Reconstruct readable C++ and organize cohesive source subsystems

Administrative source import: native x86 compilation passed for 423 authored units. Source placement and submission states are migrated separately; this commit does not imply peer acceptance.

Previous head: 35d2a8cb36
Payload SHA256: 592f016d2730c5593bb653aa054c1e5f76a6df72c8f5a09e66f74876e2e33dee
This commit is contained in:
ragnarok-clanker 2026-10-25 07:42:41 +00:00
commit a47d20f8be
890 changed files with 11796 additions and 16664 deletions

View file

@ -1,387 +0,0 @@
#include "Client/UnhandledExceptionHandler.h"
#include <windows.h>
#include <dbghelp.h>
#include <psapi.h>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <string>
// STATIC: 0x01389c78
// GLOBAL: gl_24469
CUnhandledExceptionHandler* g_unhandledExceptionHandler = nullptr;
// STATIC: 0x01389c7c
// GLOBAL: gl_24470
int (*g_unhandledExceptionCallback)() = nullptr;
// STATIC: 0x01389c80
// GLOBAL: gl_24359
char g_filename[264] = {};
// STATIC: 0x01389d88
// GLOBAL: gl_24471
char g_moduleBaseName[260] = {};
// STATIC: 0x01389e90
// GLOBAL: gl_24360
char g_crashString[8096] = {};
// STATIC: 0x0173ad64
// GLOBAL: gl_24472
extern uint32_t g_clientVersion;
// STATIC: 0x0171dd30
// GLOBAL: gl_24473
extern uint32_t g_launchInfo[32];
// STATIC: 0x01733550
// GLOBAL: gl_24476
extern int g_playerX;
// STATIC: 0x01733554
// GLOBAL: gl_24477
extern int g_playerY;
// STATIC: 0x0173a770
// GLOBAL: gl_24478
extern int64_t g_startTimeTicks;
// STATIC: 0x0173a778
// GLOBAL: gl_24479
extern int64_t g_loginTimeTicks;
// STATIC: 0x01732638
// GLOBAL: gl_24474
extern const uint8_t g_session[];
// STATIC: 0x013495b8
// GLOBAL: gl_24475
extern const uint8_t g_world[];
namespace {
int ReadPlayerJob() {
return *reinterpret_cast<const int*>(reinterpret_cast<uintptr_t>(g_session) + 0x1628);
}
const char* ReadPlayerJobName(int jobId) {
const auto* const* namesBegin = *reinterpret_cast<const char* const* const*>(reinterpret_cast<uintptr_t>(g_session) + 0xFA8);
const auto* const* namesEnd = *reinterpret_cast<const char* const* const*>(reinterpret_cast<uintptr_t>(g_session) + 0xFAC);
if (!namesBegin || !namesEnd || namesBegin >= namesEnd) {
return "";
}
size_t count = namesEnd - namesBegin;
if (static_cast<size_t>(jobId) >= count || !namesBegin[jobId]) {
return "";
}
return namesBegin[jobId];
}
const char* ReadCurrentMapName() {
if (*reinterpret_cast<const int*>(reinterpret_cast<uintptr_t>(g_world) + 0x58) == 1) {
void* zone = *reinterpret_cast<void* const*>(reinterpret_cast<uintptr_t>(g_world) + 0x04);
if (zone != nullptr) {
return reinterpret_cast<const char*>(reinterpret_cast<uintptr_t>(zone) + 0x68);
}
}
return nullptr;
}
}
extern "C" long long __cdecl _Xtime_get_ticks();
// OFFSET: 0x00635A70
// FUNCTION: fn_04701
CUnhandledExceptionHandler::CUnhandledExceptionHandler() {
}
// OFFSET: 0x00635A80
// FUNCTION: fn_04702
CUnhandledExceptionHandler::~CUnhandledExceptionHandler() = default;
// OFFSET: 0x00635AB0
// FUNCTION: fn_04703
bool InitUnhandledExceptionHandler(int (*callback)()) {
if (g_unhandledExceptionHandler != nullptr) {
return false;
}
auto* handler = new CUnhandledExceptionHandler();
if (!handler) {
g_unhandledExceptionHandler = nullptr;
return false;
}
g_unhandledExceptionCallback = callback;
GetModuleFileNameA(nullptr, g_filename, sizeof(g_filename));
const char* baseName = strrchr(g_filename, '\\');
if (baseName) {
baseName++;
} else {
baseName = g_filename;
}
_snprintf_s(g_moduleBaseName, sizeof(g_moduleBaseName), static_cast<size_t>(-1), "%s", baseName);
char* sep = strrchr(g_filename, '\\');
if (sep) {
*sep = '\0';
}
char* dot = strrchr(g_moduleBaseName, '.');
if (dot) {
*dot = '\0';
}
SetUnhandledExceptionFilter(TopLevelExceptionFilter);
_set_invalid_parameter_handler(InvalidParameterHandler);
_set_purecall_handler(PurecallHandler);
g_unhandledExceptionHandler = handler;
return true;
}
// OFFSET: 0x00635C10
// FUNCTION: fn_04704
int CleanupUnhandledExceptionHandler() {
if (g_unhandledExceptionHandler != nullptr) {
delete g_unhandledExceptionHandler;
g_unhandledExceptionHandler = nullptr;
}
return 0;
}
// OFFSET: 0x00635C30
// FUNCTION: fn_04705
INT_PTR CALLBACK DialogFunc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg == WM_INITDIALOG) {
HWND item = GetDlgItem(hDlg, 1006);
RECT rect = {};
SetWindowTextA(item, g_crashString);
GetWindowRect(hDlg, &rect);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
int dlgHeight = rect.bottom - rect.top;
int y = (screenHeight / 2) - (dlgHeight / 2);
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int dlgWidth = rect.right - rect.left;
int x = (screenWidth / 2) - (dlgWidth / 2);
MoveWindow(hDlg, x, y, dlgWidth, dlgHeight, TRUE);
} else if (uMsg == WM_COMMAND) {
if (LOWORD(wParam) == 2) {
size_t len = strlen(g_crashString);
HGLOBAL memory = GlobalAlloc(GMEM_MOVEABLE, len + 1);
if (memory != nullptr) {
char* locked = static_cast<char*>(GlobalLock(memory));
if (locked != nullptr) {
memcpy(locked, g_crashString, len + 1);
GlobalUnWire(memory);
if (OpenClipboard(hDlg)) {
EmptyClipboard();
SetClipboardData(CF_TEXT, memory);
CloseClipboard();
}
HWND button = GetDlgItem(hDlg, 7);
SetFocus(button);
} else {
GlobalFree(memory);
}
}
} else if (LOWORD(wParam) == 7) {
EndDialog(hDlg, 7);
}
} else {
return FALSE;
}
return TRUE;
}
// OFFSET: 0x00635DB0
// FUNCTION: fn_04706
BOOL CALLBACK EnumerateLoadedModulesCallback(PCSTR moduleName, ULONG moduleBase, ULONG moduleSize, PVOID userContext) {
auto* address = static_cast<const DWORD*>(userContext);
if (*address < moduleBase || *address > moduleBase + moduleSize) {
return TRUE;
}
sprintf(&g_crashString[strlen(g_crashString)], "%s", moduleName);
return FALSE;
}
// OFFSET: 0x00635E00
// FUNCTION: fn_04707
void __cdecl InvalidParameterHandler(
const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved
) {
EXCEPTION_RECORD record = {};
CONTEXT context = {};
EXCEPTION_POINTERS exceptionInfo = {&record, &context};
RtlCaptureContext(&context);
record.ExceptionCode = 0xC000000D;
record.NumberParameters = 3;
record.ExceptionInformation[0] = reinterpret_cast<ULONG_PTR>(expression);
record.ExceptionInformation[1] = reinterpret_cast<ULONG_PTR>(file);
record.ExceptionInformation[2] = static_cast<ULONG_PTR>(line);
TopLevelExceptionFilter(&exceptionInfo);
abort();
}
// OFFSET: 0x00635E90
// FUNCTION: fn_04708
void __cdecl PurecallHandler() {
EXCEPTION_RECORD record = {};
CONTEXT context = {};
EXCEPTION_POINTERS exceptionInfo = {&record, &context};
RtlCaptureContext(&context);
record.ExceptionCode = 0xC0000025;
TopLevelExceptionFilter(&exceptionInfo);
abort();
}
// OFFSET: 0x00635F00
// FUNCTION: fn_04709
LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) {
PCONTEXT context = exceptionInfo->ContextRecord;
HMODULE dbgHelp = LoadLibraryA("dbghelp.dll");
if (dbgHelp != nullptr) {
auto pStackWalk = reinterpret_cast<BOOL(WINAPI*)(
DWORD, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE,
PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE
)>(GetProcAddress(dbgHelp, "StackWalk"));
auto pGetTimestamp = reinterpret_cast<DWORD(WINAPI*)(HMODULE)>(
GetProcAddress(dbgHelp, "GetTimestampForLoadedLibrary")
);
auto pEnumerateLoadedModules = reinterpret_cast<BOOL(WINAPI*)(
HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID
)>(GetProcAddress(dbgHelp, "EnumerateLoadedModules"));
HMODULE module = GetModuleHandleA(nullptr);
CHAR filename[256] = {};
GetModuleFileNameA(module, filename, sizeof(filename));
DWORD timestamp = pGetTimestamp ? pGetTimestamp(module) : 0;
sprintf(&g_crashString[strlen(g_crashString)], "Module Name: %s\r\n", filename);
const char* timeString = _ctime32(reinterpret_cast<const __time32_t*>(&timestamp));
sprintf(&g_crashString[strlen(g_crashString)], "Time Stamp: 0x%08x - %s\r\n", timestamp, timeString);
sprintf(&g_crashString[strlen(g_crashString)], "Version: 0x%08x\r\n", g_clientVersion);
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
sprintf(&g_crashString[strlen(g_crashString)], "Exception Type: 0x%08x\r\n", exceptionInfo->ExceptionRecord->ExceptionCode);
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
HANDLE process = GetCurrentProcess();
HANDLE thread = GetCurrentThread();
STACKFRAME frame = {};
frame.AddrPC.Offset = context->Eip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Esp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
sprintf(&g_crashString[strlen(g_crashString)], "eax: 0x%08x\tebx: 0x%08x\r\n", context->Eax, context->Ebx);
sprintf(&g_crashString[strlen(g_crashString)], "ecx: 0x%08x\tedx: 0x%08x\r\n", context->Ecx, context->Edx);
sprintf(&g_crashString[strlen(g_crashString)], "esi: 0x%08x\tedi: 0x%08x\r\n", context->Esi, context->Edi);
sprintf(&g_crashString[strlen(g_crashString)], "ebp: 0x%08x\tesp: 0x%08x\r\n", context->Ebp, context->Esp);
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
for (int i = 0; i < 512; ++i) {
if (frame.AddrPC.Offset == 0) {
break;
}
if (!pStackWalk(IMAGE_FILE_MACHINE_I386, process, thread, &frame, context, nullptr, nullptr, nullptr, nullptr)) {
break;
}
sprintf(&g_crashString[strlen(g_crashString)], "0x%08x\t", frame.AddrPC.Offset);
pEnumerateLoadedModules(process, EnumerateLoadedModulesCallback, &frame.AddrPC.Offset);
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
}
const auto* stack = reinterpret_cast<const unsigned char*>(context->Esp);
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
sprintf(
&g_crashString[strlen(g_crashString)],
"stack %08x - %08x\r\n",
static_cast<unsigned int>(reinterpret_cast<uintptr_t>(stack)),
static_cast<unsigned int>(reinterpret_cast<uintptr_t>(stack + 1024))
);
for (int i = 0; i < 16; ++i) {
sprintf(&g_crashString[strlen(g_crashString)], "%08X : ", static_cast<unsigned int>(reinterpret_cast<uintptr_t>(stack)));
for (int j = 0; j < 16; ++j) {
sprintf(&g_crashString[strlen(g_crashString)], "%02X ", *stack++);
}
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
}
sprintf(&g_crashString[strlen(g_crashString)], "\r\nLaunch Info \r\n");
int launchIndex = 0;
for (int k = 0; k < 4; ++k) {
for (int m = 0; m < 8; ++m) {
sprintf(&g_crashString[strlen(g_crashString)], "%04X ", g_launchInfo[launchIndex++]);
}
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
}
int jobId = ReadPlayerJob();
const char* jobName = ReadPlayerJobName(jobId);
sprintf(&g_crashString[strlen(g_crashString)], "\r\nJob : %s\r\n", jobName);
const char* mapName = ReadCurrentMapName();
if (mapName != nullptr) {
sprintf(&g_crashString[strlen(g_crashString)], "%s %d %d\r\n", mapName, g_playerX, g_playerY);
}
sprintf(
&g_crashString[strlen(g_crashString)],
"\r\n%I64d - %I64d",
g_startTimeTicks / 10000000LL,
g_loginTimeTicks / 10000000LL
);
int64_t reportTime = _Xtime_get_ticks() / 10000000LL;
PROCESS_MEMORY_COUNTERS memCounters = {};
double workingSet = 0.0;
double pagefile = 0.0;
if (K32GetProcessMemoryInfo(process, &memCounters, sizeof(memCounters))) {
workingSet = static_cast<double>(static_cast<uint32_t>(memCounters.WorkingSetSize >> 10));
pagefile = static_cast<double>(static_cast<uint32_t>(memCounters.PagefileUsage >> 10));
}
sprintf(&g_crashString[strlen(g_crashString)], "\r\nReport Time: %I64d(%.0lf/%.0lf)\r\n", reportTime, workingSet, pagefile);
FreeLibrary(dbgHelp);
} else {
sprintf(&g_crashString[strlen(g_crashString)], "Can't find DbgHelp.DLL !!!");
}
DialogBoxParamA(GetModuleHandleA(nullptr), MAKEINTRESOURCEA(117), nullptr, DialogFunc, 0);
if (g_unhandledExceptionCallback != nullptr) {
g_unhandledExceptionCallback();
}
return EXCEPTION_EXECUTE_HANDLER;
}