panel public release
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# panel-native DayZ runtime image.
|
||||
#
|
||||
# DayZ ships a native Linux binary (SteamCMD app 223350). No Wine. The
|
||||
# binary is a static-ish x86_64 ELF that pulls in the usual i386 pile
|
||||
# (steamclient.so is 32-bit) + a couple of Bohemia's own shared libs
|
||||
# that live under <install>/.
|
||||
#
|
||||
# Expected runtime layout inside the container:
|
||||
# /game — SteamCMD-installed DayZ Server
|
||||
# /game/DayZServer — server binary (Bohemia's launcher wrapper)
|
||||
# /game/serverDZ.cfg — primary config file (symlinked to /game-saves)
|
||||
# /game/battleye/ — BattlEye config + beserver.cfg (RCON port + pw)
|
||||
# /game/profiles — logs, bans, RPT crash dumps (symlinked to /game-saves)
|
||||
# /game-saves/ — operator data volume (configs, profiles, world DB)
|
||||
|
||||
FROM debian:12-slim
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
TZ=Etc/UTC \
|
||||
LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8
|
||||
|
||||
RUN dpkg --add-architecture i386 \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
locales \
|
||||
tini \
|
||||
curl \
|
||||
lib32gcc-s1 \
|
||||
lib32stdc++6 \
|
||||
libc6:i386 \
|
||||
libcurl4 \
|
||||
libxml2 \
|
||||
procps \
|
||||
&& sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
|
||||
&& locale-gen \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN groupadd -g 1000 panel \
|
||||
&& useradd -u 1000 -g 1000 -m -s /bin/bash panel \
|
||||
&& mkdir -p /game /game-saves \
|
||||
&& chown -R panel:panel /game /game-saves
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 2302/udp 2303/udp 2304/udp 2305/udp
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "--", "/entrypoint.sh"]
|
||||
@@ -0,0 +1,82 @@
|
||||
# DayZ — panel-native module
|
||||
|
||||
Panel-native DayZ dedicated server, native-Linux (no Wine). Steam app 223350.
|
||||
|
||||
## The Steam-login gotcha
|
||||
|
||||
**DayZ is paid content.** SteamCMD refuses `+login anonymous` with `No subscription`. The manifest sets `requires_steam_login: true` on the update provider, which tells the controller to gate install/update behind the Steam-login modal. Flow:
|
||||
|
||||
1. Create a DayZ instance in the panel. Auto-update is intentionally skipped (agent sees `requires_steam_login` on the provider and doesn't kick off the first Update).
|
||||
2. Click **Update** on the instance.
|
||||
3. Panel returns `{steam_login_required: true}` and the browser pops a login modal.
|
||||
4. Enter your Steam username + password. If Steam Guard is enabled on your account, also enter the 5-char code from your email / Steam Mobile app.
|
||||
5. Panel runs a one-shot `docker run steamcmd/steamcmd +login <user> <pass>` to verify, stores the password encrypted (AES-GCM, key HKDF-derived from the panel's CA private key), and caches the SSFN sentry file in a panel-wide volume (`panel-steamcmd-auth`) so future updates skip Steam Guard.
|
||||
6. Retry Update — panel injects creds into the SteamCMD sidecar and downloads ~5 GB of DayZ server files.
|
||||
|
||||
Your Steam account must own the DayZ base game (app 221100). The dedicated-server app itself (223350) is a free tool; ownership of the base game is what grants download rights.
|
||||
|
||||
## Image + runtime
|
||||
|
||||
- `panel-dayz:latest` — debian:12-slim, 32-bit runtime libs (`libc6:i386`, `lib32gcc-s1`, `lib32stdc++6`) for `steamclient.so`, plus `libcurl4`/`libxml2`. No Wine.
|
||||
- Binary: `/game/DayZServer` (ELF64, native).
|
||||
- Config: `/game-saves/serverDZ.cfg` (symlinked to `/game/serverDZ.cfg`).
|
||||
- Profiles (logs, bans, RPTs): `/game-saves/profiles/` (symlinked to `/game/profiles`).
|
||||
- BattlEye config: `/game/battleye/beserver_x64.cfg` (port + password written on first boot from `BE_PASSWORD` env var).
|
||||
|
||||
## RCON — BattlEye protocol
|
||||
|
||||
DayZ uses BattlEye's proprietary UDP RCON, not Source RCON. The panel's `be_rcon` adapter handles:
|
||||
|
||||
- Login handshake (password auth → single-byte success/fail)
|
||||
- Sequenced commands with per-seq ack tracking
|
||||
- Multi-part response reassembly for long outputs (`players` on busy servers)
|
||||
- Server-pushed events (chat/join/leave) ack'd automatically
|
||||
- 30-second keep-alive ping (BE disconnects idle clients after ~45s)
|
||||
|
||||
Commands wired:
|
||||
|
||||
- `list` → `players`
|
||||
- `broadcast {msg}` → `say -1 {msg}`
|
||||
- `kick {player}` → `kick {player}`
|
||||
- `ban {player}` → `ban {player}`
|
||||
- `shutdown` → `#shutdown`
|
||||
|
||||
## Ports
|
||||
|
||||
| Port | Proto | Purpose |
|
||||
|------|-------|---------|
|
||||
| 2302 | UDP | Game + Steam query (same port — Bohemia convention) |
|
||||
| 2303 | UDP | Additional instance offset (+1) |
|
||||
| 2304 | UDP | Additional instance offset (+2) |
|
||||
| 2305 | UDP | Additional instance offset (+3) |
|
||||
| 2310 | UDP | BattlEye RCON (internal) |
|
||||
|
||||
## Environment vars
|
||||
|
||||
| Var | Default | Notes |
|
||||
|-----|---------|-------|
|
||||
| `SERVER_NAME` | `panel DayZ` | Shown in the DayZ server browser |
|
||||
| `SERVER_PORT` | `2302` | Game + Steam-query UDP port |
|
||||
| `SERVER_PASSWORD` | *(empty)* | Optional client join password |
|
||||
| `BE_PASSWORD` | `panel_be` | BattlEye RCON admin password (edit before exposing) |
|
||||
| `CPU_COUNT` | `2` | `-cpuCount=` arg to the server binary |
|
||||
|
||||
## Log events
|
||||
|
||||
- **Join:** `Player "<name>" is connected`
|
||||
- **Leave:** `Player "<name>" disconnected`
|
||||
- **Chat:** `Chat("<name>"): <msg>`
|
||||
|
||||
## Known gotchas
|
||||
|
||||
- **Steam credentials are a one-time ceremony per panel.** Once stored, the cached SSFN blob means subsequent updates don't re-prompt. If Steam invalidates your session (machine change, long inactivity), the modal will pop again with `{need_guard: true}` — enter a fresh code.
|
||||
- **BattlEye RCON port collides by convention.** 2310 is our default; if you run multiple DayZ instances on the same host, bump via the panel's Network Ports editor.
|
||||
- **Modded servers need `@<ModName>` in the launch command.** The entrypoint doesn't wire this yet — drop mod pbos into `/game/` and add `-mod=@<ModName>` via a manual launcher edit (or wait for a follow-up that exposes `EXTRA_ARGS` as an env var).
|
||||
- **`steamQueryPort` must equal the game port** in `serverDZ.cfg` or DayZ refuses to register with Steam's master server. Our seeded config follows this.
|
||||
- **BattlEye can kick you for "kick #0 CreateVehicle Restriction..."** type messages on vanilla — these are server-side integrity checks. Tune `verifySignatures` and the `battleye/bans.txt` / `permissions.txt` files via the Files tab.
|
||||
|
||||
## References
|
||||
|
||||
- [Bohemia Interactive: Hosting a Linux Server (DayZ)](https://community.bistudio.com/wiki/DayZ:Hosting_a_Linux_Server)
|
||||
- [BattlEye RCON Protocol](https://www.battleye.com/downloads/BERConProtocol.txt)
|
||||
- [Steam — DayZ Server (app 223350)](https://steamdb.info/app/223350/)
|
||||
@@ -0,0 +1,204 @@
|
||||
#!/bin/bash
|
||||
# panel-native DayZ entrypoint.
|
||||
#
|
||||
# Contract:
|
||||
# /game — SteamCMD-installed DayZ Server (app 223350). Populated
|
||||
# by the panel's SteamCMD updater sidecar, which uses the
|
||||
# operator-supplied Steam credentials (the module manifest
|
||||
# sets requires_steam_login: true).
|
||||
# /game-saves — serverDZ.cfg + profiles/ (logs, bans, RPTs) + optional
|
||||
# mpmissions/ override tree.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
log() { printf '[panel-dayz] %s\n' "$*"; }
|
||||
|
||||
# ----- stage 1: root-only bootstrap -----
|
||||
if [[ "$(id -u)" = "0" ]]; then
|
||||
chown -R panel:panel /game /game-saves /home/panel 2>/dev/null || true
|
||||
log "dropping privileges to panel (UID 1000)"
|
||||
exec setpriv --reuid=panel --regid=panel --clear-groups \
|
||||
--inh-caps=-all --bounding-set=-all \
|
||||
env \
|
||||
HOME=/home/panel \
|
||||
SERVER_NAME="${SERVER_NAME:-panel DayZ}" \
|
||||
SERVER_PORT="${SERVER_PORT:-2302}" \
|
||||
SERVER_PASSWORD="${SERVER_PASSWORD:-}" \
|
||||
BE_PASSWORD="${BE_PASSWORD:-panel_be}" \
|
||||
CPU_COUNT="${CPU_COUNT:-2}" \
|
||||
LD_LIBRARY_PATH="/game:${LD_LIBRARY_PATH:-}" \
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
/entrypoint.sh "$@"
|
||||
fi
|
||||
|
||||
GAME_DIR=/game
|
||||
SAVE_DIR=/game-saves
|
||||
DEDI_EXE="${GAME_DIR}/DayZServer"
|
||||
|
||||
if [[ ! -x "${DEDI_EXE}" ]]; then
|
||||
log "ERROR: ${DEDI_EXE} not found or not executable."
|
||||
log " Run 'Update' on this server in the panel — the modal will"
|
||||
log " prompt for Steam credentials (DayZ is paid content; the"
|
||||
log " anonymous SteamCMD login won't work)."
|
||||
exit 78 # EX_CONFIG
|
||||
fi
|
||||
|
||||
# --- persist profiles into /game-saves ---
|
||||
# DayZ writes RPT crash logs, ADM admin logs, and BattlEye bans to
|
||||
# <install>/profiles/. Move out to the save volume + symlink back on
|
||||
# first boot so SteamCMD validate can't wipe them.
|
||||
mkdir -p "${SAVE_DIR}/profiles"
|
||||
if [[ -d "${GAME_DIR}/profiles" && ! -L "${GAME_DIR}/profiles" ]]; then
|
||||
mv "${GAME_DIR}/profiles"/* "${SAVE_DIR}/profiles/" 2>/dev/null || true
|
||||
rm -rf "${GAME_DIR}/profiles"
|
||||
fi
|
||||
ln -sfn "${SAVE_DIR}/profiles" "${GAME_DIR}/profiles"
|
||||
|
||||
# --- seed serverDZ.cfg on first boot ---
|
||||
CFG="${SAVE_DIR}/serverDZ.cfg"
|
||||
if [[ ! -s "${CFG}" ]]; then
|
||||
log "seeding serverDZ.cfg (first boot)"
|
||||
cat > "${CFG}" <<EOF
|
||||
hostname = "${SERVER_NAME}";
|
||||
password = "${SERVER_PASSWORD}";
|
||||
passwordAdmin = "";
|
||||
enableWhitelist = 0;
|
||||
disableVoN = 0;
|
||||
vonCodecQuality = 7;
|
||||
disable3rdPerson = 0;
|
||||
disableCrosshair = 0;
|
||||
serverTime = "SystemTime";
|
||||
serverTimeAcceleration = 12;
|
||||
serverNightTimeAcceleration = 1;
|
||||
serverTimePersistent = 0;
|
||||
guaranteedUpdates = 1;
|
||||
loginQueueConcurrentPlayers = 5;
|
||||
loginQueueMaxPlayers = 500;
|
||||
instanceId = 1;
|
||||
storageAutoFix = 1;
|
||||
verifySignatures = 2;
|
||||
forceSameBuild = 1;
|
||||
timeStampFormat = "Short";
|
||||
logAverageFps = 1;
|
||||
logMemory = 1;
|
||||
logPlayers = 1;
|
||||
logFile = "server_console.log";
|
||||
adminLogPlayerHitsOnly = 0;
|
||||
adminLogPlacement = 1;
|
||||
adminLogBuildActions = 1;
|
||||
adminLogPlayerList = 1;
|
||||
disableBanlist = 0;
|
||||
BattlEye = 1;
|
||||
respawnTime = 5;
|
||||
steamQueryPort = ${SERVER_PORT};
|
||||
maxPing = 200;
|
||||
MissionTemplate = "dayzOffline.chernarusplus";
|
||||
class Missions
|
||||
{
|
||||
class DayZ
|
||||
{
|
||||
template = "dayzOffline.chernarusplus";
|
||||
};
|
||||
};
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Point /game/serverDZ.cfg at the save-volume copy so the binary's default
|
||||
# relative-path lookup finds it.
|
||||
ln -sf "${CFG}" "${GAME_DIR}/serverDZ.cfg"
|
||||
|
||||
# --- BattlEye RCON config ---
|
||||
# DayZ ships a `battleye/` dir that contains a NESTED `battleye/` subdir with
|
||||
# a duplicate `beserver_x64.so`. The DayZ launcher (`-BEpath=battleye`) loads
|
||||
# BE from there and expects `beserver_x64.cfg` to sit alongside the nested
|
||||
# lib — i.e. `battleye/battleye/beserver_x64.cfg`, NOT `battleye/beserver_x64.cfg`.
|
||||
# Writing to the outer dir (which is what most tutorials show) results in BE
|
||||
# initializing but never binding the RCON port, with no error in the log.
|
||||
#
|
||||
# We unconditionally overwrite both locations so operator env changes take
|
||||
# effect on the next boot. We also purge stale `beserver_x64_active_<token>.cfg`
|
||||
# files BE writes after first handshake — if the password has changed, the
|
||||
# active copy will mismatch and BE refuses incoming RCON packets.
|
||||
#
|
||||
# Reference: AMP's dayz-experimental.kvp uses `{{$FullBaseDir}}battleye` as
|
||||
# the BE path and their PreStartStages purge the active file the same way.
|
||||
BE_DIR="${GAME_DIR}/battleye"
|
||||
for CFGPATH in "${BE_DIR}/beserver_x64.cfg" "${BE_DIR}/battleye/beserver_x64.cfg"; do
|
||||
if [[ -d "$(dirname "${CFGPATH}")" ]]; then
|
||||
log "writing ${CFGPATH} (RCON port 2305, pw from BE_PASSWORD)"
|
||||
cat > "${CFGPATH}" <<EOF
|
||||
RConPassword ${BE_PASSWORD}
|
||||
RConPort 2305
|
||||
RConIP 0.0.0.0
|
||||
RestrictRCon 0
|
||||
RConLog 1
|
||||
UseLocationsToBan 0
|
||||
LogFile 0
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
# Purge stale active-session files (both locations).
|
||||
rm -f "${BE_DIR}/beserver_x64_active_"*.cfg 2>/dev/null || true
|
||||
rm -f "${BE_DIR}/battleye/beserver_x64_active_"*.cfg 2>/dev/null || true
|
||||
|
||||
cd "${GAME_DIR}"
|
||||
log "starting DayZ dedicated server"
|
||||
log " name: ${SERVER_NAME}"
|
||||
log " game port: ${SERVER_PORT}/udp"
|
||||
log " rcon port: 2305/udp (internal, BattlEye)"
|
||||
log " cfg: ${CFG}"
|
||||
|
||||
trap 'log "SIGTERM received"; kill -TERM "${DZ_PID:-0}" 2>/dev/null || true; wait "${DZ_PID:-0}" 2>/dev/null || true; exit 0' TERM INT
|
||||
|
||||
# --- mod list dynamic build ---
|
||||
# Panel's mod manager maintains two plain-text files on the save volume:
|
||||
# /game-saves/panel-mods.txt — one @ModFolder per line → -mod=
|
||||
# /game-saves/panel-servermods.txt — one @ModFolder per line → -servermod=
|
||||
# Blank lines and lines starting with '#' are ignored. This lets the mod
|
||||
# manager edit a human-readable file and have the server pick up the new
|
||||
# load order on the next start without entrypoint code changes.
|
||||
build_mod_arg() {
|
||||
local file="$1" prefix="$2"
|
||||
[[ -s "$file" ]] || { echo ""; return; }
|
||||
local joined=""
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
line="${line%$'\r'}" # strip trailing CR (Windows edits)
|
||||
line="${line#"${line%%[![:space:]]*}"}" # ltrim
|
||||
line="${line%"${line##*[![:space:]]}"}" # rtrim
|
||||
[[ -z "$line" || "$line" == \#* ]] && continue
|
||||
if [[ -z "$joined" ]]; then joined="$line"
|
||||
else joined="${joined};${line}"
|
||||
fi
|
||||
done < "$file"
|
||||
if [[ -n "$joined" ]]; then
|
||||
echo "${prefix}${joined}"
|
||||
fi
|
||||
}
|
||||
MOD_ARG="$(build_mod_arg "${SAVE_DIR}/panel-mods.txt" '-mod=')"
|
||||
SERVERMOD_ARG="$(build_mod_arg "${SAVE_DIR}/panel-servermods.txt" '-servermod=')"
|
||||
[[ -n "${MOD_ARG}" ]] && log "loading mods: ${MOD_ARG}"
|
||||
[[ -n "${SERVERMOD_ARG}" ]] && log "loading server-mods: ${SERVERMOD_ARG}"
|
||||
|
||||
# DayZ's documented launch command:
|
||||
# ./DayZServer -config=serverDZ.cfg -port=2302 -BEpath=battleye \
|
||||
# -profiles=profiles -dologs -adminlog -netlog \
|
||||
# -freezecheck -doScriptLogs -cpuCount=2
|
||||
# [-mod=@A;@B] [-servermod=@X]
|
||||
DZ_ARGS=(
|
||||
-config=serverDZ.cfg
|
||||
-port="${SERVER_PORT}"
|
||||
"-BEpath=${GAME_DIR}/battleye"
|
||||
-profiles=profiles
|
||||
-dologs
|
||||
-adminlog
|
||||
-netlog
|
||||
-freezecheck
|
||||
-doScriptLogs
|
||||
"-cpuCount=${CPU_COUNT}"
|
||||
)
|
||||
[[ -n "${MOD_ARG}" ]] && DZ_ARGS+=("${MOD_ARG}")
|
||||
[[ -n "${SERVERMOD_ARG}" ]] && DZ_ARGS+=("${SERVERMOD_ARG}")
|
||||
|
||||
exec stdbuf -oL -eL "${DEDI_EXE}" "${DZ_ARGS[@]}" &
|
||||
DZ_PID=$!
|
||||
wait "${DZ_PID}"
|
||||
@@ -0,0 +1,144 @@
|
||||
# DayZ dedicated server module.
|
||||
#
|
||||
# Native-Linux binary via SteamCMD app 223350 ("DayZ Server"). App is
|
||||
# paid content — SteamCMD refuses `+login anonymous` with
|
||||
# "No subscription". We set `requires_steam_login: true` which makes the
|
||||
# controller gate updates behind the Steam-login modal; operators sign in
|
||||
# once with a Steam account that owns DayZ (base game app 221100 — NOT
|
||||
# the dedicated-server app itself — grants download entitlement).
|
||||
#
|
||||
# RCON is BattlEye's proprietary UDP protocol, not Source or WebSocket.
|
||||
# The panel's new `be_rcon` adapter speaks it natively (MD5-challenge
|
||||
# login, sequenced commands with ack packets, keep-alive pings).
|
||||
#
|
||||
# References:
|
||||
# https://community.bistudio.com/wiki/DayZ:Hosting_a_Linux_Server
|
||||
# https://www.battleye.com/downloads/BERConProtocol.txt
|
||||
|
||||
id: dayz
|
||||
name: "DayZ"
|
||||
version: 0.1.0
|
||||
authors:
|
||||
- panel contributors
|
||||
|
||||
supported_modes:
|
||||
- docker
|
||||
|
||||
runtime:
|
||||
docker:
|
||||
# Built locally from ./Dockerfile. Rebuild with:
|
||||
# docker build -t panel-dayz:latest modules/dayz
|
||||
image: panel-dayz:latest
|
||||
# Host networking -- container shares the host net namespace, so
|
||||
# any port the game/mod binds is directly on the LAN. AMP-like
|
||||
# model. Multi-instance safety comes from env-driven per-instance
|
||||
# ports (panel allocator + env: mapping on each ports entry).
|
||||
network_mode: host
|
||||
browseable_root: /game-saves
|
||||
browseable_roots:
|
||||
- name: "Saves & Configs"
|
||||
path: /game-saves
|
||||
hint: "serverDZ.cfg + profiles/ (logs, bans, RPTs) + mpmissions/ world state"
|
||||
- name: "Game Files"
|
||||
path: /game
|
||||
hint: "DayZServer binary + core keys/, shipped mpmissions, BattlEye/"
|
||||
env:
|
||||
SERVER_NAME: "panel DayZ"
|
||||
SERVER_PORT: "2302"
|
||||
BE_PASSWORD: "panel_be" # BattlEye RCON admin password
|
||||
SERVER_PASSWORD: "" # optional client join password
|
||||
CPU_COUNT: "2" # -cpuCount= for the server binary
|
||||
volumes:
|
||||
- { type: volume, name: "panel-$INSTANCE_ID-saves", container: "/game-saves" }
|
||||
- { type: volume, name: "panel-$INSTANCE_ID-game", container: "/game" }
|
||||
# Shared DayZ Workshop cache — multiple DayZ instances download and use
|
||||
# the same workshop content. Each instance creates @ModName symlinks in
|
||||
# its own /game/ pointing at this shared tree, so disk space is saved
|
||||
# and one download serves N instances.
|
||||
- { type: volume, name: "panel-dayz-workshop", container: "/game/steamapps/workshop" }
|
||||
- { target: "$DATA_PATH/logs", container: "/game-saves/logs" }
|
||||
|
||||
# DayZ ports:
|
||||
# 2302/udp — primary game + query (Bohemia's convention: game port and
|
||||
# Steam query are the SAME port, unlike Source-engine games)
|
||||
# 2303/udp — additional-instance offset (+1)
|
||||
# 2304/udp — additional-instance offset (+2)
|
||||
# 2305/udp — additional-instance offset (+3)
|
||||
# 27016/udp — alternate Steam-query port (some community servers expose)
|
||||
# 2310/udp — BattlEye RCON (BE_PORT + 1 by convention; configurable)
|
||||
ports:
|
||||
- { name: game, proto: udp, default: 2302, required: true, env: SERVER_PORT } # entrypoint reads SERVER_PORT (declared in docker env); query shares this port
|
||||
- { name: reserved, proto: udp, default: 2303, required: false }
|
||||
- { name: battleye, proto: udp, default: 2304, required: false } # client BE anti-cheat traffic
|
||||
- { name: rcon, proto: udp, default: 2305, internal: true } # BE RCON (AMP convention)
|
||||
|
||||
resources:
|
||||
min_ram_mb: 4096
|
||||
recommended_ram_mb: 8192
|
||||
|
||||
# Per-instance generated RCON secret. The agent generates a random
|
||||
# 24-byte token at create time (pkg/module GenerateSecrets), which
|
||||
# overrides the env default for BE_PASSWORD below — so every instance
|
||||
# gets a unique password. The weak env default only applies to
|
||||
# containers launched outside the panel.
|
||||
secrets:
|
||||
- name: BE_PASSWORD
|
||||
description: "DayZ BattlEye RCON password — generated per instance"
|
||||
generated: true
|
||||
|
||||
rcon:
|
||||
adapter: be_rcon
|
||||
host_port: rcon
|
||||
auth: password
|
||||
password_secret: BE_PASSWORD
|
||||
# Legacy fallback only (pre-generated-secret instances). New instances
|
||||
# always get the generated BE_PASSWORD secret above.
|
||||
password_literal: "panel_be"
|
||||
commands:
|
||||
list: "players"
|
||||
broadcast: "say -1 {msg}"
|
||||
kick: "kick {player}"
|
||||
ban: "ban {player}"
|
||||
save: "#shutdown" # DayZ has no "save" command; use shutdown as a placeholder
|
||||
shutdown: "#shutdown"
|
||||
|
||||
state_sources:
|
||||
- type: rcon
|
||||
command: "players"
|
||||
every: 60s
|
||||
|
||||
# Log-line event patterns (RE2). Patterns observed from a real DayZ
|
||||
# 1.24 server log; tighten after smoke test if needed.
|
||||
events:
|
||||
join:
|
||||
pattern: 'Player "(?P<name>[^"]+)" is connected'
|
||||
kind: join
|
||||
leave:
|
||||
pattern: 'Player "(?P<name>[^"]+)" disconnected'
|
||||
kind: leave
|
||||
chat:
|
||||
pattern: 'Chat\("(?P<name>[^"]+)"\): (?P<msg>.+)'
|
||||
kind: chat
|
||||
|
||||
update_providers:
|
||||
- id: stable
|
||||
kind: steamcmd
|
||||
app_id: "223350"
|
||||
install_path: /game
|
||||
# DayZ is paid content. Anonymous SteamCMD returns "No subscription".
|
||||
# Operator logs in once via the panel's Steam-login modal; the cached
|
||||
# SSFN blob (via the shared panel-steamcmd-auth volume) makes
|
||||
# subsequent updates skip the 2FA prompt.
|
||||
requires_steam_login: true
|
||||
|
||||
# --- Manifest-driven UI metadata (WI-07) --------------------------
|
||||
# Consumed by the CONTROLLER/dashboard only (the controller loads its
|
||||
# own ./modules copy at startup); the agent ignores these at runtime.
|
||||
# ready_pattern is a JavaScript regex (slash-delimited when it needs
|
||||
# flags) moved verbatim from the dashboard's READY_PATTERNS map.
|
||||
ready_pattern: '/Mission read from bank|BattlEye Server: Initialized|Server World: Initialized|NetServer: (:\d+)?started|Creating a new world/i'
|
||||
appearance:
|
||||
emoji: "🧟"
|
||||
grad: "linear-gradient(135deg,#2d3e2e,#6b7f56)"
|
||||
art: "/game-art/dayz.jpg"
|
||||
steam: "221100"
|
||||
Reference in New Issue
Block a user