View the documentation docs.5stack.gg
This repo holds the CS2 game server images and the tooling that keeps them honest.
| App | What it is | Image |
|---|---|---|
apps/counterstrikesharp |
CS2 server + 5stack plugin on CounterStrikeSharp | ghcr.io/5stackgg/game-server-css |
apps/swiftly |
the same plugin on SwiftlyS2 | ghcr.io/5stackgg/game-server-sw |
apps/player-management-css / apps/player-management-sw |
enforces panel bans, mutes and gags on community servers | ships inside both game-server images |
apps/gamedata-validator |
checks our byte-pattern signatures still resolve after a CS2 update | ghcr.io/5stackgg/gamedata-validator |
apps/simulator |
a stand-in game server that plays matches without CS2, for developing the panel | ghcr.io/5stackgg/game-server-sim |
shared/ holds what the two plugins have in common: the server cfg/, the setup scripts/,
the signature gamedata/, and the framework-agnostic C# (entities, enums, utilities) that both
FiveStack.csproj files pull in with a Compile glob. It compiles into each plugin assembly —
nothing extra ships in the plugin zip.
Both plugins are published to releases. They version independently and share one tag namespace, so pick by prefix:
- CounterStrikeSharp —
css-v0.0.N, assetFiveStack-css-v0.0.N.zip - SwiftlyS2 —
sw-v0.0.N, assetFiveStack-sw-v0.0.N.zip
A release's body is the minimum CS2 build id it runs on; the API reads it to choose which release a
node gets. CI writes it when the release is created, from min-game-build.json,
so it must stay a bare number.
When a CS2 update breaks a plugin (the gamedata validator failing for that runtime), run the Set Min Game Build workflow from main before shipping the fix. Leave the build id blank to use the current public CS2 build. The run shows the build id it resolved and waits for approval before committing it; it refuses an id that is not higher than the current one. Every release that plugin cuts afterwards requires that build, so nodes still on the old one keep the release that works there. Tick retag latest when the fix has already shipped; without it, the fix stays the old build's newest release.
The old build only ever hands out its newest release again, so the run then deletes the older releases on
it and their images (scripts/remove-releases.sh <css|sw> <build id> does the same by hand). Deleting
the images needs the repo to have the Admin role on the game-server-css and game-server-sw packages
(package settings → Manage Actions access); a release whose image fails to delete is kept, so rerunning
the script retries it.
The approval comes from the min-game-build environment (Settings → Environments). Give it required
reviewers, or the run commits without waiting.
Community (non-Ranked) dedicated servers run no match plugin, so the sanctions a moderator sets in
the panel reach them through this plugin instead. It syncs every 30 seconds and whenever the panel
sends player_management_refresh, kicks banned players, mutes voice and blocks chat. It has no
byte-pattern signatures, so a CS2 update does not break it.
A server on a 5stack node loads it automatically. Anywhere else, take the asset from the same
release as the match plugin and extract it into game/csgo:
- CounterStrikeSharp:
PlayerManagement-css-v0.0.N.zip, configured inaddons/counterstrikesharp/configs/plugins/PlayerManagement/PlayerManagement.json - SwiftlyS2:
PlayerManagement-sw-v0.0.N.zip, configured inaddons/swiftlys2/configs/plugins/PlayerManagement/config.jsonc(under aPlayerManagementkey)
Either config takes API_DOMAIN, SERVER_ID and SERVER_API_PASSWORD; the panel's player
management card shows the values for each server. Environment variables of the same names win over
the file. Over RCON, player_management_status reports what the plugin sees.
Licensed under the GNU GPL v3, with the additional terms in NOTICE: keep the "Powered by 5Stack" credit, and do not present a modified version as the official 5Stack. CounterStrikeSharp and SwiftlyS2 let their plugins use only the GPL or MIT, so this repository uses the GPL. Versions published before this change remain under the MIT License. For other licensing, contact @lukepolo. By contributing you agree to the terms in CONTRIBUTING.md.