Add support for multiple components in mod loaders

This commit is contained in:
comp500 2019-09-19 02:17:28 +01:00
parent 79a62c735e
commit 1dc5618bca

View File

@ -16,9 +16,9 @@ import (
"github.com/comp500/packwiz/core" "github.com/comp500/packwiz/core"
"github.com/fatih/camelcase" "github.com/fatih/camelcase"
"github.com/igorsobreira/titlecase"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/igorsobreira/titlecase"
) )
// initCmd represents the init command // initCmd represents the init command
@ -130,37 +130,46 @@ var initCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
var modLoaderVersion string modLoaderVersions := make(map[string]string)
if modLoaderName != "none" { if modLoaderName != "none" {
versions, latestVersion, err := modLoaders[modLoaderName](mcVersion) components := modLoaders[modLoaderName]
modLoaderVersion = viper.GetString("init.modloader-version")
if len(modLoaderVersion) == 0 { for _, component := range components {
if viper.GetBool("init.modloader-latest") { versions, latestVersion, err := component.VersionListGetter(mcVersion)
modLoaderVersion = latestVersion if err != nil {
} else { fmt.Printf("Error loading versions: %s\n", err)
fmt.Print("Mod loader version [" + latestVersion + "]: ") os.Exit(1)
modLoaderVersion, err = bufio.NewReader(os.Stdin).ReadString('\n') }
if err != nil { componentVersion := viper.GetString("init." + component.Name + "-version")
fmt.Printf("Error reading input: %s\n", err) if len(componentVersion) == 0 {
os.Exit(1) if viper.GetBool("init." + component.Name + "-latest") {
} componentVersion = latestVersion
// Trims both CR and LF } else {
modLoaderVersion = strings.ToLower(strings.TrimSpace(strings.TrimRight(modLoaderVersion, "\r\n"))) fmt.Print(component.FriendlyName + " version [" + latestVersion + "]: ")
if len(modLoaderVersion) == 0 { componentVersion, err = bufio.NewReader(os.Stdin).ReadString('\n')
modLoaderVersion = latestVersion if err != nil {
fmt.Printf("Error reading input: %s\n", err)
os.Exit(1)
}
// Trims both CR and LF
componentVersion = strings.ToLower(strings.TrimSpace(strings.TrimRight(componentVersion, "\r\n")))
if len(componentVersion) == 0 {
componentVersion = latestVersion
}
} }
} }
} found := false
found := false for _, v := range versions {
for _, v := range versions { if componentVersion == v {
if modLoaderVersion == v { found = true
found = true break
break }
} }
} if !found {
if !found { fmt.Println("Given " + component.FriendlyName + " version cannot be found!")
fmt.Println("Given mod loader version cannot be found!") os.Exit(1)
os.Exit(1) }
modLoaderVersions[component.Name] = componentVersion
} }
} }
@ -194,7 +203,9 @@ var initCmd = &cobra.Command{
}, },
} }
if modLoaderName != "none" { if modLoaderName != "none" {
pack.Versions[modLoaderName] = modLoaderVersion for k, v := range modLoaderVersions {
pack.Versions[k] = v
}
} }
// Refresh the index and pack // Refresh the index and pack
@ -233,7 +244,7 @@ func init() {
initCmd.Flags().String("name", "", "The name of the modpack (omit to define interactively)") initCmd.Flags().String("name", "", "The name of the modpack (omit to define interactively)")
initCmd.Flags().String("index-file", "index.toml", "The index file to use") initCmd.Flags().String("index-file", "index.toml", "The index file to use")
viper.BindPFlag("init.index-file", initCmd.Flags().Lookup("index-file")) viper.BindPFlag("init.index-file", initCmd.Flags().Lookup("index-file"))
initCmd.Flags().String("mc-version", "", "The version of Minecraft to use (omit to define interactively)") initCmd.Flags().String("mc-version", "", "The Minecraft version to use (omit to define interactively)")
viper.BindPFlag("init.mc-version", initCmd.Flags().Lookup("mc-version")) viper.BindPFlag("init.mc-version", initCmd.Flags().Lookup("mc-version"))
initCmd.Flags().BoolP("latest", "l", false, "Automatically select the latest version of Minecraft") initCmd.Flags().BoolP("latest", "l", false, "Automatically select the latest version of Minecraft")
viper.BindPFlag("init.latest", initCmd.Flags().Lookup("latest")) viper.BindPFlag("init.latest", initCmd.Flags().Lookup("latest"))
@ -243,10 +254,16 @@ func init() {
viper.BindPFlag("init.reinit", initCmd.Flags().Lookup("reinit")) viper.BindPFlag("init.reinit", initCmd.Flags().Lookup("reinit"))
initCmd.Flags().String("modloader", "", "The mod loader to use (omit to define interactively)") initCmd.Flags().String("modloader", "", "The mod loader to use (omit to define interactively)")
viper.BindPFlag("init.modloader", initCmd.Flags().Lookup("modloader")) viper.BindPFlag("init.modloader", initCmd.Flags().Lookup("modloader"))
initCmd.Flags().String("modloader-version", "", "The mod loader version to use (omit to define interactively)")
viper.BindPFlag("init.modloader-version", initCmd.Flags().Lookup("modloader-version")) // ok this is epic
initCmd.Flags().BoolP("modloader-latest", "L", false, "Automatically select the latest version of the mod loader") for _, loader := range modLoaders {
viper.BindPFlag("init.modloader-latest", initCmd.Flags().Lookup("modloader-latest")) for _, component := range loader {
initCmd.Flags().String(component.Name+"-version", "", "The "+component.FriendlyName+" version to use (omit to define interactively)")
viper.BindPFlag("init."+component.Name+"-version", initCmd.Flags().Lookup(component.Name+"-version"))
initCmd.Flags().Bool(component.Name+"-latest", false, "Automatically select the latest version of "+component.FriendlyName)
viper.BindPFlag("init."+component.Name+"-latest", initCmd.Flags().Lookup(component.Name+"-latest"))
}
}
} }
type mcVersionManifest struct { type mcVersionManifest struct {
@ -304,10 +321,44 @@ type mavenMetadata struct {
} `xml:"versioning"` } `xml:"versioning"`
} }
// Gets a list of modloader versions and latest version for a given Minecraft version type modLoaderComponent struct {
var modLoaders = map[string]func(mcVersion string) ([]string, string, error){ Name string
"fabric": func(mcVersion string) ([]string, string, error) { FriendlyName string
res, err := http.Get("https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml") VersionListGetter func(mcVersion string) ([]string, string, error)
}
var modLoaders = map[string][]modLoaderComponent{
"fabric": []modLoaderComponent{
modLoaderComponent{
Name: "fabric",
FriendlyName: "Fabric loader",
VersionListGetter: fetchMavenVersionList("https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml"),
},
modLoaderComponent{
Name: "yarn",
FriendlyName: "Yarn (mappings)",
VersionListGetter: fetchMavenVersionPrefixedList("https://maven.fabricmc.net/net/fabricmc/yarn/maven-metadata.xml", "Yarn"),
},
},
"forge": []modLoaderComponent{
modLoaderComponent{
Name: "forge",
FriendlyName: "Forge",
VersionListGetter: fetchMavenVersionPrefixedList("https://files.minecraftforge.net/maven/net/minecraftforge/forge/maven-metadata.xml", "Forge"),
},
},
"liteloader": []modLoaderComponent{
modLoaderComponent{
Name: "liteloader",
FriendlyName: "LiteLoader",
VersionListGetter: fetchMavenVersionPrefixedList("http://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/maven-metadata.xml", "LiteLoader"),
},
},
}
func fetchMavenVersionList(url string) func(mcVersion string) ([]string, string, error) {
return func(mcVersion string) ([]string, string, error) {
res, err := http.Get(url)
if err != nil { if err != nil {
return []string{}, "", err return []string{}, "", err
} }
@ -318,55 +369,33 @@ var modLoaders = map[string]func(mcVersion string) ([]string, string, error){
return []string{}, "", err return []string{}, "", err
} }
return out.Versioning.Versions.Version, out.Versioning.Release, nil return out.Versioning.Versions.Version, out.Versioning.Release, nil
}, }
"forge": func(mcVersion string) ([]string, string, error) { }
res, err := http.Get("https://files.minecraftforge.net/maven/net/minecraftforge/forge/maven-metadata.xml")
if err != nil { func fetchMavenVersionPrefixedList(url string, friendlyName string) func(mcVersion string) ([]string, string, error) {
return []string{}, "", err return func(mcVersion string) ([]string, string, error) {
} res, err := http.Get(url)
dec := xml.NewDecoder(res.Body) if err != nil {
out := mavenMetadata{} return []string{}, "", err
err = dec.Decode(&out) }
if err != nil { dec := xml.NewDecoder(res.Body)
return []string{}, "", err out := mavenMetadata{}
} err = dec.Decode(&out)
allowedVersions := make([]string, 0, len(out.Versioning.Versions.Version)) if err != nil {
for _, v := range out.Versioning.Versions.Version { return []string{}, "", err
if strings.HasPrefix(v, mcVersion) { }
allowedVersions = append(allowedVersions, v) allowedVersions := make([]string, 0, len(out.Versioning.Versions.Version))
} for _, v := range out.Versioning.Versions.Version {
} if strings.HasPrefix(v, mcVersion) {
if len(allowedVersions) == 0 { allowedVersions = append(allowedVersions, v)
return []string{}, "", errors.New("no Forge versions available for this Minecraft version") }
} }
if strings.HasPrefix(out.Versioning.Release, mcVersion) { if len(allowedVersions) == 0 {
return allowedVersions, out.Versioning.Release, nil return []string{}, "", errors.New("no " + friendlyName + " versions available for this Minecraft version")
} }
return allowedVersions, allowedVersions[len(allowedVersions)-1], nil if strings.HasPrefix(out.Versioning.Release, mcVersion) {
}, return allowedVersions, out.Versioning.Release, nil
"liteloader": func(mcVersion string) ([]string, string, error) { }
res, err := http.Get("http://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/maven-metadata.xml") return allowedVersions, allowedVersions[len(allowedVersions)-1], nil
if err != nil { }
return []string{}, "", err
}
dec := xml.NewDecoder(res.Body)
out := mavenMetadata{}
err = dec.Decode(&out)
if err != nil {
return []string{}, "", err
}
allowedVersions := make([]string, 0, len(out.Versioning.Versions.Version))
for _, v := range out.Versioning.Versions.Version {
if strings.HasPrefix(v, mcVersion) {
allowedVersions = append(allowedVersions, v)
}
}
if len(allowedVersions) == 0 {
return []string{}, "", errors.New("no LiteLoader versions available for this Minecraft version")
}
if strings.HasPrefix(out.Versioning.Release, mcVersion) {
return allowedVersions, out.Versioning.Release, nil
}
return allowedVersions, allowedVersions[len(allowedVersions)-1], nil
},
} }