From 85a941de81288e658a3403418d91e413c02ce3d9 Mon Sep 17 00:00:00 2001 From: kayomn Date: Wed, 21 Dec 2022 23:32:30 +0000 Subject: [PATCH] Fix hardcoded install path for game --- main.go | 160 +++++++++++++++++++++------------- manager.go | 250 +++++++++++++++++++++++++++-------------------------- 2 files changed, 229 insertions(+), 181 deletions(-) diff --git a/main.go b/main.go index d20090c..3709c3c 100644 --- a/main.go +++ b/main.go @@ -34,16 +34,22 @@ var commands = []Command{ requiredArguments[0], requiredArguments[1]) } - if gameError := WithGame(providedArguments[0], func(game *Game) error { - for _, archivePath := range providedArguments[1:] { - if installError := game.InstallMod(archivePath); installError != nil { - return installError - } - } + var game, gameOpenError = OpenGame(providedArguments[0]) - return nil - }); gameError != nil { - return "", gameError + if gameOpenError != nil { + return "", gameOpenError + } + + defer func() { + if closeError := game.Close(); closeError != nil { + panic(closeError) + } + }() + + for _, archivePath := range providedArguments[1:] { + if installError := game.InstallMod(archivePath); installError != nil { + return "", installError + } } return "mods installed", nil @@ -62,10 +68,20 @@ var commands = []Command{ requiredArguments[0], requiredArguments[1]) } - if gameError := WithGame(providedArguments[0], func(game *Game) error { - return game.RemoveMods(providedArguments[1:]) - }); gameError != nil { - return "", gameError + var game, gameOpenError = OpenGame(providedArguments[0]) + + if gameOpenError != nil { + return "", gameOpenError + } + + defer func() { + if closeError := game.Close(); closeError != nil { + panic(closeError) + } + }() + + if removeModsError := game.RemoveMods(providedArguments[1:]); removeModsError != nil { + return "", removeModsError } return "removed mods", nil @@ -84,19 +100,25 @@ var commands = []Command{ requiredArguments[0], requiredArguments[1], requiredArguments[2]) } - if gameError := WithGame(providedArguments[0], func(game *Game) error { - if removeError := game.RenameMod(providedArguments[1], - providedArguments[2]); removeError != nil { + var game, gameOpenError = OpenGame(providedArguments[0]) - return removeError - } - - return nil - }); gameError != nil { - return "", gameError + if gameOpenError != nil { + return "", gameOpenError } - return "", nil + defer func() { + if closeError := game.Close(); closeError != nil { + panic(closeError) + } + }() + + if renameError := game.RenameMod( + providedArguments[1], providedArguments[2]); renameError != nil { + + return "", renameError + } + + return "renamed", nil }, }, @@ -112,30 +134,32 @@ var commands = []Command{ requiredArguments[0], requiredArguments[1]) } - var modManifest = "" + var game, gameOpenError = OpenGame(providedArguments[0]) - if gameError := WithGame(providedArguments[0], func(game *Game) error { - var format = providedArguments[1] - var formatter, formatterExists = formatters[format] - - if !(formatterExists) { - return fmt.Errorf("unsupported format: `%s`", format) - } - - var manifestBuilder = strings.Builder{} - - if formatError := formatter(&manifestBuilder, game.Mods); formatError != nil { - return formatError - } - - modManifest = manifestBuilder.String() - - return nil - }); gameError != nil { - return "", gameError + if gameOpenError != nil { + return "", gameOpenError } - return modManifest, nil + defer func() { + if closeError := game.Close(); closeError != nil { + panic(closeError) + } + }() + + var format = providedArguments[1] + var formatter, formatterExists = formatters[format] + + if !(formatterExists) { + return "", fmt.Errorf("unsupported format: `%s`", format) + } + + var manifestBuilder = strings.Builder{} + + if formatError := formatter(&manifestBuilder, game.Mods); formatError != nil { + return "", formatError + } + + return manifestBuilder.String(), nil }, }, @@ -151,20 +175,26 @@ var commands = []Command{ requiredArguments[0], requiredArguments[1]) } - if gameError := WithGame(arguments[0], func(game *Game) error { - if cleanError := game.CleanDeployedMods(); cleanError != nil { - return cleanError - } + var game, gameOpenError = OpenGame(arguments[0]) - for _, modName := range arguments[1:] { - if deployError := game.DeployMod(modName); deployError != nil { - return deployError - } - } + if gameOpenError != nil { + return "", gameOpenError + } - return nil - }); gameError != nil { - return "", gameError + defer func() { + if closeError := game.Close(); closeError != nil { + panic(closeError) + } + }() + + if cleanError := game.CleanDeployedMods(); cleanError != nil { + return "", cleanError + } + + for _, modName := range arguments[1:] { + if deployError := game.DeployMod(modName); deployError != nil { + return "", deployError + } } return "deployed", nil @@ -182,10 +212,20 @@ var commands = []Command{ return "", fmt.Errorf("expected %s", requiredArguments[0]) } - if gameError := WithGame(arguments[0], func(game *Game) error { - return game.CleanDeployedMods() - }); gameError != nil { - return "", gameError + var game, gameOpenError = OpenGame(arguments[0]) + + if gameOpenError != nil { + return "", gameOpenError + } + + defer func() { + if closeError := game.Close(); closeError != nil { + panic(closeError) + } + }() + + if cleanDeployedModsError := game.CleanDeployedMods(); cleanDeployedModsError != nil { + return "", cleanDeployedModsError } return "cleaned", nil diff --git a/manager.go b/manager.go index 3ad08eb..d87f951 100644 --- a/manager.go +++ b/manager.go @@ -47,6 +47,92 @@ func (game *Game) CleanDeployedMods() error { return nil } +func (game *Game) Close() error { + // Write deployed files to disk. + var deployedListPath, deployedListPathError = game.cachePath("deployed.txt") + + if deployedListPathError != nil { + return deployedListPathError + } + + var deployedListFile, deployedListCreateError = os.Create(deployedListPath) + + if deployedListCreateError != nil { + return deployedListCreateError + } + + defer func() { + if syncError := deployedListFile.Sync(); syncError != nil { + panic(syncError) + } + + if closeError := deployedListFile.Close(); closeError != nil { + panic(closeError) + } + }() + + var deployedListWriter = bufio.NewWriter(deployedListFile) + + defer func() { + if flushError := deployedListWriter.Flush(); flushError != nil { + panic(flushError) + } + }() + + for _, filePath := range game.DeployedFilePaths { + if _, writeError := deployedListWriter.WriteString(filePath); writeError != nil { + return writeError + } + + if writeError := deployedListWriter.WriteByte('\n'); writeError != nil { + return writeError + } + } + + // Read mod info from disk. + var modInfoPath, modInfoPathError = game.configPath("mods.ini") + + if modInfoPathError != nil { + return modInfoPathError + } + + var modInfoFile, modInfoCreateError = os.Create(modInfoPath) + + if modInfoCreateError != nil { + return modInfoCreateError + } + + defer func() { + if closeError := modInfoFile.Close(); closeError != nil { + panic(closeError) + } + }() + + var modInfoEntries = make([]ini.Entry, 0, len(game.Mods)*3) + + for name, mod := range game.Mods { + modInfoEntries = append(modInfoEntries, ini.Entry{ + Section: name, + Key: "source", + Value: mod.Source, + }) + + modInfoEntries = append(modInfoEntries, ini.Entry{ + Section: name, + Key: "format", + Value: mod.Format, + }) + + modInfoEntries = append(modInfoEntries, ini.Entry{ + Section: name, + Key: "version", + Value: mod.Version, + }) + } + + return ini.Write(modInfoFile, modInfoEntries) +} + func (game *Game) DeployMod(name string) error { var mod, exists = game.Mods[name] @@ -154,7 +240,7 @@ func (game *Game) DeployMod(name string) error { } type Game struct { - ID string + Name string DeployedFilePaths []string OverwrittenFilePaths []string Mods map[string]Mod @@ -313,6 +399,46 @@ type Mod struct { Version string } +func OpenGame(name string) (Game, error) { + var configPath, configPathError = os.UserConfigDir() + + if configPathError != nil { + return Game{}, configPathError + } + + var gamesFile, gamesOpenError = os.Open(filepath.Join(configPath, "modman", "games.ini")) + + if gamesOpenError != nil { + if os.IsNotExist(gamesOpenError) { + return Game{}, fmt.Errorf("no games registered") + } + + return Game{}, gamesOpenError + } + + var gamesParser = ini.NewParser(gamesFile) + + for entry := gamesParser.Parse(); !(gamesParser.IsEnd()); entry = gamesParser.Parse() { + if (entry.Key == "path") && (entry.Section == name) { + var game = Game{ + Name: name, + OverwrittenFilePaths: make([]string, 0, 512), + DeployedFilePaths: make([]string, 0, 512), + Mods: make(map[string]Mod), + Path: "/home/kayomn/.steam/steam/steamapps/common/Fallout 4/Data", + } + + if loadError := game.Load(); loadError != nil { + return Game{}, loadError + } + + return game, nil + } + } + + return Game{}, fmt.Errorf("game not registered: %s", name) +} + func (game *Game) RemoveMods(names []string) error { for _, name := range names { if _, exists := game.Mods[name]; !(exists) { @@ -369,124 +495,6 @@ func (game *Game) RenameMod(modName string, newName string) error { return nil } -func (game *Game) Save() error { - // Write deployed files to disk. - var deployedListPath, deployedListPathError = game.cachePath("deployed.txt") - - if deployedListPathError != nil { - return deployedListPathError - } - - var deployedListFile, deployedListCreateError = os.Create(deployedListPath) - - if deployedListCreateError != nil { - return deployedListCreateError - } - - defer func() { - if syncError := deployedListFile.Sync(); syncError != nil { - panic(syncError) - } - - if closeError := deployedListFile.Close(); closeError != nil { - panic(closeError) - } - }() - - var deployedListWriter = bufio.NewWriter(deployedListFile) - - defer func() { - if flushError := deployedListWriter.Flush(); flushError != nil { - panic(flushError) - } - }() - - for _, filePath := range game.DeployedFilePaths { - if _, writeError := deployedListWriter.WriteString(filePath); writeError != nil { - return writeError - } - - if writeError := deployedListWriter.WriteByte('\n'); writeError != nil { - return writeError - } - } - - // Read mod info from disk. - var modInfoPath, modInfoPathError = game.configPath("mods.ini") - - if modInfoPathError != nil { - return modInfoPathError - } - - var modInfoFile, modInfoCreateError = os.Create(modInfoPath) - - if modInfoCreateError != nil { - return modInfoCreateError - } - - defer func() { - if closeError := modInfoFile.Close(); closeError != nil { - panic(closeError) - } - }() - - var modInfoEntries = make([]ini.Entry, 0, len(game.Mods)*3) - - for name, mod := range game.Mods { - modInfoEntries = append(modInfoEntries, ini.Entry{ - Section: name, - Key: "source", - Value: mod.Source, - }) - - modInfoEntries = append(modInfoEntries, ini.Entry{ - Section: name, - Key: "format", - Value: mod.Format, - }) - - modInfoEntries = append(modInfoEntries, ini.Entry{ - Section: name, - Key: "version", - Value: mod.Version, - }) - } - - return ini.Write(modInfoFile, modInfoEntries) -} - -func WithGame(gameName string, action func(*Game) error) error { - var supportedGames = []string{"fallout4", "falloutnv", "skyrim"} - - for _, supportedGame := range supportedGames { - if gameName == supportedGame { - var game = Game{ - ID: supportedGame, - OverwrittenFilePaths: make([]string, 0, 512), - DeployedFilePaths: make([]string, 0, 512), - Mods: make(map[string]Mod), - Path: "/home/kayomn/.steam/steam/steamapps/common/Fallout 4/Data", - } - - if loadError := game.Load(); loadError != nil { - return loadError - } - - if actionError := action(&game); actionError != nil { - return actionError - } - - if saveError := game.Save(); saveError != nil { - return saveError - } - - return nil - } - } - - return fmt.Errorf("%s: game not supported", gameName) -} - func (game *Game) cachePath(path string) (string, error) { var dirPath, pathError = os.UserCacheDir() @@ -494,7 +502,7 @@ func (game *Game) cachePath(path string) (string, error) { return "", pathError } - dirPath = filepath.Join(dirPath, "modman", game.ID) + dirPath = filepath.Join(dirPath, "modman", game.Name) if mkdirError := os.MkdirAll(dirPath, 0755); mkdirError != nil { return "", mkdirError @@ -510,7 +518,7 @@ func (game *Game) configPath(path string) (string, error) { return "", pathError } - dirPath = filepath.Join(dirPath, "modman", game.ID) + dirPath = filepath.Join(dirPath, "modman", game.Name) if mkdirError := os.MkdirAll(dirPath, 0755); mkdirError != nil { return "", mkdirError