suprepupre/wow-optimize

GitHub: suprepupre/wow-optimize

面向《魔兽世界》3.3.5a 的引擎级性能优化 DLL,通过内存分配器替换、Lua VM 快速路径和 SSE2 向量化运算消除卡顿并修复底层 bug。

Stars: 90 | Forks: 8

# wow_optimize 针对《魔兽世界》3.3.5a (WotLK) 的性能优化 DLL 作者:SUPREMATIST wow_optimize 从引擎和 runtime 层面优化了 WoW 3.3.5a:内存分配、Lua VM 行为、Lua 库快速路径、计时器、文件 I/O、网络、内存碎片、锁竞争、修复了长达 16 年的战斗日志 bug,以及其他底层瓶颈。 当前的公开版本主要专注于真实的帧时间稳定性、长时间游戏的流畅度、重度 addon 环境下的表现,以及在不启用历史上曾出现安全问题的功能的前提下,降低 Lua/runtime 开销。 ## v3.13.0 版本更新内容 此版本标志着一个巨大的里程碑,汇集了自 **v3.11.0** 以来开发的大量性能恢复、稳定性更新和 runtime 强化功能。超过 32 项优化特性已经过验证、稳定并被激活,带来了显著更流畅、无卡顿的体验。 ### 核心性能与分配器更新 (自 v3.11.0 起) - **mimalloc 分配器重定向** — 使用 Microsoft 的高性能 `mimalloc` 引擎替换了 WoW 静态链接的 CRT 内存分配器(`malloc`、`free`、`realloc`、`calloc`、`_msize` 和 `_recalloc`)。利用自定义的转换防护和原子激活机制,来解决在长时间游戏、切换角色或传送过程中的 32 位虚拟地址 (VA) 碎片问题。 - **自适应清理与 VA 压力调节器** — 内存管理器会根据 OS 虚拟内存压力动态调整分配器的清理延迟(当最大空闲块较低时进行积极清理,否则进行温和清理以避免重新提交页面错误风暴)。 - **WoW 内部 strlen/memcpy/memset SSE2 替代方案** — 为关键的 CRT 字符串和内存操作内联了手写的汇编替代方案,以避免资源加载时的标量瓶颈。包含针对 $\ge$ 256 KB 副本的非临时流式存储。 - **Free 包装器快速路径** — 将释放操作引导至绕过二进制文件中最热路径之一上的冗余堆遍历开销。 - **Hook 启用批处理** — 通过在启动初始化期间通过单次快照批处理激活 MinHook hook,将启动时间缩短了 1.7 秒以上。 ### Lua VM 与 C-API 内联 (自 v3.11.0 起) - **安全的内联缓存与栈操作** — 恢复并验证了 `luaH_getstr`(16384 个条目带预取)、`lua_rawgeti`(8192 条目数组直接与哈希缓存)、`lua_toboolean` 和 `lua_objlen` 的优化内联路径,与引擎字节布局完全匹配。 - **Lua VM 内联快速路径组** — 超过 30 个内联辅助程序(安全组 1、2 和 3)已稳定并激活(例如 `string.gsub` 纯字面量匹配、`math.fmod`、`math.modf`、`string.char`、`select`、`rawequal`、`strjoin`、`strsplit` 等)。 - **自适应 GC 步调** — Lua 垃圾回收间隔会根据帧时间限制和 VA 压力触发器进行动态缩放。 ### SIMD 几何、数学与物理 (自 v3.11.0 起) - **双精度四元数归一化 (`CQuaternion::Normalize`)** — 完全稳定并重新启用了自定义的 SSE2 四元数归一化 hook (`0x00979110`)。通过从 32 位浮点数迁移到 64 位双精度,它与原始 FPU 输出完全匹配,防止了浮点精度漂移,并彻底解决了转向时的摄像机抖动 bug。 - **线程安全的 SIMD 统计计数器** — 使用原子 32 位 `InterlockedIncrement` 操作强化了所有物理、剔除和旋转统计计数器,以防止渲染线程与异步引擎工作线程之间的数据竞争。 - **向量化视锥剔除与几何数学** — 使用 SSE2 向量化运算符绕过了传统的 x87 FPU 栈计算,用于矩阵乘法 (`CMatrix::operator*` 位于 `0x004C1F00`)、矩阵-向量变换(3D/4D 变换位于 `0x004C21B0` 和 `0x004C2270`)、刚体反转和 `CFrustum` 视锥剔除。 - **SSE2 网络 GUID 解包** — 在网络数据包处理器内向量化了网络 GUID 解包(`CDataStore::GetWowGUID` 位于 `0x0076DC20`)。 ### Lua VM — 安全内联缓存 (已激活) - `luaH_getstr`:带有内容验证的桶索引缓存(16384 个条目)— 在 GC 重新哈希期间安全 - `lua_rawgeti`:数组直接 O(1) 路径 + 桶索引哈希部分缓存(8192 个条目) - `luaV_gettable` 安全补丁:在将 TValue 类型字段用作数组索引之前进行验证 ### 6 个 CPU 端优化模块 - **屏幕外动画节流**:基于距离的 3 级更新速率(满速 / 1:4 / 1:16) - **SSE2 数学**:矩阵乘法、4×4 矩阵乘法、四元数归一化、视锥 AABB 对 4 平面剔除、视锥点剔除、射线-三角形相交、矩阵-向量变换、粒子模拟节流、网络 GUID 解包、BGRA↔ARGB 批量交换、预乘 alpha - **战斗文本批处理**:256 条目的环形缓冲区,每帧刷新 - **UI 布局脏标记缓存**:以帧指针为键的 4096 插槽,基于世代的失效机制 - **网络心跳过滤器**:在最近发送过数据时抑制 CMSG_PING/CMSG_TIME_SYNC_RESP - **不变 Lua 脚本缓存**:用于 UnitHealth/UnitPower/UnitClass 结果的 256 插槽缓存 ### 内存与异步 - 64 字节对齐的 8 级 slab 分配器(64B–8192B),用于缓存行对齐的热点结构 - 16384 条目的 GUID→对象 FNV-1a 哈希表,支持无锁读取 - 2 线程 SPMC 工作池(2048 个插槽),用于即发即忘的任务调度 ### 基础设施与诊断 - 50-API infra_patch:对象池、去重、帧时间平滑、自适应缓存 TTL - 20-feature hot_patch:数据存储查找缓存、删除预取、提示框提前退出、事件去重 - 3-hook hook_prefetch:在清理/删除/数据存储重置路径上进行 SSE2 预取 - CrashDumper:128 插槽特性注册表 + 256 条目 hook 调用追踪 + minidump/文本崩溃报告 - 冻结 watchdog:10 秒阈值,带每特性活动报告 - 带速率限制日志记录的优先级 watchdog ### 缓存 - 提示框 LRU(512 插槽,30s TTL),regex 编译模式(256 插槽,120s TTL) - SSE2 三角函数查找表(4096 条目 sin/cos,1024 条目 atan) - 渲染状态去重(256 插槽),事件名称查找/哈希缓存 - 事件名称查找/哈希缓存 ## 当前状态 ### 性能指标(真实世界测试) - **帧时间**:在重度 addon 的团队副本中帧时间更平滑 - **CPU 使用率**:在重度 addon 的游戏中显著降低 - **Lua 操作**:更快的表查找(getstr/rawgeti 缓存)和库快速路径 - **计时缓存**:高 QPC 缓存命中率 - **字符串格式化**:高快速路径命中率 ## 当前特性集 ### 内存与分配器 - **将 WoW 的静态 CRT 分配器重定向至 mimalloc** *(已启用)* — `malloc`/`free`/`realloc`/`calloc`/`_msize`/`_recalloc` 作为一个封闭集被路由至 mimalloc 并带有转换防护,用于在长时间会话中对 32 位 VA 进行碎片整理(参见 *新优化*)。`GlobalAlloc(GMEM_FIXED)` 也由 mimalloc 提供服务。 - **自适应清理延迟 + 内存压力调节器** — 清理激进程度随 VA 压力而缩放;在严重压力下强制 `mi_collect` - Lua 分配器替换 *(已禁用 — 登录期间指针损坏;上面的 CRT 重定向是安全路径)* - WoW `free` 包装器快速路径(调用 WoW 自身的 `free`,跳过冗余的 `_msize` 堆遍历) - Lua 字符串表预调整大小,以减少哈希调整大小引起的峰值 - 为进程堆和新堆启用低碎片堆 (LFH) - 后台堆压缩器(将 VA 扫描推迟到加载界面) ### Lua runtime - 自适应手动 Lua GC - 4 级 GC 步进: - 正常 - 战斗 - 空闲 - 加载 - GC 步进与 !LuaBoost 同步 - 安全的 Lua 统计数据导出至 addon - Lua 重载检测与干净的重初始化 ### WoW API 结果缓存 - `GetItemInfo` - 8192 插槽缓存,直接内存访问 *(已禁用 - 会破坏 Aux / WCollections / ElvUI)* - `GetSpellInfo` - 已禁用(图标损坏,重登时崩溃) ### Lua 内部缓存 - `luaH_getstr` - 带世代保护的表字符串键查找缓存(8192 插槽,受 SEH 保护) - `luaH_getstr` 内联 v2 - 带 SSE2 预取的安全桶索引缓存(16384 个条目) - `lua_rawgeti` 内联 v2 - 安全的数组直接 + 桶索引缓存(8192 个条目) ### Lua 快速路径 - 第一阶段: - `string.format` - 第二阶段(安全,基于 Lua API) - **已启用**: - `string.find` (纯文本模式) - `string.match` (安全的部分快速路径) - `string.rep` - `string.gsub` (纯字面量快速路径) - `type` - `math.floor` - `math.ceil` - `math.abs` - `math.max` (2 个参数) - `math.min` (2 个参数) - `math.random` - `math.sqrt` - `math.fmod` - `math.modf` - `string.len` - `string.byte` - `string.char` - `tostring` - `tonumber` - `select` - `rawequal` - `string.sub` - `string.lower` - `string.upper` - `table.concat` (已禁用 - 直接的 RawTValue* 栈写入会导致卡死) - `unpack` (已禁用 - 直接的 RawTValue* 栈写入会导致卡死) - `ipairs` (已禁用 - 闭包工厂与 WoW 迭代器模式不兼容) - C 全局快速路径 - **已启用**: - `strjoin` - `strtrim` - `strsplit` ### Lua VM 内部机制 - 出于公开稳定性考虑,`luaV_concat` 和 `luaS_newlstr` hook 已被禁用 - 基线安全的 VM 操作,零开销 - 字符串表预调整大小保持激活状态,以防止重新哈希造成的卡死 ### 计时器与帧步调 - 主线程上的 PreciseSleep - 自动单客户端 / 多客户端计时行为 - `GetTickCount` 重定向至基于 QPC 的计时 - `timeGetTime` 重定向至相同的 QPC 时间线 - QueryPerformanceCounter 合并缓存 - 自适应计时器分辨率 - 硬编码的 FPS 上限从 200 提高到 999 ### 文件 I/O - MPQ 句柄追踪 - 追溯 MPQ 句柄扫描器 - 用于 MPQ 访问的顺序扫描提示 - 自适应 MPQ 预读缓存 - 跳过已追踪 MPQ 句柄的 `FlushFileBuffers` - `GetFileAttributesA` 缓存 - `SetFilePointer` 重定向至 `SetFilePointerEx` ### 线程与同步 - 基于 SRWLOCK 的文件缓存锁定 - 主线程优先级设为 ABOVE_NORMAL - 理想处理器分配 - 进程优先级设为 ABOVE_NORMAL - CriticalSection 自旋计数和自旋优先进入路径 - TLS 缓存的 `GetCurrentThreadId` 和伪句柄快速路径 ### 网络 - `TCP_NODELAY` - 立即 ACK 频率 - 套接字缓冲区调整 - 低延迟 TOS - keepalive (30秒空闲 5秒间隔 — 经过调整以保持 NAT 活跃,同时不会因瞬态网络抖动而断开连接) ### 异步加载与预取 使用工作线程和无锁队列的特性。状态反映了当前公开的安全配置;各个开关位于 `src/version.h` 中。 - **异步法术数据预取** - 在施法完成前预测性加载法术数据,减少施法延迟,带无锁队列(4096 个条目)和缓存(4096 个条目)的工作线程 *(已禁用 — 占位工作线程,无生产者)* - **多线程 addon 调度器** - 在工作线程池(4 个线程)中并行化 addon OnUpdate 回调,减少在重度 addon 设置中的主线程 CPU 占用,带无锁队列(8192 个条目)的批处理 *(已禁用 - 对 WoW 游戏状态的未同步写入)* - **预测性 MPQ 预取** - 追踪区域转换并预测下一个区域,在传送前将纹理/模型/WMO 预取到 OS 缓存中,减少区域加载卡顿,带无锁队列(2048 个条目)的工作线程池(2 个线程) *(已启用)* - **多线程战斗日志解析器** - 将战斗日志解析卸载到工作线程,减少团队副本中的主线程 CPU 占用,带异步处理的无锁队列 *(已禁用 — 占位工作线程,无生产者)* - **声音预取** - 根据施法、区域转换、战斗状态预测并预取声音文件,带无锁队列(1024 个条目)的工作线程池(2 个线程) *(已禁用 — 占位工作线程,无生产者)* - **异步任务/成就加载** - 异步任务日志和成就数据加载,带无锁队列(512 个条目)的工作线程 *(已禁用 — 占位工作线程,无生产者)* - **多线程姓名版渲染器** - 将姓名版渲染卸载到工作线程,减少 25 人团队副本中的主线程 CPU 占用,优先级系统(目标 > 焦点 > 附近 > 远程) *(已禁用 - 对 WoW 游戏状态的未同步写入)* - **模型/M2 缓存** - 用于已加载模型的同步 LRU 缓存(1024 个条目),消除冗余模型加载 *(已启用)* - **异步纹理加载** - 带无锁队列(8192 个条目)和 LRU 缓存(2048 个条目)的工作线程池(2 个线程) *(已禁用 — 占位工作线程,无生产者)* - **Addon 调度器** - 轻量级事件驱动的 addon 更新调度 *(已启用)* ### 其他 runtime 优化 - 战斗日志优化器 - **修复了长达 16 年的战斗日志 bug**(日志保留时间从 300 秒增加到 1800 秒,事件不再在长时间会话中丢失) - `CompareStringA` 快速 ASCII 路径 - `MultiByteToWideChar` / `WideCharToMultiByte` - SSE2 ASCII 快速路径(在兼容 ASCII 的代码页上为纯 ASCII 字符串绕过 NLS) - `lstrlenA` / `lstrlenW` 快速路径 - 无调试器时 `OutputDebugStringA` 空操作 - 快速 `IsBadReadPtr` / `IsBadWritePtr` - 定期统计信息转储 - CRT `pow()` 整数快速路径 (x^2=x*x, sqrt, 等.) - CRT `strstr` SSE2 Boyer-Moore-Horspool ### SSE2 字符串/内存快速路径 (WoW-内部,已激活) 在已验证的地址处替换 WoW 自身的静态链接 CRT 例程: - WoW `strlen` (sub_76EE30) - 16 字节对齐的 SSE2 扫描,页面安全 - WoW `memset` (0x40BB80, 1108 个调用者) - 完整 SSE2 + 非临时 ≥2 MB - WoW `memcpy` (0x40CB10, 719 个调用者) - SSE2 16–255 B + 非临时 ≥256 KB,重叠安全 - WoW `_strnicmp` (0x76E780, 1013 个调用者) - SSE2 ASCII 不区分大小写比较 - `strstr` - SSE2 Boyer–Moore–Horspool - `MultiByteToWideChar` / `WideCharToMultiByte` - SSE2 ASCII 快速路径 ### SSE2 数学与几何 (WoW-内部,已激活) - SSE2 4×4 矩阵乘法 — `CMatrix::operator*` (0x4C1F00) - SSE2 矩阵-向量变换 — 3D 点 × 4x4 矩阵 (0x4C21B0), 4D 向量 × 4x4 矩阵 (0x4C2270), 原位点 × 4x4 (0x4C2300) - SSE2 `C3Vector::Normalize` — 0x4C3420 + 0x4C3600 (全精度 `sqrtss`/`divss`,复制了引擎防护) - SSE2 `CMatrix::Transpose` — 0x4C23D0 (`_MM_TRANSPOSE4_PS`, 按位一致) - SSE2 视锥点剔除 — `CFrustum::IsPointVisible` (0x983D70) - SSE2 Möller-Trumbore 射线-三角形相交 — 32 位索引 (0x9836B0), 16 位索引 (0x983490) - SSE2 视锥 AABB 对 4 平面剔除 - SSE2 BGRA↔ARGB 批量交换,预乘 alpha - 网络 GUID SSE2 解包 — `CDataStore::GetWowGUID` (0x76DC20) - SSE2 四元数归一化 *(已启用 — 稳健的双精度数学)* - 粒子模拟节流 — `CParticleEmitter::SimulateParticle` (0x981D40) *(已禁用 — 0x981D40 是粒子生成/初始化例程,而不是可跳过的推进步骤;节流它会导致粒子未初始化,渲染为彩色闪光)* ### Lua 事件合并 *(已禁用)* - Hook `FrameScript_SignalEvent` (0x81AC90) 以每帧缓冲并对高频 UI 事件去重 - **已禁用**:抑制事件并在一帧后重新触发会改变事件的时间/顺序,并且在角色切换崩溃发生的世界内 → 界面销毁期间尚未得到验证。在能够在游戏中确认之前,稳定性胜过去重带来的收益。 ### 内核调用缓存 (38 个 hook) 批次 1-8:`GetSystemTimeAsFileTime` (基于 QPC 的 1ms 刷新), `GetACP`, `GetUserDefaultLangID`, `GetProcessHeap`, `CharUpperA/W`, `CharLowerA/W`, `MapVirtualKeyA`, `GetThreadPriority` 批次 11-20:`GetOEMCP`, `GetDoubleClickTime`, `GetCursorPos`, `GetSysColor`, `GetCaretBlinkTime`, `IsWindow`, `GetDesktopWindow`, `GetFocus` 批次 21-26:`GetTickCount64` (QPC 支持), `ShowCursor`, `GetVersionExA`, `GetSystemMetrics`, `IsDebuggerPresent` (空操作), `GetSystemInfo`, `RegQueryValueExA` 批次 31-38:`GetCurrentProcess`, `GetCurrentThread`, `GetCPInfo` 及相关内核缓存 ### 加载界面优化 - 在 HD 客户端(>500MB 工作集)上跳过 UR 内存竞技场预留 - 动态 VA 内存竞技场:在加载期间预留 256MB,之后释放 - Sleep hook:对 >16ms 的等待进行批量 Sleep(空闲时占用更少 CPU) ### VA 竞技场 (虚拟地址竞技场) - 带有 `MEM_TOP_DOWN` 的 512MB 高地址预留竞技场 - Wow.exe 调用者过滤 - 仅处理来自 WoW 可执行代码的分配 - 用于正确多页分配/取消分配的跨度追踪 - 正确的 `MEM_DECOMMIT` / `MEM_RELEASE` 行为 - 减少 WoW 大型分配造成的 32 位地址空间碎片 ## 实际中的改进 ### 你会注意到 - 更平滑的帧时间 - 更少的随机微型卡顿 - 更好的长时间游戏流畅度 - 在重度 addon 的游戏中更低的 Lua 开销 - 随着时间推移分配器碎片化减少 - 在繁重的 UI 和 addon 工作负载下更好的响应速度 - 更快的区域转换和传送 - 减少施法延迟 - 更流畅的重度 addon 游戏 ### 你可能会注意到 - 在城市和团队副本中最低 FPS 略有提升 - 减少了“长时间游戏后客户端变得卡顿”的感觉 - 更平滑的加载过渡 - 更快的重度 Lua addon 行为表现 ### 你不应期望 - 仅靠一个 hook 就带来平均 FPS 的巨大提升 - 视觉变化 - 神奇地修复损坏的 addon - 游戏自动化 这是一个引擎和 runtime 优化 DLL,而不是 UI 大修。 ## 推荐组合 为了获得最佳效果,请将 wow_optimize 与 [!LuaBoost](https://github.com/suprepupre/LuaBoost) 结合使用。 | 层级 | 工具 | 用途 | |------|------|---------| | 引擎 / C / Win32 | `wow_optimize.dll` | 分配器, Lua VM, 计时器, 文件 I/O, 网络, runtime 开销降低 | | Lua / Addon | `!LuaBoost` | GC 控制, 加载辅助, 表池, 更新调度器, 诊断 | ## 安装说明 ### 选项 A - 代理加载 复制到你的 WoW 文件夹中: - `version.dll` - `wow_optimize.dll` 然后正常启动 WoW。 ### 选项 B - 加载器 复制: - `wow_loader.exe` - `wow_optimize.dll` 然后启动 `wow_loader.exe`。 ### 选项 C - 手动注入 复制: - `wow_optimize.dll` - 你的注入器 然后在 WoW 启动后进行注入。 ## 兼容性与设置 1. 将 `!LuaBoost` addon 安装到 `Interface\AddOns\` 中。 2. **禁用冲突的 addon:** 移除或禁用任何第三方的 GC 优化器(`GarbageProtector`、`GarbageCollector`、`SmartGC` 等)以及战斗日志修复(`CombatLogFix` 等)。DLL 原生处理这些功能;同时运行会导致重复 hook、内存损坏或崩溃。 3. **调整伤害统计设置:** 在你的统计 addon 中禁用内置的垃圾回收/内存优化,以防止重复执行 Lua GC。 - **Skada:** ![Skada 设置](https://raw.githubusercontent.com/suprepupre/wow-optimize/main/images/image1_Skada_settings.png) - **DBM:** ![DBM 设置](https://raw.githubusercontent.com/suprepupre/wow-optimize/main/images/image2_DBM_settings.png) ## 多客户端支持 wow_optimize 会自动检测是否正在运行多个 WoW 实例。 - 单客户端: - 精确睡眠 - 0.5 毫秒计时器 - 多客户端: - 基于让步的睡眠 - 1.0 毫秒计时器 - 降低工作集目标 与在所有客户端上强制执行激进的单客户端计时相比,这减少了 CPU 压力。 ## macOS / Apple Silicon (WoWSilicon) wow_optimize 可在 macOS 上通过 [WoWSilicon](https://github.com/WoWSilicon/WoWSilicon) 运行,它使用 Wine + [rosettax87](https://github.com/athei/x87sidecar) 转译,在 Apple Silicon 上原生运行 WoW 3.3.5a。 ### DLL 加载顺序 在 `dlls.txt` 中,`winerosetta.dll` 必须在 `libSiliconPatch.dll` 之前加载: ``` mods/winerosetta.dll mods/libSiliconPatch.dll mods/wow_optimize.dll ``` 调换前两者的顺序会导致 rosetta 错误。在没有 wow_optimize 的情况下顺序无关紧要,但在加载了它的情况下,转译层必须在安装任何 hook 之前完成初始化。 ### 测试鸣谢 macOS/WoWSilicon 兼容性由 **David** (`_oldq`) 测试。 ## 构建 构建目标始终为 Win32 i386,但你可以在 Windows 主机(原生 MSVC)或 macOS 主机(交叉编译)上生成它。两种路径都驱动相同的 `CMakeLists.txt`,并发布二进制等效的 DLL(差异在 ~30 KB 以内)。 ### Windows (原生 MSVC) 要求: - Windows 10 或 11 - 带有 C++ 桌面工作负载的 Visual Studio - CMake - Win32 / 32 位构建配置 ``` git clone https://github.com/suprepupre/wow-optimize.git cd wow-optimize build.bat ``` 输出: - `build\Release\wow_optimize.dll` - `build\Release\version.dll` - `build\Release\wow_loader.exe` ### macOS (编译至 Win32) 要求: - macOS (Apple Silicon 或 Intel) - Homebrew - [xwin](https://github.com/Jake-Shadle/xwin) 用于获取 Windows SDK / MSVC CRT 一次性设置: ``` brew install llvm lld cmake ninja xwin splat --output /opt/xwin ``` 构建: ``` git clone https://github.com/suprepupre/wow-optimize.git cd wow-optimize make ``` 输出: - `build/wow_optimize.dll` - `build/version.dll` - `build/wow_loader.exe` Makefile 通过 `cmake/toolchain-clang-msvc-x86.cmake` 中的工具链文件驱动 `clang-cl` (Homebrew `llvm`) 和 `lld-link` (Homebrew `lld`)。`make verify` 会打印 PE 头;`make clean` / `make rebuild` 按预期工作。如果你的路径不同,请在命令行上覆盖 `LLVM_DIR`、`LLD_DIR` 或 `XWIN`。 ## 核心架构 ### 主要模块 - `dllmain.cpp` - Win32 hook、分配器、计时器、文件 I/O、网络、线程、VA 竞技场 - `lua_optimize.cpp` - Lua VM 分配器、自适应 GC(具有帧时间缩放和 VA 压力覆盖)、Lua 全局变量桥接 - `lua_fastpath.cpp` - `string.format` 和运行时发现的第二阶段 hook(24/27 个函数) - `lua_vm_engine.cpp` - 带有内联缓存的直接线程化 Lua VM 解释器 - `lua_getstr_inline.cpp` - 用于 luaH_getstr 的安全桶索引缓存(16384 个条目) - `lua_rawgeti_inline.cpp` - 用于 lua_rawgeti 的安全数组直接 + 桶索引缓存(8192) - `lua_pushnumber_fast.cpp` - 用于 lua_pushnumber 的直接 TValue 栈写入 - `lua_gettable_safety.cpp` - TValue 类型验证崩溃修复 - `hooks_render.cpp` - 3 级屏幕外动画节流,跳过后缓冲区 LockRect - `hooks_simd.cpp` - SSE2 矩阵乘法、4×4 矩阵乘法、四元数归一化、视锥 AABB/点剔除、射线-三角形相交、矩阵-向量变换、粒子模拟节流、BGRA↔ARGB、预乘 alpha - `hooks_logic.cpp` - 战斗文本批处理、UI 布局缓存、心跳过滤器、脚本缓存 - `hooks_memory.cpp` - 64B 对齐的 slab 分配器,16384 条目 GUID 哈希表 - `hooks_async.cpp` - 2 线程工作池、粒子 SSE2、ADT 预取 - `event_coalescer.cpp` - 通过 FrameScript_SignalEvent hook 实现的 Lua 事件合并,每帧去重 - `network_guid_sse2.cpp` - 用于 CDataStore::GetWowGUID 的 SSE2 无分支 GUID 解包 - `d3d9_state_manager.cpp` - 15-hook D3D9 vtable 补丁器(已禁用 — DXVK 冲突) - `hot_patch.cpp` - 20 个运行时热补丁优化 - `infra_patch.cpp` - 50 个基础设施 API(池、缓存、去重、性能监视器) - `hook_prefetch.cpp` - 用于清理/删除/重置路径的 3 个 SSE2 预取 hook - `data_caches.cpp` - 10 个游戏数据查找缓存(法术、M2、FMOD、DBC 等) - `compute_caches.cpp` - 10 个计算/转换缓存(BZ2、顶点 SSE2、regex 扩展等) - `crash_dumper.cpp` - 带有特性追踪和 hook 追踪的增强型崩溃报告器 - `lua_internals.cpp` - 稳定的 VM 基线(禁用了不安全的 hook) - `combatlog_optimize.cpp` - 战斗日志保留和清理行为 - `combatlog_mt.cpp` - 多线程战斗日志解析器 - `texture_async.cpp` - 带有工作线程池的异步纹理加载 - `spell_prefetch.cpp` - 异步法术数据预取 - `addon_dispatcher.cpp` - 多线程 addon 更新调度器 - `model_async.cpp` - 模型/M2 缓存 - `mpq_prefetch.cpp` - 预测性 MPQ 预取 - `api_cache.cpp` - `GetItemInfo` 缓存 - `ui_cache.cpp` - 在公开安全构建中已禁用 - `version_proxy.cpp` - 代理加载器 - `wow_loader.cpp` - 独立加载器可执行文件 ## 故障排除 | 问题 | 解决方案 | |---------|----------| | 代理 DLL 未加载(无日志文件) | 使用 `wow_loader.exe`,或在 `Wow.exe` 属性中取消勾选 **“禁用全屏优化”**:
![Wow.exe 属性](https://raw.githubusercontent.com/suprepupre/wow-optimize/main/images/wow.exe_properties.png) | | 杀毒软件标记了该 DLL | Hook/注入工具通常会触发误报。源代码开放以供审查。 | | `FATAL: MinHook initialization failed` | 另一个 hook DLL 冲突。禁用其他注入器/覆盖层。 | | `ERROR: No CRT DLL found` | 检测到非标准的 WoW 构建。 | | Socket 显示 `fail` | 在某些 Windows 版本上正常 - 某些网络选项需要管理员权限。 | | 伤害统计仍然损坏 | 移除 `CombatLogFix` 或类似 addon。两个修复器发生冲突。 | | 没有明显区别 | 在插件较少的高端 PC 上属于预期情况。 | | `[UICache] DISABLED` | 非标准的 WoW 构建 - 未找到方法表。 | | 多客户端 CPU 使用率高 | 预期情况。每个客户端都运行全面优化。如果需要,从辅助客户端中移除 `version.dll`。 | | “我使用 DXVK 或 Vulkan” | 完全支持。无 D3D9 状态缓存依赖项。 | | `Large pages: no permission` | 仅供参考 — **并非**崩溃原因。Large pages 是一种可选的 TLB 优化(mimalloc 2 MB OS 页面);没有它们,DLL 在普通的 4 KB 页面上也能正常运行。要启用它们,请参阅下文的[修复 `Large pages: no permission`](#fixing-large-pages-no-permission)。 | ### 修复 `Large pages: no permission` 此日志行意味着你的 Windows 账户不具有 **Lock pages in memory**(锁定内存中的页面)权限。DLL 只能在该账户已经拥有该权限的情况下*使用*它 — 它无法为你授予该权限。授予它是可选的,并且仅启用 large-page TLB 优化;其他所有功能在没有它的情况下也能正常工作。 **1. 授予该权限** 1. 按 `Win+R`,输入 `secpol.msc`,并以管理员身份运行(本地安全策略)。 2. 转到 **本地策略 → 用户权限分配 → Lock pages in memory**。 3. 点击 **添加用户或组**,输入你的 Windows 用户名,点击 **检查名称**,然后点击 **确定**。 4. 注销并重新登录(或重启)以使更改生效。 **2. 仍然显示 `no permission`?使用组通配符** 如果以管理员身份运行仍然产生 `no permission` 日志行,则可能是你的 Windows 用户名在策略工具中没有正确映射。请添加通用组而不是特定账户: 1. 再次打开 `secpol.msc`。 2. 返回到 **本地策略 → 用户权限分配 → Lock pages in memory**。 3. 清除你的特定账户名。 4. 点击 **添加用户或组**,输入 `Administrators`(复数),点击 **检查名称**,然后点击 **确定**。 5. 再次点击 **添加用户或组**,输入 `Users`(复数),点击 **检查名称**,然后点击 **确定**。 6. 重启你的电脑。 重启后,日志应显示为 `Large pages: ENABLED for mimalloc`。如果你完全不想更改策略,这一行也是无害的,可以忽略 — 或者在 `src/version.h` 中设置 `TEST_ENABLE_LARGE_PAGES 0` 以彻底使该尝试静默。 ## 项目结构 ``` wow-optimize/ ├── src/ │ ├── allocators/ # mimalloc redirect, cache governor, heap compactor │ ├── core/ # DLL entry, proxy loader, features config (version.h) │ ├── diagnostics/ # EIP sampling profiler, crash reporter, CVar watchdog │ ├── hooks_subsystems/ # D3D9 state manager, CRT string fast-paths, event/data caches │ ├── runtime_vm/ # Lua C-API detour hooks, stack query inline paths, VM engine │ ├── simd_math/ # SSE2 4x4 matrix, frustum point culling, raycast overrides │ └── threading/ # Multi-threaded work pool dispatcher ├── CMakeLists.txt # Build system definition ├── README.md # Project overview & documentation └── LICENSE # Project license ``` ## 许可证 MIT 许可证 - 自由使用、修改和分发。
标签:C/C++, Linux, Lua虚拟机, UML, 事务性I/O, 内存管理, 性能优化, 检测绕过, 游戏模组, 魔兽世界