refactor: merge openwa-types and openwa-lib into unified openwa-core crate
Browse filesThe split between openwa-types (pure types/addresses) and openwa-lib
(rebase/wa_call/typed wrappers) was arbitrary and added friction when
deciding where new code belongs. Merged both into openwa-core.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This view is limited to 50 files because it contains too many changes. See raw diff
- CLAUDE.md +7 -6
- Cargo.lock +5 -11
- crates/{openwa-lib → openwa-core}/Cargo.toml +2 -5
- crates/{openwa-types → openwa-core}/src/address.rs +0 -0
- crates/{openwa-types → openwa-core}/src/class_type.rs +0 -0
- crates/{openwa-types → openwa-core}/src/ddgame.rs +0 -0
- crates/{openwa-types → openwa-core}/src/ddgame_wrapper.rs +0 -0
- crates/{openwa-types → openwa-core}/src/dssound.rs +0 -0
- crates/{openwa-types → openwa-core}/src/fixed.rs +0 -0
- crates/{openwa-types → openwa-core}/src/frontend.rs +0 -0
- crates/{openwa-types → openwa-core}/src/game_info.rs +0 -0
- crates/{openwa-types → openwa-core}/src/landscape.rs +0 -0
- crates/{openwa-types → openwa-core}/src/lib.rs +5 -0
- crates/{openwa-types → openwa-core}/src/message.rs +0 -0
- crates/{openwa-types → openwa-core}/src/opengl.rs +0 -0
- crates/{openwa-lib → openwa-core}/src/rebase.rs +1 -1
- crates/{openwa-types → openwa-core}/src/render.rs +0 -0
- crates/{openwa-types → openwa-core}/src/scheme.rs +0 -0
- crates/{openwa-types → openwa-core}/src/sound.rs +0 -0
- crates/{openwa-types → openwa-core}/src/speech.rs +0 -0
- crates/{openwa-types → openwa-core}/src/sprite.rs +0 -0
- crates/{openwa-types → openwa-core}/src/task.rs +0 -0
- crates/{openwa-lib → openwa-core}/src/wa/ddgame.rs +2 -2
- crates/{openwa-lib → openwa-core}/src/wa/frontend.rs +1 -1
- crates/{openwa-lib → openwa-core}/src/wa/mfc.rs +1 -1
- crates/{openwa-lib → openwa-core}/src/wa/mod.rs +0 -0
- crates/{openwa-lib → openwa-core}/src/wa/registry.rs +0 -0
- crates/{openwa-lib → openwa-core}/src/wa/resource.rs +0 -0
- crates/{openwa-lib → openwa-core}/src/wa_call.rs +0 -0
- crates/{openwa-types → openwa-core}/src/weapon.rs +0 -0
- crates/{openwa-types → openwa-core}/tests/fixtures/beginner.wsc +0 -0
- crates/{openwa-types → openwa-core}/tests/fixtures/classic.wsc +0 -0
- crates/{openwa-types → openwa-core}/tests/fixtures/shopping.wsc +0 -0
- crates/{openwa-types → openwa-core}/tests/scheme_parse.rs +1 -1
- crates/openwa-harness/Cargo.toml +1 -1
- crates/openwa-harness/src/lib.rs +1 -1
- crates/openwa-lib/src/lib.rs +0 -5
- crates/openwa-types/Cargo.toml +0 -5
- crates/openwa-wormkit/Cargo.toml +1 -2
- crates/openwa-wormkit/src/hook.rs +1 -1
- crates/openwa-wormkit/src/lib.rs +1 -1
- crates/openwa-wormkit/src/replacements/config.rs +7 -7
- crates/openwa-wormkit/src/replacements/frontend.rs +5 -5
- crates/openwa-wormkit/src/replacements/input.rs +4 -4
- crates/openwa-wormkit/src/replacements/render.rs +4 -4
- crates/openwa-wormkit/src/replacements/scheme.rs +6 -6
- crates/openwa-wormkit/src/replacements/sound.rs +4 -4
- crates/openwa-wormkit/src/replacements/speech.rs +4 -4
- crates/openwa-wormkit/src/replacements/team.rs +2 -2
- crates/openwa-wormkit/src/replacements/weapon.rs +3 -3
CLAUDE.md
CHANGED
|
@@ -19,13 +19,13 @@ cargo build -p openwa-wormkit --release
|
|
| 19 |
cargo build -p openwa-validator --release
|
| 20 |
|
| 21 |
# Run tests (openwa-types is pure Rust, works on any host)
|
| 22 |
-
cargo test -p openwa-
|
| 23 |
|
| 24 |
# Run harness tests (must be 32-bit, needs WA.exe on disk)
|
| 25 |
cargo test --target i686-pc-windows-msvc -p openwa-harness
|
| 26 |
|
| 27 |
# Single test
|
| 28 |
-
cargo test -p openwa-
|
| 29 |
```
|
| 30 |
|
| 31 |
## Deploy to Game
|
|
@@ -70,7 +70,7 @@ Environment variables:
|
|
| 70 |
|
| 71 |
## Crate Architecture
|
| 72 |
|
| 73 |
-
- **`openwa-
|
| 74 |
- **`openwa-wormkit`** — Unified WormKit cdylib that replaces WA functions with Rust and optionally validates types against live memory. Logs to `OpenWA.log` (hooks) and `OpenWA_validation.log` (validation). Uses MinHook for inline hooking. Validation is enabled via `OPENWA_VALIDATE=1` env var.
|
| 75 |
- **`openwa-harness`** — Offline test harness that loads WA.exe into process memory via `LoadLibraryExA(DONT_RESOLVE_DLL_REFERENCES)` for testing without running the game.
|
| 76 |
|
|
@@ -106,10 +106,11 @@ For `__usercall` functions, use a naked trampoline to capture register params be
|
|
| 106 |
|
| 107 |
## Key Files
|
| 108 |
|
| 109 |
-
- `crates/openwa-
|
|
|
|
|
|
|
|
|
|
| 110 |
- `crates/openwa-wormkit/src/replacements/` — Function replacements (one file per subsystem)
|
| 111 |
-
- `crates/openwa-wormkit/src/wa_call.rs` — Helpers for calling WA functions (thiscall, stdcall wrappers)
|
| 112 |
-
- `crates/openwa-wormkit/src/rebase.rs` — ASLR delta computation
|
| 113 |
- `docs/re-notes/` — Reverse engineering documentation (task hierarchy, memory map, frontend screens)
|
| 114 |
- `docs/plans/` — Design docs and implementation plans
|
| 115 |
|
|
|
|
| 19 |
cargo build -p openwa-validator --release
|
| 20 |
|
| 21 |
# Run tests (openwa-types is pure Rust, works on any host)
|
| 22 |
+
cargo test -p openwa-core
|
| 23 |
|
| 24 |
# Run harness tests (must be 32-bit, needs WA.exe on disk)
|
| 25 |
cargo test --target i686-pc-windows-msvc -p openwa-harness
|
| 26 |
|
| 27 |
# Single test
|
| 28 |
+
cargo test -p openwa-core -- scheme_parse::parse_beginner_v2
|
| 29 |
```
|
| 30 |
|
| 31 |
## Deploy to Game
|
|
|
|
| 70 |
|
| 71 |
## Crate Architecture
|
| 72 |
|
| 73 |
+
- **`openwa-core`** — Types, addresses, parsers, ASLR rebasing, and typed WA function wrappers. The source of truth for all reverse-engineered type layouts and known addresses (`address.rs`). Contains `rebase` (ASLR delta), `wa_call` (calling convention helpers), and `wa/` (typed handle wrappers like `DDGameWrapperHandle`, `CWndHandle`).
|
| 74 |
- **`openwa-wormkit`** — Unified WormKit cdylib that replaces WA functions with Rust and optionally validates types against live memory. Logs to `OpenWA.log` (hooks) and `OpenWA_validation.log` (validation). Uses MinHook for inline hooking. Validation is enabled via `OPENWA_VALIDATE=1` env var.
|
| 75 |
- **`openwa-harness`** — Offline test harness that loads WA.exe into process memory via `LoadLibraryExA(DONT_RESOLVE_DLL_REFERENCES)` for testing without running the game.
|
| 76 |
|
|
|
|
| 106 |
|
| 107 |
## Key Files
|
| 108 |
|
| 109 |
+
- `crates/openwa-core/src/address.rs` — All known WA.exe addresses with comments
|
| 110 |
+
- `crates/openwa-core/src/wa_call.rs` — Helpers for calling WA functions (thiscall, stdcall wrappers)
|
| 111 |
+
- `crates/openwa-core/src/rebase.rs` — ASLR delta computation
|
| 112 |
+
- `crates/openwa-core/src/wa/` — Typed WA function wrappers (MFC, frontend, registry, DDGame)
|
| 113 |
- `crates/openwa-wormkit/src/replacements/` — Function replacements (one file per subsystem)
|
|
|
|
|
|
|
| 114 |
- `docs/re-notes/` — Reverse engineering documentation (task hierarchy, memory map, frontend screens)
|
| 115 |
- `docs/plans/` — Design docs and implementation plans
|
| 116 |
|
Cargo.lock
CHANGED
|
@@ -72,34 +72,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
| 72 |
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
| 73 |
|
| 74 |
[[package]]
|
| 75 |
-
name = "openwa-
|
| 76 |
version = "0.1.0"
|
| 77 |
dependencies = [
|
| 78 |
-
"libc",
|
| 79 |
-
"openwa-types",
|
| 80 |
"windows-sys",
|
| 81 |
]
|
| 82 |
|
| 83 |
[[package]]
|
| 84 |
-
name = "openwa-
|
| 85 |
version = "0.1.0"
|
| 86 |
dependencies = [
|
| 87 |
-
"
|
|
|
|
| 88 |
"windows-sys",
|
| 89 |
]
|
| 90 |
|
| 91 |
-
[[package]]
|
| 92 |
-
name = "openwa-types"
|
| 93 |
-
version = "0.1.0"
|
| 94 |
-
|
| 95 |
[[package]]
|
| 96 |
name = "openwa-wormkit"
|
| 97 |
version = "0.1.0"
|
| 98 |
dependencies = [
|
| 99 |
"heapless",
|
| 100 |
"minhook",
|
| 101 |
-
"openwa-
|
| 102 |
-
"openwa-types",
|
| 103 |
"windows-sys",
|
| 104 |
]
|
| 105 |
|
|
|
|
| 72 |
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
| 73 |
|
| 74 |
[[package]]
|
| 75 |
+
name = "openwa-core"
|
| 76 |
version = "0.1.0"
|
| 77 |
dependencies = [
|
|
|
|
|
|
|
| 78 |
"windows-sys",
|
| 79 |
]
|
| 80 |
|
| 81 |
[[package]]
|
| 82 |
+
name = "openwa-harness"
|
| 83 |
version = "0.1.0"
|
| 84 |
dependencies = [
|
| 85 |
+
"libc",
|
| 86 |
+
"openwa-core",
|
| 87 |
"windows-sys",
|
| 88 |
]
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
[[package]]
|
| 91 |
name = "openwa-wormkit"
|
| 92 |
version = "0.1.0"
|
| 93 |
dependencies = [
|
| 94 |
"heapless",
|
| 95 |
"minhook",
|
| 96 |
+
"openwa-core",
|
|
|
|
| 97 |
"windows-sys",
|
| 98 |
]
|
| 99 |
|
crates/{openwa-lib → openwa-core}/Cargo.toml
RENAMED
|
@@ -1,11 +1,8 @@
|
|
| 1 |
[package]
|
| 2 |
-
name = "openwa-
|
| 3 |
version = "0.1.0"
|
| 4 |
edition = "2021"
|
| 5 |
-
description = "
|
| 6 |
-
|
| 7 |
-
[dependencies]
|
| 8 |
-
openwa-types = { path = "../openwa-types" }
|
| 9 |
|
| 10 |
[target.'cfg(target_os = "windows")'.dependencies]
|
| 11 |
windows-sys = { version = "0.59", features = [
|
|
|
|
| 1 |
[package]
|
| 2 |
+
name = "openwa-core"
|
| 3 |
version = "0.1.0"
|
| 4 |
edition = "2021"
|
| 5 |
+
description = "Core library for Worms Armageddon reverse engineering — types, addresses, and runtime utilities"
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
[target.'cfg(target_os = "windows")'.dependencies]
|
| 8 |
windows-sys = { version = "0.59", features = [
|
crates/{openwa-types → openwa-core}/src/address.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/class_type.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/ddgame.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/ddgame_wrapper.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/dssound.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/fixed.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/frontend.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/game_info.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/landscape.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/lib.rs
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
| 1 |
pub mod class_type;
|
| 2 |
pub mod message;
|
| 3 |
pub mod weapon;
|
|
@@ -16,3 +18,6 @@ pub mod game_info;
|
|
| 16 |
pub mod scheme;
|
| 17 |
pub mod speech;
|
| 18 |
pub mod address;
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#![allow(non_snake_case)]
|
| 2 |
+
|
| 3 |
pub mod class_type;
|
| 4 |
pub mod message;
|
| 5 |
pub mod weapon;
|
|
|
|
| 18 |
pub mod scheme;
|
| 19 |
pub mod speech;
|
| 20 |
pub mod address;
|
| 21 |
+
pub mod rebase;
|
| 22 |
+
pub mod wa;
|
| 23 |
+
pub mod wa_call;
|
crates/{openwa-types → openwa-core}/src/message.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/opengl.rs
RENAMED
|
File without changes
|
crates/{openwa-lib → openwa-core}/src/rebase.rs
RENAMED
|
@@ -2,7 +2,7 @@
|
|
| 2 |
|
| 3 |
use std::sync::atomic::{AtomicU32, Ordering};
|
| 4 |
|
| 5 |
-
use
|
| 6 |
|
| 7 |
/// Delta to add to Ghidra addresses to get runtime addresses.
|
| 8 |
static REBASE_DELTA: AtomicU32 = AtomicU32::new(0);
|
|
|
|
| 2 |
|
| 3 |
use std::sync::atomic::{AtomicU32, Ordering};
|
| 4 |
|
| 5 |
+
use crate::address::va;
|
| 6 |
|
| 7 |
/// Delta to add to Ghidra addresses to get runtime addresses.
|
| 8 |
static REBASE_DELTA: AtomicU32 = AtomicU32::new(0);
|
crates/{openwa-types → openwa-core}/src/render.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/scheme.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/sound.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/speech.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/sprite.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/task.rs
RENAMED
|
File without changes
|
crates/{openwa-lib → openwa-core}/src/wa/ddgame.rs
RENAMED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
//! Typed handle for DDGameWrapper — the main game engine wrapper object.
|
| 2 |
|
| 3 |
-
use
|
| 4 |
-
use
|
| 5 |
|
| 6 |
/// Zero-cost handle to a DDGameWrapper instance (raw pointer as u32).
|
| 7 |
///
|
|
|
|
| 1 |
//! Typed handle for DDGameWrapper — the main game engine wrapper object.
|
| 2 |
|
| 3 |
+
use crate::ddgame::DDGame;
|
| 4 |
+
use crate::game_info::GameInfo;
|
| 5 |
|
| 6 |
/// Zero-cost handle to a DDGameWrapper instance (raw pointer as u32).
|
| 7 |
///
|
crates/{openwa-lib → openwa-core}/src/wa/frontend.rs
RENAMED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
//! WA-internal frontend function wrappers.
|
| 2 |
|
| 3 |
use crate::rebase::rb;
|
| 4 |
-
use
|
| 5 |
|
| 6 |
/// Frontend__PaletteAnimation (0x422180)
|
| 7 |
///
|
|
|
|
| 1 |
//! WA-internal frontend function wrappers.
|
| 2 |
|
| 3 |
use crate::rebase::rb;
|
| 4 |
+
use crate::address::va;
|
| 5 |
|
| 6 |
/// Frontend__PaletteAnimation (0x422180)
|
| 7 |
///
|
crates/{openwa-lib → openwa-core}/src/wa/mfc.rs
RENAMED
|
@@ -2,7 +2,7 @@
|
|
| 2 |
|
| 3 |
use crate::rebase::rb;
|
| 4 |
use crate::wa_call;
|
| 5 |
-
use
|
| 6 |
|
| 7 |
/// Zero-cost handle to a CWnd-derived MFC window (raw pointer as u32).
|
| 8 |
#[derive(Clone, Copy)]
|
|
|
|
| 2 |
|
| 3 |
use crate::rebase::rb;
|
| 4 |
use crate::wa_call;
|
| 5 |
+
use crate::address::va;
|
| 6 |
|
| 7 |
/// Zero-cost handle to a CWnd-derived MFC window (raw pointer as u32).
|
| 8 |
#[derive(Clone, Copy)]
|
crates/{openwa-lib → openwa-core}/src/wa/mod.rs
RENAMED
|
File without changes
|
crates/{openwa-lib → openwa-core}/src/wa/registry.rs
RENAMED
|
File without changes
|
crates/{openwa-lib → openwa-core}/src/wa/resource.rs
RENAMED
|
File without changes
|
crates/{openwa-lib → openwa-core}/src/wa_call.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/src/weapon.rs
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/tests/fixtures/beginner.wsc
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/tests/fixtures/classic.wsc
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/tests/fixtures/shopping.wsc
RENAMED
|
File without changes
|
crates/{openwa-types → openwa-core}/tests/scheme_parse.rs
RENAMED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
use std::path::Path;
|
| 2 |
|
| 3 |
-
use
|
| 4 |
ExtendedOptions, SchemeFile, SchemeVersion, EXTENDED_OPTIONS_DEFAULTS,
|
| 5 |
EXTENDED_OPTIONS_SIZE, SCHEME_PAYLOAD_V1, SCHEME_PAYLOAD_V2, WEAPONS_V1_COUNT,
|
| 6 |
};
|
|
|
|
| 1 |
use std::path::Path;
|
| 2 |
|
| 3 |
+
use openwa_core::scheme::{
|
| 4 |
ExtendedOptions, SchemeFile, SchemeVersion, EXTENDED_OPTIONS_DEFAULTS,
|
| 5 |
EXTENDED_OPTIONS_SIZE, SCHEME_PAYLOAD_V1, SCHEME_PAYLOAD_V2, WEAPONS_V1_COUNT,
|
| 6 |
};
|
crates/openwa-harness/Cargo.toml
CHANGED
|
@@ -5,7 +5,7 @@ edition = "2021"
|
|
| 5 |
description = "Offline test harness — loads WA.exe into process memory for validation"
|
| 6 |
|
| 7 |
[dependencies]
|
| 8 |
-
openwa-
|
| 9 |
libc = "0.2"
|
| 10 |
|
| 11 |
[target.'cfg(target_os = "windows")'.dependencies]
|
|
|
|
| 5 |
description = "Offline test harness — loads WA.exe into process memory for validation"
|
| 6 |
|
| 7 |
[dependencies]
|
| 8 |
+
openwa-core = { path = "../openwa-core" }
|
| 9 |
libc = "0.2"
|
| 10 |
|
| 11 |
[target.'cfg(target_os = "windows")'.dependencies]
|
crates/openwa-harness/src/lib.rs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
#![allow(non_snake_case)]
|
| 2 |
|
| 3 |
-
use
|
| 4 |
|
| 5 |
#[cfg(target_os = "windows")]
|
| 6 |
use windows_sys::Win32::System::LibraryLoader::{LoadLibraryExA, DONT_RESOLVE_DLL_REFERENCES};
|
|
|
|
| 1 |
#![allow(non_snake_case)]
|
| 2 |
|
| 3 |
+
use openwa_core::address::va;
|
| 4 |
|
| 5 |
#[cfg(target_os = "windows")]
|
| 6 |
use windows_sys::Win32::System::LibraryLoader::{LoadLibraryExA, DONT_RESOLVE_DLL_REFERENCES};
|
crates/openwa-lib/src/lib.rs
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
#![allow(non_snake_case)]
|
| 2 |
-
|
| 3 |
-
pub mod rebase;
|
| 4 |
-
pub mod wa;
|
| 5 |
-
pub mod wa_call;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
crates/openwa-types/Cargo.toml
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
[package]
|
| 2 |
-
name = "openwa-types"
|
| 3 |
-
version = "0.1.0"
|
| 4 |
-
edition = "2021"
|
| 5 |
-
description = "Type definitions for Worms Armageddon reverse engineering"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
crates/openwa-wormkit/Cargo.toml
CHANGED
|
@@ -8,8 +8,7 @@ description = "WormKit DLL that replaces WA.exe functions with Rust reimplementa
|
|
| 8 |
crate-type = ["cdylib"]
|
| 9 |
|
| 10 |
[dependencies]
|
| 11 |
-
openwa-
|
| 12 |
-
openwa-lib = { path = "../openwa-lib" }
|
| 13 |
heapless = "0.9"
|
| 14 |
minhook = "0.9"
|
| 15 |
|
|
|
|
| 8 |
crate-type = ["cdylib"]
|
| 9 |
|
| 10 |
[dependencies]
|
| 11 |
+
openwa-core = { path = "../openwa-core" }
|
|
|
|
| 12 |
heapless = "0.9"
|
| 13 |
minhook = "0.9"
|
| 14 |
|
crates/openwa-wormkit/src/hook.rs
CHANGED
|
@@ -317,7 +317,7 @@ use std::ffi::c_void;
|
|
| 317 |
use minhook::MinHook;
|
| 318 |
|
| 319 |
use crate::log_line;
|
| 320 |
-
use
|
| 321 |
|
| 322 |
/// Install a MinHook inline hook on a WA.exe function.
|
| 323 |
///
|
|
|
|
| 317 |
use minhook::MinHook;
|
| 318 |
|
| 319 |
use crate::log_line;
|
| 320 |
+
use openwa_core::rebase::rb;
|
| 321 |
|
| 322 |
/// Install a MinHook inline hook on a WA.exe function.
|
| 323 |
///
|
crates/openwa-wormkit/src/lib.rs
CHANGED
|
@@ -54,7 +54,7 @@ fn clear_log() -> std::io::Result<()> {
|
|
| 54 |
fn run() -> Result<(), String> {
|
| 55 |
let _ = clear_log();
|
| 56 |
|
| 57 |
-
let delta =
|
| 58 |
let _ = log_line(&format!(
|
| 59 |
"=== OpenWA WormKit DLL loaded ===\n ASLR delta: 0x{delta:08X}"
|
| 60 |
));
|
|
|
|
| 54 |
fn run() -> Result<(), String> {
|
| 55 |
let _ = clear_log();
|
| 56 |
|
| 57 |
+
let delta = openwa_core::rebase::init();
|
| 58 |
let _ = log_line(&format!(
|
| 59 |
"=== OpenWA WormKit DLL loaded ===\n ASLR delta: 0x{delta:08X}"
|
| 60 |
));
|
crates/openwa-wormkit/src/replacements/config.rs
CHANGED
|
@@ -9,9 +9,9 @@
|
|
| 9 |
//! - GameInfo__LoadOptions (0x460AC0): game options from registry
|
| 10 |
//! - Options__GetCrashReportURL (0x5A63F0): crash report URL from registry
|
| 11 |
|
| 12 |
-
use
|
| 13 |
use crate::log_line;
|
| 14 |
-
use
|
| 15 |
|
| 16 |
const THEME_PATH: &str = "data\\current.thm";
|
| 17 |
const CLEAN_ALL_FLAG_OFFSET: usize = 0xE0;
|
|
@@ -86,7 +86,7 @@ unsafe extern "stdcall" fn hook_delete_key_recursive(hkey: u32, subkey: u32) ->
|
|
| 86 |
|
| 87 |
let _ = log_line(&format!("[Config] DeleteKeyRecursive: {subkey_str}"));
|
| 88 |
|
| 89 |
-
let result =
|
| 90 |
hkey as usize as HKEY,
|
| 91 |
&subkey_str,
|
| 92 |
);
|
|
@@ -114,7 +114,7 @@ unsafe extern "stdcall" fn hook_registry_clean_all(struct_ptr: u32) {
|
|
| 114 |
];
|
| 115 |
|
| 116 |
for section in §ions {
|
| 117 |
-
|
| 118 |
}
|
| 119 |
|
| 120 |
// Clear the NetSettings INI section
|
|
@@ -138,8 +138,8 @@ unsafe extern "stdcall" fn hook_registry_clean_all(struct_ptr: u32) {
|
|
| 138 |
/// Reads game options from the Windows registry and copies various globals
|
| 139 |
/// into the GameInfo struct at known offsets.
|
| 140 |
unsafe extern "stdcall" fn hook_load_options(gi_ptr: u32) {
|
| 141 |
-
use
|
| 142 |
-
use
|
| 143 |
|
| 144 |
let gi = &mut *(gi_ptr as *mut GameInfo);
|
| 145 |
|
|
@@ -273,7 +273,7 @@ unsafe extern "cdecl" fn hook_get_crash_report_url() -> u32 {
|
|
| 273 |
let buf = rb(va::G_CRASH_REPORT_URL) as *mut u8;
|
| 274 |
let buf_slice = core::slice::from_raw_parts_mut(buf, CRASH_REPORT_URL_BUF_SIZE);
|
| 275 |
|
| 276 |
-
let len =
|
| 277 |
"Options",
|
| 278 |
"CrashReportURL",
|
| 279 |
buf_slice,
|
|
|
|
| 9 |
//! - GameInfo__LoadOptions (0x460AC0): game options from registry
|
| 10 |
//! - Options__GetCrashReportURL (0x5A63F0): crash report URL from registry
|
| 11 |
|
| 12 |
+
use openwa_core::address::va;
|
| 13 |
use crate::log_line;
|
| 14 |
+
use openwa_core::rebase::rb;
|
| 15 |
|
| 16 |
const THEME_PATH: &str = "data\\current.thm";
|
| 17 |
const CLEAN_ALL_FLAG_OFFSET: usize = 0xE0;
|
|
|
|
| 86 |
|
| 87 |
let _ = log_line(&format!("[Config] DeleteKeyRecursive: {subkey_str}"));
|
| 88 |
|
| 89 |
+
let result = openwa_core::wa::registry::delete_key_recursive(
|
| 90 |
hkey as usize as HKEY,
|
| 91 |
&subkey_str,
|
| 92 |
);
|
|
|
|
| 114 |
];
|
| 115 |
|
| 116 |
for section in §ions {
|
| 117 |
+
openwa_core::wa::registry::delete_key_recursive(HKEY_CURRENT_USER, section);
|
| 118 |
}
|
| 119 |
|
| 120 |
// Clear the NetSettings INI section
|
|
|
|
| 138 |
/// Reads game options from the Windows registry and copies various globals
|
| 139 |
/// into the GameInfo struct at known offsets.
|
| 140 |
unsafe extern "stdcall" fn hook_load_options(gi_ptr: u32) {
|
| 141 |
+
use openwa_core::wa::registry::read_profile_int;
|
| 142 |
+
use openwa_core::game_info::GameInfo;
|
| 143 |
|
| 144 |
let gi = &mut *(gi_ptr as *mut GameInfo);
|
| 145 |
|
|
|
|
| 273 |
let buf = rb(va::G_CRASH_REPORT_URL) as *mut u8;
|
| 274 |
let buf_slice = core::slice::from_raw_parts_mut(buf, CRASH_REPORT_URL_BUF_SIZE);
|
| 275 |
|
| 276 |
+
let len = openwa_core::wa::registry::read_profile_string(
|
| 277 |
"Options",
|
| 278 |
"CrashReportURL",
|
| 279 |
buf_slice,
|
crates/openwa-wormkit/src/replacements/frontend.rs
CHANGED
|
@@ -6,10 +6,10 @@
|
|
| 6 |
use std::sync::atomic::{AtomicU32, Ordering};
|
| 7 |
|
| 8 |
use crate::log_line;
|
| 9 |
-
use
|
| 10 |
-
use
|
| 11 |
-
use
|
| 12 |
-
use
|
| 13 |
|
| 14 |
// Frontend dialog struct offsets (MFC CDialog-derived)
|
| 15 |
const DIALOG_FLAGS: usize = 0x3C;
|
|
@@ -52,7 +52,7 @@ unsafe extern "cdecl" fn frontend_change_screen_impl(dialog: u32, screen_id: u32
|
|
| 52 |
|
| 53 |
let palette_param = *((dialog as usize + DIALOG_PALETTE_PARAM) as *const u32);
|
| 54 |
let eax_value = *((dialog as usize + DIALOG_PALETTE_OBJ) as *const u32);
|
| 55 |
-
|
| 56 |
|
| 57 |
for i in 1u32..=2 {
|
| 58 |
let vtable = *(dialog as *const u32);
|
|
|
|
| 6 |
use std::sync::atomic::{AtomicU32, Ordering};
|
| 7 |
|
| 8 |
use crate::log_line;
|
| 9 |
+
use openwa_core::wa::mfc::{CDialogHandle, CWndHandle};
|
| 10 |
+
use openwa_core::wa_call;
|
| 11 |
+
use openwa_core::address::va;
|
| 12 |
+
use openwa_core::frontend::ScreenId;
|
| 13 |
|
| 14 |
// Frontend dialog struct offsets (MFC CDialog-derived)
|
| 15 |
const DIALOG_FLAGS: usize = 0x3C;
|
|
|
|
| 52 |
|
| 53 |
let palette_param = *((dialog as usize + DIALOG_PALETTE_PARAM) as *const u32);
|
| 54 |
let eax_value = *((dialog as usize + DIALOG_PALETTE_OBJ) as *const u32);
|
| 55 |
+
openwa_core::wa::frontend::palette_animation(eax_value, palette_param);
|
| 56 |
|
| 57 |
for i in 1u32..=2 {
|
| 58 |
let vtable = *(dialog as *const u32);
|
crates/openwa-wormkit/src/replacements/input.rs
CHANGED
|
@@ -14,10 +14,10 @@ use std::sync::atomic::{AtomicU32, Ordering};
|
|
| 14 |
|
| 15 |
use crate::hook;
|
| 16 |
use crate::log_line;
|
| 17 |
-
use
|
| 18 |
-
use
|
| 19 |
-
use
|
| 20 |
-
use
|
| 21 |
|
| 22 |
/// Trampoline to the original TurnManager_ProcessFrame.
|
| 23 |
static ORIG_TURN_MANAGER: AtomicU32 = AtomicU32::new(0);
|
|
|
|
| 14 |
|
| 15 |
use crate::hook;
|
| 16 |
use crate::log_line;
|
| 17 |
+
use openwa_core::rebase::rb;
|
| 18 |
+
use openwa_core::address::va;
|
| 19 |
+
use openwa_core::ddgame::DDGame;
|
| 20 |
+
use openwa_core::ddgame_wrapper::DDGameWrapper;
|
| 21 |
|
| 22 |
/// Trampoline to the original TurnManager_ProcessFrame.
|
| 23 |
static ORIG_TURN_MANAGER: AtomicU32 = AtomicU32::new(0);
|
crates/openwa-wormkit/src/replacements/render.rs
CHANGED
|
@@ -3,10 +3,10 @@
|
|
| 3 |
//! All functions enqueue commands to the RenderQueue's downward-growing buffer.
|
| 4 |
//! Calling conventions are __usercall variants with register + stack params.
|
| 5 |
|
| 6 |
-
use
|
| 7 |
-
use
|
| 8 |
-
use
|
| 9 |
-
use
|
| 10 |
|
| 11 |
use crate::hook::{self, usercall_trampoline};
|
| 12 |
|
|
|
|
| 3 |
//! All functions enqueue commands to the RenderQueue's downward-growing buffer.
|
| 4 |
//! Calling conventions are __usercall variants with register + stack params.
|
| 5 |
|
| 6 |
+
use openwa_core::rebase::rb;
|
| 7 |
+
use openwa_core::address::va;
|
| 8 |
+
use openwa_core::render::*;
|
| 9 |
+
use openwa_core::task::{BungeeTrailTask, WeaponAimTask};
|
| 10 |
|
| 11 |
use crate::hook::{self, usercall_trampoline};
|
| 12 |
|
crates/openwa-wormkit/src/replacements/scheme.rs
CHANGED
|
@@ -15,9 +15,9 @@ use std::path::Path;
|
|
| 15 |
use std::sync::atomic::{AtomicU32, Ordering};
|
| 16 |
|
| 17 |
use crate::log_line;
|
| 18 |
-
use
|
| 19 |
-
use
|
| 20 |
-
use
|
| 21 |
ExtendedOptions, SchemeFile, SchemeVersion, EXTENDED_OPTIONS_DEFAULTS, EXTENDED_OPTIONS_SIZE,
|
| 22 |
SCHEME_PAYLOAD_V1, SCHEME_PAYLOAD_V2, SCHEME_PAYLOAD_V3,
|
| 23 |
};
|
|
@@ -355,7 +355,7 @@ unsafe extern "fastcall" fn hook_init_from_data(
|
|
| 355 |
dest: u32,
|
| 356 |
name_cstring: u32,
|
| 357 |
) {
|
| 358 |
-
use
|
| 359 |
|
| 360 |
// Step 1: Copy 0xD8 bytes (V1 payload) from src_data to dest+0x14
|
| 361 |
core::ptr::copy_nonoverlapping(
|
|
@@ -440,7 +440,7 @@ unsafe extern "stdcall" fn hook_scan_directory(cstring_param: u32) {
|
|
| 440 |
let _ = log_line("[Scheme] ScanDirectory completed (Rust)");
|
| 441 |
|
| 442 |
// Release the CString parameter's refcount (caller transferred ownership)
|
| 443 |
-
|
| 444 |
}
|
| 445 |
|
| 446 |
/// Parse a scheme filename matching the pattern `{{DD}} name.wsc`.
|
|
@@ -530,7 +530,7 @@ const BUILTIN_SCHEME_NAMES: [&str; 14] = [
|
|
| 530 |
/// Zeros slot flags, scans for existing scheme files, then extracts missing
|
| 531 |
/// built-in schemes from PE resources (type "SCHEMES") to User\Schemes\.
|
| 532 |
unsafe extern "stdcall" fn hook_extract_builtins() {
|
| 533 |
-
use
|
| 534 |
|
| 535 |
// Step 1: Zero 16 bytes of slot flags (4 DWORDs covering slots 0-15)
|
| 536 |
let slot_flags = rb(va::SCHEME_SLOT_FLAGS) as *mut u8;
|
|
|
|
| 15 |
use std::sync::atomic::{AtomicU32, Ordering};
|
| 16 |
|
| 17 |
use crate::log_line;
|
| 18 |
+
use openwa_core::rebase::rb;
|
| 19 |
+
use openwa_core::address::va;
|
| 20 |
+
use openwa_core::scheme::{
|
| 21 |
ExtendedOptions, SchemeFile, SchemeVersion, EXTENDED_OPTIONS_DEFAULTS, EXTENDED_OPTIONS_SIZE,
|
| 22 |
SCHEME_PAYLOAD_V1, SCHEME_PAYLOAD_V2, SCHEME_PAYLOAD_V3,
|
| 23 |
};
|
|
|
|
| 355 |
dest: u32,
|
| 356 |
name_cstring: u32,
|
| 357 |
) {
|
| 358 |
+
use openwa_core::wa::mfc::{cstring_release, CStringRef};
|
| 359 |
|
| 360 |
// Step 1: Copy 0xD8 bytes (V1 payload) from src_data to dest+0x14
|
| 361 |
core::ptr::copy_nonoverlapping(
|
|
|
|
| 440 |
let _ = log_line("[Scheme] ScanDirectory completed (Rust)");
|
| 441 |
|
| 442 |
// Release the CString parameter's refcount (caller transferred ownership)
|
| 443 |
+
openwa_core::wa::mfc::cstring_release(cstring_param);
|
| 444 |
}
|
| 445 |
|
| 446 |
/// Parse a scheme filename matching the pattern `{{DD}} name.wsc`.
|
|
|
|
| 530 |
/// Zeros slot flags, scans for existing scheme files, then extracts missing
|
| 531 |
/// built-in schemes from PE resources (type "SCHEMES") to User\Schemes\.
|
| 532 |
unsafe extern "stdcall" fn hook_extract_builtins() {
|
| 533 |
+
use openwa_core::wa::resource;
|
| 534 |
|
| 535 |
// Step 1: Zero 16 bytes of slot flags (4 DWORDs covering slots 0-15)
|
| 536 |
let slot_flags = rb(va::SCHEME_SLOT_FLAGS) as *mut u8;
|
crates/openwa-wormkit/src/replacements/sound.rs
CHANGED
|
@@ -9,10 +9,10 @@
|
|
| 9 |
|
| 10 |
use std::sync::atomic::Ordering;
|
| 11 |
|
| 12 |
-
use
|
| 13 |
-
use
|
| 14 |
-
use
|
| 15 |
-
use
|
| 16 |
|
| 17 |
use crate::hook;
|
| 18 |
use crate::log_line;
|
|
|
|
| 9 |
|
| 10 |
use std::sync::atomic::Ordering;
|
| 11 |
|
| 12 |
+
use openwa_core::address::va;
|
| 13 |
+
use openwa_core::ddgame::{DDGame, SoundQueueEntry};
|
| 14 |
+
use openwa_core::sound::SoundId;
|
| 15 |
+
use openwa_core::task::CGameTask;
|
| 16 |
|
| 17 |
use crate::hook;
|
| 18 |
use crate::log_line;
|
crates/openwa-wormkit/src/replacements/speech.rs
CHANGED
|
@@ -12,10 +12,10 @@ use std::sync::atomic::{AtomicU32, Ordering};
|
|
| 12 |
|
| 13 |
use heapless::CString;
|
| 14 |
|
| 15 |
-
use
|
| 16 |
-
use
|
| 17 |
-
use
|
| 18 |
-
use
|
| 19 |
|
| 20 |
use crate::hook::{self, usercall_trampoline};
|
| 21 |
use crate::log_line;
|
|
|
|
| 12 |
|
| 13 |
use heapless::CString;
|
| 14 |
|
| 15 |
+
use openwa_core::rebase::rb;
|
| 16 |
+
use openwa_core::wa::ddgame::DDGameWrapperHandle;
|
| 17 |
+
use openwa_core::address::va::{self, game_info_offsets};
|
| 18 |
+
use openwa_core::speech::SpeechLineTableEntry;
|
| 19 |
|
| 20 |
use crate::hook::{self, usercall_trampoline};
|
| 21 |
use crate::log_line;
|
crates/openwa-wormkit/src/replacements/team.rs
CHANGED
|
@@ -10,8 +10,8 @@
|
|
| 10 |
//! - CheckAnyWormState0x8b (0x522970): scan all teams for state 0x8b
|
| 11 |
//! - SetActiveWorm_Maybe (0x522500): update team active state and counters
|
| 12 |
|
| 13 |
-
use
|
| 14 |
-
use
|
| 15 |
|
| 16 |
use crate::hook::{self, usercall_trampoline};
|
| 17 |
|
|
|
|
| 10 |
//! - CheckAnyWormState0x8b (0x522970): scan all teams for state 0x8b
|
| 11 |
//! - SetActiveWorm_Maybe (0x522500): update team active state and counters
|
| 12 |
|
| 13 |
+
use openwa_core::address::va;
|
| 14 |
+
use openwa_core::ddgame::{self, TeamArenaRef};
|
| 15 |
|
| 16 |
use crate::hook::{self, usercall_trampoline};
|
| 17 |
|
crates/openwa-wormkit/src/replacements/weapon.rs
CHANGED
|
@@ -6,9 +6,9 @@
|
|
| 6 |
//! - SubtractAmmo (0x522680): decrement ammo count
|
| 7 |
//! - CountAliveWorms (0x5225A0): check if >1 worm alive on team
|
| 8 |
|
| 9 |
-
use
|
| 10 |
-
use
|
| 11 |
-
use
|
| 12 |
|
| 13 |
use crate::hook::{self, usercall_trampoline};
|
| 14 |
|
|
|
|
| 6 |
//! - SubtractAmmo (0x522680): decrement ammo count
|
| 7 |
//! - CountAliveWorms (0x5225A0): check if >1 worm alive on team
|
| 8 |
|
| 9 |
+
use openwa_core::address::va;
|
| 10 |
+
use openwa_core::ddgame::{self, TeamArenaRef};
|
| 11 |
+
use openwa_core::weapon::Weapon;
|
| 12 |
|
| 13 |
use crate::hook::{self, usercall_trampoline};
|
| 14 |
|