Skip to content

Repository files navigation

fancy-plugin-example

A Cargo workspace of small, annotated Fancy Mumble server plugins. Each member crate compiles to a self-contained cdylib that you drop into /etc/mumble/plugins and enable with a single INI switch — no server recompile, no rebuild, no link edit.

Layout

fancy-plugin-example/
├── Cargo.toml                # workspace root (lints, shared deps)
├── rust-toolchain.toml       # pins the Rust toolchain
└── examples/
    ├── greeter/              # slash command + button + modal + plugin messages
    ├── gallery-showcase/     # Container + Section + Thumbnail + MediaGallery
    ├── info-card/            # Section + Button accessory + Toast follow-up
    └── feedback-form/        # multi-field TextInput modal

Each example is intentionally small. When in doubt, add a new example rather than piling features onto an existing one.

Crate Slash command Demonstrates
fancy-greeter /greet Slash command, button, modal, toast, plugin messages, persistent config
fancy-gallery-showcase /showcase TextDisplay, Thumbnail, MediaGallery, Container (visual-only)
fancy-info-card /info Section with a Button accessory, #[component] handler, Toast
fancy-feedback-form /feedback Multi-field TextInput modal, #[modal] handler

Prerequisites

Tool Version
Rust as pinned by rust-toolchain.toml (currently 1.95.0)

That is the whole list: cargo build fetches the plugin API itself. Nothing else needs checking out.

The API lives in Starling, the Rust server, and is pulled in over git:

mumble-plugin-api = { git = "https://github.com/Fancy-Mumble/starling.git", branch = "main" }

It used to be a path dependency on a sibling checkout of the C++ mumble-server, whose tree still carries a copy. That copy is frozen, so a plugin built against it is built against the past; Starling is where the API is maintained now. Nothing about the ABI changed in the move — the same binary loads in either server — but there is no longer a reason to check out a C++ server to build a Rust plugin.

A plugin must be built against the same API version as the server that will load it. The host reads the version out of the binary before it does anything else, and refuses a mismatch with has ABI version N but host expects M rather than loading it and misbehaving. If you run a server built from a particular Starling commit, pin the dependency to that commit.

Building against a local Starling

Checking out Starling beside this repo and uncommenting the [patch] block at the foot of the root Cargo.toml builds every example against that working tree instead of the branch. That is what you want when changing the API itself.

Build

# Build every example.
cargo build --release

# Or just one.
cargo build --release -p fancy-info-card

Each crate emits the cdylib at target/release/lib<name>.{so,dylib} (or <name>.dll on Windows).

Test & lint

cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test  --workspace

The lint policy is defined once in the root [workspace.lints] block and inherited by every member via [lints] workspace = true.

CI artefacts

The workflow runs the lint/test gate once for the whole workspace, then fans out to a (example × os) matrix. Every job uploads a single drop-in archive named <crate>-<os>-<arch>.{tar.gz|zip} containing:

  • the platform-appropriate cdylib
  • the matching plugin.example.ini
  • the per-crate README.md

Tagging vX.Y.Z additionally attaches every archive to a GitHub Release.

Writing your own plugin

Copy whichever example is closest to what you want, rename the crate, and add it to the workspace members list in the root Cargo.toml. Update the matrix in .github/workflows/ci.yml to ship a build of your new plugin.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages