Skip to content

Addons

The Addons tab (/launcher/addons) lists every client-side optional addon the operator published for the currently active game and lets the player install, update or remove each one in place.

Schema & catalogue

cluster.optional_addons carries the catalogue. Migration 163 adds an optional game_id INTEGER so each addon either targets a specific game (matched by cluster.games.id) or stays cross-game when the column is NULL. The public list endpoint:

GET /api/v1/addons?game_slug=<slug>

filters to rows where game_id IS NULL OR g.slug = $1, so cross-game UI mods stay visible alongside game-specific entries.

GET /api/v1/addons/:id/download streams the raw .rcaddon zip and bumps download_count.

Install pipeline

The launcher exposes four Tauri commands:

Command What it does
fetch_addons(api_base, game_slug?) Returns the catalogue scoped to the game.
list_installed_addons(wow_path) Walks <wow_path>/Interface/AddOns/ and reads .splintertree-addon.json from every folder we've previously installed into.
install_addon(api_base, wow_path, addon_id) Pulls metadata, downloads the zip, wipes any previous install of the same folder_name, unpacks each entry under <wow_path>/Interface/AddOns/<folder>/ (rejecting .. and absolute paths), then writes a .splintertree-addon.json manifest with {id, name, folder_name, version, installed_at}.
remove_addon(wow_path, folder_name) Refuses paths with slashes / .., and refuses to wipe folders without our own manifest, so the player's manually-installed AddOns stay safe.

The presence of .splintertree-addon.json is the only marker the launcher trusts — that's how it tells "we installed this" from "user installed it themselves" or "shipped with WoW".

UI behaviour

  • Each card shows name, version, author, category, zip size, and total install count.
  • Installed-state badge: green installed when versions match, orange update badge when the catalogue version differs from the installed manifest. Both states surface a Remove button.
  • Install / Update buttons are disabled outside the Tauri shell (the browser preview can't write to disk).
  • Switching active games reloads the catalogue; the installed list stays the same since folders are global to the WoW install regardless of which game the player is currently on.

Wire format

The .rcaddon is just a deflate zip. Entries are written exactly as the zip carries them (the enclosed_name check rejects any path that would escape <wow_path>/Interface/AddOns/). Operators can produce one with zip -r MyAddon.rcaddon MyAddon/.