# ModpackChecker Development Status Report **Date:** April 6, 2026 **Task:** #26 - Modpack Version Checker (Blueprint Extension) **Status:** Development Paused — Awaiting Hybrid Detection Implementation **Chronicler:** #63 --- ## Executive Summary ModpackChecker is functionally complete but **not commercially viable** in its current state. The extension requires manual egg variable configuration per server, which is unacceptable for: - Michael's 21 production servers - BuiltByBit customers expecting plug-and-play **Next milestone:** Implement hybrid auto-discovery system before BuiltByBit launch. --- ## What Works ✅ ### Core Functionality - **Dashboard Badge:** Colored dot next to server names (orange=update, cyan=current) - **Console Widget:** StatBlock-style card in right column with click-to-check - **Admin Panel:** CurseForge API key config, dark theme callouts, PRO tier badges - **API Routes:** Clean URLs, no double-prefixing - **4-Platform Support:** CurseForge, Modrinth, FTB, Technic - **Rate Limiting:** 2 requests/minute per server, 429 handling in UI - **Caching:** 60-second TTL on dashboard, 12-hour Technic build cache ### Code Quality - Centralized `ModpackApiService` for all API calls - Short error codes in UI ("Not configured", "Wait 60s", "API error") - Gemini-reviewed architecture (4 batch review complete) - Proper authorship (Firefrost Gaming / Frostystyle) --- ## What's Broken ❌ ### Blueprint Packaging Issues **Problem:** Blueprint production install behaves differently than dev mode. | Issue | Dev Mode | Production Install | |-------|----------|-------------------| | `build.sh` execution | ✅ Runs | ❌ Does NOT run | | App files (Controllers, Services, Commands) | Auto-copied via conf.yml | ❌ Stays in `.blueprint/extensions/` subfolder | | Frontend injection | Via build.sh sed commands | ❌ Must use conf.yml wrapper fields | | File locations | `.blueprint/dev/` | `.blueprint/extensions/modpackchecker/` (reorganized) | **Root Cause:** Our `conf.yml` uses `requests.app: "app"` which tells Blueprint where source files are, but we relied on `build.sh` to inject React components. Blueprint doesn't run build.sh on `blueprint -install`. **Solution Required:** Rewrite `conf.yml` to use Blueprint's native wrapper injection fields OR find the correct production deployment method. ### Manual Deployment Steps Required (Live Panel) When installing on a fresh panel, these manual steps were required: ```bash # 1. Copy PHP files to correct locations cp .blueprint/extensions/modpackchecker/app/Http/Controllers/ModpackAPIController.php /var/www/pterodactyl/app/Http/Controllers/ cp .blueprint/extensions/modpackchecker/app/Services/ModpackApiService.php /var/www/pterodactyl/app/Services/ cp .blueprint/extensions/modpackchecker/app/Console/Commands/CheckModpackUpdates.php /var/www/pterodactyl/app/Console/Commands/ # 2. Copy React components cp .blueprint/extensions/modpackchecker/views/server/wrapper.tsx /var/www/pterodactyl/resources/scripts/components/server/ModpackVersionCard.tsx cp .blueprint/extensions/modpackchecker/views/dashboard/UpdateBadge.tsx /var/www/pterodactyl/resources/scripts/components/dashboard/UpdateBadge.tsx # 3. Inject into AfterInformation.tsx cat > /var/www/pterodactyl/resources/scripts/blueprint/components/Server/Terminal/AfterInformation.tsx << 'EOF' import React from 'react'; import ModpackVersionCard from "@/components/server/ModpackVersionCard"; /* blueprint/import */ export default () => { return ( <> {/* blueprint/react */} ); }; EOF # 4. Inject UpdateBadge into ServerRow.tsx sed -i '1i import UpdateBadge from "@/components/dashboard/UpdateBadge";' /var/www/pterodactyl/resources/scripts/components/dashboard/ServerRow.tsx sed -i 's|{server.name}

|{server.name}

|' /var/www/pterodactyl/resources/scripts/components/dashboard/ServerRow.tsx # 5. Rebuild composer dump-autoload php artisan optimize:clear export NODE_OPTIONS=--openssl-legacy-provider && yarn build:production ``` ### UX Blocker — Egg Variable Dependency **The showstopper:** ModpackChecker requires these egg variables per server: - `MODPACK_PLATFORM` (curseforge, modrinth, ftb, technic) - `MODPACK_ID` (platform-specific ID) - `MODPACK_CURRENT_VERSION` (optional, for update detection) **Problem:** Standard Forge/NeoForge/Fabric eggs don't have these variables. Adding them requires: - Modifying every egg - Configuring every server - Teaching customers how to find modpack IDs This is unacceptable for commercial release. --- ## Gemini's Recommended Solution ### Hybrid Auto-Discovery + Self-Service Model **Phase 1: Auto-Discovery (Cron Job)** ``` 1. Check egg variables (fastest) 2. If missing → Read manifest.json via DaemonFileRepository (CurseForge) 3. If missing → Read modrinth.index.json (Modrinth) 4. Save to DB with detection_method = 'egg' | 'file' | 'manual' ``` **Phase 2: Self-Service Fallback (Console Widget)** - If unconfigured: Show "Configure Manually" button - Modal lets server owner select platform + paste modpack ID - Saves to DB with `detection_method = 'manual'` - `is_user_overridden = true` prevents cron from overwriting ### Implementation Details **DaemonFileRepository Usage:** ```php use Pterodactyl\Repositories\Wings\DaemonFileRepository; private function detectCurseForge(Server $server): ?string { try { $this->fileRepository->setServer($server); $content = $this->fileRepository->getContent('manifest.json'); $manifest = json_decode($content, true); return $manifest['projectID'] ?? null; } catch (\Exception $e) { return null; } } ``` **Database Schema Additions:** ```php $table->string('detection_method')->default('unknown'); // egg, file, manual $table->boolean('is_user_overridden')->default(false); // prevents auto-overwrite ``` **Critical Warning from Gemini:** - File detection via Wings API is a network call - **NEVER do this on page load** — only in cron job - CurseForge fingerprinting is **rejected** — too resource intensive --- ## File Locations ### Repository ``` firefrost-services/services/modpack-version-checker/ ├── blueprint-extension/ # Source code │ ├── conf.yml │ ├── build.sh │ ├── README.md │ ├── CHANGELOG.md │ ├── icon.png │ ├── app/ │ │ ├── Console/Commands/CheckModpackUpdates.php │ │ ├── Http/Controllers/ModpackAPIController.php │ │ └── Services/ModpackApiService.php │ ├── admin/ │ │ ├── controller.php │ │ └── view.blade.php │ ├── database/migrations/ │ ├── routes/client.php │ └── views/ │ ├── server/wrapper.tsx │ └── dashboard/UpdateBadge.tsx └── releases/ └── modpackchecker-1.0.0.blueprint # Packaged (has issues) ``` ### Dev Panel (64.50.188.128) - Extension dev folder: `/var/www/pterodactyl/.blueprint/dev/` - Works correctly in dev mode ### Live Panel (45.94.168.138) - Extension folder: `/var/www/pterodactyl/.blueprint/extensions/modpackchecker/` - Required manual file copying (see above) - Panel version: 1.12.1 (dev is 1.12.2) --- ## API Endpoints ``` POST /api/client/extensions/modpackchecker/servers/{server}/check → Manual version check, rate limited 2/min GET /api/client/extensions/modpackchecker/status → Returns cached status for all user's servers ``` --- ## Testing Notes ### CurseForge Test Data - **FTB StoneBlock 4:** Project ID `1373378` - Latest version as of April 2026: `1.9.6` ### Modrinth Test Data (no API key needed) - **Adrenaserver:** Slug `adrenaserver` --- ## Next Steps (Task #95) ### Priority 1: Hybrid Detection System 1. Add `detection_method` and `is_user_overridden` columns to migration 2. Inject `DaemonFileRepository` into `CheckModpackUpdates` command 3. Implement `detectCurseForge()` and `detectModrinth()` methods 4. Update cron logic: egg vars → file detection → skip if manual override 5. Test on live panel with real modpack servers ### Priority 2: Self-Service UI 1. Update `wrapper.tsx` with "Configure Manually" button 2. Create configuration modal (Platform dropdown + ID input) 3. Add new API endpoint: `POST /servers/{server}/configure` 4. Store manual config with `is_user_overridden = true` ### Priority 3: Fix Blueprint Packaging 1. Research Blueprint's native wrapper injection (`conf.yml` fields) 2. Eliminate dependency on `build.sh` for production installs 3. Re-test full install cycle on clean panel 4. Update `modpackchecker-1.0.0.blueprint` package ### Priority 4: Documentation 1. Update README with hybrid detection explanation 2. Document supported manifest file formats 3. Add troubleshooting section 4. Screenshot gallery for BuiltByBit listing --- ## Commits Today | Hash | Message | |------|---------| | 35315c2 | Batch 1 fixes - routes, migration, build.sh | | 8e37120 | Batch 2 fixes - ModpackApiService, rate limiting | | 5a607c8 | Batch 3+4 fixes - frontend, admin, docs | | d735e3d | Wizard review fixes - UI polish | | c160647 | Move card to right column, StatBlock style | | 05d2164 | Console card redesign - short error codes | | 6e15a62 | Update website link to Discord | | 1a3e884 | Release v1.0.0 packaged blueprint file | | e59ee04 | Fix check_interval validation (nullable) | --- ## Gemini Consultations All saved in `docs/consultations/`: - `gemini-blueprint-confyml-2026-04-06.md` - `gemini-technic-api-fix-2026-04-06.md` - `gemini-batch1-review.md` through `gemini-batch4-review.md` - `gemini-modpack-detection-consultation.md` (today's UX pivot) --- *Fire + Frost + Foundation = Where Love Builds Legacy* 💙🔥❄️