Read character name from select screen data and realm from CVar when
the player clicks Enter World, before InitializeLogBuffer fires.
Removes GUID/name-cache fallback — no more early passthrough to wrong paths.
Organize combat/raw/chat logs into Logs\<realm>\<char>\ directories.
Lazy path setup on first InitializeLogBuffer call resolves character
and realm names, creates directory tree, and reuses files modified
within 30 minutes for session continuation. Chat log added to the
redirection system. Session marker now includes realm name.
Paths not yet redirected before login — needs earlier hook point.
SuperWoWhook.dll calls InitializeLogBuffer directly with hardcoded
"Logs\WoWCombatLog.txt", bypassing the path pointer table. Hook
InitializeLogBuffer itself to intercept the path argument and
substitute our timestamped filename, regardless of caller. Also
redirects WoWRawCombatLog.txt to a matching timestamped file.
TODO: session marker (COMBATLOG_SESSION) needs to be written as the
first line in each log file -- currently it appears after SuperWoW's
initial writes (COMBATANT_INFO, ZONE_INFO) because the write hook
fires too late.
TODO: consolidate small/empty WoWCombatLog_*.txt files on startup.
Instead of hooking EnableChatLogging or SignalEvent (which fire too late
or before the log file is open), hook WriteFormattedLogMessage directly.
On the first write to the combat log, prepend COMBATLOG_SESSION with the
player name resolved via the name cache. This guarantees the session
marker is the very first line in the file.
Also add World_HandleLogoutCleanup (0x491180) hook to reset per-session
state on real logout/disconnect (not /reload), and move remove_on_shutdown
cleanup from shutdownDetour to logoutDetour.
Switch from GetObjectPtr→GetUnitName (object manager, not populated
at LoggingCombat time) to RetrieveNPCDataFromCache (name cache,
available early). Remove the SignalEvent probe hook that was only
for discovery.
Ghidra disasm confirms RET 0xC (callee cleans 3 args). Third arg is a
va_list pointer, not the variadic args directly. For %s, vsprintf reads
*(char**)va_list -- previous code passed &name_buf causing vsprintf to
interpret "Munj" (0x6A6E754D) as a char* and crash at strlen.
Fix: pass &name_ptr (pointer to the char*) and remove caller stack
cleanup. Added detailed research to RESEARCH.md.
The old code called GetObjectByGUID (0x464870) as __fastcall with the
GUID in ECX/EDX, but the function is actually __stdcall with the u64
GUID on the stack. This ABI mismatch caused a crash.
Switched to perfboost's two-step approach with correct conventions:
1. GetObjectPtr (0x464870) — __stdcall(u64 guid) → object ptr
2. CGUnit_C::GetUnitName (0x609210) — __thiscall(ECX=unit, 0) → char*
Also added ESI/EDI/EBX clobber barrier in the EnableChatLogging detour
and copy name to stack buffer before log write.