- Rust 56.6%
- PHP 18.4%
- TypeScript 7.4%
- CSS 6.5%
- JavaScript 5.4%
- Other 5.7%
|
|
||
|---|---|---|
| admin | ||
| dashboard | ||
| database/migrations | ||
| docs | ||
| legacy/standalone | ||
| private | ||
| public | ||
| requests | ||
| .gitignore | ||
| conf.yml | ||
| icon.svg | ||
| install.sh | ||
| README.md | ||
| ROADMAP.md | ||
CmMinecraftUpdater
A Pterodactyl Blueprint extension that adds a Minecraft / Hytale server, plugin, and mod updater directly into the panel's existing UI.
It detects what your server is running (Paper, Purpur, Spigot, Fabric, Forge, NeoForge, Quilt, Hytale), looks up the latest builds against Mojang, PaperMC, Fabric meta, Forge promotions, NeoForge maven, Hangar, Modrinth, and CurseForge, and lets users with the right Pterodactyl subuser permissions update the server jar, plugins, and mods with one click — all without leaving the panel.
Why an extension and not a separate web app? Earlier prototypes shipped as a standalone Rust web service. Operator feedback was clear: this is a panel addon, not another service to host. The Blueprint extension is now the primary delivery channel; the original Rust service is preserved under
legacy/standalone/for sidecar deployments.
Features at a glance
| Feature | Where it lives in the panel | Screenshot |
|---|---|---|
| Server build status & one-click update | Server detail → Updater → Updates | docs/screenshots/01-updates.svg |
| Plugin & mod diff against Hangar / Modrinth / CurseForge | Server detail → Updater → Updates | (same as above) |
| Marketplace search | Server detail → Updater → Marketplace | docs/screenshots/02-marketplace.svg |
| Player kick / op / deop with audit | Server detail → Updater → Players | docs/screenshots/03-players.svg |
| Catalogue settings + audit log | Admin → Extensions → CmMinecraftUpdater | docs/screenshots/04-admin-settings.svg |
| Install script output | terminal | docs/screenshots/05-install.svg |
Updates panel
Detects the installed server build, queries the upstream resolver for the
latest, and renders a per-plugin / per-mod diff with Hangar / Modrinth /
CurseForge sources. The "Update selected" button performs an HTTPS-only,
host-allow-listed, 256 MiB-capped download and atomic-rename replacement,
keeping the previous jar under plugins/.cmmu-backup/<file>.<timestamp>.
The Updates tab also exposes a pick-any-MC-version picker for the server jar — choose any MC version Paper / Purpur / Fabric / Forge / NeoForge / Vanilla publish, plus an explicit build number where the upstream API supports it (Paper, Purpur). Switching across MC versions prompts for confirmation and is logged to the audit trail as a version change rather than a build bump (world data is not migrated by the updater — that's the operator's call). See docs/UI-NOTES.md.
Marketplace panel
Search across Modrinth, Hangar, and CurseForge from inside the server view. Results carry an icon, description, download count, and a deep link to the project page so you can verify before installing.
Players panel
Lists active players and lets users with the control.console subuser
permission kick / op / deop them. Every action is journalled to the audit
log with the panel user's email, the resolved console command, and the
target server.
Admin settings & audit log
Lives at Admin → Extensions → CmMinecraftUpdater. Configure the catalogue source priority (Modrinth-first, CurseForge-first, or Hangar-first for Bukkit-family servers), paste an optional CurseForge API key (required only for Forge / NeoForge mod lookups), set the backup retention count, and review every privileged action across the panel.
The settings page also includes a Brand assets section: upload a custom
favicon (≤ 64 KiB; PNG / ICO / SVG) and logo (≤ 512 KiB; PNG / SVG) shown
in the client-area Updater panel and the standalone login screen. SVG
uploads are passed through a small allow-list sanitiser that strips
<script> elements, on* event-handler attributes, javascript: URLs,
and <foreignObject> blocks before the file is written.
Install
sudo ./install.sh
Builds a .blueprint archive from this repository and hands it off to the
Blueprint CLI, which copies the files into your Pterodactyl install, runs
the migrations, and triggers the private/install.sh post-install hook.
Requirements
- A working Pterodactyl panel install (this extension does not support Pelican yet — see Roadmap → "Open follow-ups").
- The Blueprint Framework installed against the same panel: https://blueprint.zip
php8.1+ (matches Pterodactyl's own requirement),zip, andbashavailable on the panel host.
Install
git clone https://github.com/CrashMediaIT/CmMinecraftupdater-.git
cd CmMinecraftupdater-
sudo ./install.sh # install / upgrade
sudo ./install.sh --remove # uninstall
Environment overrides understood by install.sh:
| Variable | Default | Purpose |
|---|---|---|
BLUEPRINT_BIN |
blueprint |
Path to the Blueprint CLI |
PTERO_DIR |
/var/www/pterodactyl |
Pterodactyl install root |
CMMU_PURGE_AUDIT |
0 |
Set 1 and run --remove to drop the cmmu_audit table |
The first run will:
- Build
CmMinecraftUpdater.blueprintfromconf.yml,admin/,dashboard/,requests/,database/,private/, andpublic/. - Invoke
blueprint -install CmMinecraftUpdater.blueprintfrom insidePTERO_DIR. - Run
database/migrations/*.phpagainst your panel database, creatingcmmu_settingsandcmmu_audit. - Run
private/install.shto seed the default settings (modrinth_firstpriority, 1 backup kept, Hytale disabled).
Configuration
Everything is configured from the admin UI — no editing of YAML or
.env files. The settings table (cmmu_settings) stores:
| Key | Default | Notes |
|---|---|---|
default_loader_priority |
modrinth_first |
One of modrinth_first, curseforge_first, hangar_first |
curseforge_api_key |
(unset) | Required only for Forge / NeoForge mod lookups |
keep_backup_count |
1 |
How many .cmmu-backup rotations to retain |
hytale_enabled |
0 |
Stub toggle; resolver wires in once Hytale ships APIs |
Permissions
The extension reuses Pterodactyl's existing subuser permission system.
| Action | Permission(s) required |
|---|---|
| View Updates / Marketplace / Players tabs | Server view (default for any subuser) |
| Update server jar / plugins / mods | file.update |
| Kick / op / deop a player | control.console (and the file permission, since most flows touch both) |
| Edit catalogue settings, view full audit log | Root admin |
The React component hides write buttons for users who lack the relevant
permission, and RequireModifyPermission middleware enforces the same gate
server-side so the API cannot be bypassed.
Architecture
.
├── conf.yml # Blueprint manifest
├── icon.svg # Brand mark
├── install.sh # Top-level installer (wraps blueprint -install)
├── admin/
│ ├── view.blade.php # Settings + audit log card
│ ├── controller.php # POST handler for the form
│ └── admin.css # Admin AdminLTE overrides (orange/cyan accents)
├── dashboard/
│ ├── dashboard.css # Client-area glass UI, scoped to .cmmu-panel
│ └── components/Cmmu.tsx # React component injected into the server detail view
├── data → conf.yml refers to:
│ ├── private/ # install.sh, remove.sh hooks
│ └── public/ # static assets served at /extensions/cmmu/public
├── requests/
│ ├── routers/client.php # /api/client/extensions/cmmu/... routes
│ ├── views/ # (reserved for future Blade views)
│ └── app/
│ ├── Http/Controllers/ # Meta, Updates, Marketplace, Players
│ ├── Http/Middleware/ # ResolveServer, RequireModifyPermission
│ ├── Services/ # Files, Meta, Audit, JarManifestParser
│ ├── Resolvers/ # ServerJarResolver (Mojang/Paper/Fabric/Forge/NeoForge)
│ └── Lookups/ # CatalogueLookup (Hangar/Modrinth/CurseForge)
└── database/
└── migrations/ # cmmu_settings, cmmu_audit
The PHP classes live under the Pterodactyl\Extensions\Cmmu\ namespace,
which Blueprint maps onto the panel's autoloader at install time.
Security notes
- HTTPS only. Every catalogue and download URL is checked: scheme must
be
https, host must be in a small allow-list (cdn.modrinth.com,edge.forgecdn.net,hangarcdn.papermc.io, etc.). - Path traversal blocked.
FilesServicerejects any path containing..and forces a leading slash. - Username injection blocked. Player names are validated against
^[A-Za-z0-9_]{1,16}$before being substituted into a console command; CR/LF in kick reasons are stripped. - Auth is the panel's auth. No API keys are stored; every request runs inside Pterodactyl's standard client-API auth pipeline (session cookie + CSRF) so subuser permissions Just Work.
- Audit everything. Every settings change, server-jar update, plugin / mod update, and player action is logged with actor email, action, server identifier, and a JSON detail blob.
Legacy standalone Rust service
The previous standalone implementation (a tiny_http web server with an
embedded SPA, Phases 1–7 of the original roadmap) has been moved to
legacy/standalone/ and remains buildable with
cargo build --release. It is the behavioural reference the PHP services
were ported from, and is the right choice if you want a sidecar updater
service that talks to multiple panels at once.
See legacy/standalone/README.md for that
flow.
Roadmap
See ROADMAP.md. All eight phases of the Blueprint extension are complete; open follow-ups (live player list via console websocket, multipart modpack install, Hytale / Pelican wiring) are tracked there.