Owner-authorized source migration: 31 helper-only translation units were merged into their callers or existing inline headers; both build manifests updated. Includes the preserved source payload, Lua configuration matching wowdecomp, and exact malloca expansion without diagnostic pragmas. 449 native units compiled locally and 449 staged units compiled by the pinned server toolchain. No previously byte-matched function regressed. Compiler mapping diagnostics remain recorded as needs_cleanup, not accepted or peer-confirmed. Existing independent review records are preserved. README.md is intentionally unchanged.
218 lines
5.3 KiB
C++
218 lines
5.3 KiB
C++
#include "Contents/Hotkeys/UserHotkeyMgr.h"
|
|
#include "Network/TextEncoding.h"
|
|
|
|
#include <new>
|
|
|
|
namespace {
|
|
// INLINED
|
|
bool HiddenInterfaceIndex(int index) {
|
|
switch (index) {
|
|
case 30:
|
|
case 33:
|
|
case 34:
|
|
case 36:
|
|
case 43:
|
|
case 45:
|
|
case 53:
|
|
case 58:
|
|
case 62:
|
|
case 64:
|
|
case 65:
|
|
case 66:
|
|
case 67:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00E0A4C0
|
|
// FUNCTION: fn_23797
|
|
int HotkeyCount(LuaScript& script, int tab) {
|
|
int count = 0;
|
|
if (script.Call("GetOriginalHotKeyListSize", "d>d", tab + 1, &count)) {
|
|
if (tab == 1) {
|
|
int hidden = 0;
|
|
|
|
for (int index = 30; index < count; ++index) {
|
|
hidden += HiddenInterfaceIndex(index);
|
|
}
|
|
|
|
return count - hidden;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
// OFFSET: 0x00E12E50
|
|
// FUNCTION: fn_23820
|
|
int HotkeyIndex(LuaScript& script, int tab, int index) {
|
|
if (tab == 1 && index >= 30) {
|
|
for (int candidate = 30; candidate <= index; ++candidate) {
|
|
index += HiddenInterfaceIndex(candidate);
|
|
}
|
|
}
|
|
|
|
int count = 0;
|
|
script.Call("GetOriginalHotKeyListSize", "d>d", tab + 1, &count);
|
|
return index >= count ? -1 : index;
|
|
}
|
|
}
|
|
|
|
// STATIC: 0x013898E4
|
|
// GLOBAL: gl_24356
|
|
CUserHotkeyMgr* g_userHotkeyMgr;
|
|
|
|
// OFFSET: 0x005F7AA0
|
|
// FUNCTION: fn_04052
|
|
CUserHotkeyMgr::CUserHotkeyMgr() : m_enabled(true), m_loaded(false), m_changes(0), m_version2(false) {
|
|
}
|
|
|
|
// OFFSET: 0x005F7CE0
|
|
CUserHotkeyMgr::~CUserHotkeyMgr() = default;
|
|
|
|
// OFFSET: 0x005F7F70
|
|
// FUNCTION: fn_04056
|
|
bool CUserHotkeyMgr::Initialize() {
|
|
if (g_userHotkeyMgr) {
|
|
return false;
|
|
}
|
|
|
|
g_userHotkeyMgr = new (std::nothrow) CUserHotkeyMgr;
|
|
if (!g_userHotkeyMgr) {
|
|
return false;
|
|
}
|
|
|
|
if (!g_userHotkeyMgr->m_enabled) {
|
|
delete g_userHotkeyMgr;
|
|
g_userHotkeyMgr = nullptr;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// OFFSET: 0x005F8080
|
|
// FUNCTION: fn_04057
|
|
void CUserHotkeyMgr::Shutdown() {
|
|
if (g_userHotkeyMgr) {
|
|
delete g_userHotkeyMgr;
|
|
g_userHotkeyMgr = nullptr;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x005F88D0
|
|
// FUNCTION: fn_04062
|
|
void CUserHotkeyMgr::Reset() {
|
|
this->m_original.clear();
|
|
this->m_loaded = false;
|
|
this->m_changes = 0;
|
|
this->m_version2 = false;
|
|
}
|
|
|
|
// OFFSET: 0x005BC420
|
|
// FUNCTION: fn_03464
|
|
void CUserHotkeyMgr::LoadV2(LuaScript& script, Json::Value& data) {
|
|
Json::Value values = data["UserHotkey_V2"];
|
|
if (values.empty()) {
|
|
this->m_version2 = false;
|
|
} else {
|
|
this->m_version2 = true;
|
|
ClearUserHotkeys(script);
|
|
LoadUserHotkeyTab(script, values["SkillBar_1Tab"], 0);
|
|
LoadUserHotkeyTab(script, values["SkillBar_2Tab"], 3);
|
|
LoadUserHotkeyTab(script, values["InterfaceTab"], 1);
|
|
LoadUserHotkeyTab(script, values["EmotionTab"], 2);
|
|
SaveUserHotkeys(script);
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x005F85A0
|
|
// FUNCTION: fn_04061
|
|
void CUserHotkeyMgr::Capture(LuaScript& script) {
|
|
this->m_original.clear();
|
|
|
|
for (int tab : {0, 3, 1, 2}) {
|
|
const int count = HotkeyCount(script, tab);
|
|
|
|
for (int row = 0; row < count; ++row) {
|
|
const int index = HotkeyIndex(script, tab, row);
|
|
if (index == -1) {
|
|
continue;
|
|
}
|
|
|
|
int key1, key2;
|
|
const char* keyText = nullptr;
|
|
const char* description = nullptr;
|
|
|
|
if (script.Call("GetUserHotKeyInfo", "dd>ddss", tab + 1, index, &key1, &key2, &keyText, &description)) {
|
|
std::string text = description;
|
|
if (!text.empty()) {
|
|
this->m_original.push_back({tab, index, key1, key2, text});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x005F8100
|
|
// FUNCTION: fn_04060
|
|
bool CUserHotkeyMgr::HasUserAssignments(LuaScript& script) const {
|
|
for (int tab : {0, 3, 1, 2}) {
|
|
const int count = HotkeyCount(script, tab);
|
|
|
|
for (int row = 0; row < count; ++row) {
|
|
const int index = HotkeyIndex(script, tab, row);
|
|
if (index == -1) {
|
|
continue;
|
|
}
|
|
|
|
int key1 = 0, key2 = 0;
|
|
const char* keyText = nullptr;
|
|
const char* description = nullptr;
|
|
|
|
if (script.Call("GetUserHotKeyInfo", "dd>ddss", tab + 1, index, &key1, &key2, &keyText, &description) && std::string(description).size()) {
|
|
if (script.Call("GetOriginalHotKeyInfo", "dd>ddss", tab + 1, index, &key1, &key2, &keyText, &description) && std::string(description).size()) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// OFFSET: 0x005F80E0
|
|
// FUNCTION: fn_04059
|
|
bool CUserHotkeyMgr::HasChanges(LuaScript& script) const {
|
|
return static_cast<std::int32_t>(this->m_changes) > 0 || this->m_version2 || this->HasUserAssignments(script);
|
|
}
|
|
|
|
// OFFSET: 0x005BD2C0
|
|
// FUNCTION: fn_03471
|
|
void CUserHotkeyMgr::Export(LuaScript& script, Json::Value& data) {
|
|
this->Capture(script);
|
|
const std::list<Hotkey> snapshot = this->m_original;
|
|
Json::Value tabs[4];
|
|
|
|
for (const Hotkey& hotkey : snapshot) {
|
|
Json::Value value;
|
|
value["index"] = hotkey.index;
|
|
value["key1"] = hotkey.key1;
|
|
value["key2"] = hotkey.key2;
|
|
value["desc"] = ToUtf8(hotkey.description, g_textCodePage);
|
|
|
|
if (hotkey.tab >= 0 && hotkey.tab < 4) {
|
|
tabs[hotkey.tab].append(value);
|
|
}
|
|
}
|
|
|
|
Json::Value version2;
|
|
version2["SkillBar_1Tab"] = tabs[0];
|
|
version2["SkillBar_2Tab"] = tabs[3];
|
|
version2["InterfaceTab"] = tabs[1];
|
|
version2["EmotionTab"] = tabs[2];
|
|
data["UserHotkey_V2"] = version2;
|
|
data["UserHotkey"] = Json::Value();
|
|
}
|