Consultation Round 3: Wings API works, manifest.json doesn't survive install
Proved DaemonFileRepository works via live test. Proved manifest.json is discarded after installation on all tested servers. Sneak's Pirate Pack false positive documented. New ideas: fingerprinting, .modpackchecker file, calibration UX.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# Gemini Consultation: Installer Version Detection — Round 3
|
||||
|
||||
**Date:** April 13, 2026
|
||||
**From:** Michael (The Wizard) + Claude (Chronicler #85)
|
||||
**To:** Gemini (Architectural Partner)
|
||||
**Re:** Wings API works but manifest.json doesn't survive installation — new findings
|
||||
|
||||
---
|
||||
|
||||
## Hey Gemini! 👋
|
||||
|
||||
We tested your proposal directly against live servers before writing a single line
|
||||
of code. Good news and bad news.
|
||||
|
||||
---
|
||||
|
||||
## What We Proved
|
||||
|
||||
### ✅ Wings API via DaemonFileRepository WORKS
|
||||
|
||||
We ran a live test using Pterodactyl's `DaemonFileRepository` from within the
|
||||
Panel's PHP/Laravel context (via `php artisan tinker`). It authenticated correctly
|
||||
and we successfully listed directory contents from a live server. The approach
|
||||
is technically sound.
|
||||
|
||||
```php
|
||||
$repo = app(\Pterodactyl\Repositories\Wings\DaemonFileRepository::class)
|
||||
->setServer($server);
|
||||
$dir = $repo->getDirectory('/'); // Works perfectly
|
||||
```
|
||||
|
||||
### ❌ manifest.json Does NOT Survive Installation
|
||||
|
||||
We checked multiple servers — DeceasedCraft (CurseForge), All The Mods 10
|
||||
(CurseForge), and others. None of them have `manifest.json`, `minecraftinstance.json`,
|
||||
`modpack.json`, `pack.json`, or `version.json` in their root directories after
|
||||
installation.
|
||||
|
||||
The Pterodactyl modpack installer unpacks the files and discards the manifest.
|
||||
By the time ModpackChecker runs, there's no version file to read.
|
||||
|
||||
Files we found in DeceasedCraft root (representative sample):
|
||||
```
|
||||
config/, mods/, libraries/, logs/, scripts/
|
||||
banned-ips.json, banned-players.json, ops.json
|
||||
forge-1.18.2-40.2.4-installer.jar.log
|
||||
server.jar, server.properties, eula.txt
|
||||
```
|
||||
|
||||
No manifest. No version file. Nothing we can parse for version info.
|
||||
|
||||
### ⚠️ The "Up To Date" False Positive Problem
|
||||
|
||||
Sneak's Pirate Pack shows a blue checkmark (up to date). But it's not detecting
|
||||
correctly — it seeded `current_version` from the latest API result
|
||||
(`Sneak's Pirate Pack NEW`) and since that's the only release, current === latest.
|
||||
Technically "correct" but for the wrong reason. Same root bug everywhere.
|
||||
|
||||
---
|
||||
|
||||
## The Core Problem Restated
|
||||
|
||||
After installation, there is NO file on the server filesystem that tells us
|
||||
which version of the modpack is installed. The installer uses and discards
|
||||
the manifest. The only record of what was installed is in the
|
||||
`modpack_installations` table — which only has `provider` and `modpack_id`,
|
||||
no version.
|
||||
|
||||
---
|
||||
|
||||
## New Wild Ideas Based On What We Found
|
||||
|
||||
Given these constraints, here's what we're thinking — please poke holes or
|
||||
confirm:
|
||||
|
||||
1. **CurseForge File ID from the installer log filename** — We found
|
||||
`forge-1.18.2-40.2.4-installer.jar.log` in the root. That's the Forge
|
||||
version, not the modpack. But could there be a CurseForge-specific log
|
||||
or temp file left behind that contains the pack file ID?
|
||||
|
||||
2. **Read the `mods/` directory and fingerprint** — CurseForge has a
|
||||
fingerprinting API. Could we get a list of mod jar filenames from the
|
||||
`mods/` directory via Wings, hash them or use their names, and match
|
||||
against CurseForge's fingerprint API to identify the exact pack version?
|
||||
Wild, but CurseForge actually supports this.
|
||||
|
||||
3. **Write our own version file at calibration time** — When the admin first
|
||||
sets up ModpackChecker (or clicks "Force Version Sync"), we write a small
|
||||
`.modpackchecker` file to the server root via Wings `putContent()`. It
|
||||
stores `{"version": "5.10.15", "file_id": "xxx"}`. Future cron runs read
|
||||
this file instead of manifest.json. The file persists across server
|
||||
restarts. Only gets updated when the admin updates and clicks sync.
|
||||
|
||||
4. **Accept "Unknown" for now, make calibration the UX** — For April 15,
|
||||
show "Version Unknown — Click to Calibrate" state. The calibrate dropdown
|
||||
already exists and lets the admin pick their current version from the
|
||||
release history. Once they pick it, we store the file ID and future
|
||||
comparisons are accurate. Not zero-config, but one-time-per-server setup.
|
||||
|
||||
5. **Something we haven't thought of** — You know this space better than we
|
||||
do. Is there anything in the CurseForge API, Pterodactyl internals, or
|
||||
Wings that could give us the installed file ID without manual input?
|
||||
|
||||
---
|
||||
|
||||
## Constraints Reminder
|
||||
|
||||
- Cannot require manual admin intervention as standard workflow
|
||||
- Wings API is available and working (DaemonFileRepository confirmed)
|
||||
- `putContent()` is also available — we CAN write files to server filesystem
|
||||
- `current_file_id` and `latest_file_id` columns exist and ready
|
||||
- April 15 soft launch — pragmatic wins
|
||||
- This is a BuiltByBit product — solution must work for any Pterodactyl install
|
||||
|
||||
---
|
||||
|
||||
Thanks Gemini! 🔥❄️
|
||||
|
||||
— Michael + Claude (Chronicler #85)
|
||||
Reference in New Issue
Block a user