add readme

This commit is contained in:
67
2026-06-19 21:04:09 +08:00
parent 8c1d390781
commit 89bb2c3e38
+615
View File
@@ -0,0 +1,615 @@
# DayZ Memory C++ Overlay
Windows C++20 DayZ DMA reader with an ImGui/DirectX 11 overlay and a browser-based web radar.
The application attaches to `DayZ_x64.exe` through VolkDMA, resolves the current DayZ runtime structures, reads entities in the background, and publishes the same live snapshot to two frontends:
- A transparent desktop overlay for ESP, skeletons, loot, bullet trails, and aim-assist visualizations.
- A local HTTP/SSE web radar with map tiles, filters, player lists, bullet paths, and remote browser support.
Use this only on systems and servers where you are allowed to inspect the target process. The built-in web server is plain HTTP; set a password before exposing it outside localhost or your trusted LAN.
## Features
- External DMA-backed memory access through VolkDMA.
- Runtime signature scanning and static offsets for DayZ structures.
- Automatic reconnect behavior when the process/session drops.
- High-frequency camera reads decoupled from entity scans.
- Player, infected, animal, vehicle, loot, corpse, and bullet snapshots.
- Player skeleton rendering with cached bone pointer chains and gap filling.
- Health, held weapon, worn items, names, boxes, head circles, and configurable draw distances.
- Ballistic aim dot using local weapon ammo velocity and drag values.
- Bullet trail visualization for active, completed, and phantom bullet tracks.
- Configurable item category filters from `config/item_filters.json`.
- DirectX 11 transparent overlay with a Lumin/ImGui menu.
- Built-in HTTP server with:
- `GET /` static radar UI
- `GET /api/bootstrap`
- `GET /api/state`
- `GET /events` server-sent events
- `GET /tile`
- `GET /map-image`
- `GET /api/debug`
- CORS support for serving the web UI from a different origin.
- Optional `Caddyfile` for static webroot hosting and API proxying.
- Embedded map support for known maps, with runtime disk PNG overrides.
- DMA throughput stats shown in the overlay info panel.
## Requirements
### Platform
- Windows x64.
- Visual Studio 2022 Build Tools or full Visual Studio with the MSVC x64 toolchain.
- Windows SDK with DirectX 11 headers/libraries.
- CMake 3.20 or newer.
- Git.
- Internet access during the first CMake configure, unless dependencies are already cached.
### External dependency: VolkDMA
`CMakeLists.txt` expects VolkDMA at this sibling path:
```text
../dayz-dma/dma-dayz-cpp-master/VolkDMA
```
That directory must contain:
- `src/dma.cpp`
- `src/process.cpp`
- `src/inputstate.cpp`
- `include/VolkDMA/...`
- `external/vmm`
- `external/leechcore`
- `dlls/vmm.dll`
- `dlls/leechcore.dll`
- `dlls/FTD3XX.dll`
If your VolkDMA checkout lives somewhere else, update `VOLKDMA_ROOT` near the top of `CMakeLists.txt`.
### Fetched dependencies
CMake downloads these with `FetchContent`:
- `nlohmann/json` v3.11.3
- `spdlog` v1.14.1
- `cpp-httplib` v0.18.1
- `stb` from upstream master
The ImGui/Lumin/FreeType pieces are vendored under `external/lumin`.
## Repository Layout
```text
.
|-- CMakeLists.txt
|-- Caddyfile
|-- config/
| |-- config.cfg
| `-- item_filters.json
|-- external/lumin/
|-- maps/ # optional, git-ignored map PNGs
|-- src/
| |-- Core/ # shared runtime models
| |-- Memory/ # VolkDMA/VMM access wrapper
| |-- Overlay/ # DirectX/ImGui overlay and menu bridge
| |-- Readers/ # entity, item, bullet, scoreboard readers
| |-- Resolvers/ # world/local player/network metadata resolvers
| |-- Runtime/ # service loop and snapshot orchestration
| |-- SigScanner/ # signature scanner
| `-- Web/ # web radar server, snapshots, maps, bullet cache
`-- webroot/ # browser radar UI
```
Build output is normally placed under `build/<config>/`. Post-build steps copy runtime DLLs, `config/`, `webroot/`, `maps/`, and icon font assets next to the executable.
## Quick Start
From a Developer PowerShell or a shell with MSVC available:
```powershell
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release
```
Run from the output directory so relative paths resolve to the copied assets:
```powershell
cd .\build\Release
.\dayz-memory-cpp.exe
```
Typical launch flow:
1. Start DayZ and join a server.
2. Start `dayz-memory-cpp.exe`.
3. Watch the console or `logs/dayz-memory.log` for attach/status messages.
4. Press `INSERT` to open or close the overlay menu.
5. Open `http://localhost:7777` for the web radar.
## Running From an IDE
Use the `dayz-memory-cpp` CMake target.
Recommended debug/run settings:
- Generator/platform: x64 MSVC.
- Working directory: `$<TARGET_FILE_DIR:dayz-memory-cpp>` or the concrete output folder such as `build/Debug`.
- Configuration: `Release` for normal use, `Debug` for development.
Running from the repository root can work for some files, but the executable also needs the copied DLLs and data directories. The output directory is the least surprising working directory.
## Runtime Controls
- `INSERT`: toggle the overlay menu.
- `Config -> Save Config`: writes overlay settings to `config/overlay.json`.
- `Config -> Exit`: closes the overlay and stops the process.
- `Ctrl+C` in the console: requests shutdown.
Menu tabs:
- `Aim`: ballistic dot and bullet trail toggles.
- `Visuals`: player/world ESP toggles and draw distances.
- `Loot`: item category filters sourced from `config/item_filters.json`.
- `Info`: connection status, entity counts, local position, DMA stats, web radar info.
- `Config`: monitor/render resolution overrides, save, and exit.
## Configuration
There are two config files:
- `config/config.cfg`: INI-style runtime reader settings.
- `config/overlay.json`: JSON overlay/web settings, created or updated by the menu.
Both paths are resolved relative to the process working directory. Post-build copies the repository `config/` directory next to the executable.
### `config/config.cfg`
The parser accepts `key = value` lines and ignores `#` comments. Missing keys keep the code defaults.
Supported runtime keys:
| Key | Default if omitted | Purpose |
| --- | --- | --- |
| `processName` | `DayZ_x64.exe` | Target process name. |
| `useMemoryMap` | `true` | Enables VolkDMA memory map usage. |
| `networkMetadataRefreshMs` | `30000` | Server name/version/map refresh interval. |
| `scoreboardRefreshMs` | `30000` | Scoreboard refresh interval. |
| `nearEntityRefreshMs` | `20` | Near entity list refresh interval. |
| `farEntityRefreshMs` | `50` | Far entity list refresh interval. |
| `slowEntityRefreshMs` | `100` | Slow entity list refresh interval. |
| `bulletRefreshMs` | `50` | Bullet table refresh interval. |
| `itemRefreshMs` | `200` | Item scan refresh interval. |
| `playersRefreshMs` | `16` | Player projection/update interval. |
| `boneRefreshMs` | `4` | Bone scatter refresh interval. |
| `liveLoopIdleMs` | `1` | Main loop idle sleep. Lower is more responsive and more CPU-heavy. |
| `reconnectThreshold` | `5` | Consecutive failures before reconnect. |
| `reconnectGracePeriodMs` | `5000` | Delay after session loss before reconnect. |
| `farEntityBatchSize` | `64` | Far entity batch size per tick. |
| `slowEntityBatchSize` | `64` | Slow entity batch size per tick. |
| `itemBatchSize` | `64` | Item batch size per tick. |
| `bonePlayerMaxDist` | `500.0` | Max player distance for skeleton reads. |
| `boneZombieMaxDist` | `250.0` | Max infected distance for skeleton reads. |
| `vmmRefreshMs` | `30000` | VMMDLL cache refresh cadence. |
| `itemSpatialFilterRadius` | `300.0` | Max item distance from local player published to overlay/web. |
The checked-in file intentionally keeps conservative refresh rates. Reduce intervals only when you have enough DMA/CPU headroom.
### `config/overlay.json`
If the file does not exist, defaults from `OverlayConfig` are used. Saving from the menu creates it.
Example:
```json
{
"showPlayers": true,
"showAnimals": true,
"showZombies": true,
"showItems": true,
"showBox": true,
"showSkeleton": true,
"showHeadDot": false,
"showCorpses": false,
"showWeapon": true,
"showHealthBar": true,
"showHealthNumber": false,
"playerMaxDist": 1000.0,
"animalMaxDist": 1000.0,
"zombieMaxDist": 500.0,
"itemMaxDist": 200.0,
"overlayWidth": 0,
"overlayHeight": 0,
"renderWidth": 0,
"renderHeight": 0,
"stretchToFill": true,
"webBindAddress": "0.0.0.0",
"webPort": 7777,
"webPassword": ""
}
```
Resolution notes:
- `overlayWidth` and `overlayHeight` should be the monitor resolution.
- `renderWidth` and `renderHeight` should be the resolution DayZ actually renders at.
- Leave render dimensions at `0` when the game render resolution matches the monitor.
- Set `stretchToFill` to `false` if the game is letterboxed or pillarboxed instead of stretched.
### `config/item_filters.json`
Loot categories are data-driven. Each top-level key is a category and can match by:
- `Name`
- `TypeName`
- `ConfigName`
- `ModelName`
Values may be a string or an array of strings. Matching is case-insensitive substring matching after normalization.
Example:
```json
{
"isWeapon": {
"desc": "Weapons",
"Color": "#f43f5e",
"TypeName": "weapon"
},
"isFood": {
"desc": "Food and drinks",
"Color": "#22c55e",
"ModelName": ["\\food\\", "\\drinks\\"]
}
}
```
If `item_filters.json` is missing, `ItemFilterCatalog` writes a default file.
## Web Radar
When the app starts, it launches an HTTP server using settings from `config/overlay.json`.
Default URL:
```text
http://localhost:7777
```
LAN access:
```text
http://<overlay-pc-ip>:7777
```
The overlay `Info` tab lists detected local URLs.
### Authentication
Set `webPassword` in `config/overlay.json` before exposing the radar beyond localhost:
```json
{
"webPassword": "change-me"
}
```
Remote clients append the password as a query parameter:
```text
http://<host>:7777/?password=change-me
```
Loopback requests are allowed without a password. An empty password disables password checks.
### API Endpoints
| Endpoint | Description |
| --- | --- |
| `/` | Serves `webroot/index.html`. |
| `/api/bootstrap` | Initial map/filter/server metadata. |
| `/api/state` | Latest full JSON state for polling clients. |
| `/events` | Server-sent events stream for live updates. |
| `/tile` | Serves 512x512 map tiles. |
| `/map-image` | Serves the full map image when available. |
| `/api/debug` | Debug information for paths and runtime state. |
Cross-origin `GET` and `OPTIONS` requests are supported so the UI can be hosted separately from the C++ backend.
### Static Hosting With Caddy
The included `Caddyfile` serves `webroot/` on port `8080` and proxies API/data endpoints to the C++ backend on `7777`.
From the repository root:
```powershell
caddy run
```
Open:
```text
http://localhost:8080
```
This mode keeps browser requests same-origin on `:8080` while Caddy proxies `/api/*`, `/tile`, `/map-image`, and `/events` to the backend.
### Static Host With `server=` Parameter
The web UI can also be hosted somewhere else and pointed at the backend:
```text
http://static-host/index.html?server=http://192.168.1.25:7777&password=change-me
```
The `server` value is stripped of a trailing slash in `webroot/app.js`.
## Map Images
Map PNGs are loaded from:
```text
maps/<map-id>.png
```
The folder is resolved relative to the executable directory. The repository `maps/` directory is git-ignored because map images are large/user-supplied.
Supported map IDs:
| File | Map |
| --- | --- |
| `chernarusplus.png` | ChernarusPlus |
| `livonia.png` | Livonia / Enoch |
| `namalsk.png` | Namalsk |
| `banov.png` | Banov |
| `deadfall.png` | Deadfall |
| `deerisle.png` | Deer Isle |
| `esseker.png` | Esseker |
| `lux.png` | Lux |
| `sakhal.png` | Sakhal |
| `takistan.png` | Takistan |
| `alteria.png` | Alteria |
Runtime disk files take priority. CMake can also embed map PNGs that exist under repository `maps/` at configure time. Re-run CMake after adding new map images if you want them embedded into the executable.
The tile server cuts maps into 512x512 PNG tiles and caches encoded tile bytes in memory after first request.
## Architecture
### Startup
`src/main.cpp` performs startup:
1. Creates `logs/`.
2. Initializes spdlog.
3. Loads `config/config.cfg` into `RuntimeConfig`.
4. Loads `config/overlay.json` into `OverlayConfig`.
5. Starts `WebRadarServer`.
6. Starts `DayZRuntimeService`.
7. Creates the overlay and enters the DirectX/ImGui render loop.
### Memory Layer
`src/Memory/VmmAccessor.*` wraps VolkDMA process access:
- Initializes DMA/VMM.
- Finds and attaches to `DayZ_x64.exe`.
- Applies `fix_cr3`.
- Performs typed reads, raw reads, string reads, and scatter reads.
- Tracks total bytes and scatter calls for DMA stats.
- Re-applies CR3 after `ForceRefresh()`.
### Runtime Service
`src/Runtime/DayZRuntimeService.*` owns the background reader threads.
The main live loop:
- Waits for a valid process/session.
- Resolves base objects and runtime offsets.
- Refreshes near/far/slow entity lists at configured intervals.
- Refreshes scoreboard and network metadata.
- Reads local player and camera data.
- Reads bullets and items.
- Projects raw entities into typed player/animal/zombie/vehicle/loot snapshots.
- Refreshes bones using scatter reads.
- Publishes a `RuntimeUpdate` snapshot to overlay and web server consumers.
A separate camera loop keeps projection data fresher than the heavier entity scans.
### Readers and Resolvers
- `Resolvers/BaseObjectResolver.*`: resolves core world/network pointers.
- `Resolvers/LocalPlayerResolver.*`: resolves local player data.
- `Resolvers/NetworkMetadataReader.*`: reads server metadata.
- `Readers/NearEntityListReader.*`: near entity list.
- `Readers/FarEntityListReader.*`: far entity list.
- `Readers/SlowEntityListReader.*`: slow entity list.
- `Readers/ItemListReader.*`: loot/item extraction.
- `Readers/BulletTableReader.*`: active bullet reads and direction inference.
- `Readers/ClientScoreboardReader.*`: scoreboard player entries.
- `Readers/EntityCategoryProjector.*`: classifies raw entities into typed output lists.
- `Readers/ItemFilterCatalog.*`: loads and applies loot filter rules.
### Signature and Offset Handling
- `src/SigScanner/SigScanner.*` scans the module with page-sized scatter reads.
- `src/Offsets.h` contains known static offsets.
- `src/RuntimeOffsets.h` stores runtime-resolved addresses/offsets used by readers.
After a DayZ update, signature patterns and offsets are the first places to check if attach succeeds but data is wrong.
### Overlay
- `src/Overlay/OverlayWindow.*`: Win32 window, DirectX 11 device, swap chain, ImGui backend, font setup.
- `src/Overlay/GameOverlay.*`: ESP rendering, projection, menu state, smoothing, bullet trails, ballistic dot.
- `src/Overlay/MenuBridge.h`: pointer bridge between project state and the vendored Lumin menu.
- `external/lumin/framework/gui.cpp`: actual menu layout.
### Web Radar
- `src/Web/WebRadarServer.*`: HTTP routes, SSE broadcast, auth, CORS.
- `src/Web/WebSnapshotService.*`: converts `RuntimeUpdate` into JSON.
- `src/Web/BulletTrackCache.*`: keeps bullet path history for web and overlay visualizations.
- `src/Web/MapRegistry.*`: known maps, aliases, world-to-map coordinate transforms.
- `src/Web/MapTileService.*`: map image loading, tile generation, PNG caching.
- `webroot/`: static browser UI.
## Logs
Logs are written to:
```text
logs/dayz-memory.log
```
The file sink logs at trace level and is truncated on each run. The console sink defaults to info level.
Useful messages to look for:
- Process attach and reconnect events.
- Signature scan results.
- Base object/session readiness.
- Skeleton loss diagnostics.
- Ammo chain diagnostics for ballistic prediction.
- Periodic live heartbeat with player/zombie counts.
## Build Notes
- The project is Windows-only and intentionally fails CMake configure on non-Windows platforms.
- The target is `dayz-memory-cpp`.
- C++ standard is C++20.
- MSVC builds with `/W4`, `/permissive-`, `/utf-8`, and warnings not treated as errors.
- `NOMINMAX`, `IMGUI_ENABLE_FREETYPE`, and `IMGUI_DEFINE_MATH_OPERATORS` are set for the target.
- Runtime DLLs are copied from `${VOLKDMA_ROOT}/dlls` after build.
- `webroot/`, `config/`, `maps/`, and Lumin icon fonts are copied after build.
## Troubleshooting
### CMake cannot find VolkDMA files
Confirm this path exists:
```text
../dayz-dma/dma-dayz-cpp-master/VolkDMA
```
If your checkout is elsewhere, edit `VOLKDMA_ROOT` in `CMakeLists.txt`.
### Dependency download fails during configure
The first configure fetches dependencies from GitHub. Check network/proxy access or use a CMake dependency cache with the packages already populated.
### Executable exits immediately with `0xC0000135`
That status usually means a DLL is missing. Confirm these files are next to `dayz-memory-cpp.exe`:
- `vmm.dll`
- `leechcore.dll`
- `FTD3XX.dll`
Rebuild the target or manually verify `${VOLKDMA_ROOT}/dlls` contains those DLLs.
### Overlay opens but ESP alignment is wrong
Open `Config` and set:
- Monitor resolution in `overlayWidth` / `overlayHeight`.
- Game render resolution in `renderWidth` / `renderHeight` if DayZ renders at a different resolution.
- `stretchToFill` according to your GPU/display scaling mode.
Save config and restart if needed.
### Web radar is blank
Check:
- The app is attached and `Info` shows connected.
- The browser URL points to the correct host/port.
- `webPassword` matches the `?password=` parameter for remote clients.
- `webBindAddress` is not restricted to `127.0.0.1` when using another device.
- Firewall allows the configured port.
### Map background is missing
Place a supported PNG at:
```text
maps/<map-id>.png
```
Example:
```text
maps/chernarusplus.png
```
If you added the PNG to the repository `maps/` folder and want it embedded, re-run CMake configure and rebuild.
### Caddy serves 404s
Run `caddy run` from the repository root so `root * ./webroot` resolves correctly, or adjust the `root` path in `Caddyfile`.
### Port is already in use
Change `webPort` in `config/overlay.json`, then restart. If using Caddy, also update the upstream port in `Caddyfile`.
### Attach succeeds but entity data is wrong
DayZ offsets or signatures may be stale. Check:
- `src/Offsets.h`
- `src/RuntimeOffsets.h`
- `src/SigScanner/SigScanner.cpp`
- `logs/dayz-memory.log`
Runtime structures can change after a DayZ update even when the process name and module still resolve.
## Development Workflow
### Add a new memory field
1. Add or update the offset in `src/Offsets.h` or runtime scanner logic.
2. Read the value in the appropriate resolver/reader.
3. Add fields to `src/Core/Models.h` or `RuntimeUpdate` if the value must cross module boundaries.
4. Publish the field to overlay or web code.
5. Add diagnostics around pointer-chain failures if the chain is fragile.
### Add an overlay option
1. Add the value to `OverlayConfig` if it should be configurable.
2. Load/save it in `src/Config.cpp`.
3. Add a member in `GameOverlay`.
4. Sync it in `GameOverlay::SyncConfig()`.
5. Expose it through `MenuBridge`.
6. Add the control in `external/lumin/framework/gui.cpp`.
7. Use the toggle in the draw path.
### Add a web radar field
1. Add it to the relevant runtime model.
2. Serialize it in `WebSnapshotService`.
3. Consume it in `webroot/app.js`.
4. Style it in `webroot/style.css` when needed.
5. Update bootstrap data if the frontend needs metadata or filter definitions.
## Known Limitations
- Windows-only.
- Offsets/signatures must match the current DayZ build.
- Built-in web server is HTTP only; use Caddy, a tunnel, or another reverse proxy for TLS.
- Web auth is a simple query-parameter password, not a full user/session system.
- Map recognition depends on server map metadata and the known map alias table.
- Browser map images require correctly named PNGs unless embedded at build time.
- Overlay projection depends on correct monitor/render resolution configuration.
## License and Third-Party Code
This repository vendors or fetches third-party components. Check their upstream licenses before redistributing binaries:
- Dear ImGui under `external/lumin/thirdparty/imgui`.
- FreeType under `external/lumin/thirdparty/freetype`.
- Lumin framework under `external/lumin/framework`.
- nlohmann/json, spdlog, cpp-httplib, and stb through CMake `FetchContent`.
- VolkDMA and its bundled VMM/LeechCore dependencies from the sibling checkout.