diff --git a/main.go b/main.go index 570098a..ecabd87 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,9 @@ import ( "io" "log" "os" + "os/exec" "path/filepath" + "strings" "github.com/joho/godotenv" ) @@ -28,42 +30,115 @@ func init() { } const ( - steamcmdEnvKey = "STEAMCMD" - appEnvKey = "APP" + steamcmdEnvKey = "STEAMCMD" + steamcmdScriptPathEnvKey = "STEAMCMD_SCRIPT" + appEnvKey = "APP" + usernameEnvKey = "USERNAME" + passwordEnvKey = "PASSWORD" ) func main() { envfile := flag.String("envfile", ".env", "") flag.Parse() + args := flag.Args() + if len(args) == 0 { + Error.Println("No args specified, please pass space delimited list of workshop ids for downloading") + return + } + env, err := loadEnv(*envfile) if err != nil { Error.Printf("Error leading env file: %v", err) return } - steamcmdexe, ok := env[steamcmdEnvKey] + steamcmdPath, ok := env[steamcmdEnvKey] if !ok { - Error.Printf("SteamCMD not found in env, please specify %s", steamcmdEnvKey) + Error.Printf("SteamCMD not found in env, please specify '%s'", steamcmdEnvKey) return } + steamcmdPath = filepath.Clean(steamcmdPath) + steamcmdExe := filepath.Join(steamcmdPath, "steamcmd.exe") + tempfile, err := os.Open(steamcmdExe) + if err != nil { + Error.Printf("Error opening SteamCMD, does it exist?: %v", err) + return + } + tempfile.Close() + + steamcmdScriptPath, ok := env[steamcmdScriptPathEnvKey] + if !ok { + steamcmdScriptPath = filepath.Join(steamcmdPath, "script") + log.Printf("SteamCMD script not found in env, using '%s'", steamcmdScriptPath) + log.Printf("Specify script path with '%s'", steamcmdScriptPathEnvKey) + } app, ok := env[appEnvKey] if !ok { - Error.Printf("App not found in env, please specify %s", appEnvKey) + Error.Printf("App not found in env, please specify '%s'", appEnvKey) return } - args := flag.Args() - log.Printf("Using steamcmd at %s", steamcmdexe) - log.Printf("Downloading %d items for %s", len(args), app) + username, ok := env[usernameEnvKey] + if !ok { + username = "anonymous" + log.Printf("Username not found in env, using '%s'", username) + log.Printf("If you want to log in specify '%s' and '%s'", usernameEnvKey, passwordEnvKey) + } + password, ok := env[passwordEnvKey] + if !ok { + password = "" + log.Printf("Password not found in env, using empty") + } + + log.Printf("Using steamcmd at '%s'", steamcmdPath) + log.Printf("As user '%s'", username) + log.Printf("Downloading %d items for '%s'", len(args), app) + + scriptContents := make([]string, 0, len(args)+4) + scriptContents = append(scriptContents, "@ShutdownOnFailedCommand 0") + scriptContents = append(scriptContents, "@NoPromptForPassword 1") + scriptContents = append(scriptContents, fmt.Sprintf("login %s %s", username, password)) + for _, arg := range args { + scriptContents = append(scriptContents, fmt.Sprintf("workshop_download_item %s %s", app, arg)) + } + scriptContents = append(scriptContents, "quit") + + scriptFileHandle, err := os.OpenFile(steamcmdScriptPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0755) + if err != nil { + Error.Println("Could not open steamcmd script file") + return + } + defer scriptFileHandle.Close() + _, err = scriptFileHandle.Write([]byte(strings.Join(scriptContents, "\n"))) + if err != nil { + Error.Println("Could not write to steamcmd script file") + return + } + log.Printf("Wrote %d lines to script file", len(scriptContents)) + + steamcmdExe, _ = filepath.Abs(steamcmdExe) + steamcmdScriptPath, _ = filepath.Abs(steamcmdScriptPath) + log.Printf("Running steamcmd at %s", steamcmdExe) + cmd := exec.Command(steamcmdExe, "+runscript", steamcmdScriptPath) + cmd.Dir = steamcmdPath + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + err = cmd.Run() + if err != nil { + Error.Printf("SteamCMD failed with code %v", err) + return + } + log.Printf("All done") } func loadEnv(fpath string) (map[string]string, error) { res := make(map[string]string) fpath = filepath.Clean(fpath) - log.Printf("Trying to open env file at %s", fpath) + log.Printf("Trying to open env file at '%s'", fpath) file, err := os.Open(fpath) if err != nil {