Documentation menu

Changelog

Note on this page. Through v2.11.0 the changelog tracks per-release entries. From v2.12.0 onwards releases shipped faster than the changelog kept up — the catch-up section below condenses the work across v2.12 → v2.17.0 by theme. Per-release release notes for the controller live under RELEASE_NOTES_v2.X.md in the DayzServerController repo; we're working on automating their import here.

Cloud Phase 1 & 2 — Trust graph + operator console (May 2026)

A large wave of Citadel Cloud features landed: the cross-server trust graph and the browser-native operator console.

Added — Live Ops Console

A real-time, browser-native view of every server running the Citadel agent (guide): live map (positions, vehicles, world events), kill feed, searchable chat, and server-metric sparklines. Near-real-time via polling plus a Server-Sent-Events stream. One-click quick actions (kick / ban / heal / kill / message, plus server-wide broadcast and AI/vehicle wipes) delivered to the agent — no RCON required.

Added — RCon Copilot

Plain-English → a reviewed, structured plan over your telemetry, executed only on confirmation, with a mass-action guard (guide). The model picks from constrained options; Citadel compiles a safe read-only query — it never writes raw SQL.

Added — Suspicious Activity & Server Health

Rule-based cheat scoring (impossible accuracy, headshot ratio, long-range consistency) surfaced as a ranked, reviewable feed with a sticky label loop; plus metric-anomaly alerts (low FPS, AI/entity spikes, restart loops) against each server's 7-day baseline (guide).

Added — Replay

Scrub or play back any window of telemetry — time-synced positions, kills, and chat on the map — with a shareable link to the exact moment (guide).

Added — On-call & Web Push

A mobile-first, installable on-call triage view with push notifications for crashes, anomalies, flagged cheaters, and the moderation queue (guide).

Added — Trust Network

Canonical Citadel IDs, explainable trust scores, a public per-identifier lookup API with signed proofs, a cloud-side Discord bot any community can install, auto-captured forensic ban evidence, a weighted reviewer pool for appeals/high-impact bans, and a partner bulk export feed (guide, API reference).

Changed — Payments migrated to Stripe

New subscriptions and donations now run through Stripe; pre-migration customers stay on Paddle until they cancel or renew. License issuance reads a single provider-neutral subscription status regardless of biller.

Changed — Pricing

Citadel base dropped to $9.99/mo (or $99.99/yr, down from $14.99/$149.99); Citadel Cloud is $9.99/mo or $99.99/yr (annual is new) with the 7-day trial. A free Trust Lookup tier (public trust-score API + the cloud Discord bot, no account) is now the front door. Pricing stays flat — no per-server fees: one subscription covers your whole fleet. Existing subscribers are grandfathered at their current rate.

v2.12 → v2.17.0 — Catch-up (April 2026)

Six versions' worth of work landed during a focused security + Cloud-launch push. Headlines below.

Added — Citadel Cloud add-on

The optional Citadel Cloud subscription ($10/mo, 7-day trial, on top of the $14.99 Citadel base) launched as the surface for cross-server features. The first feature behind the entitlement is Cloud Bans — a customer-vouched community ban pool with a full reputation model (vouch_weight, overturn penalties, manual-review threshold, public appeal flow). See the new Citadel Cloud and Cloud Bans guides.

License JWTs now carry an entitlements claim (['citadel'] or ['citadel', 'cloud']) and Cloud-entitled tokens are issued with a tighter lifetime (default 4h vs 24h) so post-cancel access fades quickly.

Added — Two-factor authentication (TOTP)

Full TOTP support landed on both the controller (/api/auth/mfa/*) and the cloud (/api/v1/auth/2fa/*). Backup codes, encrypted secret storage, password re-auth required for enrollment changes. See the Two-Factor Authentication guide. Recommended for any account that can change billing, manage other users, or run server-control actions.

Added — Lifecycle hooks

Drop pre-start.bat / started.ps1 / stopped.py / crashed.cmd into <installDir>/lifecycle_hooks/ and Citadel will run them at the matching server lifecycle event. CITADEL_SERVER_* env vars are injected. See Lifecycle Hooks.

Changed — Email + password auth replaces Steam OpenID

The post-pivot auth model is now email + password with bcrypt + JWT-in-cookie. Steam OpenID is gone. Existing accounts with the legacy Steam binding sign in with their email + password going forward — see the Citadel License page.

Changed — Discord bot 3-layer security model

The bot's authentication contract was re-shaped into three independent policy layers: a built-in discord-bot Citadel role (with per-action ACTION_PERMISSIONS gating), HMAC-signed X-Discord-Sig attribution per call, and per-Discord-user role mapping in data/discord-user-roles.json. The legacy single-role check still runs alongside. See the Discord Bot guide → Security.

Changed — File editor split (files.edit-scripts)

Editing .bat / .cmd / .ps1 / .sh files via the file browser now requires the new files.edit-scripts permission AND the destination must resolve under <installDir>/lifecycle_hooks/. None of the built-in roles include the new permission by default. Prevents config-edit access from quietly escalating to remote code execution on the server box.

Added — fail2ban + per-(IP, username) lockout

Failed sign-ins are now tracked per-(IP, username) with escalating lockouts (60s → 5min → 1h). An attacker who knows your username can no longer lock you out from arbitrary IPs. Applies to /login, /login/2fa, /set-password, /password-reset/confirm, and /license/activate.

Added — Setup-wizard one-shot lock

data/.first-run-completed now persists across setup_complete.json deletion. Once the wizard runs once, it's locked — preventing an attacker who can write to data/ from re-arming the wizard for an unauthenticated takeover. See Re-running the wizard.

Browser sessions now use an HttpOnly auth-token cookie + a JS-readable csrf-token cookie + X-CSRF-Token header on state-changing calls. Bearer remains the path for desktop and scripted clients. See REST API Reference → Authentication.

Added — Cloud-side hardening (audit fixes)

A targeted security audit on the cloud half landed a stack of fixes:

  • Cloud Bans gating fix — the paid feature was previously gated on the wrong subscription column; now correctly requires the Cloud add-on.
  • Login + activate timing-uniform — bcrypt always runs against either the real hash or a precomputed dummy, so missing-account responses no longer leak via timing.
  • Reset / welcome tokens stored as SHA-256 digests — raw token only ever leaves in the email; a leaked DB snapshot can't be used to take over an unconsumed link.
  • Webhook idempotency reworkprocessedAt is stamped inside the same transaction as side effects; on failure, the claim is released so Paddle's retry can pick it up cleanly. New claimedAt column with a 5-min TTL prevents two concurrent retries double-processing.
  • 2FA setup re-auth — a stolen session can no longer rotate a pending TOTP secret out from under a legitimate user.
  • CORS * refused in production — the API refuses to boot if CORS_ORIGINS contains * under NODE_ENV=production.
  • Direct-origin nginx 403 — requests that bypass Cloudflare and hit the origin VPS directly are refused at nginx based on a CIDR allowlist of Cloudflare's published ranges.
  • Logger redact pathsAuthorization, Cookie, Paddle-Signature, password fields, tokens, JWTs, TOTP secrets, etc. are masked in all log output.
  • Telemetry HMAC (opt-in) — desktop installs that ship the embedded HMAC key sign their batches; the API verifies if a signature is present (strict mode flips on once the fleet upgrades).

Added — Admin operational dashboard

A /admin route gated by role tiers (support < finance < admin) gained customer search, per-user device management, "Resend welcome email" / "Sync from Paddle" buttons, webhook event log with replay, and a stats overview tile. The legacy is_super_admin flag is auto-migrated to admin_role = 'admin' on every boot.

Added — Per-machine telemetry caps

Telemetry /events now enforces a per-machineIdHash hourly cap (100/hr) sitting between the per-minute global limit and the existing 5000/day daily cap. Catches misconfigured installs before they eat the daily budget.

Added — Discord user-roles CRUD endpoints

GET / PUT / DELETE /api/discord/user-roles[/:discordUserId] (gated on users.manage) for the per-Discord-user role mapping that's Layer 3 of the new bot security model.

Added — Audit log codes reference

A canonical list of every audit-log action string with what triggers it, including new codes like discord.denied, discord.sig-rejected, file.edit-script, file.write-blocked. See Audit Log Codes.


v2.11.0 (desktop app)

License activation fix + safe upgrades + manual update check.

Fixed — License activation HTTP 404

The desktop client was pointing at https://citadels.cc/api/v1/license/activate, but the Fastify API lives on the api.citadels.cc subdomain — the marketing site has no /api/v1/* routes. Fixed the default URL. Temporary workaround for older installs: set CITADEL_LICENSE_API=https://api.citadels.cc in the install-directory .env and restart the service.

Added — Safe upgrade path

Re-installing over an existing Citadel install now preserves user customizations properly:

  • Service stops BEFORE file copy — prevents node.exe from locking backend files
  • Electron window closed — prevents app.asar locks during upgrade
  • .env preserved — custom env vars survive the upgrade (backed up and restored automatically)
  • data/ preserved — server configs, backups, license cache, user DB all untouched

Added — Manual update check

Help → Check for Updates… in the app menu bar. Triggers an immediate check instead of waiting for the 6-hour periodic poll. Shows a native dialog with the result. New About Citadel dialog too.

v2.11.0

Admin dashboard + Steam Workshop link for @CitadelAdmin mod

Added — Admin Dashboard at /admin

A full operational dashboard gated by admin role. Answers 90% of customer-support questions in one click instead of SSHing + running SQL.

  • Overview page — live stat cards: MRR estimate, active subscriptions, 7-day signups, 24h webhook health. Subscription breakdown by status. Signup trend (24h / 7d / 30d / all-time).

  • Customers tab — paginated user list with search by email + filter by subscription status. Click through to a detail page with:

    • Full subscription state (status, renews, Paddle IDs — all copyable)
    • Device activations with per-device revoke
    • Resend welcome email (generates fresh 24h link, returns the URL for hand-delivery if email itself fails)
    • Sync from Paddle — one-click force-refresh of subscription state from Paddle's API. Prevents "why is their status wrong in my DB" debugging.
    • Grant/revoke admin role — switch between support / finance / admin / none
  • Webhooks tab — chronological event log auto-refreshing every 20s. Filter by outcome (ok / error / skipped) or event type. Click an event for full detail view with parsed payload, error traces, and copy-to-clipboard.

  • Role-based access — three tiers:

    • support — customer lookup, resend welcome, view webhooks
    • finance — everything support can + full subscription details
    • admin — full control: edit users, force sync, grant roles, replay webhooks

    Hierarchy: admin > finance > support. Existing super-admin accounts auto-migrate to admin_role = 'admin'.

New section on the account page linking directly to the Steam Workshop page for the admin mod (ID 3676936117). Customers now know exactly where to get the in-game mod that powers Live Ops, kill feed, chat log, and 50+ admin commands.

Added — Webhook payload storage + replay scaffolding

Every incoming Paddle webhook now stores its signed raw_body in the webhook_events table so admins can inspect the exact payload that caused a problem. Lays groundwork for one-click event replay from the admin dashboard.

API additions

  • GET /api/v1/admin/stats/overview (support+)
  • GET /api/v1/admin/users?q=&status=&role=&limit=&offset= (support+)
  • GET /api/v1/admin/users/:id (support+)
  • PATCH /api/v1/admin/users/:id (admin only)
  • POST /api/v1/admin/users/:id/resend-welcome (support+)
  • POST /api/v1/admin/users/:id/reconcile-paddle (admin only — fetches from Paddle API)
  • POST /api/v1/admin/users/:id/grant-role (admin only)
  • DELETE /api/v1/admin/users/:userId/devices/:deviceId (admin only)
  • GET /api/v1/admin/webhooks/recent (support+)
  • GET /api/v1/admin/webhooks/:eventId (support+)
  • POST /api/v1/admin/webhooks/:eventId/replay (admin only)

Changed

  • GET /api/v1/auth/me response now includes adminRole so the account page can show the Admin Dashboard shortcut.

v2.10.0

Editable trader NPC spawns — drag on map, edit gear, Add/Delete NPCs

The Spawns tab was view-only: you could see where your trader NPCs were but couldn't move them, edit their gear, or add new ones without hand-editing .map files. That's fixed.

Added — Full NPC spawn editing

  • Drag NPCs on the map to reposition them — drop and the X/Z update live. Orange markers are spawns in the currently-selected file so you can tell what you're editing at a glance.
  • "Click to Place" mode — toggle it on, click anywhere on the map, and a new NPC is added to the selected file at that location.
  • Inline table editing — EntityClass, X, Z, and Yaw are editable directly in the row. Expand a row for TraderFile reference, Y (terrain height), Pitch, Roll, and gear.
  • Gear list editor — add item class names (e.g. CombatKnife, AKM) and remove them with a click. Was previously a read-only chip display.
  • Add NPC button in the file header for keyboard-first workflows (no map click needed).
  • Delete NPC per-row, with a ✕ button. Deleting the expanded row auto-collapses.
  • Per-file dirty indicator — sidebar shows an ● on files with unsaved changes; header shows "● unsaved" plus a Save button that enables only when there's something to save.

Fixed — Spawns data layer was wrong

  • The Spawns tab was pulling from /trader-editor/traders (JSON trader configs) instead of /trader-editor/spawns (the parsed .map files). Fields were lowercase in the backend response but the UI read uppercase keys, so positions rendered as - a lot. Now uses the correct endpoint with spawn.entityClass, spawn.position.{x,y,z}, spawn.orientation.{yaw,pitch,roll}, and spawn.gear[].

v2.9.0

Expansion editor perf + Trader editor quality-of-life

Changed — Expansion Editor (massive perf win)

  • Lazy-loads configs on demand. Previously, opening the Expansion editor fetched all 32 config files in a single monolithic request and blocked the page until every one was parsed. Now the page loads instantly with just the lightweight manifest, and each section's file is fetched only when you click into it (and cached after that).
  • Sidebar search — a filter box at the top of the section sidebar lets you find a section by label or filename. Useful for the 23-section sidebar that spans Settings, Mission, Notifications, AI, Hardline, Market, and more.
  • Per-section loading state — a small loader appears while a file is fetching instead of the old blank pane.
  • No more duplicate fetch of the expansion endpoint — the legacy code hit the same endpoint twice to populate a metadata cache. Merged into a single meta call.

Added — Mod Config API endpoints

  • GET /api/servers/:id/mod-configs/:schemaId/meta — lightweight manifest (no file content) for fast editor bootstrapping
  • GET /api/servers/:id/mod-configs/:schemaId/file?fileName=… — single file fetch for lazy loading

Benefits any mod with a schema manifest (Expansion today, TraderPlus and others tomorrow).

Changed — Trader Editor

  • Search in Traders tab — filter trader config files by name (was: no search, painful with 15+ trader files)
  • Search in Zones tab — filter the zone details table by display name or zone ID
  • Search in NPC Spawns tab — filter spawn files by name AND by NPC EntityClass ("where does Hermit spawn?")
  • Bulk price factor + offset — the Categories bulk edit now has three modes:
    • Set to value (original behavior)
    • × Factor — multiply every selected item's field by N (e.g. 1.5 = raise all prices 50%)
    • + Offset — add N to every field (use negative for subtraction) Admins can e.g. "select all items, ×1.2 every price" in one shot instead of editing dozens individually.

Deferred to v2.10

  • TraderPlus support — genuinely a new editor (different file format, different UI). Focused session coming.
  • Spawns editing (drag-on-map, gear editor) — stretch goal.

v2.8.1

Hotfix — Files editor bundled locally (no more CDN dependency)

Fixed

  • Files browser editor was still failing to load on machines where cdnjs.cloudflare.com was blocked by a firewall, ad-blocker, or DNS filter. The previous CSP fix (v2.5.1) made the CSP correct, but the editor still depended on a reachable CDN — which is wrong for a local-first tool.
  • Monaco editor is now bundled locally via the monaco-editor npm package. The Files page's editor bundle grew ~3.7 MB (lazy-loaded, only when you open the Files page), but the app now works fully offline for file editing and is immune to cdnjs outages, corporate firewalls, and ad-blocker false positives.
  • Cleaned up CSP — removed the 'unsafe-eval' exception that was needed for Monaco's AMD loader, and removed cdnjs.cloudflare.com from connectSrc (it's still in scriptSrc for Socket.IO and Font Awesome).

v2.8.0

Daily Ops — Console rebuild, Logs search, System Dashboard alerts

The features you touch every session got the polish they deserved. Less friction in your daily workflow.

Added — Console (full rebuild)

  • Command history — ↑/↓ arrows recall your last 50 commands per server (persisted to localStorage — survives app restarts).
  • Favorites bar — star a command to pin it above the input. One click to re-run. Right-click a chip to unpin. Defaults to players, uptime, server.
  • Live autocomplete — type a command prefix and a dropdown shows all matching allowed RCON verbs with their descriptions. Navigate with ↑/↓, accept with Tab or Enter, dismiss with Esc.
  • Inline help — the description of the current command appears below the input so you don't have to remember syntax.
  • Output filters — All / Server / RCON toggle in the header.
  • Copy any line — double-click a log line to copy it with full timestamp + source tag.
  • Clear visible buffer — tidies the display without touching the server's real logs.
  • /rcon/commands endpoint — exposes the whitelist with descriptions so the autocomplete stays in sync with whatever the server-side validator allows.

Added — Logs (multi-filter + export)

  • Message-contains search — debounced 200ms, searches both message text and source names.
  • Multi-select source filter — chip row of every distinct source (rpt/lifecycle/crash/etc) with counts. Toggle any combination.
  • Level filter — dropdown for INFO / WARN / ERROR / all.
  • Time range presets — last 15 min, 1 hr, 6 hrs, 24 hrs, or all time.
  • CSV export — download filtered logs with one click. Filename includes server name + date.
  • Live-feed pause — hit Pause to study a window without new entries sliding in. Resume re-enables the stream.
  • All filters combinable — e.g. "errors from rpt in the last 6 hours containing the word 'access'" is a single view now.
  • /api/servers/:id/logs/sources and /logs/export.csv endpoints added. Main list endpoint gets q, from, to, offset, multi-source support while staying backward-compatible with the old array response for unfiltered callers.
  • Threshold alerts — when CPU, memory, or disk usage crosses a warning threshold (default 90/90/95%), Citadel fires a warning notification with a 15-minute cooldown per metric. The notification bell lights up + a toast pops on screen — you see the alert even if the dashboard isn't open.
  • Background sampler — a new lightweight process samples CPU/RAM every 30 seconds and disk every 10 minutes, maintaining a rolling 24-hour history buffer. Started automatically on backend boot.
  • Trend view with time range picker — switch between 15m, 1h, 6h, 24h views of host metrics. Chart data is downsampled server-side so 24h still renders smoothly.
  • Visible threshold banner — when a metric is currently over its limit, a yellow banner at the top of the dashboard tells you which metric(s), the current value, and the threshold.
  • Per-card "⚠ High" indicators when a metric is currently over threshold.
  • "Cloud Offline" badge now clickable — links to the subscription page with an explanation of what the connection does.
  • /api/system/metrics/history?range=… endpoint for the trend data.

v2.7.0

Admin Team — Watchlist, Audit Log, Notifications

Closes the gap between what our marketing said we shipped and what you actually saw when you opened the app. All three pillars of the "Admin Power Tools" feature set now have first-class UI.

Added — Watchlist

  • New page at /watchlist — global list of flagged players (cheaters, griefers, staff-watch). Formerly API-only with no interface.
  • Real-time hit alerts — when a watched player joins ANY of your servers, an in-app notification fires (and webhooks go to Discord etc). Matches by SteamID (preferred) or name fallback.
  • Tags with color-coded chipscheater, griefer, staff, vip, banned, or anything you invent. Filter the list by tag.
  • Notes + reason fields — short reason chip for the table, longer admin note for context.
  • Hit tracking — per-entry lifetime hit count and last-seen timestamp, so you can spot which flags are still active.
  • Bulk operations — multi-select + bulk delete for cleanup.
  • Search — debounced search across name, SteamID, reason, note.
  • Updated backend — extended CRUD: GET (with filters), POST, PATCH, DELETE, POST /bulk-delete. Now also writes audit log entries for every add/update/remove.

Added — Audit Log

  • Dedicated page at /audit — was previously buried in a tab inside the Users page.
  • Multi-dimensional filtering — free-text search + user dropdown + action dropdown + from/to date range. All filters combinable.
  • CSV export — one-click export of filtered entries for incident review or compliance. Respects the current filter state.
  • Color-coded actions — destructive (red), moderation (amber), server ops (blue), auth (purple). Read-at-a-glance severity.
  • Pagination — 100 entries per page.
  • /api/audit/actions and /api/audit/users endpoints backing the filter dropdowns.
  • Permission-gatedusers.manage required (admins/owners only).

Added — Notifications history

  • Dedicated page at /notifications — full browsable history that the bell icon in the top bar now links to ("View all notifications →").
  • Toast pop on high-severity arrivals — warning and error notifications automatically surface as toasts (6-10 second duration). Info/success stay silent to avoid chat-spam fatigue.
  • Filters — by severity, server, event type, free text. All combinable.
  • Per-notification delete — surgical cleanup instead of the all-or-nothing "Clear all".
  • Live updates — socket-pushed notifications merge into the view in real time.
  • /api/notifications/unread-count and /api/notifications/facets endpoints for cheaper badge polling and filter dropdowns.

Changed

  • Users page — the former Audit Log tab is replaced by an "Audit Log →" button that navigates to the new dedicated page.
  • Sidebar — added Watchlist and (for admin/owner roles) Audit Log entries.

v2.6.0

Auto-updater, Mod Configs auto-detection, Spawnable Types rework

Added — Auto-updater

  • electron-updater is wired up — Citadel now polls GitHub Releases on launch and every 6 hours. When a new version ships, it downloads silently and shows a "Restart & Install" banner at the top of the app. No more manual re-downloads for customers.
  • Visible update progress — the app-wide banner shows download percent in real time, and falls back to a dismissible red error surface if the updater can't reach GitHub (rare, but caught instead of silently doing nothing).
  • Manifest-driveninstaller/build.js now generates latest.yml alongside CitadelSetup-{version}.exe. Upload both to the GitHub Release and the updater handles the rest.

Added — Mod Configs auto-detection

  • "Auto-detected Configs" section on the Mod Configs page — walks your server's profiles/ directory and surfaces every JSON config file, grouped by mod folder. Works for any mod that writes configs without us having to write a schema manifest.
  • Click-through editor — each detected file opens in the familiar JSON editor with Ctrl+S save, Back button, unsaved-changes guard.
  • Refuses to corrupt — save validates JSON parses before writing; malformed content is blocked with a clear error (you can still hand-edit the raw text to rescue a broken file).
  • Smart exclusionsExpansionMod/ (has its own dedicated editor), BattlEye/, DayZServer/ runtime state, and storage_* persistence folders are skipped automatically.
  • Safety caps — recursive scan is depth-limited to 4 levels and capped at 2,000 files with a visible "truncated" warning if a pathological tree is encountered.
  • Path-traversal hardened — the detected-file endpoint rejects any path outside the resolved profile dir, even if explicitly requested.

Reworked — Spawnable Types editor

  • Parser rewritten on fast-xml-parser — replaces the old hand-rolled regex approach. Preserves every field including <damage> ranges, <hoarder> flags, and preset="1" references on items (previously silently dropped on save — critical data-integrity fix).
  • Preset references (new) — items within attachment/cargo groups can now be toggled between Item (direct class name) and Preset (references an entry in cfgrandompresets.xml). Preset mode shows a searchable autocomplete of available preset names.
  • Side-panel detail view — replaces the accordion expand-row pattern that was unusable with real DayZ configs (500+ types × 15+ nested groups). Click a row, the detail panel slides in; hit Esc to close.
  • Damage range editor — new per-type <damage min max> controls, previously ungraspable through the UI.
  • Column sorting — Name / Hoarder / Attachment count / Cargo count, ascending or descending.
  • Debounced search (180ms) — no more render thrash on each keystroke.
  • 200 items/page (was: 100) — matches the Types editor's pagination for consistent UX across the Economy Editors suite.
  • Dedicated routes for presetsGET /api/servers/:id/spawnabletypes/presets returns summarized presets by kind (cargo/attachments).

Fixed

  • (already in v2.5.1) Files browser editor was blank on click — CSP blocked Monaco from fetching its runtime modules. Fixed both connectSrc and workerSrc directives.

v2.5.1

Hotfix — Files editor

Fixed

  • Files browser editor was blank — clicking a file opened a tab with the correct breadcrumb but the Monaco code editor never rendered. Root cause: the Content-Security-Policy blocked Monaco from fetching its runtime modules (connectSrc missing cdnjs.cloudflare.com) and from spawning its web workers (workerSrc not set). Fixed both directives plus added a visible failure state if the editor ever fails to load again — no more silent blank panes.

v2.5.0

Live Ops Dashboard — Kill Feed, PvP Leaderboard, Chat Log, Player Profiles & Backup Scheduling

Added — Kill Feed & PvP Analytics

  • Live kill feed — Real-time PvP kill stream with weapon, distance, zone, and headshot detection. Socket-based, throttled, filterable by time window
  • Interactive kill map — Every kill plotted on the satellite map with killer/victim positions, color-coded by weapon class, click for details
  • Per-wipe PvP leaderboard — Persistent leaderboard per server tracking kills, headshots, longest shot, K/D ratio, favorite weapons. Auto-resets when Dangerzone wipes the server
  • PvP analytics tab — Top weapons bar chart, kill-hour histogram, distance distribution (0-50m / 50-100m / 100-200m / 200-400m / 400-800m / 800m+), top-3 killer side-by-side comparison
  • /api/servers/:id/pvp/* endpoints — Leaderboard, stats, per-player stats, recent kills, and admin reset
  • BarChart component — Canvas-based horizontal bar chart added to the frontend component library, zero chart-library dependencies

Added — Chat Log Viewer

  • Searchable chat archive — Channel-color-coded messages with full-text search, player filter, channel filter, debounced queries
  • Live feed mode — Socket-driven real-time chat with pause/resume control; preserves your filter state across pauses
  • CSV export — Download filtered chat history as CSV. Respects active filters. Streams server-side for large archives
  • Channel badges — Direct, global, vehicle, radio, transmit, admin each rendered with distinct color-mix badges

Added — Player Profiles & History

  • Persistent cross-wipe profiles — Every player gets a profile that persists across server wipes. Unlike PvP stats (which wipe), profiles accumulate forever
  • Session tracking — Automatic session open/close via roster-diff. Tracks totalSessions, totalPlayMs, full session history with start/end/duration
  • Alias tracking — Captures every name a player has used. "Also known as" on the profile header. Search matches any past alias
  • Lifetime stats — Kills, deaths, headshots, K/D, headshot %, first seen, last seen, IPs observed (capped at 5)
  • Chat history per player — Last 100 messages with channel and timestamp, filterable in-place
  • Event timeline — Last 150 events (connects, disconnects, chats, kills, deaths, suicides) with icon-coded rows and inline detail
  • Admin notes — Per-player notes with author, timestamp, and deletion audit. Persistent, visible to all admins. Ctrl/⌘+Enter to save
  • Player history search modal — Search every known player (including offline) on the Players page. Results show online badge, notes count, aliases, sessions, play time, K/D
  • Player name link-through — Clicking a name in the live Players list or anywhere else opens the full profile at /servers/:id/players/:steamId
  • /api/servers/:id/players/search, /profile, /notes endpoints — Full REST API for profile access and note CRUD

Added — Backup Scheduling UI

  • Dedicated Backups page — Backups get their own route (/servers/:id/backups) and sidebar entry, not buried in settings
  • Frequency presets — 15min / 30min / 1h / 2h / 6h / 12h / 24h plus Custom for everything else
  • Retention by days — Automatic pruning when backup age exceeds configured maxKeepDays
  • Backup-on-startup option — Automatically snapshot before every server boot
  • Path editor — Add/remove directories with Enter-key shortcut, wildcard support, chip-style UI
  • Backup list — Filter by manual / automated / all, with download, restore, delete, and preview actions
  • Preview modal — Inspect archive contents without extracting, showing path tree and file sizes

Added — Admin Power Tools (previously shipped, newly surfaced)

  • Audit Log — Every admin action recorded: who, when, what. Now documented and promoted on the marketing site
  • Webhooks & Discord — Outbound webhooks on player join, ban, wipe, restart, and custom events
  • Priority Queue — VIP slot reservations with time-limited grants and role tiers (already shipped in v2.4.0, now properly revealed)
  • System Dashboard — Host CPU/RAM/disk/process monitoring for admin teams

Changed — Citadel socket event pipeline

  • Unified event dispatcherbridge.on('events') now fans out to both pvp-stats and player-profiles stores in a single try/catch. Previously only pvp-stats was hooked
  • Roster-diff sessionsbridge.on('players') now drives player-profiles.syncRoster() to open/close sessions based on presence, without depending on mod-emitted connect/disconnect events (works regardless of mod event schema)

Changed — Marketing site

  • Quest Creator-first positioning — Homepage now leads with "Build quests. Run empires." Dedicated Quest Studio spotlight section just below the hero with all 10 Expansion objective types called out
  • New "Live Ops Dashboard" section — Features the v2.5.0 work (kill feed, leaderboard, chat log, profiles, backups, live map)
  • New "Admin Power Tools" section — Reveals audit log, webhooks, priority queue, and system dashboard as a first-class capability category
  • Pricing checklist expanded — From 14 items to 22, grouped into Flagship / Live Ops / Editors / Mod Configs / Admin / Core
  • Legal cleanup — Privacy and Terms pages updated to reflect post-pivot reality (email+password auth, Paddle as MoR, local-only data)

v2.4.0

Priority Queue, Config Editor Expansion & Ban Kick Messages

Added — Priority Queue (VIP System)

  • Automated priority.txt sync — Adding or removing a VIP entry instantly updates every server's priority.txt file. DayZ reads the file live since 1.13 — no restart needed
  • Time-limited VIP — Set expiration with presets (30 days, 90 days, 1 year, permanent) or a custom date. Expired entries are auto-cleaned every 60 seconds
  • Role tiers — Entries categorized as VIP, Supporter, or Premium with color-coded badges
  • Priority Queue management page — Full CRUD UI with search, expiration countdown display, add/edit modals, import/export, and expired entry cleanup
  • 8 API endpoints — Complete REST API for priority queue management (GET/POST/PATCH/DELETE /api/priority-queue, export, import, cleanup)
  • Server lifecycle sync — Priority queue re-synced to priority.txt on every server start, restart, and external process detection
  • Moderator accesspriority.manage permission added to the built-in moderator role

Added — Ban Kick Messages

  • Configurable kick message — Customize the message shown to banned players with {reason} and {banId} placeholders
  • Appeal URL — Set a Discord invite or appeal URL that replaces "our Discord" in the default kick message
  • Settings UI — New "Ban Settings" section in the Settings page for configuring kick message and appeal URL
  • Environment variablesBAN_KICK_MESSAGE and BAN_APPEAL_URL for configuration via .env

Changed — Config Editor

  • 49 fields across 7 sections — Expanded from 12 flat fields to 49 organized fields: Server Identity, Gameplay, Time & Environment, Voice & Communication, Network & Performance, Persistence & Base Building, Logging
  • Bug fix — Corrected disableThirdPerson to disable3rdPerson (the actual serverDZ.cfg key name)
  • Popular additionsenableCfgGameplayFile, logAverageFps, logMemory, logPlayers, adminLogPlayerHitsOnly, adminLogPlacement, adminLogBuildActions, simulatedPlayersBatch, multithreadedReplication, storageAutoFix, and many more

v2.3.0

Performance Audit, QoL Feature Pipeline & Discord Bot Expansion

Performance

  • 34-item performance audit — Comprehensive codebase audit with all findings resolved
  • Eliminated blocking I/O — Replaced fs.readFileSync/fs.writeFileSync with async equivalents across sidecar, backend, and mod manager
  • Socket.IO room scoping — All server-scoped events now broadcast to per-server rooms instead of global emits
  • Memory leak fixes — Proper cleanup of RCON listeners, polling intervals, and event handlers on server removal
  • Debounced file watchers — RPT tailer and sidecar watchers debounced to prevent CPU spikes on rapid file changes
  • Lazy module loading — Heavy modules loaded on demand instead of at startup
  • Connection pooling — Sidecar HTTP requests reuse persistent agents

Added — Player Actions

  • Unstuck — Teleport stuck players to the terrain surface (mod + sidecar + backend + frontend + Discord)
  • Freeze/Unfreeze — Lock a player in place or release them (mod + sidecar + backend + frontend + Discord)
  • Message Player — Send a direct in-game message to a specific player (mod + sidecar + backend + frontend + Discord)
  • Teleport to Player — Teleport one player to another player's location (mod + sidecar + backend + frontend)
  • View Loadout — Inspect a player's full inventory with item class, quantity, and health percentage (mod + sidecar + backend + frontend)

Added — Vehicle & Config Actions

  • Vehicle Teleport — Teleport a vehicle to specific world coordinates (mod + sidecar + backend)
  • Config Reload — Live reload of mod configuration without server restart (mod + sidecar + backend)

Added — Discord Bot

  • 5 new slash commands/unstuck, /freeze, /strip, /explode, /dm for direct admin actions
  • Expanded admin panel — 9 admin action buttons across 2 rows (was 4 in 1 row): Heal, Unstuck, Spawn Item, Teleport, Message, Freeze, Strip Gear, Kill, Explode
  • Message player modal — Discord modal for composing direct messages to players from the panel
  • 5 new backend action handlersactionUnstuck, actionFreeze, actionStrip, actionExplode, actionMessage in discord.routes.js

Added — DayZ Mod (@CitadelAdmin)

  • UnstuckPlayer action — Finds terrain surface height and teleports player above it
  • FreezePlayer action — Sets player movement speed multiplier to 0 (freeze) or restores it (unfreeze)
  • TeleportToPlayer action — Resolves target player by Steam ID and teleports source to their position
  • GetLoadout action — Serializes full player inventory (clothing, attachments, cargo) as JSON response
  • MessagePlayer action — Sends an in-game notification message to a specific player
  • TeleportVehicle action — Moves a vehicle to specified world coordinates
  • ReloadConfig action — Re-reads mod configuration files at runtime

Changed

  • Frontend PlayersPage — Player action dropdown reorganized into sections: Helpful (Heal, Unstuck, Spawn, Message), Info (View Loadout, Teleport To Player), Moderation (Freeze, Unfreeze, Strip, Kick), Dangerous (Explode, Kill, Ban)
  • ActionType constants — New frozen enum entries for all added actions with capability sets, labels, audit codes, and route maps
  • Discord bot architecture — 31-file structure (was 26) with expanded button dispatch map (40 handlers)

v2.2.1

Messenger Templates, Deployment Fixes & Scheduler Reliability

Added

  • Messenger templates — 14 pre-built broadcast message templates across 4 categories (Welcome, Rules, Community, Gameplay) with one-click creation
  • Template picker modal — Category-filtered template browser with message preview, interval, and delay settings (same pattern as webhook templates)
  • mpmissions scaffoldingmpmissions/ and map-specific subfolder (mpmissions/dayzOffline.<map>/) now created during deployment and rebuild

Fixed

  • Experimental branch app ID — Fixed SteamCMD downloading the DayZ client (1024020) instead of the experimental dedicated server (1042420). Affected deploy, rebuild, and auto-update
  • Scheduler restart reliability — Replaced unreliable RCON #restart with full process lifecycle (restartServer() from server-lifecycle.js) for scheduled restarts, stops, and starts
  • Scheduler status gate — Scheduler jobs now process regardless of server status (required for start actions to fire when server is stopped)
  • Scheduler RCON gate — Only pre-action steps (warnings, lock, kick) require RCON; action execution works regardless of RCON availability

v2.2.0

Discord Bot Enterprise Overhaul

Architecture

  • Modular rewrite — Refactored 1,518-line monolithic bot.js into 26 files across a clean module structure (commands/, handlers/, ui/, utils/)
  • Auto-loading commands — Command files auto-discovered and registered via commands/index.js
  • Button dispatch map — 35 button handlers use object lookup instead of if/else chain
  • Shared server lifecyclestartServer() and stopServer() extracted into server-lifecycle.js, used by both web panel and Discord bot (includes port checks, firewall rules, lifecycle hooks, sidecar/tailer management, notifications, webhooks)

Added

  • 5 new slash commands/playerinfo, /heal, /kill, /teleport, /spawnitem for admin actions directly from Discord
  • Per-user cooldown system — Three tiers: query (3s), admin (10s), control (30s) preventing spam
  • Input validation — Steam64 ID format checking, coordinate validation, workshop ID validation, broadcast message sanitization
  • Markdown escaping — Player names in embeds escaped to prevent Discord formatting exploits
  • Audit trail attribution — Every Discord action (start, stop, kick, RCON, mod operations, admin actions) logged with Discord username and user ID
  • Webhook integration — Kick, mod install/uninstall, and all lifecycle actions now fire webhooks from Discord
  • Multi-server presence — Bot status rotates through all servers showing aggregate player count
  • Modal builders — Dedicated modal constructors for broadcast, RCON, player info, kick, teleport, spawn item, mod install, mod actions

Fixed

  • Events.ClientReady — Bot was silently failing to register the ready handler (was using string 'clientReady' instead of Events.ClientReady enum)
  • Interaction deferral — All API calls now properly deferReply()/deferUpdate() before processing, preventing 3-second timeout failures
  • "undefined" responses — All handlers now fallback to 'Action completed' instead of showing undefined
  • Discord lifecycle bypass — Start/stop/restart from Discord now uses the same lifecycle as the web panel (was missing hooks, sidecar, firewall, port checks, notifications)

Security

  • Discord input sanitizationsanitize.js validates all user inputs before they reach the backend
  • Broadcast sanitization — Control characters stripped, message length capped at 256 characters
  • Cooldown enforcement — Rate limiting prevents rapid-fire abuse of admin commands
  • Fail-closed admin check — All admin commands verify role before processing

Changed

  • server-control.routes.js — Simplified start/stop routes to delegate to shared startServer()/stopServer() from server-lifecycle.js
  • discord.routes.js — Rewritten to use shared lifecycle functions, add audit logging on all mutating actions, consume Discord user attribution params

Removed

  • Deprecated action aliases — Legacy action aliases removed from discord.routes.js

v2.1.0

Security Hardening, Console Overhaul, and Live Map Enhancements

Added

  • Rich console — Real-time RPT log streaming via rpt-tailer.js, unified with RCON output
  • Live map actions — Teleport, heal, kill, strip, explode players; vehicle actions; world controls (time, weather, AI/vehicle wipe); spawn items at coordinates
  • Live map markers — Font Awesome icons for players, vehicles, and map events
  • Windows Firewall management — Automatic inbound allow rules for game/query/RCON ports with UAC elevation
  • Windows Service — Install Citadel as a CitadelServer Windows Service for auto-start on boot
  • Setup wizard — Guided 5-step first-run setup (admin account, SteamCMD, server profile)
  • Mod cache — Downloaded mods cached locally to speed up reinstalls across servers
  • Automated messenger — Scheduled broadcast messages to players via RCON
  • Concurrent restart guard — Prevents duplicate restart operations on the same server
  • Vehicle health display — Normalized 0-100% health bar on live map vehicle markers
  • @CitadelAdmin auto-install — Server-side mod automatically deployed on server start

Security

  • Server-scoped authorization — All map and dangerzone routes now use authForServer() instead of auth()
  • RCON password stripping — Server API responses no longer include rconPassword
  • XSS prevention — HTML escaping on player names in Leaflet map markers
  • Mass-assignment protection — Mod PATCH endpoint restricted to allowlisted fields only
  • PowerShell injection defense — Server names sanitized before use in firewall rule commands
  • Spawn quantity cap — Item spawn limited to max 100 in both DayZ mod and sidecar
  • RCON message isolationserverId added to RCON events to prevent cross-server contamination
  • Targeted player messagingMessagePlayer uses RPCSingleParam instead of broadcast ChatPlayer

Fixed

  • Batch startspawnDayZServer() return value correctly destructured (was storing object as PID)
  • Server deletion cleanup — Properly stops sidecar, RPT tailer, and RCON on server removal
  • Mod folder names — Spaces in mod folder names no longer break DayZ -mod= launch parameter
  • Firewall elevation — Firewall rule creation now uses elevated PowerShell via Start-Process -Verb RunAs
  • HealPlayer params — Standardized to use ExtractParams pattern matching other actions

Changed

  • Console page streams RPT log lines in real-time (previously only showed lifecycle events)
  • Logs page updates in real-time via Socket.IO (previously required page refresh)
  • README and documentation updated with admin requirements, Windows Service setup, and current features

v2.0.0

Citadel — Complete Platform Rebuild

Breaking Changes

  • Rebranded from "DayZ Server Controller" / "DSC" to Citadel
  • Replaced all third-party API dependencies with the self-hosted InHouseProvider system
  • New @CitadelAdmin DayZ mod replaces @DSCAdmin

Added

  • InHouseProvider — Full-featured action provider routing through the Citadel Sidecar
  • Citadel Sidecar — Standalone Node.js server bridging backend API to DayZ server via file-based IPC
  • @CitadelAdmin DayZ Mod — Server-side EnScript mod with:
    • Command runner (file-based command queue)
    • Player tracker (periodic player snapshots)
    • Event logger (kills, connections, vehicles)
    • Player actions (heal, teleport, spawn, strip, explode)
    • Vehicle actions (delete, repair, refuel, unstuck, explode, engine kill, eject)
    • World actions (time, weather, AI wipe, vehicle wipe)
  • Provider System — Modular action dispatcher with capability reporting
  • Game file backups — Automated and manual server file backups with retention policies
  • Live map — Real-time player positions on the map
  • Role-based access control — Granular permissions system
  • Multi-server management — Control multiple DayZ instances from one dashboard
  • VitePress documentation site — Comprehensive docs with guides and API reference

Changed

  • Complete UI rebrand with Citadel shield logo and indigo/sky-blue color scheme
  • PM2 process names standardized to citadel and citadel-bot
  • All file paths use $profile:Citadel/ directory
  • Config files reference Citadel branding throughout

Removed

  • All external third-party API dependencies for core functionality