- manifest: Manifest struct (files, launch config, server info), LoadManifest, LibraryFiles/ModFiles filters - launch: Game struct (Prepare/BuildCommand/Start lifecycle) - Prepare: download manifest, resolve Java, sync files with SHA-1, soft-delete unknown mods - BuildCommand: classpath assembly, variable interpolation (, , etc.), authlib-injector injection - Start: execute the assembled command - interpolate: template replacement - cleanupUnknownMods: moves untracked mods to mods_backup/ Co-Authored-By: OWL <noreply@anthropic.com>
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
// package launch handles Minecraft process launching.
|
|
package launch
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
// Manifest describes the contents of a modpack as provided by the backend.
|
|
type Manifest struct {
|
|
MinecraftVersion string `json:"minecraft_version"`
|
|
JavaVersion int `json:"java_version"`
|
|
ServerInfo ServerInfo `json:"server_info"`
|
|
Files []ManifestFile `json:"files"`
|
|
Launch LaunchConfig `json:"launch"`
|
|
}
|
|
|
|
// ServerInfo is the game server address injected into servers.dat.
|
|
type ServerInfo struct {
|
|
Name string `json:"name"`
|
|
IP string `json:"ip"`
|
|
}
|
|
|
|
// ManifestFile is a single file entry with SHA-1 verification.
|
|
type ManifestFile struct {
|
|
Path string `json:"path"`
|
|
Hash string `json:"hash"`
|
|
Size int64 `json:"size"`
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
// LaunchConfig contains the JVM and game arguments template.
|
|
type LaunchConfig struct {
|
|
MainClass string `json:"mainClass"`
|
|
JVMArgs []string `json:"jvmArgs"`
|
|
GameArgs []string `json:"gameArgs"`
|
|
NativeLibs []string `json:"nativeLibs"`
|
|
AuthLibInjector string `json:"authLibInjector"` // URL to authlib-injector.jar
|
|
}
|
|
|
|
// LoadManifest reads and parses a manifest.json from disk.
|
|
func LoadManifest(path string) (*Manifest, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("reading manifest %s: %w", path, err)
|
|
}
|
|
var m Manifest
|
|
if err := json.Unmarshal(data, &m); err != nil {
|
|
return nil, fmt.Errorf("parsing manifest %s: %w", path, err)
|
|
}
|
|
return &m, nil
|
|
}
|
|
|
|
// LibraryFiles returns the subset of Files that are .jar libraries (classpath).
|
|
func (m *Manifest) LibraryFiles() []ManifestFile {
|
|
var libs []ManifestFile
|
|
for _, f := range m.Files {
|
|
if len(f.Path) > 4 && f.Path[len(f.Path)-4:] == ".jar" {
|
|
libs = append(libs, f)
|
|
}
|
|
}
|
|
return libs
|
|
}
|
|
|
|
// ModFiles returns the subset of Files that go into the mods/ directory.
|
|
func (m *Manifest) ModFiles() []ManifestFile {
|
|
var mods []ManifestFile
|
|
for _, f := range m.Files {
|
|
if len(f.Path) > 5 && f.Path[:5] == "mods/" {
|
|
mods = append(mods, f)
|
|
}
|
|
}
|
|
return mods
|
|
}
|