508 lines
16 KiB
Markdown
508 lines
16 KiB
Markdown
# DayZ Memory C++ Overlay
|
|
|
|
A Windows C++20 DMA reader for DayZ using VolkDMA backend. Reads game memory in real-time and streams data to two frontends: an overlay ESP (DirectX 11 + ImGui) and a web radar (HTTP + SSE).
|
|
|
|
**Use only on authorized systems.** The web server runs plain HTTP — protect with a password before exposing beyond localhost.
|
|
|
|
## Features
|
|
|
|
**Memory & Reading:**
|
|
- DMA-backed memory access (VolkDMA)
|
|
- Runtime signature scanning + static offsets
|
|
- Auto-reconnect on process/session drop
|
|
- High-frequency camera reads
|
|
- Efficient batched entity scanning
|
|
|
|
**Overlay (DirectX 11 + ImGui):**
|
|
- Player/zombie/animal/vehicle/loot ESP
|
|
- Player skeletons with interpolation
|
|
- Health bars, held weapons, worn items
|
|
- Configurable draw distances
|
|
- Ballistic aim dot (weapon velocity + drag)
|
|
- Bullet trail visualization
|
|
- Lumin menu with live config save
|
|
|
|
**Web Radar (HTTP + SSE):**
|
|
- Real-time map with pan/zoom
|
|
- Entity filters + player list
|
|
- Bullet path visualization
|
|
- Server-sent events for live updates
|
|
- Map tiles (512x512 PNG cache)
|
|
- Optional Caddy proxy for static hosting
|
|
- CORS support
|
|
|
|
## Requirements
|
|
|
|
**Build:**
|
|
- Windows x64
|
|
- Visual Studio 2022 (MSVC toolchain)
|
|
- Windows SDK (DirectX 11)
|
|
- CMake 3.20+
|
|
- Git
|
|
- Internet (first configure only, to fetch dependencies)
|
|
|
|
**VolkDMA:**
|
|
Must be at this location (or update `VOLKDMA_ROOT` in CMakeLists.txt):
|
|
```
|
|
../dayz-dma/dma-dayz-cpp-master/VolkDMA/
|
|
```
|
|
|
|
**Auto-fetched:**
|
|
- nlohmann/json 3.11.3
|
|
- spdlog 1.14.1
|
|
- cpp-httplib 0.18.1
|
|
- stb
|
|
|
|
Vendored in `external/lumin/`: ImGui, Lumin framework, FreeType
|
|
|
|
## 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
|
|
|
|
**Keys:**
|
|
- `INSERT` — toggle menu
|
|
- `Ctrl+C` in console — shutdown
|
|
|
|
**Menu Tabs:**
|
|
- `Aim` — ballistics, bullet trails
|
|
- `Visuals` — ESP toggles, draw distances
|
|
- `Loot` — item filters (from `config/item_filters.json`)
|
|
- `Info` — status, entity counts, DMA throughput, web radar URLs
|
|
- `Config` — resolution/render overrides, save settings, exit
|
|
|
|
## Configuration
|
|
|
|
Two config files (both in working directory, copied at build):
|
|
|
|
- **`config/config.cfg`** — INI format, runtime reader settings (refresh intervals, batch sizes)
|
|
- **`config/overlay.json`** — JSON, overlay/web UI settings (auto-created/updated by menu)
|
|
|
|
### `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** (`main.cpp`):
|
|
1. Create logs, init spdlog
|
|
2. Load `config/config.cfg` → `RuntimeConfig`
|
|
3. Load `config/overlay.json` → `OverlayConfig`
|
|
4. Start `WebRadarServer`, `DayZRuntimeService`
|
|
5. Create overlay, enter DX11 render loop
|
|
|
|
**Memory** (`VmmAccessor`):
|
|
- Wraps VolkDMA/VMM access
|
|
- Finds + attaches to `DayZ_x64.exe`
|
|
- Typed/raw/string/scatter reads
|
|
- Tracks DMA throughput
|
|
|
|
**Runtime Service** (`DayZRuntimeService`):
|
|
- Main loop: wait for process, resolve base objects
|
|
- Refresh entity lists at configured intervals
|
|
- Read players, bullets, items, bones
|
|
- Publish `RuntimeUpdate` snapshot to overlay + web
|
|
|
|
**Readers/Resolvers:**
|
|
- `BaseObjectResolver` — world/network ptrs
|
|
- `LocalPlayerResolver`, `NetworkMetadataReader`
|
|
- `NearEntityListReader`, `FarEntityListReader`, `SlowEntityListReader`
|
|
- `ItemListReader`, `BulletTableReader`, `ClientScoreboardReader`
|
|
- `EntityCategoryProjector` — raw ents → typed lists
|
|
- `ItemFilterCatalog` — loot categorization
|
|
|
|
**Offsets & Signatures:**
|
|
- `Offsets.h` — static known offsets
|
|
- `RuntimeOffsets.h` — runtime-resolved addresses
|
|
- `SigScanner.cpp` — module pattern scanning
|
|
- *After DayZ updates: check these first if data is wrong*
|
|
|
|
**Overlay** (DirectX 11 + ImGui):
|
|
- `OverlayWindow` — Win32 window, DX device, font atlas
|
|
- `GameOverlay` — ESP rendering, projection, trails, ballistics
|
|
- `MenuBridge` → `external/lumin/framework/gui.cpp` (menu layout)
|
|
|
|
**Web Radar:**
|
|
- `WebRadarServer` — HTTP routes, SSE, auth, CORS
|
|
- `WebSnapshotService` — `RuntimeUpdate` → JSON
|
|
- `BulletTrackCache` — bullet history
|
|
- `MapTileService` — tile generation + PNG cache
|
|
- `webroot/` — 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 can't find VolkDMA**
|
|
- Check: `../dayz-dma/dma-dayz-cpp-master/VolkDMA/` exists
|
|
- If elsewhere, set `VOLKDMA_ROOT` in CMakeLists.txt
|
|
|
|
**Dependency fetch fails**
|
|
- First configure needs internet (GitHub FetchContent)
|
|
- Check network/proxy; use pre-cached deps if offline
|
|
|
|
**Exit code `0xC0000135`** (DLL missing)
|
|
- Verify these exist next to exe: `vmm.dll`, `leechcore.dll`, `FTD3XX.dll`
|
|
- Rebuild or copy from `${VOLKDMA_ROOT}/dlls`
|
|
|
|
**Overlay ESP misaligned**
|
|
- Open `Config` tab, set:
|
|
- `overlayWidth` / `overlayHeight` = monitor resolution
|
|
- `renderWidth` / `renderHeight` = game render resolution (if different)
|
|
- `stretchToFill` = match your GPU scaling
|
|
|
|
**Web radar blank**
|
|
- Check `Info` tab: attached + connected?
|
|
- Browser URL correct (host/port)?
|
|
- `webPassword` matches `?password=` param?
|
|
- `webBindAddress` not `127.0.0.1` for remote?
|
|
- Firewall allows port?
|
|
|
|
**Map background missing**
|
|
- Place PNG: `maps/<map-id>.png` (e.g., `maps/chernarusplus.png`)
|
|
- To embed: add to repo `maps/`, re-run CMake, rebuild
|
|
|
|
**Caddy serves 404s**
|
|
- Run `caddy run` from repo root, or fix `root` path in Caddyfile
|
|
|
|
**Port in use**
|
|
- Change `webPort` in `config/overlay.json`, restart
|
|
- If using Caddy, also update upstream port
|
|
|
|
**Attach OK but data wrong**
|
|
- DayZ offsets/signatures may be stale post-update
|
|
- Check: `Offsets.h`, `SigScanner.cpp`, `logs/dayz-memory.log`
|
|
|
|
## Development Workflow
|
|
|
|
**Add a memory field:**
|
|
1. Add offset to `Offsets.h` or scanner logic
|
|
2. Read in appropriate resolver/reader
|
|
3. Add to `Models.h` / `RuntimeUpdate` if cross-module
|
|
4. Publish to overlay or web
|
|
5. Add diagnostics for fragile chains
|
|
|
|
**Add overlay option:**
|
|
1. `OverlayConfig` struct + `Config.cpp` load/save
|
|
2. Add to `GameOverlay` class
|
|
3. Sync in `GameOverlay::SyncConfig()`
|
|
4. Expose via `MenuBridge`
|
|
5. Add control in `external/lumin/framework/gui.cpp`
|
|
6. Use in draw path
|
|
|
|
**Add web radar field:**
|
|
1. Add to runtime model
|
|
2. Serialize in `WebSnapshotService`
|
|
3. Consume in `webroot/app.js`
|
|
4. Style in `webroot/style.css`
|
|
5. Update bootstrap data if needed
|
|
|
|
## Known Limitations
|
|
|
|
- Windows-only
|
|
- Offsets/signatures must match current DayZ build
|
|
- Web server is HTTP only (use Caddy/proxy for TLS)
|
|
- Web auth is query-param password, not full session system
|
|
- Map recognition depends on server metadata + alias table
|
|
- Browser map images need correctly named PNGs (or embed at build)
|
|
- Overlay accuracy depends on monitor/render resolution config
|
|
|
|
## Third-Party Code
|
|
|
|
Vendored/fetched components — check licenses before redistribution:
|
|
- ImGui, FreeType (under `external/lumin/`)
|
|
- Lumin framework, nlohmann/json, spdlog, cpp-httplib, stb
|
|
- VolkDMA + VMM/LeechCore (sibling checkout)
|