# Architecture Ehwrj is split into small modules so that local API access, state derivation, rendering, and platform integration stay separate. ## Data Flow ```text War Thunder local API -> Ehwrj.Core.Services.WarThunderClient -> Ehwrj.App.Services.LiveMapService -> Ehwrj.App.Models.LiveSnapshot -> MainWindow / OverlayWindow -> MapCanvas / OverlayCanvas ``` ## Modules ### Ehwrj.Core - `WarThunderClient` is the only module allowed to perform network requests. - Its base address is fixed to `http://127.0.0.1:8111/`. - `ProcessProbe` checks whether `aces.exe` is present. - `MapInfo` parses `/map_info.json`. - `MapObject` parses `/map_obj.json`. - `FlightState` parses optional `/state` telemetry such as `TAS, km/h`, `IAS, km/h`, `Vy, m/s`, and `H, m`. - `BattleMessage` normalizes optional `/hudmsg` and `/gamechat` messages. - `MapObjectKind` classifies player, ally, squad, enemy, objective, and unknown objects. - `ObjectTracker` estimates motion from consecutive object positions. - `CoordinateProjector` converts map coordinates into viewport coordinates. `Ehwrj.Core` targets plain `net8.0` and has no UI dependency. Parser tolerance is intentionally concentrated in `Ehwrj.Core`: - numeric JSON strings are parsed with invariant culture and comma decimal fallback - map bounds can come from scalar min/max fields, `map_min`/`map_max` arrays, `bounds`, or `grid_size` - object position can come from scalar `x`/`y` style fields or `pos`/`position` style arrays - object direction can come from scalar `dx`/`dy` style fields or `dir`/`direction`/`velocity` style arrays ### Ehwrj.App - `LiveMapService` owns the polling loop and converts endpoint responses into immutable UI snapshots. - `SettingsStore` persists user settings under `%LOCALAPPDATA%\Ehwrj`. - `OverlaySettings` holds user-adjustable overlay controls. - `UiText` and `LanguageOption` provide the clean-room English/Korean UI language layer. - `LiveSnapshot` is the single render input for both the main map and overlay. - `MainViewModel` coordinates commands and live state for the Avalonia UI. ### Rendering - `MapCanvas` draws the main map preview, including player-relative rotation of the map plane and projected tactical objects. - `OverlayCanvas` draws the transparent overlay surface. - Rendering code receives a `LiveSnapshot` and `OverlaySettings`; it does not perform I/O. - Overlay setting changes invalidate the drawing surface directly, so UI sliders and text settings are reflected without restarting the polling loop. ### Overlay Controls The overlay settings mirror the benign controls identified in the analyzed live map resource: - minimap visibility, aircraft scale, and Mach threshold - spot radar visibility, detection range, spread, vertical scale, and vertical offset - marker opacity, arrow scale, arrow outline, and colors - distance, Mach, and closure speed label toggles - per-label font size, outline width, color, and opacity ### Platform Integration - `Win32.MakeOverlayClickThrough` is the only Windows interop hook. - It applies click-through and no-activate extended styles to the optional overlay window. - It is guarded with `OperatingSystem.IsWindows()`. ### Developer Tooling - `Ehwrj.Tools.LocalApiStub` serves deterministic `/map_info.json`, `/map_obj.json`, and `/map.img` responses on loopback. - It also serves optional `/state`, `/hudmsg`, and `/gamechat` responses for player info and battle log development. - The stub lets contributors exercise the UI without running War Thunder. - The generated map image is produced in memory and the moving aircraft data is deterministic. - `Ehwrj.Tools.Capture` captures real local API responses into fixture directories. - It writes `capture-report.txt` so captured fixtures can be checked for parser coverage, raw object field frequency, unknown object samples, replay readiness, and tuning gaps. - `LocalApiStub --fixture-dir` replays captured fixtures before falling back to generated responses. ## Safety Rules The project intentionally has no module for clipboard monitoring, startup persistence, ZIP mutation, PE resource updates, or external network communication. New features should preserve these boundaries.