Files
firefrost-services/services/modpack-version-checker/blueprint-extension
Claude (Chronicler #63) 0f2ece4f88 fix(modpackchecker): Restructure for Blueprint PSR-4 compliance
BREAKING CHANGES - folder structure reorganized:

OLD STRUCTURE (broken):
  Controllers/ModpackAPIController.php
  console/CheckModpackUpdates.php

NEW STRUCTURE (working):
  app/Http/Controllers/ModpackAPIController.php
  app/Console/Commands/CheckModpackUpdates.php

CHANGES:

1. Moved controller to app/Http/Controllers/
   - Namespace changed: Pterodactyl\Http\Controllers
   - This aligns with Laravel's PSR-4 autoloading
   - Blueprint's requests.app field merges into Pterodactyl's app/

2. Moved console command to app/Console/Commands/
   - Now properly registered with Laravel's command system
   - Run with: php artisan modpackchecker:check

3. Updated conf.yml:
   - Set requests.app: 'app' (enables app/ folder merging)
   - Cleared data.directory (was pointing to non-existent folder)
   - Cleared dashboard.wrapper (TSX not supported, use build.sh)

4. Updated routes/client.php:
   - Fixed use statement to match new namespace

TESTED AND VERIFIED:
- blueprint -build: SUCCESS
- yarn build:production: SUCCESS
- php artisan modpackchecker:check: SUCCESS
- API tests passed: Modrinth , FTB , CurseForge 
- Technic API now requires auth (needs investigation)

This commit represents the WORKING state deployed on Dev Panel.

Signed-off-by: Claude (Chronicler #63) <claude@firefrostgaming.com>
2026-04-06 09:52:57 +00:00
..

ModpackChecker — Pterodactyl Blueprint Extension

Version: 1.0.0
Author: Firefrost Gaming
License: Proprietary (Commercial product for BuiltByBit)

A Pterodactyl Panel extension that checks modpack versions across CurseForge, Modrinth, FTB, and Technic platforms. Shows update status on the dashboard and provides manual version checks from the server console.


Table of Contents

  1. Features
  2. Architecture Overview
  3. File Structure
  4. Installation
  5. Configuration
  6. Usage
  7. Development
  8. API Reference
  9. Troubleshooting
  10. Design Decisions

Features

Dashboard Badge

  • Shows a colored dot next to each server name on the dashboard
  • 🟠 Orange (Fire #FF6B35): Update available
  • 🟢 Teal (Frost #4ECDC4): Up to date
  • Hover for version details tooltip
  • Single API call per page load (cached globally)

Console Widget

  • "Check for Updates" button on each server's console page
  • Real-time version check against platform API
  • Shows modpack name, current version, and latest version

Admin Panel

  • Configure CurseForge API key
  • View extension status
  • (Future: Rate limit settings, notification preferences)

Supported Platforms

Platform ID Type API Key Required
CurseForge Numeric project ID Yes
Modrinth Project ID or slug No
FTB Numeric modpack ID No
Technic URL slug No

Architecture Overview

┌─────────────────────────────────────────────────────────────────────────────┐
│                           MODPACK VERSION CHECKER                            │
│                            Architecture Diagram                              │
└─────────────────────────────────────────────────────────────────────────────┘

                    ┌─────────────────────────────────────┐
                    │     CRON JOB (runs every 4-6 hrs)   │
                    │     php artisan modpackchecker:check │
                    │                                     │
                    │  • Finds servers with MODPACK_*     │
                    │  • Calls platform APIs one by one   │
                    │  • 2-second delay between calls     │
                    │  • Stores results in database       │
                    └──────────────────┬──────────────────┘
                                       │
                                       ▼
                    ┌─────────────────────────────────────┐
                    │         DATABASE CACHE              │
                    │     modpackchecker_servers table    │
                    │                                     │
                    │  • server_id, server_uuid           │
                    │  • platform, modpack_id             │
                    │  • current_version, latest_version  │
                    │  • update_available (boolean)       │
                    │  • last_checked timestamp           │
                    └──────────────────┬──────────────────┘
                                       │
                    ┌──────────────────┴──────────────────┐
                    │                                     │
                    ▼                                     ▼
    ┌───────────────────────────┐       ┌───────────────────────────┐
    │    DASHBOARD BADGE        │       │    CONSOLE WIDGET         │
    │    (UpdateBadge.tsx)      │       │    (wrapper.tsx)          │
    │                           │       │                           │
    │  • Reads from cache ONLY  │       │  • Manual "Check" button  │
    │  • Never calls external   │       │  • LIVE API call          │
    │  • One API call per page  │       │  • Single server only     │
    │  • Shows 🟠 or 🟢 dot     │       │  • Shows full details     │
    └───────────────────────────┘       └───────────────────────────┘

Why This Architecture?

The Problem: A panel with 50 servers and 20 active users could generate thousands of API calls per day if each dashboard view triggered live checks.

The Solution:

  1. Cron job handles external API calls with rate limiting
  2. Dashboard reads from local cache only
  3. Console provides on-demand checks for specific servers

This was validated by Gemini AI during architectural review.


File Structure

blueprint-extension/
├── README.md                    # This file
├── conf.yml                     # Blueprint configuration
├── build.sh                     # Injection script (runs during blueprint -build)
│
├── Controllers/
│   └── ModpackAPIController.php # API endpoints (manualCheck, getStatus)
│
├── admin/
│   ├── controller.php           # Admin panel logic
│   └── view.blade.php           # Admin panel UI
│
├── console/
│   └── CheckModpackUpdates.php  # Laravel cron command
│
├── database/
│   └── migrations/
│       └── 2024_XX_XX_create_modpackchecker_servers_table.php
│
├── routes/
│   └── client.php               # API route definitions
│
└── views/
    ├── server/
    │   └── wrapper.tsx          # Console "Check for Updates" widget
    └── dashboard/
        └── UpdateBadge.tsx      # Dashboard status dot component

Installation

Prerequisites

  • Pterodactyl Panel v1.11+
  • Blueprint Framework (beta-2026-01 or newer)
  • PHP 8.1+
  • Node.js 18+

Steps

  1. Copy extension to Blueprint directory:

    cp -r blueprint-extension /var/www/pterodactyl/.blueprint/extensions/modpackchecker
    chown -R www-data:www-data /var/www/pterodactyl/.blueprint/extensions/modpackchecker
    
  2. Build the extension:

    cd /var/www/pterodactyl
    blueprint -build
    
  3. Compile frontend assets:

    export NODE_OPTIONS=--openssl-legacy-provider
    yarn build:production
    
  4. Run database migration:

    php artisan migrate
    
  5. Restart PHP-FPM:

    systemctl restart php8.3-fpm
    
  6. Set up cron job:

    # Add to /etc/crontab or crontab -e
    0 */6 * * * www-data cd /var/www/pterodactyl && php artisan modpackchecker:check >> /dev/null 2>&1
    

Configuration

Server Egg Variables

For modpack detection, set these variables in your server's egg:

Variable Description Example
MODPACK_PLATFORM Platform name modrinth, curseforge, ftb, technic
MODPACK_ID Platform-specific ID adrenaserver (Modrinth slug)
MODPACK_CURRENT_VERSION Installed version 1.7.0

CurseForge API Key

CurseForge requires an API key. To configure:

  1. Apply for API access at https://docs.curseforge.com/
  2. Go to Admin Panel → Extensions → ModpackChecker
  3. Enter your API key and save

Usage

Dashboard Badge

No action needed — badges appear automatically for servers that:

  • Have MODPACK_PLATFORM egg variable set
  • Have been checked by the cron job at least once

Manual Check

  1. Go to any server's console page
  2. Click "Check for Updates" button
  3. View results showing modpack name and version status

Cron Command

Run manually for testing:

cd /var/www/pterodactyl
php artisan modpackchecker:check

Output:

Starting modpack update check...
Found 12 servers with modpack configuration
Checking: ATM9 Server (a1b2c3d4-...)
  🟠 UPDATE AVAILABLE: All The Mods 9 - 0.2.60
Checking: Vanilla+ (e5f6g7h8-...)
  🟢 Up to date: Vanilla+ - 1.2.0
Modpack update check complete!

Development

Local Development

  1. Enable Blueprint developer mode in admin panel
  2. Make changes in .blueprint/dev/ or .blueprint/extensions/modpackchecker/
  3. Run blueprint -build after changes
  4. Run yarn build:production for frontend changes

Testing API Endpoints

# Manual check (requires auth token)
curl -X POST "https://panel.example.com/api/client/servers/{uuid}/ext/modpackchecker/check" \
  -H "Authorization: Bearer {token}"

# Get all statuses (requires auth token)
curl "https://panel.example.com/api/client/extensions/modpackchecker/status" \
  -H "Authorization: Bearer {token}"

Adding a New Platform

  1. Add check method to ModpackAPIController.php (e.g., checkNewPlatform())
  2. Add to the match() statement in checkVersion()
  3. Add same method to CheckModpackUpdates.php
  4. Update this README

API Reference

POST /api/client/servers/{server}/ext/modpackchecker/check

Manual version check for a specific server. Makes live API call.

Response:

{
    "success": true,
    "platform": "modrinth",
    "modpack_id": "adrenaserver",
    "modpack_name": "Adrenaserver",
    "latest_version": "1.7.0+1.21.1.fabric",
    "status": "checked"
}

GET /api/client/extensions/modpackchecker/status

Get cached status for all servers accessible to the authenticated user.

Response:

{
    "a1b2c3d4-...": {
        "update_available": true,
        "modpack_name": "All The Mods 9",
        "current_version": "0.2.51",
        "latest_version": "0.2.60"
    },
    "e5f6g7h8-...": {
        "update_available": false,
        "modpack_name": "Adrenaserver",
        "current_version": "1.7.0",
        "latest_version": "1.7.0"
    }
}

Troubleshooting

Badge not showing

  1. Check server has MODPACK_PLATFORM variable set
  2. Run cron command manually: php artisan modpackchecker:check
  3. Check modpackchecker_servers table for entries

"CurseForge API key not configured"

  1. Go to Admin → Extensions → ModpackChecker
  2. Enter your CurseForge API key
  3. Key must have mod read permissions

500 errors on check

  1. Check PHP error log: tail -f /var/log/php8.3-fpm.log
  2. Verify controller namespace: Pterodactyl\BlueprintFramework\Extensions\modpackchecker\Controllers
  3. Restart PHP-FPM: systemctl restart php8.3-fpm

Build.sh not running

  1. Ensure file is executable: chmod +x build.sh
  2. Check Blueprint version supports build scripts
  3. Run manually from panel root: bash .blueprint/extensions/modpackchecker/build.sh

Design Decisions

Why cache instead of live checks?

Rate limits. CurseForge allows ~1000 requests/day for personal keys. A busy panel could exhaust that in hours without caching.

Why 2-second sleep in cron?

Prevents burst traffic to APIs. 50 servers × 2 seconds = ~2 minute runtime, which is acceptable for a background job.

Why inline styles in React?

The component is injected into Pterodactyl's build. Adding CSS classes would require modifying their build pipeline. Inline styles are self-contained.

Why separate console widget and dashboard badge?

Different use cases:

  • Dashboard: Quick overview, needs to be fast → cached
  • Console: User wants current info → live API call is acceptable

Credits

Development Team:

  • Architecture design: Gemini AI
  • Implementation: Chroniclers #52, #62, #63 (Claude instances)
  • Project Lead: Michael "Frostystyle" Krause

Part of Firefrost Gaming
Fire + Frost + Foundation = Where Love Builds Legacy 🔥❄️💙