diff --git a/cmd/oplcli.go b/cmd/oplcli.go index 6ce3397..776e10f 100644 --- a/cmd/oplcli.go +++ b/cmd/oplcli.go @@ -18,10 +18,18 @@ type ArtCmd struct { OutputDirectory string `arg:"--output,-o" help:"where to download art files" default:"."` } +type CfgCmd struct { + Files []string `arg:"positional,required"` + OutputDirectory string `arg:"--output,-o" help:"where to download cfg files" default:"."` + Override bool `arg:"-f,--force" help:"Override existing cfg files"` + Append bool `arg:"-a,--append" help:"Append to existing cfg files"` +} + type args struct { Scan *ScanCmd `arg:"subcommand:scan"` Rename *RenameCmd `arg:"subcommand:rename"` Art *ArtCmd `arg:"subcommand:art"` + Cfg *CfgCmd `arg:"subcommand:cfg"` } func Run() { @@ -35,6 +43,22 @@ func Run() { oplcli.Rename(args.Rename.Files, oplcli.Config{}) case args.Art != nil: oplcli.DownloadGameArt(args.Art.Files, args.Art.OutputDirectory, oplcli.Config{}) + case args.Cfg != nil: + if args.Cfg.Override && args.Cfg.Append { + p.FailSubcommand("Can only append or override cfg files", "cfg") + } + + var mode oplcli.FileMode = oplcli.ModeOnlyCreate + + if args.Cfg.Append { + mode = oplcli.ModeAppend + } + + if args.Cfg.Override { + mode = oplcli.ModeOverride + } + + oplcli.DownloadCfg(args.Cfg.Files, args.Cfg.OutputDirectory, mode, oplcli.Config{}) default: p.Fail("Must specify command") } diff --git a/internal/cfg.go b/internal/cfg.go new file mode 100644 index 0000000..caefd1f --- /dev/null +++ b/internal/cfg.go @@ -0,0 +1,81 @@ +package oplcli + +import ( + "fmt" + "io" + "net/http" + "os" + "path" +) + +type FileMode int + +const ( + ModeOverride FileMode = iota + ModeAppend + ModeOnlyCreate +) + +func downloadCfgForGame(gameID string, output string, mode FileMode) error { + url := getDownloadURLFromGithub(gameID) + + filePath := path.Join(output, fmt.Sprintf("%s.cfg", gameID)) + + file, err := openFileBasedOnMode(filePath, mode) + if err != nil { + return err + } + defer file.Close() + + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = io.Copy(file, resp.Body) + if err != nil { + return err + } + + return nil +} + +func openFileBasedOnMode(filePath string, mode FileMode) (*os.File, error) { + _, err := os.Stat(filePath) + if err != nil { + if err != os.ErrNotExist { + file, err := os.Create(filePath) + if err != nil { + return nil, err + } + return file, nil + } + } + + if mode == ModeOverride { + file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return nil, err + } + return file, nil + } + + if mode == ModeAppend { + file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + return nil, err + } + return file, nil + } + + return nil, fmt.Errorf("File already exists") + +} + +func getDownloadURLFromGithub(gameID string) string { + // const baseURL = "https://raw.githubusercontent.com/VTSTech/PS2-OPL-CFG/refs/heads/master/CFG/" // This one is more basic + const baseURL = "https://raw.githubusercontent.com/Tom-Bruise/PS2-OPL-CFG-Database/refs/heads/master/CFG_en/" // This one contains descriptions and more + + return fmt.Sprintf("%s/%s.cfg", baseURL, gameID) +} diff --git a/internal/oplcli.go b/internal/oplcli.go index ee36a12..0f9a983 100644 --- a/internal/oplcli.go +++ b/internal/oplcli.go @@ -76,3 +76,19 @@ func DownloadGameArt(files []string, output string, config Config) { downloadArtForGame(gameID, output) } } + +func DownloadCfg(files []string, output string, mode FileMode, config Config) { + for _, file := range files { + fmt.Printf("Scanning file: %s\n", file) + + gameID, err := scanGameFileForID(file) + if err != nil { + fmt.Printf("Failed to scan game file: %s", err) + os.Exit(1) + } + + fmt.Printf("Found game ID: %s\n", gameID) + + downloadCfgForGame(gameID, output, mode) + } +}