diff --git a/curseforge/cursedir_other.go b/curseforge/cursedir_other.go new file mode 100644 index 0000000..8d0134d --- /dev/null +++ b/curseforge/cursedir_other.go @@ -0,0 +1,10 @@ +// +build !windows + +package curseforge + +import "errors" + +// Stub version, so that getCurseDir exists +func getCurseDir() (string, error) { + return "", errors.New("not compiled for windows") +} diff --git a/curseforge/cursedir_windows.go b/curseforge/cursedir_windows.go new file mode 100644 index 0000000..0d274e2 --- /dev/null +++ b/curseforge/cursedir_windows.go @@ -0,0 +1,25 @@ +package curseforge + +import ( + "errors" + "os" + "path/filepath" + + "golang.org/x/sys/windows" +) + +func getCurseDir() (string, error) { + path, err := windows.KnownFolderPath(windows.FOLDERID_Documents, 0) + if err != nil { + return "", err + } + curseDir := filepath.Join(path, "Curse") + if _, err := os.Stat(curseDir); err == nil { + return curseDir, nil + } + curseDir = filepath.Join(path, "Twitch") + if _, err := os.Stat(curseDir); err == nil { + return curseDir, nil + } + return "", errors.New("Curse installation directory cannot be found") +} diff --git a/curseforge/import.go b/curseforge/import.go index 67ade4e..0afc363 100644 --- a/curseforge/import.go +++ b/curseforge/import.go @@ -4,11 +4,13 @@ import ( "bufio" "bytes" "encoding/json" + "errors" "fmt" "io" "io/ioutil" "os" "path/filepath" + "runtime" "strings" "github.com/comp500/packwiz/core" @@ -37,16 +39,63 @@ var importCmd = &cobra.Command{ Short: "Import an installed curseforge modpack, from a download URL or a downloaded pack zip, or an installed metadata json file", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { + inputFile := args[0] var packImport importPackMetadata - if strings.HasPrefix(args[0], "http") { + + if strings.HasPrefix(inputFile, "http") { fmt.Println("it do be a http doe") os.Exit(0) } else { // Attempt to read from file - f, err := os.Open(args[0]) + var f *os.File + inputFileStat, err := os.Stat(inputFile) + if err == nil && inputFileStat.IsDir() { + // Apparently os.Open doesn't fail when file given is a directory, only when it gets read + err = errors.New("cannot open directory") + } + if err == nil { + f, err = os.Open(inputFile) + } if err != nil { - fmt.Printf("Error opening file: %s\n", err) - os.Exit(1) + found := false + var errInstance error + var errManifest error + var errCurse error + + // Look for other files/folders + if _, errInstance = os.Stat(filepath.Join(inputFile, "minecraftinstance.json")); errInstance == nil { + inputFile = filepath.Join(inputFile, "minecraftinstance.json") + found = true + } else if _, errManifest = os.Stat(filepath.Join(inputFile, "manifest.json")); errManifest == nil { + inputFile = filepath.Join(inputFile, "manifest.json") + found = true + } else if runtime.GOOS == "windows" { + var dir string + dir, errCurse = getCurseDir() + if errCurse == nil { + curseInstanceFile := filepath.Join(dir, "Minecraft", "Instances", inputFile, "minecraftinstance.json") + if _, errCurse = os.Stat(curseInstanceFile); errCurse == nil { + inputFile = curseInstanceFile + found = true + } + } + } + + if found { + f, err = os.Open(inputFile) + if err != nil { + fmt.Printf("Error opening file: %s\n", err) + os.Exit(1) + } + } else { + fmt.Printf("Error opening file: %s\n", err) + fmt.Printf("Also attempted minecraftinstance.json: %s\n", errInstance) + fmt.Printf("Also attempted manifest.json: %s\n", errManifest) + if errCurse != nil { + fmt.Printf("Also attempted to load a Curse/Twitch modpack named \"%s\": %s\n", inputFile, errCurse) + } + os.Exit(1) + } } defer f.Close() @@ -93,7 +142,7 @@ var importCmd = &cobra.Command{ fmt.Printf("Error parsing JSON: %s\n", err) os.Exit(1) } - packMeta.srcFile = args[0] + packMeta.srcFile = inputFile packImport = packMeta } } diff --git a/go.mod b/go.mod index 63b583f..ae0564d 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/spf13/cobra v0.0.5 github.com/spf13/viper v1.4.0 github.com/vbauerster/mpb/v4 v4.7.0 + golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 gopkg.in/dixonwille/wlog.v2 v2.0.0 // indirect gopkg.in/dixonwille/wmenu.v4 v4.0.2 ) diff --git a/go.sum b/go.sum index 98762b0..cda6c12 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872 h1:cGjJzUd8RgBw428LXP65YXni0aiGNA4Bl+ls8SmLOm8= golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 h1:/zi0zzlPHWXYXrO1LjNRByFu8sdGgCkj2JLDdBIB84k= +golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=