Merge branch 'golang-dev' of https://gitea.piwalker.net/piwalker/FCLauncher into golang-dev

This commit is contained in:
cuptain 2024-11-02 12:14:08 +11:00
commit 6f6a00cb45
5 changed files with 174 additions and 2 deletions

View File

@ -289,6 +289,10 @@ func (i *InstanceManager) LaunchInstance(instance string) {
if err != nil { if err != nil {
fmt.Printf("unable to get launch args: %s\n", err) fmt.Printf("unable to get launch args: %s\n", err)
} }
if instanceObject.ForgeVersion != "" {
args = append(args, "--launchTarget")
args = append(args, "forge_client")
}
fmt.Printf("Args: %+v", args) fmt.Printf("Args: %+v", args)
child := exec.Command(filepath.Join(dir, "java", fmt.Sprintf("java-%d-%s", instanceObject.JavaVersion, suffix), "bin", execName), args...) child := exec.Command(filepath.Join(dir, "java", fmt.Sprintf("java-%d-%s", instanceObject.JavaVersion, suffix), "bin", execName), args...)
child.Dir = filepath.Join(dir, "instances", instance, "minecraft") child.Dir = filepath.Join(dir, "instances", instance, "minecraft")
@ -415,3 +419,44 @@ common:
} }
} }
} }
func (i *InstanceManager) InstallForge(instance string, forgeVersion string) {
instanceObject, err := i.GetInstance(instance)
if err != nil {
fmt.Printf("Unable to find instance: %s\n", err)
}
installData, err := GetForgeInstallData(instanceObject.MinecraftVersion, forgeVersion)
if err != nil {
fmt.Printf("Unable to get install data: %s\n", err)
}
dir, _ := os.UserConfigDir()
InstallForgeLibs(instanceObject.MinecraftVersion, forgeVersion, filepath.Join(dir, "FCLauncher", "lib"))
instanceObject.ForgeVersion = forgeVersion
outer:
for _, lib := range installData.Libraries {
tokens := strings.Split(lib.Downloads.Artifact.Path, string(os.PathSeparator))
pkg := tokens[len(tokens)-2]
instanceObject.Libraries = append(instanceObject.Libraries, lib.Downloads.Artifact.Path)
for ind, path := range instanceObject.Libraries {
tokens := strings.Split(path, string(os.PathSeparator))
if pkg == tokens[len(tokens)-3] {
instanceObject.Libraries[ind] = filepath.Join(ProcessMavenPath(lib.Name), ProcessMavenFilename(lib.Name))
fmt.Printf("duplicate library %s\n", pkg)
continue outer
}
}
}
instanceObject.MainClass = installData.MainClass
f, _ := os.OpenFile(filepath.Join(dir, "FCLauncher", "instances", instance, "instance.json"), os.O_CREATE|os.O_RDWR, 0755)
data, _ := json.Marshal(instanceObject)
defer f.Close()
f.Write(data)
for ind, inst := range i.instances {
if inst.InstanceName == instance {
i.instances[ind] = instanceObject
break
}
}
}

View File

@ -1,10 +1,18 @@
package main package main
import ( import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"os"
"path/filepath"
"strings" "strings"
"time"
"github.com/zhyee/zipstream"
) )
type Forge struct{} type Forge struct{}
@ -15,6 +23,31 @@ type ForgeVersion struct {
Url string Url string
} }
type ForgeLibraryArtifact struct {
Path string
Url string
Sha1 string
}
type ForgeLibraryDownload struct {
Artifact ForgeLibraryArtifact
}
type ForgeLibrary struct {
Name string
Downloads ForgeLibraryDownload
}
type ForgeInstallData struct {
Id string
Time time.Time
ReleaseTime time.Time
InheritsFrom string
Type string
MainClass string
Libraries []ForgeLibrary
}
func parseForgeVersions(html string) []ForgeVersion { func parseForgeVersions(html string) []ForgeVersion {
lines := strings.Split(html, "\n") lines := strings.Split(html, "\n")
parsing := false parsing := false
@ -68,3 +101,85 @@ func (Forge) GetForgeVersions(mcVersion string) ([]ForgeVersion, error) {
data, _ := io.ReadAll(resp.Body) data, _ := io.ReadAll(resp.Body)
return parseForgeVersions(string(data)), nil return parseForgeVersions(string(data)), nil
} }
func GetForgeInstallDataFromVersion(version ForgeVersion) (ForgeInstallData, error) {
resp, err := http.Get(version.Url)
if err != nil {
return ForgeInstallData{}, fmt.Errorf("unable to pull jar file: %e", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return ForgeInstallData{}, fmt.Errorf("unable to pull jar file: %s", resp.Status)
}
zs := zipstream.NewReader(resp.Body)
for {
entry, err := zs.GetNextEntry()
if err == io.EOF {
break
}
if entry.Name != "version.json" {
continue
}
f, _ := entry.Open()
defer f.Close()
data, _ := io.ReadAll(f)
installData := ForgeInstallData{}
json.Unmarshal(data, &installData)
return installData, nil
}
return ForgeInstallData{}, fmt.Errorf("unable to find version.json")
}
func GetForgeInstallData(mcVersion string, forgeVersion string) (ForgeInstallData, error) {
versions, err := Forge{}.GetForgeVersions(mcVersion)
if err != nil {
return ForgeInstallData{}, fmt.Errorf("failed to pull forge versions: %e", err)
}
for _, version := range versions {
if version.Version == forgeVersion {
return GetForgeInstallDataFromVersion(version)
}
}
return ForgeInstallData{}, fmt.Errorf("unable to find the requested version")
}
func InstallForgeLibs(mcVersion string, forgeVersion string, libDir string) {
installData, err := GetForgeInstallData(mcVersion, forgeVersion)
if err != nil {
fmt.Printf("Unable to get install data: %s\n", err)
}
for _, lib := range installData.Libraries {
if _, err := os.Stat(filepath.Join(libDir, lib.Downloads.Artifact.Path)); err == nil {
if f, err := os.OpenFile(filepath.Join(libDir, lib.Downloads.Artifact.Path), os.O_RDONLY, 0755); err == nil {
defer f.Close()
data, _ := io.ReadAll(f)
sha := sha1.Sum(data)
if hex.EncodeToString(sha[:20]) == lib.Downloads.Artifact.Sha1 {
continue
}
}
}
resp, err := http.Get(lib.Downloads.Artifact.Url)
if err != nil {
fmt.Printf("Unable to download library %s: %s\n", lib.Name, err)
continue
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
fmt.Printf("Unable to download library %s: %s\n", lib.Name, resp.Status)
continue
}
tokens := strings.Split(lib.Downloads.Artifact.Path, "/")
path := ""
for ind, token := range tokens {
if ind == len(tokens)-1 {
break
}
path = filepath.Join(path, token)
}
os.MkdirAll(filepath.Join(libDir, path), 0755)
f, _ := os.OpenFile(filepath.Join(libDir, lib.Downloads.Artifact.Path), os.O_CREATE|os.O_RDWR, 0755)
defer f.Close()
io.Copy(f, resp.Body)
}
}

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import {InstallVanilla, LaunchInstance, GetInstances, InstallQuilt, InstallFabric, CheckUpdate} from '../wailsjs/go/main/InstanceManager.js' import {InstallVanilla, LaunchInstance, GetInstances, InstallForge, InstallQuilt, InstallFabric, CheckUpdate} from '../wailsjs/go/main/InstanceManager.js'
import {GetVersions} from '../wailsjs/go/main/App.js' import {GetVersions} from '../wailsjs/go/main/App.js'
import {GetFabricVersions} from '../wailsjs/go/main/Fabric.js' import {GetFabricVersions} from '../wailsjs/go/main/Fabric.js'
import {GetQuiltVersions} from '../wailsjs/go/main/Quilt.js' import {GetQuiltVersions} from '../wailsjs/go/main/Quilt.js'
@ -93,7 +93,13 @@
$loading = false $loading = false
updateLists() updateLists()
}) })
case "forge":
InstallForge(name, forge_ver).then(() => {
$addingInstance = false
$loading = false
updateLists()
})
break
} }
}) })
} }

View File

@ -10,6 +10,8 @@ export function GetInstances():Promise<Array<string>>;
export function InstallFabric(arg1:string,arg2:string):Promise<void>; export function InstallFabric(arg1:string,arg2:string):Promise<void>;
export function InstallForge(arg1:string,arg2:string):Promise<void>;
export function InstallModpack(arg1:main.Modpack,arg2:string):Promise<void>; export function InstallModpack(arg1:main.Modpack,arg2:string):Promise<void>;
export function InstallQuilt(arg1:string,arg2:string):Promise<void>; export function InstallQuilt(arg1:string,arg2:string):Promise<void>;

View File

@ -18,6 +18,10 @@ export function InstallFabric(arg1, arg2) {
return window['go']['main']['InstanceManager']['InstallFabric'](arg1, arg2); return window['go']['main']['InstanceManager']['InstallFabric'](arg1, arg2);
} }
export function InstallForge(arg1, arg2) {
return window['go']['main']['InstanceManager']['InstallForge'](arg1, arg2);
}
export function InstallModpack(arg1, arg2) { export function InstallModpack(arg1, arg2) {
return window['go']['main']['InstanceManager']['InstallModpack'](arg1, arg2); return window['go']['main']['InstanceManager']['InstallModpack'](arg1, arg2);
} }