Add option to specify additional game versions (closes #25)

This commit is contained in:
comp500 2021-05-04 19:07:29 +01:00
parent 6557719c1f
commit 7bedd820c2
6 changed files with 76 additions and 11 deletions

View File

@ -73,3 +73,8 @@ For use on servers, add the `-g` flag to disable the GUI and `-s server` to down
- `packwiz cf install Sodium` (by search)
- `packwiz cf install --addon-id 394468 --file-id 3067101` (if all else fails)
- If files aren't being found, try running the `packwiz refresh` command to update the index!
## Options
- Additional options can be configured in the `[options]` section of `pack.toml`, as follows:
- `mods-folder` The folder to save mod metadata files into, for the install commands
- `acceptable-game-versions` A list of additional Minecraft versions to accept when installing or updating mods

View File

@ -26,6 +26,7 @@ type Pack struct {
Client map[string]toml.Primitive `toml:"client"`
Server map[string]toml.Primitive `toml:"server"`
Export map[string]map[string]interface{} `toml:"export"`
Options map[string]interface{} `toml:"options"`
}
// LoadPack loads the modpack metadata to a Pack struct
@ -35,6 +36,14 @@ func LoadPack() (Pack, error) {
return Pack{}, err
}
// Read options into viper
if modpack.Options != nil {
err := viper.MergeConfigMap(modpack.Options)
if err != nil {
return Pack{}, err
}
}
if len(modpack.Index.File) == 0 {
modpack.Index.File = "index.toml"
}

View File

@ -2,6 +2,7 @@ package curseforge
import (
"errors"
"github.com/spf13/viper"
"regexp"
"strconv"
"strings"
@ -199,6 +200,34 @@ func createModFile(modInfo modInfo, fileInfo modFileInfo, index *core.Index) err
return index.RefreshFileWithHash(path, format, hash, true)
}
func matchGameVersion(mcVersion string, modMcVersion string) bool {
if getCurseforgeVersion(mcVersion) == modMcVersion {
return true
} else {
for _, v := range viper.GetStringSlice("acceptable-game-versions") {
if getCurseforgeVersion(v) == modMcVersion {
return true
}
}
return false
}
}
func matchGameVersions(mcVersion string, modMcVersions []string) bool {
for _, modMcVersion := range modMcVersions {
if getCurseforgeVersion(mcVersion) == modMcVersion {
return true
} else {
for _, v := range viper.GetStringSlice("acceptable-game-versions") {
if getCurseforgeVersion(v) == modMcVersion {
return true
}
}
}
}
return false
}
type cfUpdateData struct {
ProjectID int `mapstructure:"project-id"`
FileID int `mapstructure:"file-id"`
@ -271,7 +300,7 @@ func (u cfUpdater) CheckUpdate(mods []core.Mod, mcVersion string) ([]core.Update
// For snapshots, curseforge doesn't put them in GameVersionLatestFiles
for _, v := range modInfos[i].LatestFiles {
// Choose "newest" version by largest ID
if sliceContainsString(v.GameVersions, getCurseforgeVersion(mcVersion)) && v.ID > fileID {
if matchGameVersions(mcVersion, v.GameVersions) && v.ID > fileID {
updateAvailable = true
fileID = v.ID
fileInfoData = v
@ -284,7 +313,7 @@ func (u cfUpdater) CheckUpdate(mods []core.Mod, mcVersion string) ([]core.Update
// TODO: change to timestamp-based comparison??
// TODO: manage alpha/beta/release correctly, check update channel?
// Choose "newest" version by largest ID
if file.GameVersion == getCurseforgeVersion(mcVersion) && file.ID > fileID {
if matchGameVersion(mcVersion, file.GameVersion) && file.ID > fileID {
updateAvailable = true
fileID = file.ID
fileName = file.Name

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"github.com/sahilm/fuzzy"
"github.com/spf13/viper"
"os"
"strings"
@ -268,7 +269,13 @@ func (r modResultsList) Len() int {
func searchCurseforgeInternal(args []string, mcVersion string) (bool, modInfo) {
fmt.Println("Searching CurseForge...")
searchTerm := strings.Join(args, " ")
results, err := getSearch(searchTerm, getCurseforgeVersion(mcVersion))
// If there are more than one acceptable version, we shouldn't filter by game version at all (as we can't filter by multiple)
filterGameVersion := getCurseforgeVersion(mcVersion)
if len(viper.GetStringSlice("acceptable-game-versions")) > 0 {
filterGameVersion = ""
}
results, err := getSearch(searchTerm, filterGameVersion)
if err != nil {
fmt.Println(err)
os.Exit(1)
@ -343,7 +350,7 @@ func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileIn
for _, v := range modInfoData.LatestFiles {
// Choose "newest" version by largest ID
if sliceContainsString(v.GameVersions, getCurseforgeVersion(mcVersion)) && v.ID > fileID {
if matchGameVersions(mcVersion, v.GameVersions) && v.ID > fileID {
fileID = v.ID
fileInfoData = v
fileInfoObtained = true
@ -352,7 +359,7 @@ func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileIn
// TODO: change to timestamp-based comparison??
for _, v := range modInfoData.GameVersionLatestFiles {
// Choose "newest" version by largest ID
if v.GameVersion == getCurseforgeVersion(mcVersion) && v.ID > fileID {
if matchGameVersion(mcVersion, v.GameVersion) && v.ID > fileID {
fileID = v.ID
fileInfoObtained = false // Make sure we get the file info
}
@ -363,7 +370,7 @@ func getLatestFile(modInfoData modInfo, mcVersion string, fileID int) (modFileIn
}
if fileID == 0 {
return modFileInfo{}, errors.New("mod not available for this minecraft version")
return modFileInfo{}, errors.New("mod not available for the configured Minecraft version(s) (use the acceptable-remote-versions option to accept more)")
}
fileInfoData, err := getFileInfo(modInfoData.ID, fileID)

View File

@ -3,6 +3,7 @@ package modrinth
import (
"errors"
"fmt"
"github.com/spf13/viper"
"os"
"regexp"
"strings"
@ -97,7 +98,7 @@ func installViaSearch(query string, pack core.Pack) error {
return err
}
results, err := getModIdsViaSearch(query, mcVersion)
results, err := getModIdsViaSearch(query, append([]string{mcVersion}, viper.GetStringSlice("acceptable-game-versions")...))
if err != nil {
return err
}
@ -142,7 +143,7 @@ func installMod(mod Mod, pack core.Pack) error {
return err
}
if latestVersion.ID == "" {
return errors.New("mod is not available for this minecraft version or mod loader")
return errors.New("mod is not available for this Minecraft version (use the acceptable-remote-versions option to accept more) or mod loader")
}
return installVersion(mod, latestVersion, pack)

View File

@ -3,6 +3,7 @@ package modrinth
import (
"encoding/json"
"errors"
"github.com/spf13/viper"
"io/ioutil"
"net/http"
"net/url"
@ -115,14 +116,22 @@ type VersionFile struct {
Primary bool // Is the file the primary file?
}
func getModIdsViaSearch(query string, version string) ([]ModResult, error) {
func getModIdsViaSearch(query string, versions []string) ([]ModResult, error) {
baseUrl := *modrinthApiUrlParsed
baseUrl.Path += "mod"
params := url.Values{}
params.Add("limit", "5")
params.Add("index", "relevance")
params.Add("facets", "[[\"versions:"+version+"\"]]")
facets := make([]string, 0)
for _, v := range versions {
facets = append(facets, "\"versions:"+v+"\"")
}
facetsEncoded, err := json.Marshal(facets)
if err != nil {
return []ModResult{}, err
}
params.Add("facets", "["+string(facetsEncoded)+"]")
params.Add("query", query)
baseUrl.RawQuery = params.Encode()
@ -156,6 +165,11 @@ func getLatestVersion(modID string, pack core.Pack) (Version, error) {
if err != nil {
return Version{}, err
}
gameVersions := append([]string{mcVersion}, viper.GetStringSlice("acceptable-game-versions")...)
gameVersionsEncoded, err := json.Marshal(gameVersions)
if err != nil {
return Version{}, err
}
loader := getLoader(pack)
@ -165,7 +179,7 @@ func getLatestVersion(modID string, pack core.Pack) (Version, error) {
baseUrl.Path += "/version"
params := url.Values{}
params.Add("game_versions", "[\""+mcVersion+"\"]")
params.Add("game_versions", string(gameVersionsEncoded))
if loader != "any" {
params.Add("loaders", "[\""+loader+"\"]")
}