s-b-repo/nfsmw-2005-sdk
GitHub: s-b-repo/nfsmw-2005-sdk
一款跨平台的 header-only C/C++ Mod SDK,用于为《极品飞车:最高通缉》(2005)开发可同时通过 ASI Loader 和 BepInEx 6 加载的原生插件。
Stars: 3 | Forks: 0
# nfsmw_sdk — Need for Speed: Most Wanted (2005) Mod SDK

一个 header-only 的 C/C++ SDK,用于为 **NFSMW (2005)
`speed.exe`** (PE32, i386, image base `0x00400000`) 编写原生 mod。支持从
**Linux、Windows 或 macOS** 构建 mod 源码;输出始终是一个 32 位 Win32 DLL,
可在 **Ultimate-ASI-Loader** **和** BepInEx 6 下**同时**加载。
此 SDK 是
[nfsmw-2005-re](https://github.com/s-b-repo/nfsmw-2005-re) 逆向工程
项目面向 modder 的前端。地址来源于该项目的已验证 Ghidra 数据库
(`docs/sdk_addrs.json`, `docs/attribute_cracks_verified.json`,
`docs/sdk_enums.json`) 以及 berkayylmao 的 BSD-3 NFSPluginSDK。
## 为什么“支持 BepInEx”需要特别说明
NFSMW 是一款 **原生 Win32 游戏** —— 它没有 Mono/.NET/IL2CPP runtime。
BepInEx 6 的托管插件模型并不适用。真正*能*起作用的是
**BepInEx 6 NativeBootstrap (Doorstop)**:BepInEx 进行注入,然后加载
导出了 `BepInExNativePlugin_Load` 的*原生* DLL。此 SDK 会从一个共享的
`entry.c` 导出该函数**以及**一个经典的 ASI `DllMain` 工作线程,并通过一次性互锁机制确保无论哪个 loader 触发,插件都只运行一次。一个 DLL,兼容两个生态系统。
参见 [`docs/BEPINEX_INTEGRATION.md`](docs/BEPINEX_INTEGRATION.md)。
## 布局
```
sdk/
├── include/nfsmw_sdk/ header-only SDK
│ ├── nfsmw_sdk.h umbrella + NFSMW_PLUGIN_DECLARE/MAIN macros
│ ├── platform.h target detection, mem read/write, typed sugar
│ ├── globals.h typed global pointers + NFSMW_GLOBAL_* macros
│ ├── functions.h function address constants + typedef helpers
│ ├── enums.h engine enums
│ ├── attributes.h bChunk (Jenkins mix3) hash + Collection get/set
│ ├── hooks.h vtable / inline (MinHook) / JMP detour
│ ├── scan.h AOB signature scanner
│ ├── structs.h verified struct field offsets (opt-in)
│ ├── d3d9_hooks.h D3D9 EndScene/Reset render hook (opt-in)
│ ├── iat_hook.h import-table hook (opt-in)
│ ├── midhook.h mid-function register hook (opt-in)
│ ├── input.h action-binding access + poll hook (opt-in)
│ ├── lua.h register Lua 5.0.2 script natives (opt-in)
│ ├── events.h global hashed event bus (opt-in)
│ ├── hotkeys.h runtime keybinds (opt-in)
│ └── _generated_*.h AUTO-GENERATED — do not edit
├── src/entry.c unified ASI + BepInEx entry shim
├── extern/minhook/ vendored MinHook backend (BSD-2)
├── data/*.json codegen sources (addrs/attrs/enums/structs)
├── examples/ 12 buildable example mods
├── bepinex-template/ drop-in BepInEx install skeleton
├── cmake/ MinGW-w64 i686 cross toolchain + pkg config
├── tools/codegen.py regenerates _generated_*.h from data/*.json
├── tests/host_tests.py host unit tests (bChunk + AOB), run in CI
└── CMakeLists.txt cross-platform build + nfsmw_add_plugin()
```
## 预构建 mod(无需工具链)
不想自行构建?每个带标签的发布版本都提供了 12 个预编译的示例 mod
(PE32 i386,同时支持 ASI + BepInEx) —— 参见
**[Releases](https://github.com/s-b-repo/nfsmw-2005-sdk/releases)**
(`nfsmw-sdk-examples-.zip`,由 CI 基于该标签构建)。将
`.asi` 丢入 `/scripts/`,或者将 `.dll` 丢入
`/BepInEx/plugins/`。仓库本身仅包含源码;出于设计考虑,二进制文件
仅存在于 Releases 中。
## 快速开始
```
# 在任何已安装 i686-w64-mingw32 的主机 (Linux/macOS/Windows) 上:
cd sdk
cmake -S . -B build \
-DCMAKE_TOOLCHAIN_FILE=cmake/nfsmw-toolchain-mingw-i686.cmake
cmake --build build
# -> build/examples/infinite_nos.dll (BepInEx) + infinite_nos.asi (ASI)
```
将 `infinite_nos.asi` 丢入 `/scripts/` (ASI Loader) **或者**
将 `infinite_nos.dll` 丢入 `/BepInEx/plugins/` (BepInEx 6 原生插件)。
## 在你自己的项目中使用它
只需安装一次,然后通过 `find_package` 引用 —— 无需硬编码路径:
```
cmake -S sdk -B sdk/build -DNFSMW_BUILD_EXAMPLES=OFF \
-DCMAKE_TOOLCHAIN_FILE=sdk/cmake/nfsmw-toolchain-mingw-i686.cmake \
-DCMAKE_INSTALL_PREFIX=$HOME/.local
cmake --build sdk/build --target install
```
```
# 你的 mod 的 CMakeLists.txt
find_package(nfsmw_sdk CONFIG REQUIRED)
nfsmw_add_plugin(my_mod SOURCES my_mod.cpp) # -> my_mod.dll + my_mod.asi
```
(或者直接将仓库作为 vendor/submodule 引入,然后执行 `add_subdirectory(sdk)`。)
## 最小 mod
```
#include
NFSMW_PLUGIN_DECLARE("My Mod", "1.0.0", "me")
NFSMW_PLUGIN_MAIN() {
*nfsmw::Tweak_InfiniteNOS() = true;
return NFSMW_OK;
}
```
## 构建文档
- [`docs/BUILDING_LINUX.md`](docs/BUILDING_LINUX.md)
- [`docs/BUILDING_WINDOWS.md`](docs/BUILDING_WINDOWS.md)
- [`docs/BUILDING_MAC.md`](docs/BUILDING_MAC.md)
- [`docs/BEPINEX_INTEGRATION.md`](docs/BEPINEX_INTEGRATION.md)
- [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)
- [`docs/CAPABILITIES.md`](docs/CAPABILITIES.md) — **你可以/不可以 hook 和修改哪些内容** + BepInEx 实际上如何与此 SDK 关联 + 路线图
- [`docs/COOKBOOK.md`](docs/COOKBOOK.md) — **可直接复制粘贴的配方**
组合了底层原语(包括 struct-offset 字段编辑) + 诚实的“不可行”清单
## 重新生成地址表
`tools/codegen.py` 会从 `sdk/data/` 中内置的 JSON 重新构建 `_generated_addrs.h`、`_generated_attrs.h`、
`_generated_enums.h` —— 这是
SDK 自带的事实来源(以便 CI 可以验证这些头文件)。
```
python3 sdk/tools/codegen.py # regenerate
python3 sdk/tools/codegen.py --check # CI guard: nonzero if stale
```
当上游 RE 数据库(`nfsmw-2005-re/docs/`)发生更改时,请重新同步
并重新生成:
```
cp ../nfsmw-2005-re/docs/{sdk_addrs,attribute_cracks_verified,sdk_enums}.json sdk/data/
python3 sdk/tools/codegen.py
```
(如果在主 RE 项目树内运行,当 `sdk/data/` 不存在时,
`codegen.py` 会自动回退到 `../../docs/`。)
## 法律声明
BSD-3-Clause。此 SDK **不包含任何有版权的 EA 游戏数据** —— 仅包含
为互操作性而通过净室逆向工程(clean-room RE)得出的地址/偏移量。
镜像的 NFSPluginSDK 保留了 berkayylmao 的 BSD-3 许可证
(`docs/nfsplugin_sdk_mw05/LICENSE`)。内置的 MinHook 后端
(`extern/minhook/`)版权归 Tsuda Kageyu 所有,采用 BSD-2-Clause 许可证
(`extern/minhook/LICENSE.txt`) —— 与此 SDK 的 BSD-3 兼容。
`data/struct_offsets.json` / `structs.h` 中的
struct 字段偏移量是
根据 berkayylmao 的 NFSPluginSDK MW05 类型定义
(BSD-3, `docs/nfsplugin_sdk_mw05/LICENSE`)由编译器生成的;我们仅提供生成的偏移量表,而不包含其源码。你必须拥有 NFSMW 的正版副本
才能使用由此 SDK 构建的任何 mod。
支持此项目
如果此工具为你节省了时间,可以考虑用 Monero 赞助 1 美元:
478Lb78LDscQ8ukEDTZqXgEtjoBX1jMuVGvgfy2RagxZZk89YuyVYsganfLUKnwggz8YiBxhG25yWWiHUppG9uarSiseseY
XMR —— 隐私、不可追踪、深表感谢。
标签:Bash脚本, BepInEx, C/C++, Need for Speed, 事务性I/O, 客户端加密, 游戏Mod开发, 游戏逆向工程, 逆向工具, 高性能