Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

17 Commits

Folders and files

Repository files navigation

5Stack Plugin Registry

The catalog behind the 5Stack plugin directory. Every 5Stack panel polls the index this repo publishes and renders it at /plugins, so adding a plugin here makes it one-click installable on every install in the world.

Published to https://registry.5stack.gg/ by GitHub Pages, rebuilt hourly so new upstream plugin releases appear on their own. A build only deploys when what it produced differs from what the site already serves, so generated_at in the index marks the last time the catalog actually changed, not the last time the cron ran. A manual run of the workflow has a force option to redeploy regardless.

The custom domain lives in the root CNAME, which the build copies into dist/ — the published artifact is the site root, so the domain has to travel with it.

What's in a plugin

Two different things are called "plugin" in 5Stack, and both live here:

kind What it is Installed by
panel A web app that mounts as a native page at /apps/<slug> ./plugin.sh <repo> on the panel host
game A CS2 server plugin (SwiftlyS2 or CounterStrikeSharp) that loads into the game server The panel, into each node's plugin store
bundle One project shipping both halves itself Both of the above

Most things that feel like a pair are not a bundle. 5Stack Inventory is a panel plugin that names the CS2 Inventory Simulator in pairs_with and describes how it configures it in wiring — the game plugin is somebody else's project with its own entry, and republishing its releases would list the same download twice under two names. Reach for bundle only when one repo genuinely ships both halves.

Adding a plugin

  1. Drop a JSON file in registry/<kind>/<slug>.json. The filename must match the slug. Start from registry/game/inventory-simulator.json.
  2. npm run validate.
  3. Open a PR. verified: true is set during review, not by the submitter — it is the only thing telling an operator a maintainer actually looked at the plugin.

Never write a versions array. CI resolves it from the upstream repo's GitHub releases on every build, pinning each asset's URL and SHA-256 so a panel can verify what it downloads. Hand-written versions are rejected by the validator.

Linux only

5Stack game servers are Linux containers (steamrt sniper). The build filters release assets accordingly:

  • an asset naming another platform (windows, win64, osx, darwin) is never selected, and the validator rejects a glob that names one;
  • where a project ships one asset per platform, the Linux one is chosen rather than whichever GitHub returns first;
  • a release that publishes only non-Linux assets is skipped with a warning.

An asset that names no platform at all (a portable .NET zip, which is what most CS2 plugins ship) is taken as-is.

Archive layout

layout tells the installer how to unpack the release asset:

  • csgo (default) — the archive root is game/csgo, so it already contains addons/.... This is what the inventory simulator ships.
  • plugin — the archive root is the plugin folder itself. Set install_path (e.g. addons/{runtime}/plugins/MyPlugin) and the installer places it there. {runtime} expands to swiftlys2 or counterstrikesharp.

Plugins that need Valve's server guidelines off

Both frameworks ship FollowCS2ServerGuidelines: true, which blocks the calls a plugin needs to change what a player sees — custom HUDs, scoreboard text, rank badges. A plugin that cannot work without those calls declares:

"requires_server_guidelines_disabled": true

Valve's position is that this can get every GSLT on the server owner's Steam account banned, so the panel never flips it on the strength of the registry alone: the flag only surfaces a per-install opt-in, off by default, next to that warning. Set it when the plugin genuinely does not function otherwise, not when it merely has a nicer HUD if you do.

Plugins that ship workshop addons

CS2 cannot send files from a server to a player, so a plugin's custom models, sounds, particles or Panorama layouts have to reach players as a Steam Workshop addon. A plugin that needs one lists the workshop ids:

"workshop_addons": ["3791548068"]

5Stack's SwiftlyS2 image ships AddonsManager, so nothing else has to be installed: every server that loads the plugin turns it on and serves exactly the addons its plugins list. Players download them while they connect, and the server fetches each addon again whenever it mounts it, so a republished addon reaches players without a new plugin release.

The ids are strings, because a workshop id is too large for a JSON number. The entry needs a swiftlys2 variant, since the SwiftlyS2 image is the only one with AddonsManager. A CounterStrikeSharp server loading the same plugin starts without the addons and logs why.

Plugins that run a map rotation

A dedicated server can carry a map rotation set in the panel. A plugin that can play one declares where the rotation goes, and the panel writes those files on every boot of a server that has a rotation (and loads the plugin there unless the server switches it off):

"map_rotation": {
  "files": {
    "addons/swiftlys2/configs/plugins/MapChooser/maps.jsonc": {
      "MapChooserMaps": { "Maps": "{{maps}}" }
    },
    "addons/swiftlys2/configs/plugins/MapChooser/config.jsonc": {
      "MapChooser": { "Cycle": { "Enabled": true, "RandomOrder": "{{shuffle}}" } }
    }
  },
  "map": { "Name": "{{label}}", "Id": "{{id}}" }
}

{{maps}} becomes the list, one map object per entry; {{shuffle}} becomes the server's shuffle switch. In map, {{id}} is the workshop id or the map name (whatever host_workshop_map / changelevel takes), {{name}} the map name, {{label}} the display name and {{workshop_id}} the workshop id or null. A string that is exactly one token takes the token's type; anything else is text.

Each file is written whole, so a file listed here replaces anything an operator put at that path on that server. Keep documents to the keys the rotation needs: MapChooser falls back to its defaults for every key the file leaves out.

Settings and config files

cvars lists the console variables a plugin reads. A server running the plugin reports each one's description and default, and the panel turns the list into a settings form on the plugin's page.

A plugin that reads a JSON file describes it with config_path (where it is written, relative to game/csgo), config_default (what the plugin ships with, which the editor starts from) and optionally config_schema (the form to render; without one the file is edited as JSON). When the plugin finds the file through a console variable rather than a fixed path, name it in config_cvar and the panel points it at config_path on every server it writes the file to:

"config_path": "addons/swiftlys2/configs/plugins/Deathmatch/modes.json",
"config_cvar": "dm_modes_file",
"config_default": [{ "name": "Pistols", "weapons": ["deagle"], "duration": 300 }]

config_shipped says where the plugin keeps its own copy (path, as installed under game/csgo, and repo_path, in its repository), so the plugin's page can open it on a node and link to it at the release that is installed.

forced_cvars lists the console variables a plugin sets itself on every map load, after the server's configs have run. Setting one anywhere in the panel does nothing, so the panel warns when a config tries.

Runtimes are not interchangeable

A CounterStrikeSharp plugin will not load under SwiftlyS2 and vice versa, so a game plugin declares one variants entry per runtime it actually ships. A plugin with only a counterstrikesharp variant simply won't be offered on a SwiftlyS2 deployment (unless that deployment runs the CSS compatibility layer).

Local development

npm run validate      # schema + cross-entry checks, no network
npm run build         # resolves releases and writes dist/index.json
node scripts/changed.mjs   # says whether dist/ differs from the live registry

build hits the GitHub API. Set GITHUB_TOKEN to avoid the unauthenticated rate limit.

Pointing a panel somewhere else

An operator can mirror or fork this registry and point their panel at it:

Settings → Application → Game Plugins → Registry URL, or the public.plugin_registry_url setting.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages