Started work on downloading minecraft
This commit is contained in:
parent
98e03a3e60
commit
ab0bfebe87
@ -11,6 +11,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
@ -146,6 +147,17 @@ func (i *InstanceManager)InstallModpack(modpack Modpack, instanceName string){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *InstanceManager)InstallVanilla(version string, instanceName string) {
|
||||||
|
metadata, err := GetVersionMetadata(version)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Unable to obtain metadata: %s\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Version Metadata: %+v", metadata)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (i *InstanceManager)GetInstances() []Instance{
|
func (i *InstanceManager)GetInstances() []Instance{
|
||||||
return i.instances
|
return i.instances
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,21 @@ func (a *App) CheckPrerequisites() {
|
|||||||
a.Java.InstallJavaVer(21)
|
a.Java.InstallJavaVer(21)
|
||||||
a.Status("Java 21 Installed")
|
a.Status("Java 21 Installed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (App) GetVersions() ([]string, error) {
|
||||||
|
manifest, err := GetVersionManifest()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Manifest Error: %s\n", err)
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
versions := []string{}
|
||||||
|
for _, version := range manifest.Versions {
|
||||||
|
versions = append(versions, version.Id)
|
||||||
|
}
|
||||||
|
return versions, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Status(status string) {
|
func (a *App) Status(status string) {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {GetModpacks, GetModpack} from '../wailsjs/go/main/ModpackManager.js'
|
import {GetModpacks, GetModpack} from '../wailsjs/go/main/ModpackManager.js'
|
||||||
import {InstallModpack, GetInstances, CheckUpdate} from '../wailsjs/go/main/InstanceManager.js'
|
import {InstallVanilla, GetInstances, CheckUpdate} from '../wailsjs/go/main/InstanceManager.js'
|
||||||
import {LaunchInstance} from '../wailsjs/go/main/Prism.js'
|
import {LaunchInstance} from '../wailsjs/go/main/Prism.js'
|
||||||
|
import {GetVersions} from '../wailsjs/go/main/App.js'
|
||||||
import {onMount} from 'svelte'
|
import {onMount} from 'svelte'
|
||||||
import {loading} from './global.ts'
|
import {loading} from './global.ts'
|
||||||
import {slide} from 'svelte/transition'
|
import {slide} from 'svelte/transition'
|
||||||
|
|
||||||
let modpacks: Modpack[] = []
|
let modpacks: string[] = []
|
||||||
let pack: string
|
let pack: string
|
||||||
let instances: Instance[] = []
|
let instances: Instance[] = []
|
||||||
let instance: Instance
|
let instance: Instance
|
||||||
@ -14,10 +15,10 @@
|
|||||||
let name: string = "New Modpack"
|
let name: string = "New Modpack"
|
||||||
|
|
||||||
function updateLists(){
|
function updateLists(){
|
||||||
GetModpacks().then((result) => {
|
GetVersions().then((result) => {
|
||||||
modpacks = result
|
modpacks = result
|
||||||
pack = modpacks[0].Id
|
pack = modpacks[0]
|
||||||
name = modpacks[0].Name
|
name = modpacks[0]
|
||||||
})
|
})
|
||||||
GetInstances().then((result) => {
|
GetInstances().then((result) => {
|
||||||
instances = result
|
instances = result
|
||||||
@ -41,19 +42,15 @@
|
|||||||
|
|
||||||
function install(){
|
function install(){
|
||||||
$loading = true
|
$loading = true
|
||||||
GetModpack(pack).then((result) => {
|
InstallVanilla(pack, name).then(() => {
|
||||||
InstallModpack(result, name).then(() => {
|
|
||||||
updateLists()
|
|
||||||
addingInstance = false
|
addingInstance = false
|
||||||
$loading = false
|
$loading = false
|
||||||
})
|
updateLists()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function onchange(event){
|
function onchange(event){
|
||||||
GetModpack(event.target.value).then((result) => {
|
name = event.target.value
|
||||||
name = result.Name
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +68,7 @@
|
|||||||
<div transition:slide="{{duration:300}}">
|
<div transition:slide="{{duration:300}}">
|
||||||
<select id="pack" on:change={onchange} bind:value={pack} name="pack">Select a Modpack:
|
<select id="pack" on:change={onchange} bind:value={pack} name="pack">Select a Modpack:
|
||||||
{#each modpacks as pack}
|
{#each modpacks as pack}
|
||||||
<option value={pack.Id}>{pack.Name}</option>
|
<option value={pack}>{pack}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
<br/>
|
<br/>
|
||||||
|
2
fclauncher/frontend/wailsjs/go/main/App.d.ts
vendored
2
fclauncher/frontend/wailsjs/go/main/App.d.ts
vendored
@ -3,4 +3,6 @@
|
|||||||
|
|
||||||
export function CheckPrerequisites():Promise<void>;
|
export function CheckPrerequisites():Promise<void>;
|
||||||
|
|
||||||
|
export function GetVersions():Promise<Array<string>>;
|
||||||
|
|
||||||
export function Status(arg1:string):Promise<void>;
|
export function Status(arg1:string):Promise<void>;
|
||||||
|
@ -6,6 +6,10 @@ export function CheckPrerequisites() {
|
|||||||
return window['go']['main']['App']['CheckPrerequisites']();
|
return window['go']['main']['App']['CheckPrerequisites']();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GetVersions() {
|
||||||
|
return window['go']['main']['App']['GetVersions']();
|
||||||
|
}
|
||||||
|
|
||||||
export function Status(arg1) {
|
export function Status(arg1) {
|
||||||
return window['go']['main']['App']['Status'](arg1);
|
return window['go']['main']['App']['Status'](arg1);
|
||||||
}
|
}
|
||||||
|
@ -8,4 +8,6 @@ export function GetInstances():Promise<Array<main.Instance>>;
|
|||||||
|
|
||||||
export function InstallModpack(arg1:main.Modpack,arg2:string):Promise<void>;
|
export function InstallModpack(arg1:main.Modpack,arg2:string):Promise<void>;
|
||||||
|
|
||||||
|
export function InstallVanilla(arg1:string,arg2:string):Promise<void>;
|
||||||
|
|
||||||
export function SearchInstances():Promise<void>;
|
export function SearchInstances():Promise<void>;
|
||||||
|
@ -14,6 +14,10 @@ export function InstallModpack(arg1, arg2) {
|
|||||||
return window['go']['main']['InstanceManager']['InstallModpack'](arg1, arg2);
|
return window['go']['main']['InstanceManager']['InstallModpack'](arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function InstallVanilla(arg1, arg2) {
|
||||||
|
return window['go']['main']['InstanceManager']['InstallVanilla'](arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
export function SearchInstances() {
|
export function SearchInstances() {
|
||||||
return window['go']['main']['InstanceManager']['SearchInstances']();
|
return window['go']['main']['InstanceManager']['SearchInstances']();
|
||||||
}
|
}
|
||||||
|
216
fclauncher/minecraft.go
Normal file
216
fclauncher/minecraft.go
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type McVersionManifestEntry struct {
|
||||||
|
Id string
|
||||||
|
Type string
|
||||||
|
Url string
|
||||||
|
Time time.Time
|
||||||
|
ReleaseTime time.Time
|
||||||
|
Sha1 string
|
||||||
|
ComplianceLevel int
|
||||||
|
}
|
||||||
|
|
||||||
|
type McLatestEntry struct {
|
||||||
|
Release string
|
||||||
|
Snapshot string
|
||||||
|
}
|
||||||
|
|
||||||
|
type McVersionManifest struct {
|
||||||
|
Latest McLatestEntry
|
||||||
|
Versions []McVersionManifestEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
type McArguments struct {
|
||||||
|
Game []string
|
||||||
|
Jvm []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type McAssetIndex struct {
|
||||||
|
Id string
|
||||||
|
Sha1 string
|
||||||
|
Size int
|
||||||
|
TotalSize int
|
||||||
|
Url string
|
||||||
|
}
|
||||||
|
|
||||||
|
type McJavaVersion struct {
|
||||||
|
Component string
|
||||||
|
MajorVersion int
|
||||||
|
}
|
||||||
|
|
||||||
|
type McLibraryArtifact struct {
|
||||||
|
Path string
|
||||||
|
Sha1 string
|
||||||
|
Size int
|
||||||
|
Url string
|
||||||
|
}
|
||||||
|
|
||||||
|
type McLibraryDownload struct {
|
||||||
|
Artifact McLibraryArtifact
|
||||||
|
}
|
||||||
|
|
||||||
|
type McRuleOs struct {
|
||||||
|
Name string
|
||||||
|
Version string
|
||||||
|
ARch string
|
||||||
|
}
|
||||||
|
|
||||||
|
type McRule struct {
|
||||||
|
Action string
|
||||||
|
Features map[string]bool
|
||||||
|
Os McRuleOs
|
||||||
|
}
|
||||||
|
|
||||||
|
type McLibrary struct {
|
||||||
|
Downloads McLibraryDownload
|
||||||
|
Name string
|
||||||
|
Rules []McRule
|
||||||
|
}
|
||||||
|
|
||||||
|
type McDownload struct {
|
||||||
|
Sha1 string
|
||||||
|
Size int
|
||||||
|
Url string
|
||||||
|
}
|
||||||
|
|
||||||
|
type McMetadata struct {
|
||||||
|
Arguments McArguments
|
||||||
|
AssetIndex McAssetIndex
|
||||||
|
Assets string
|
||||||
|
ComplianceLevel int
|
||||||
|
Downloads map[string]McDownload
|
||||||
|
Id string
|
||||||
|
JavaVersion McJavaVersion
|
||||||
|
Libraries []McLibrary
|
||||||
|
Logging interface{}
|
||||||
|
MainClass string
|
||||||
|
MinimumLauncherVersion int
|
||||||
|
ReleaseTime time.Time
|
||||||
|
Time time.Time
|
||||||
|
Type string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVersionManifest() (McVersionManifest, error) {
|
||||||
|
resp, err := http.Get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json")
|
||||||
|
var returnError error = nil
|
||||||
|
if err == nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
if err == nil {
|
||||||
|
versionManifest := McVersionManifest{}
|
||||||
|
err = json.Unmarshal(data, &versionManifest)
|
||||||
|
if err == nil {
|
||||||
|
dir, err := os.UserConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
return versionManifest, nil
|
||||||
|
}
|
||||||
|
err = os.MkdirAll(filepath.Join(dir, "FCLauncher", "cache"), 0755)
|
||||||
|
f, err := os.OpenFile(filepath.Join(dir, "FCLauncher", "cache", "versionManifest.json"), os.O_CREATE|os.O_RDWR, 0755)
|
||||||
|
defer f.Close()
|
||||||
|
f.Write(data)
|
||||||
|
return versionManifest, nil
|
||||||
|
} else {
|
||||||
|
returnError = fmt.Errorf("Unable to parse Json: %e\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
returnError = fmt.Errorf("Unable to read version manifest: %e\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
returnError = fmt.Errorf("Unable to download version manifest: %e\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := os.UserConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
return McVersionManifest{}, returnError
|
||||||
|
}
|
||||||
|
path := filepath.Join(dir, "FCLauncher", "cache", "versionManifest.json")
|
||||||
|
if _, err = os.Stat(path); err != nil {
|
||||||
|
return McVersionManifest{}, returnError
|
||||||
|
}
|
||||||
|
f, err := os.OpenFile(path, os.O_RDONLY, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return McVersionManifest{}, returnError
|
||||||
|
}
|
||||||
|
data, _ := io.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
return McVersionManifest{}, returnError
|
||||||
|
}
|
||||||
|
versionManifest := McVersionManifest{}
|
||||||
|
err = json.Unmarshal(data, &versionManifest)
|
||||||
|
if err != nil {
|
||||||
|
return McVersionManifest{}, returnError
|
||||||
|
}
|
||||||
|
return versionManifest, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVersionMetadata(wantedVersion string) (McMetadata, error) {
|
||||||
|
manifest, err := GetVersionManifest()
|
||||||
|
if err != nil {
|
||||||
|
return McMetadata{}, fmt.Errorf("GetVersionMetadata: %e\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, version := range manifest.Versions {
|
||||||
|
if wantedVersion == version.Id {
|
||||||
|
//found it
|
||||||
|
dir, err := os.UserConfigDir()
|
||||||
|
if err == nil {
|
||||||
|
path := filepath.Join(dir, "FCLauncher", "cache", "versionMetadata", wantedVersion+".json")
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
if f, err := os.OpenFile(path, os.O_RDONLY, 0755); err == nil {
|
||||||
|
defer f.Close()
|
||||||
|
if data, err := io.ReadAll(f); err == nil {
|
||||||
|
sha := sha1.Sum(data)
|
||||||
|
if hex.EncodeToString(sha[:20]) == version.Sha1{
|
||||||
|
metadata := McMetadata{}
|
||||||
|
json.Unmarshal(data, &metadata)
|
||||||
|
fmt.Printf("Found cache!\n")
|
||||||
|
return metadata, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp, err := http.Get(version.Url)
|
||||||
|
if err != nil {
|
||||||
|
return McMetadata{}, fmt.Errorf("Unable to download metadata: %e\n", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return McMetadata{}, fmt.Errorf("Unable to download metadata: %e\n", err)
|
||||||
|
}
|
||||||
|
sha := sha1.Sum(data)
|
||||||
|
if hex.EncodeToString(sha[:20]) != version.Sha1 {
|
||||||
|
return McMetadata{}, fmt.Errorf("GetMetadata: Sha1 hash does not match\n")
|
||||||
|
}
|
||||||
|
metadata := McMetadata{}
|
||||||
|
err = json.Unmarshal(data, &metadata)
|
||||||
|
dir, err = os.UserConfigDir()
|
||||||
|
if err == nil {
|
||||||
|
path := filepath.Join(dir, "FCLauncher", "cache", "versionMetadata")
|
||||||
|
if os.MkdirAll(path, 0755) == nil {
|
||||||
|
if f, err := os.OpenFile(filepath.Join(path, wantedVersion+".json"), os.O_CREATE|os.O_RDWR, 0755); err == nil {
|
||||||
|
defer f.Close()
|
||||||
|
f.Write(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return metadata, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return McMetadata{}, fmt.Errorf("Unable to find version %s\n", wantedVersion)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user