WarcraftHelper深度指南:12个插件模块从部署到源码定制
WarcraftHelper深度指南12个插件模块从部署到源码定制【免费下载链接】WarcraftHelperWarcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelperWarcraftHelper 是一款注入魔兽争霸3进程的 Win32 辅助插件核心是帧数解锁、宽屏适配、地图大小限制解除和自动录像四类能力覆盖 1.20e 到 1.27b 五个版本。适合两类人想在 144Hz 显示器上稳定跑帧同步对战的竞技玩家以及在 21:9 超宽屏上玩战役、被中文地图名和字体重叠折磨的老玩家。① 摸清项目能力12项功能与三步上手链路整个项目就干一件事把魔兽争霸3的渲染与输入路径 Hook 住按配置文件开关逐项改造行为。全部功能由WarcraftHelper.ini控制随包出厂的默认配置如下表功能一句话说明默认开启帧率解锁 (UnlockFPS)拆掉 60FPS 上限并关闭垂直同步true自动显示 FPS (ShowFPS)游戏内常驻帧率/fps指令可关true宽屏支持 (WideScreen)重写 Projection Matrix宽屏不拉伸true窗口化自动全屏 (AutoFullScreen)启动时把窗口铺满屏幕false地图大小解锁 (UnlockMapSize)大地图正常加载true1.20e 自动显血 (ShowHPBar)老版本补单位血条1.24e 游戏自带false自动保存录像 (AutoSaveReplay)每局按时间戳存到 Replay/WHReplaytrueFPS 锁帧 (FpsLimit)按 TargetFps 限最高帧仅 1.27a/btrueTargetFps300版本差异比想象中多这张矩阵比翻源码快得多版本帧解锁/宽屏/大地图/自动录像自动显示FPS差异点1.20e全支持×需自动显血建议打 d3d8to9 补丁1.24e全支持√建议打 d3d8to9 补丁1.26a全支持√独有 U9魔兽助手崩溃修复1.27a-1.27b全支持√独有 FPS 锁帧1.27b 注册表写法不同最短上手链路三步# 1. 拉源码 git clone https://gitcode.com/gh_mirrors/wa/WarcraftHelper # 2. 构建VS2022 CMake必须 win32 平台 cd WarcraftHelper cmake . -A win32 -B build cmake --build build --config MinSizeRel # 3. 运行build/output 产物放入魔兽目录窗口化启动 war3.exe # 首次必须窗口化插件要借此把注册表里的 fps 上限改写掉② 拆解双层DLL架构与插件模块地图架构看完了先给一张目录地图只标核心文件WarcraftHelper/ ├── WHLoader/ │ └── dllmain.cpp # 引导 DLL一行代码拉起主 DLL ├── WarcraftHelper/ │ ├── dllmain.cpp # 主 DLL 入口DllMain 触发 LoadPlugins │ ├── helper.cpp # 12 个插件的注册表与统一启动 │ ├── config/ │ │ ├── config.cpp # 解析 WarcraftHelper.ini │ │ └── config.hpp │ ├── game/ │ │ ├── warcraft.cpp # 版本探测 / Hook / 内存补丁三大件 │ │ ├── warcraft.hpp │ │ └── version.hpp # 1.20e~1.27b 构建号枚举 │ └── plugin/ # 12 个功能插件全部实现 IPlugin │ ├── plugin.hpp # 接口Start()/Stop() │ ├── unlockfps.cpp # 帧率解锁 │ ├── fpslimiter.cpp # 按 TargetFps 锁帧 │ ├── widescreen.cpp # 宽屏投影矩阵 │ ├── sizebypass.cpp # 地图大小解锁 │ ├── windowfixer.cpp # F7 窗口刷新 │ ├── pathfix.cpp # 中文地图名修复 │ ├── autorep.cpp # 自动保存录像 │ ├── showfps.cpp # 游戏内 FPS 显示 │ ├── showhpbar.cpp # 1.20e 自动显血 │ ├── campaignfix.cpp # 战役修复 │ ├── u9helper.cpp # U9助手崩溃修复 │ └── replayview.cpp # 录像观战 └── d3d9/ ├── d3d9p.cpp # d3d9 代理 DLL导出表原样转发 └── d3d9.def模块之间的职责和依赖关系模块源文件职责依赖方向d3d9 代理d3d9/d3d9p.cpp导出转发给真实 d3d9代理 → WHLoader引导层WHLoader/dllmain.cpp拉起主 DLLWHLoader → WarcraftHelper.dll主入口WarcraftHelper/dllmain.cppDllMain 触发加载→ Helper插件容器WarcraftHelper/helper.cpp注册并顺序启动插件Helper → 12 个 IPlugin游戏抽象WarcraftHelper/game/warcraft.cpp版本探测/Hook/内存补丁各插件 → Game配置层WarcraftHelper/config/config.cpp解析 ini各插件 → Config帧率解锁WarcraftHelper/plugin/unlockfps.cpp拆 60FPS 上限→ Game, ConfigFPS 锁帧WarcraftHelper/plugin/fpslimiter.cpp按 TargetFps 限帧→ Game, Config宽屏WarcraftHelper/plugin/widescreen.cpp重写投影矩阵→ Game, Config大地图WarcraftHelper/plugin/sizebypass.cppNOP 掉大小检查→ Game, Config窗口修复WarcraftHelper/plugin/windowfixer.cppF7 刷新窗口→ Game数据流向可以压成四句话游戏启动时 d3d9 代理 DLL 先被系统加载它把导出函数原样转发给真实 d3d9转发实现从 d3d9/d3d9p.cpp:5 起逐个函数排开同时拉起 WHLoader.dllWHLoader 的全部逻辑就是一行LoadLibraryA(WarcraftHelper.dll)WHLoader/dllmain.cpp:12。主 DLL 的 DllMain 在DLL_PROCESS_ATTACH时构造 Helper 并调用 LoadPluginsWarcraftHelper/dllmain.cpp:13-18后者校验宿主是 war3.exe、拿到 Game.dll 基址后按注册顺序跑完 12 个 Start()WarcraftHelper/helper.cpp:58-60。版本识别发生在 Game 构造函数读 Game.dll 的文件版本信息用dwFileVersionLS 0xffff取出构建号映射到 Version 枚举warcraft.cpp:56-59、version.hpp:4-58。③ 逐层深入5个核心模块的实现每个插件的骨架都一样查配置开关 → 按版本查偏移 → Hook 或打补丁。版本不匹配直接 return插件之间零耦合。下面拆五个最硬的。帧率解锁注册表、内存补丁、Hook 三连它干的事把魔兽的 60FPS 天花板整个拆掉。底层是三招组合拳。WriteFPSLimit()用EnumDisplaySettings读出显示器真实刷新率写进游戏内部的刷新率上限1.27b 要传指针其他版本传值写法不同然后把帧率检查点的一个字节补丁成0xFF绕过内部限制再Inline Hook住GetD3d9Parameters强制PresentationInterval D3DPRESENT_INTERVAL_IMMEDIATE等于把垂直同步关掉。收尾是把窗口最小化再还原逼游戏重新初始化 D3D 让改动生效。核心写入逻辑在WarcraftHelper/plugin/unlockfps.cpp:125// WarcraftHelper/plugin/unlockfps.cpp:125 EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, dm); if (dm.dmDisplayFrequency 60) { switch (GetGameInstance()-GetGameVersion()) { case Version::v127b: SetGameOptValue(GetGameOpt(), 0, 4, (DWORD)dm.dmDisplayFrequency); // 1.27b 传指针 break; default: SetGameOptValue(GetGameOpt(), 0, 4, dm.dmDisplayFrequency); // 其余版本传值 break; } }帧率拆掉上限之后宽屏上的画面怎么不拉伸宽屏支持重写 Projection Matrix它干的事让 16:9、21:9 窗口里的画面按真实比例渲染。魔兽构建投影矩阵走的是 D3DX 的CreateMatrixPerspectiveFov但游戏自己只会按 4:3 传参数。插件 Hook 住这个函数运行时用GetWindowRect量出窗口实际宽高算出相对 4:3 的放大系数fWideScreenMul (width/height)/(4/3)再把这个系数乘进 xScale手动重写矩阵的 x/y 缩放项。五个版本的函数偏移收敛在widescreen.cpp:62-80的 switch 分支里Hook 动作在 :81。矩阵重写逻辑WarcraftHelper/plugin/widescreen.cpp:9// WarcraftHelper/plugin/widescreen.cpp:9 RECT r; float fWideScreenMul 1.0f; if (GetWindowRect(GetGameInstance()-GetGameWindow(), r)) { float width float(r.right - r.left); float rHeight 1.0f / (r.bottom - r.top); fWideScreenMul width * rHeight * 0.75f; // (width/height)/(4/3)宽屏放大系数 } float yScale 1.0f / tan(fovY * 0.5f / sqrt(aspectRatio * aspectRatio 1.0f)); float xScale yScale / (aspectRatio * fWideScreenMul); // 关键系数乘进水平缩放 outMatrix[0] xScale; outMatrix[5] yScale;解锁之后帧率可能飙到两三百怎么把它钉回你想要的值FPS 锁帧在 DrawCall 里忙等它干的事把最高帧率锁在TargetFps。这个功能只有 1.27a/1.27b 支持老版本想锁帧没戏。实现上先读游戏内部的渲染后端标识gxTypeD3D 或 OpenGL按后端选不同的 draw 入口偏移fpslimiter.cpp:42 和 :48然后 Hook 住 DrawCall。每帧到来时计算距离上一帧的间隔没到1e6/TargetFps微秒就原地忙等到了才放行原始调用。忙等循环WarcraftHelper/plugin/fpslimiter.cpp:15// WarcraftHelper/plugin/fpslimiter.cpp:15 if (GetConfig()-m_fpsLimit GetConfig()-m_targetFps 1) { LARGE_INTEGER counter; QueryPerformanceCounter(counter); std::chrono::steady_clock::time_point currentMilli std::chrono::high_resolution_clock::now(); auto diff std::chrono::durationdouble, std::micro(currentMilli - g_lastPresentMilli); while (diff.count() g_frameMicro) { // g_frameMicro 1e6 / TargetFps见 :62 currentMilli std::chrono::high_resolution_clock::now(); diff std::chrono::durationdouble, std::micro(currentMilli - g_lastPresentMilli); } g_lastPresentMilli currentMilli; } return orgDrawCall(ecx, edx, unk);帧率稳了再解决一个中国玩家绕不开的问题中文地图名。中文地图名修复GB2312 转 UTF8它干的事让 GB2312 编码命名的地图能正常显示和加载。游戏自己的GetPathName遇到中文名编不出来直接返回...或空串。插件 Hook 这个函数先放行原逻辑一旦检测到失败返回值就拿输入参数里的 GB2312 原始串走MultiByteToWideChar → WideCharToMultiByte转成 UTF8 写回输出缓冲区。同时把内部的PathCopy用NOP 指令整段抹掉pathfix.cpp:70防止它把修好的路径又覆盖回去。转码逻辑WarcraftHelper/plugin/pathfix.cpp:15// WarcraftHelper/plugin/pathfix.cpp:15 if (!strncmp(dst, ..., 3) || dst[0] 0) { // 原函数搞不定中文名的标志 int len MultiByteToWideChar(CP_ACP, 0, nameGB2312, -1, NULL, 0); wchar_t* wstr new wchar_t[len 1]; memset(wstr, 0, len 1); MultiByteToWideChar(CP_ACP, 0, nameGB2312, -1, wstr, len); len WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); if (len dst_len) { if (wstr) delete[] wstr; return rst; // 缓冲区装不下就放弃 } WideCharToMultiByte(CP_UTF8, 0, wstr, -1, dst, len, NULL, NULL); if (wstr) delete[] wstr; }对战打完了录像怎么自动归档自动保存录像路径劫持加格式转换它干的事每局结束自动存一份带时间戳的录像官方平台的 .nwg 格式也能转回 .w3g。插件 Hook 游戏的存录像函数检查路径是否以LastReplay.w3g结尾autorep.cpp:58是就改写到Replay/WHReplay/下按年月_日_时_分_秒命名的路径。官方平台录出来的是 .nwg插件会把整个文件读进内存定位Warcraft III recorded game头部定义在 warcraft.hpp:14从头部开始截出 w3g 正文写回。路径改写WarcraftHelper/plugin/autorep.cpp:70// WarcraftHelper/plugin/autorep.cpp:70 time(timep); GetModuleFileName(NULL, whpath, MAX_PATH); whpath[strrchr(whpath, \\) - whpath 1] 0; // 截掉 exe 文件名留下目录 strftime(repname, MAX_PATH, \\Replay\\WHReplay\\%Y_%m_%d_%H_%M_%S.w3g, localtime(timep)); strcat(whpath, repname); replen strlen(whpath); if (replen MAX_PATH) { // 溢出了 replen MAX_PATH - 1; whpath[replen] 0; } ret orgSaveRep(pthis, unused, whpath); // 交给原函数存盘④ 实战三种场景的ini配置三个典型场景配置全写在WarcraftHelper.ini的[Options]段键名解析逻辑在 WarcraftHelper/config/config.cpp:13-21。场景1144Hz竞技帧同步1.27b目标帧率钉死在显示器刷新率看得清帧率波动。[Options] UnlockFPS true # 解锁是锁帧的前提 FpsLimit true # 开启锁帧防帧率飘 TargetFps 144 # 钉在显示器刷新率避免撕裂和额外发热 ShowFPS true # 游戏内显示帧率/fps 可关 WideScreen true # 16:9 窗口不拉伸 AutoFullScreen false # 竞技习惯窗口化方便切屏开黑 UnlockMapSize true # 打自定义图不受大小限制 AutoSaveReplay true # 留档复盘 ShowHPBar false # 1.27b 自带显血模块组合unlockfps fpslimiter showfps widescreen autorep。场景221:9超宽战役剧情目标无黑边、无拉伸的沉浸式剧情体验。[Options] WideScreen true # 21:9 刚需投影矩阵必须重写 AutoFullScreen true # 铺满屏幕 UnlockMapSize true # 战役大图可加载 ShowHPBar true # 1.20e 需要1.24e 游戏自带可忽略 ShowFPS false # 剧情不看帧率 AutoSaveReplay true # 存档录像 UnlockFPS true # 高帧率画面更顺滑 FpsLimit false # 不锁帧让 1.27b 全速跑模块组合widescreen unlockfps sizebypass showhpbar autorep。场景3录像观战存档目标高清回放观战同时把看过的录像归档。[Options] WideScreen true # 宽屏看回放 UnlockMapSize true # 大地图回放正常加载 AutoSaveReplay true # 回放再存一份到 WHReplay ShowFPS true # 回放时盯帧率 UnlockFPS false # 回放不需要高帧率 FpsLimit false # 同上 AutoFullScreen false # 窗口化方便对照资料模块组合replayview widescreen sizebypass autorep。三场景对比配置项144Hz竞技帧同步21:9超宽战役录像观战存档UnlockFPStruetruefalseFpsLimit / TargetFpson / 144offoffWideScreentruetruetrueAutoFullScreenfalsetruefalseUnlockMapSizetruetruetrueShowFPStruefalsetrueShowHPBarfalsetruefalseAutoSaveReplaytruetruetrue⑤ 源码级调优三处可直接改的代码配置开关能覆盖 80% 的需求剩下 20% 得动源码。下面三个案例分别对应参数替换、热键映射、逻辑注入全部可直接复制。案例1参数硬编码替换把刷新率上限压到 144Hz240Hz 显示器上游戏注册表上限会被写成 240帧率同步类地图反而容易掉帧。改WarcraftHelper/plugin/unlockfps.cpp// 原始代码unlockfps.cpp:125-126 EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, dm); if (dm.dmDisplayFrequency 60) {// 改后 EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, dm); dm.dmDisplayFrequency dm.dmDisplayFrequency 144 ? 144 : dm.dmDisplayFrequency; // 上限封顶 144 if (dm.dmDisplayFrequency 60) {效果注册表写入的刷新率上限封顶 144240Hz 屏上帧同步更稳GPU 发热同步下降。案例2热键映射修改窗口刷新键 F7 改 F5F7 在某些输入法或输入法切换习惯下容易误触。改WarcraftHelper/plugin/windowfixer.cpp:31// 原始代码windowfixer.cpp:31 if (IsKeyDown(VK_F7)) {// 改后 if (IsKeyDown(VK_F5)) { // 热键换成 F5效果窗口刷新热键从 F7 迁移到 F5Listen线程里 50ms 一次的轮询逻辑windowfixer.cpp:【免费下载链接】WarcraftHelperWarcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考