mirror of
https://github.com/packwiz/packwiz.git
synced 2025-04-19 21:16:30 +02:00
Actually write mod files
but aaa it doesn't use the struct tags properly so things are bad
This commit is contained in:
parent
3fdac51d22
commit
ef98591d02
46
core/mod.go
46
core/mod.go
@ -1,23 +1,27 @@
|
|||||||
package core
|
package core
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Mod stores metadata about a mod. This is written to a TOML file for each mod.
|
// Mod stores metadata about a mod. This is written to a TOML file for each mod.
|
||||||
type Mod struct {
|
type Mod struct {
|
||||||
metaFilename string // The filename for the metadata file, used as an ID
|
metaFile string // The file for the metadata file, used as an ID
|
||||||
Name string `toml:"name"`
|
Name string `toml:"name"`
|
||||||
FileName string `toml:"filename"`
|
FileName string `toml:"filename"`
|
||||||
Side string `toml:"side,omitempty"`
|
Side string `toml:"side,omitempty"`
|
||||||
Optional bool `toml:"optional,omitempty"`
|
Optional bool `toml:"optional,omitempty"`
|
||||||
Download struct {
|
Download ModDownload `toml:"download"`
|
||||||
URL string `toml:"url"`
|
Update map[string]interface{} `toml:"update"`
|
||||||
HashFormat string `toml:"hash-format"`
|
}
|
||||||
Hash string `toml:"hash"`
|
|
||||||
} `toml:"download"`
|
// ModDownload specifies how to download the mod file
|
||||||
Update map[string]interface{} `toml:"update"`
|
type ModDownload struct {
|
||||||
|
URL string `toml:"url"`
|
||||||
|
HashFormat string `toml:"hash-format"`
|
||||||
|
Hash string `toml:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// The three possible values of Side (the side that the mod is on) are "server", "client", and "both".
|
// The three possible values of Side (the side that the mod is on) are "server", "client", and "both".
|
||||||
@ -46,10 +50,26 @@ func LoadMod(modFile string) (Mod, error) {
|
|||||||
return mod, errors.New("Update plugin " + k + " not found!")
|
return mod, errors.New("Update plugin " + k + " not found!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mod.metaFile = modFile
|
||||||
return mod, nil
|
return mod, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Mod) Write() {
|
// SetMetaName sets the mod metadata file from a given file name (to be put in the mods folder)
|
||||||
|
func (m *Mod) SetMetaName(metaName string, flags Flags) {
|
||||||
|
m.metaFile = ResolveMod(metaName, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write saves the mod file
|
||||||
|
func (m Mod) Write() error {
|
||||||
|
f, err := os.Create(m.metaFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
enc := toml.NewEncoder(f)
|
||||||
|
// Disable indentation
|
||||||
|
enc.Indent = ""
|
||||||
|
return enc.Encode(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ func (pack Pack) Write() error {
|
|||||||
func (pack Pack) GetMCVersion() (string, error) {
|
func (pack Pack) GetMCVersion() (string, error) {
|
||||||
mcVersion, ok := pack.Versions["minecraft"]
|
mcVersion, ok := pack.Versions["minecraft"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", errors.New("No Minecraft version specified in modpack!")
|
return "", errors.New("no minecraft version specified in modpack")
|
||||||
}
|
}
|
||||||
return mcVersion, nil
|
return mcVersion, nil
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package curseforge
|
package curseforge
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/comp500/packwiz/core"
|
"github.com/comp500/packwiz/core"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
@ -18,7 +20,7 @@ func init() {
|
|||||||
Usage: "Install a mod from a curseforge URL, slug or ID",
|
Usage: "Install a mod from a curseforge URL, slug or ID",
|
||||||
Aliases: []string{"add", "get"},
|
Aliases: []string{"add", "get"},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
return cmdInstall(core.FlagsFromContext(c), c.Args().Get(0))
|
return cmdInstall(core.FlagsFromContext(c), c.Args().Get(0), c.Args().Tail())
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
Name: "import",
|
Name: "import",
|
||||||
@ -33,8 +35,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileIDRegexes = [...]*regexp.Regexp{
|
var fileIDRegexes = [...]*regexp.Regexp{
|
||||||
regexp.MustCompile("https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/(.+)\\/files\\/(\\d+)"),
|
regexp.MustCompile("^https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/(.+)\\/files\\/(\\d+)$"),
|
||||||
regexp.MustCompile("https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/(.+)\\/download\\/(\\d+)"),
|
regexp.MustCompile("^https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/(.+)\\/download\\/(\\d+)$"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileIDsFromString(mod string) (bool, int, int, error) {
|
func getFileIDsFromString(mod string) (bool, int, int, error) {
|
||||||
@ -53,10 +55,10 @@ func getFileIDsFromString(mod string) (bool, int, int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var modSlugRegexes = [...]*regexp.Regexp{
|
var modSlugRegexes = [...]*regexp.Regexp{
|
||||||
regexp.MustCompile("https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)"),
|
regexp.MustCompile("^https?:\\/\\/minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)$"),
|
||||||
regexp.MustCompile("https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)"),
|
regexp.MustCompile("^https?:\\/\\/(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)$"),
|
||||||
// Exact slug matcher
|
// Exact slug matcher
|
||||||
regexp.MustCompile("[a-z][\\da-z\\-]{0,127}"),
|
regexp.MustCompile("^[a-z][\\da-z\\-]{0,127}$"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func getModIDFromString(mod string) (bool, int, error) {
|
func getModIDFromString(mod string) (bool, int, error) {
|
||||||
@ -87,7 +89,7 @@ func getModIDFromString(mod string) (bool, int, error) {
|
|||||||
return false, 0, nil
|
return false, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdInstall(flags core.Flags, mod string) error {
|
func cmdInstall(flags core.Flags, mod string, modArgsTail []string) error {
|
||||||
if len(mod) == 0 {
|
if len(mod) == 0 {
|
||||||
return cli.NewExitError("You must specify a mod.", 1)
|
return cli.NewExitError("You must specify a mod.", 1)
|
||||||
}
|
}
|
||||||
@ -111,24 +113,65 @@ func cmdInstall(flags core.Flags, mod string) error {
|
|||||||
|
|
||||||
if !done {
|
if !done {
|
||||||
done, modID, err = getModIDFromString(mod)
|
done, modID, err = getModIDFromString(mod)
|
||||||
if err != nil {
|
// Handle error later (e.g. lowercase to search instead of as a slug)
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fallback to CurseMeta search
|
if !done {
|
||||||
// TODO: how to do interactive choices? automatically assume version? ask mod from list? choose first?
|
modArgs := append([]string{mod}, modArgsTail...)
|
||||||
|
searchTerm := strings.Join(modArgs, " ")
|
||||||
|
// TODO: CurseMeta search
|
||||||
|
// TODO: how to do interactive choices? automatically assume version? ask mod from list? choose first?
|
||||||
|
fmt.Println(searchTerm)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !done {
|
||||||
|
if err == nil {
|
||||||
|
err = errors.New("Mod not found")
|
||||||
|
}
|
||||||
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("ids: %d %d %v\n", modID, fileID, done)
|
fmt.Printf("ids: %d %d %v\n", modID, fileID, done)
|
||||||
|
|
||||||
if done {
|
// TODO: get FileID if it isn't there
|
||||||
fmt.Println(mcVersion)
|
|
||||||
info, err := getModInfo(modID)
|
fmt.Println(mcVersion)
|
||||||
fmt.Println(err)
|
modInfo, err := getModInfo(modID)
|
||||||
fmt.Println(info)
|
fmt.Println(err)
|
||||||
_ = index
|
fmt.Println(modInfo)
|
||||||
|
_ = index
|
||||||
|
|
||||||
|
if fileID == 0 {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
fileInfo, err := getFileInfo(modID, fileID)
|
||||||
|
|
||||||
|
updateMap := make(map[string]interface{})
|
||||||
|
|
||||||
|
updateMap["curseforge"] = cfUpdater{
|
||||||
|
ProjectID: modID,
|
||||||
|
FileID: fileID,
|
||||||
|
// TODO: determine update channel
|
||||||
|
ReleaseChannel: "release",
|
||||||
|
}
|
||||||
|
|
||||||
|
modMeta := core.Mod{
|
||||||
|
Name: modInfo.Name,
|
||||||
|
FileName: fileInfo.FileName,
|
||||||
|
Side: core.UniversalSide,
|
||||||
|
Download: core.ModDownload{
|
||||||
|
URL: fileInfo.DownloadURL,
|
||||||
|
HashFormat: "murmur2",
|
||||||
|
Hash: strconv.Itoa(fileInfo.Fingerprint),
|
||||||
|
},
|
||||||
|
Update: updateMap,
|
||||||
|
}
|
||||||
|
modMeta.SetMetaName(modInfo.Slug, flags)
|
||||||
|
|
||||||
|
fmt.Printf("%#v\n", modMeta)
|
||||||
|
|
||||||
|
return modMeta.Write()
|
||||||
}
|
}
|
||||||
|
|
||||||
type cfUpdateParser struct{}
|
type cfUpdateParser struct{}
|
||||||
@ -140,9 +183,9 @@ func (u cfUpdateParser) ParseUpdate(updateUnparsed interface{}) (core.Updater, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
type cfUpdater struct {
|
type cfUpdater struct {
|
||||||
ProjectID int `mapstructure:"project-id"`
|
ProjectID int `mapstructure:"project-id" toml:"project-id"`
|
||||||
FileID int `mapstructure:"file-id"`
|
FileID int `mapstructure:"file-id" toml:"file-id"`
|
||||||
ReleaseChannel string `mapstructure:"release-channel"`
|
ReleaseChannel string `mapstructure:"release-channel" toml:"release-channel"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u cfUpdater) DoUpdate(mod core.Mod) (bool, error) {
|
func (u cfUpdater) DoUpdate(mod core.Mod) (bool, error) {
|
||||||
|
@ -188,6 +188,7 @@ type modFileInfo struct {
|
|||||||
Length int `json:"fileLength"`
|
Length int `json:"fileLength"`
|
||||||
FileType int `json:"releaseType"`
|
FileType int `json:"releaseType"`
|
||||||
// fileStatus? means latest/preferred?
|
// fileStatus? means latest/preferred?
|
||||||
|
DownloadURL string `json:"downloadUrl"`
|
||||||
GameVersions []string `json:"gameVersion"`
|
GameVersions []string `json:"gameVersion"`
|
||||||
Fingerprint int `json:"packageFingerprint"`
|
Fingerprint int `json:"packageFingerprint"`
|
||||||
Dependencies []struct {
|
Dependencies []struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user