No description
Find a file
Amos 71c93d5443
Stop eating the first line of every rcon reply
parse_packet split the response into type and payload at the first newline.
That is right for query replies, which are framed "statusResponse\n\key\value",
and wrong for rcon replies, which are framed "print <text>" with the first line
of the answer on the same line as the token. The token therefore swallowed it.

How much that cost depended on the command, and the worst case was silent:

  status          lost its "map: <name>" banner - cosmetic
  <dvar>          lost the value line, which is the entire answer. Querying a
                  dvar printed only "  Domain is any text"
  <typo>          lost 'Unknown command "..."' completely, so rcon-cli printed
                  nothing at all and a mistyped command was indistinguishable
                  from a server that had stopped answering

Split on the first whitespace of any kind instead, since the separator is
framing rather than payload and which one appears varies by reply. A reply with
no separator at all - t5 zombies answers an unexpected connectionless packet
with a bare "disconnect" - still parses as "type, empty body".

This was never BOIII-specific. Measured on 10.10.1.22 across t6zm, iw5mp, iw4x,
t4mp, cod4x and boiii: all six now print the first line that was being dropped
("map: zm_buried", "hostname: My Server Name"), and all six still pass the
health check afterwards - including iw5, which answers getinfo rather than
getstatus, and so exercises the fallback path the same parser backs.
2026-08-20 18:37:19 +01:00
.github/workflows SteamCMD family: generalise 7DTD support, add CS2/L4D2/HL2:DM, unify the CoD side (#9) 2026-08-16 17:12:31 +01:00
docs Refuse the published boiii.exe instead of hanging on it 2026-08-20 18:01:29 +01:00
examples feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00
scripts Stop eating the first line of every rcon reply 2026-08-20 18:37:19 +01:00
seed-configs feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00
tools feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00
.dockerignore SteamCMD family: generalise 7DTD support, add CS2/L4D2/HL2:DM, unify the CoD side (#9) 2026-08-16 17:12:31 +01:00
.gitattributes V2 layout (#4) 2026-05-25 11:56:13 +01:00
.gitignore Add rcon-cli, deduplicate shared logic, and reorganize scripts 2026-03-29 17:44:08 +01:00
CLAUDE.md feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00
Dockerfile feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00
Dockerfile.arm64 feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00
MIGRATION.md feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00
README.md feat!: replace T7x with Ezz BOIII as the Black Ops III client 2026-08-19 11:54:16 +01:00

Plutainer

Run a dedicated game server in Docker. One image, eleven games, configured with environment variables.

services:
  my-server:
    image: ghcr.io/ayymoss/plutainer:latest
    ports: ["4976:4976/udp"]
    volumes:
      - /path/to/BO2/files:/home/plutainer/gamefiles:ro
      - ./my-server:/home/plutainer/app
    environment:
      PLUTAINER_GAME: t6zm
      PLUTAINER_CONFIG_FILE: dedicated_zm.cfg
      PLUTO_SERVER_KEY: your-key-here
    restart: unless-stopped

docker compose up -d and you have a Black Ops II zombies server. Plutainer writes a working config on first start, so there is nothing to prepare beyond the game files you own.

→ Start here: the Quickstart

Supported games

Game PLUTAINER_GAME Notes
World at War (T4) t4mp, t4sp Plutonium. Needs a server key
Black Ops (T5) t5mp, t5sp Plutonium. Needs a valid server key — see why
Black Ops II (T6) t6mp, t6zm Plutonium. Needs a server key
Modern Warfare 3 (IW5) iw5mp Plutonium. Needs a server key
Modern Warfare 2 (IW4x) iw4x No key. amd64 only
Black Ops III boiii Ezz BOIII. No key
Modern Warfare (CoD4x) cod4x Multiplayer only, amd64 only. Needs a masterserver token to appear in the server browser
7 Days to Die 7dtd Native Linux server, amd64 only. Installed by SteamCMD; no gamefiles mount
Counter-Strike 2 cs2 Source 2, amd64 only. Installed by SteamCMD; ~67 GB. Needs a GSLT to be listed
Left 4 Dead 2 l4d2 Source engine, amd64 only. Installed by SteamCMD; no gamefiles mount
Half-Life 2: Deathmatch hl2dm Source engine, amd64 only. Installed by SteamCMD; no gamefiles mount

Image: ghcr.io/ayymoss/plutainer:latest — multi-arch (amd64 + arm64), with documented architecture exceptions.

Documentation

If you want to… Read
Get a first server running Quickstart
Know what your game needs Games — files, keys, config names, ports
Look up an environment variable Configuration
Understand where configs and logs live Volumes & configs
Send RCON commands RCON
Connect IW4MAdmin IW4MAdmin
Know when a server counts as healthy Healthcheck & restarts
Fix something that's broken Troubleshooting & FAQ
Copy a working compose file Examples
Upgrade from v1 Migration guide

What Plutainer does for you

  • Writes a working config on first start. Community defaults are seeded into app/configs/, and never overwrite files you've edited.
  • Fetches the server binaries. Plutonium, IW4x and BOIII updaters run at startup; CoD4x ships in the image; the SteamCMD games install themselves. You supply base game files only for the games that need them.
  • Puts every config in one folder. Edit app/configs/whatever.cfg; Plutainer symlinks it to wherever the engine expects it.
  • Keeps logs findable. app/logs/ holds stable symlinks to the active log files, wherever the game moved them.
  • Fails loudly, not endlessly. A misconfiguration holds the container in Up with a readable error instead of a restart loop.
  • Reports real health. The healthcheck asks the server for its current map — no RCON password required.

Support

Discord: https://discord.gg/JekrGGWAUg — for Plutainer setup and configuration, including IW4MAdmin.

Plutonium-specific game issues are out of scope, and some familiarity with Docker is assumed. New to Docker? Start at https://docs.docker.com/get-started/.

Credits