// 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 }