# Palworld — panel-native dedicated server module.
#
# Native Linux binary from SteamCMD app 2394010. Native Source RCON on
# port 25575 when EnableRCON=True in PalWorldSettings.ini.
#
# Reference: https://github.com/CubeCoders/AMPTemplates (PalworldLinux.kvp)

id: palworld
name: "Palworld"
version: 0.1.0
authors:
  - panel contributors

supported_modes:
  - docker

runtime:
  docker:
    image: panel-palworld: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: "World save + PalWorldSettings.ini + admin files"
      - name: "Game Files"
        path: /game
        hint: "PalServer install, binaries"
    env:
      SERVER_NAME: "panel Palworld"
      SERVER_DESCRIPTION: "A Palworld server"
      MAX_PLAYERS: "32"
      RCON_PASSWORD: "panel_rcon"
      # Pre-declared so the agent's resolve.go filter lets panel-allocated
      # ports flow through to the container env. Defaults match port defaults.
      GAME_PORT: "8211"
      QUERY_PORT: "27015"
      RCON_PORT: "25575"
    volumes:
      - { type: volume, name: "panel-$INSTANCE_ID-saves", container: "/game-saves" }
      - { type: volume, name: "panel-$INSTANCE_ID-game",  container: "/game" }
      - { target: "$DATA_PATH/logs", container: "/game-saves/logs" }

ports:
  - { name: game,  proto: udp, default: 8211,  required: true,  env: GAME_PORT }
  - { name: query, proto: udp, default: 27015, required: true,  env: QUERY_PORT }
  - { name: rcon,  proto: tcp, default: 25575, internal: true, env: RCON_PORT }

resources:
  min_ram_mb: 6144
  recommended_ram_mb: 16384   # Palworld is memory-hungry

# 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 RCON_PASSWORD below — so every instance
# gets a unique password. The weak env default only applies to
# containers launched outside the panel.
secrets:
  - name: RCON_PASSWORD
    description: "Palworld RCON password — generated per instance"
    generated: true

rcon:
  adapter: source_rcon
  host_port: rcon
  auth: source_rcon_login
  password_secret: RCON_PASSWORD
  # Legacy fallback only (pre-generated-secret instances). New instances
  # always get the generated RCON_PASSWORD secret above.
  password_literal: "panel_rcon"
  commands:
    list: "ShowPlayers"
    save: "Save"
    broadcast: "Broadcast {msg}"
    kick: "KickPlayer {player}"
    ban: "BanPlayer {player}"
    shutdown: "Shutdown 30 \"Server going down\""

state_sources:
  - type: rcon
    command: "ShowPlayers"
    every: 60s
    parse:
      kind: regex
      pattern: '^(?P<count>\d+)\s*$'    # Fallback; real parsing in playerList
      fields:
        players_online: count
# Log-derived player events. Regexes converted from CubeCoders'
# AMPTemplates (palworld.kvp) — .NET (?<n>) syntax -> Go (?P<n>).
# Sourced-from-template; not yet exercised against a live client.
events:
  join:
    pattern: '(?P<name>.+?) \S+ connected the server\. \(User id: (?P<id>[^)]+)\)$'
    kind: join
  leave:
    pattern: '(?P<name>.+?) left the server\. \(User id: (?P<id>[^)]+)\)$'
    kind: leave
  chat:
    pattern: '^(?:\[[\d-]+ [\d:]+\] )?\[CHAT\] <(?P<name>.+?)> (?P<msg>.+)$'
    kind: chat


update_providers:
  - id: stable
    kind: steamcmd
    app_id: "2394010"
    install_path: /game
    # Force Linux depot — SteamCMD's auto-detect mis-fires in Docker
    # Desktop on Windows (WSL2 backend), returning "Missing configuration"
    # on anonymous app_update. Pinning platform fixes it.
    platform: linux

# --- 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: '/Running Palworld dedicated server|Setting breakpad minidump AppID/i'
appearance:
  emoji: "🐾"
  grad: "linear-gradient(135deg,#006d77,#83c5be)"
  art: "/game-art/palworld.jpg"
  steam: "1623730"
