Comprehensive documentation of: - What works (core functionality, code quality) - What's broken (Blueprint packaging, UX blocker) - Manual deployment steps required for live panel - Gemini's hybrid auto-discovery recommendation - DaemonFileRepository usage for file detection - Database schema additions needed - Next steps (Task #95) - All commits from today's session ModpackChecker is functional but not commercially viable until hybrid detection system is implemented. Signed-off-by: Claude (Chronicler #63) <claude@firefrostgaming.com>
9.6 KiB
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
ModpackApiServicefor 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:
# 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 */}
<ModpackVersionCard />
</>
);
};
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}</p>|{server.name}<UpdateBadge serverUuid={server.uuid} /></p>|' /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 = trueprevents cron from overwriting
Implementation Details
DaemonFileRepository Usage:
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:
$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
- Add
detection_methodandis_user_overriddencolumns to migration - Inject
DaemonFileRepositoryintoCheckModpackUpdatescommand - Implement
detectCurseForge()anddetectModrinth()methods - Update cron logic: egg vars → file detection → skip if manual override
- Test on live panel with real modpack servers
Priority 2: Self-Service UI
- Update
wrapper.tsxwith "Configure Manually" button - Create configuration modal (Platform dropdown + ID input)
- Add new API endpoint:
POST /servers/{server}/configure - Store manual config with
is_user_overridden = true
Priority 3: Fix Blueprint Packaging
- Research Blueprint's native wrapper injection (
conf.ymlfields) - Eliminate dependency on
build.shfor production installs - Re-test full install cycle on clean panel
- Update
modpackchecker-1.0.0.blueprintpackage
Priority 4: Documentation
- Update README with hybrid detection explanation
- Document supported manifest file formats
- Add troubleshooting section
- 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.mdgemini-technic-api-fix-2026-04-06.mdgemini-batch1-review.mdthroughgemini-batch4-review.mdgemini-modpack-detection-consultation.md(today's UX pivot)
Fire + Frost + Foundation = Where Love Builds Legacy 💙🔥❄️