package main import ( "archive/tar" "bufio" "bytes" "compress/gzip" "fmt" "io" "os" "os/exec" "path/filepath" "runtime" "strings" "time" "github.com/zhyee/zipstream" ) type Prism struct { app *App } func (Prism) CheckInstalled() bool { path, _ := os.UserConfigDir() _, err := os.Stat(filepath.Join(path, "FCLauncher", "prism")) if err == nil { return true } else { return false } } func (p *Prism) Install() { suffix := "lin.tar.gz" shortSuffix := "lin" if runtime.GOOS == "windows" { suffix = "win.zip" shortSuffix = "win" } buff := new(bytes.Buffer) HttpDownload("prism/prism-"+suffix, buff, p.app.Ctx) path, _ := os.UserConfigDir() os.MkdirAll(filepath.Join(path, "FCLauncher", "prism"), 0755) if runtime.GOOS == "windows" { zr := zipstream.NewReader(buff) for { entry, err := zr.GetNextEntry() if err == io.EOF { break } if err != nil { return } target := filepath.Join(path, "FCLauncher", "prism", entry.Name) if !entry.IsDir() { rc, err := entry.Open() if err != nil { return } f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, entry.FileInfo().Mode()) if err != nil { return } if _, err := io.Copy(f, rc); err != nil { return } f.Close() rc.Close() } else { if _, err := os.Stat(target); err != nil { if err := os.MkdirAll(target, 0755); err != nil { return } } } } } else { gzip, _ := gzip.NewReader(buff) defer gzip.Close() tr := tar.NewReader(gzip) out: for { header, err := tr.Next() switch { case err == io.EOF: break out case err != nil: return case header == nil: continue } target := filepath.Join(path, "FCLauncher", "prism", header.Name) switch header.Typeflag { case tar.TypeDir: if _, err := os.Stat(target); err != nil { if err := os.MkdirAll(target, 0755); err != nil { return } } case tar.TypeReg: f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) if err != nil { return } if _, err := io.Copy(f, tr); err != nil { return } f.Close() } } } dir, _ := os.UserConfigDir() buff = new(bytes.Buffer) HttpDownload("prism/prismlauncher.cfg", buff, nil) scanner := bufio.NewScanner(buff) f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "prism", "prismlauncher.cfg"), os.O_CREATE|os.O_RDWR, 0755) defer f.Close() for scanner.Scan() { line := scanner.Text() if strings.HasPrefix(line, "JavaPath") { line = fmt.Sprintf("JavaPath=%s/FCLauncher/java/java-21-%s", strings.ReplaceAll(dir, "\\", "/"), shortSuffix) } if strings.HasPrefix(line, "LastHostname") { host, _ := os.Hostname() line = fmt.Sprintf("LastHostname=%s", host) } f.WriteString(line + "\n") } } func (Prism)GetInstanceDir() string{ dir, _ := os.UserConfigDir() return filepath.Join(dir, "FCLauncher", "prism", "instances") } func (Prism)getExecutableName() string { execName := "PrismLauncher" if runtime.GOOS == "windows" { execName = "prismlauncher.exe" } return execName } func (p *Prism)ImportModpack(path string) { dir, _ := os.UserConfigDir() child := exec.Command(filepath.Join(dir, "FCLauncher", "prism", p.getExecutableName()), "-I", path) child.Start() tokens := strings.Split(path, string(os.PathSeparator)) versionPath := filepath.Join(dir, "FCLauncher", "prism", "instances",strings.Split(tokens[len(tokens)-1], ".")[0], ".minecraft", "version.txt") for { time.Sleep(time.Second * 3) if _, err := os.Stat(versionPath); err == nil { break } } child.Process.Kill() } func (p *Prism)LaunchInstance(instance Instance) { p.app.Status(fmt.Sprintf("Launching %s", instance.InstanceName)) dir, _ := os.UserConfigDir() child := exec.Command(filepath.Join(dir, "FCLauncher", "prism", p.getExecutableName()), "-l", instance.InstanceName) child.Start() }