package process import ( "fmt" "log" "os" "os/exec" "time" ) const ( rustAppID = "258550" // Rust Dedicated Server App ID ) // SteamCMD handles SteamCMD operations for game server updates type SteamCMD struct { path string } // NewSteamCMD creates a new SteamCMD instance func NewSteamCMD(path string) *SteamCMD { return &SteamCMD{ path: path, } } // UpdateRustServer updates the Rust Dedicated Server via SteamCMD func (sc *SteamCMD) UpdateRustServer(validate bool) error { log.Printf("Starting SteamCMD update for Rust Server (validate=%v)", validate) // Check if SteamCMD exists if _, err := os.Stat(sc.path); os.IsNotExist(err) { return fmt.Errorf("steamcmd not found at: %s", sc.path) } startTime := time.Now() // Build SteamCMD command // +login anonymous +force_install_dir /path/to/rust +app_update 258550 validate +quit args := []string{ "+login", "anonymous", "+force_install_dir", getServerInstallDir(), "+app_update", rustAppID, } if validate { args = append(args, "validate") } args = append(args, "+quit") log.Printf("Executing: %s %v", sc.path, args) // Create command cmd := exec.Command(sc.path, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr // Run SteamCMD (this will block until update completes) if err := cmd.Run(); err != nil { return fmt.Errorf("steamcmd update failed: %w", err) } duration := time.Since(startTime) log.Printf("SteamCMD update completed in %v", duration) return nil } // UpdateRustServerWithPath updates the Rust server to a specific install directory func (sc *SteamCMD) UpdateRustServerWithPath(installPath string, validate bool) error { log.Printf("Starting SteamCMD update for Rust Server at %s (validate=%v)", installPath, validate) // Check if SteamCMD exists if _, err := os.Stat(sc.path); os.IsNotExist(err) { return fmt.Errorf("steamcmd not found at: %s", sc.path) } startTime := time.Now() // Build SteamCMD command args := []string{ "+login", "anonymous", "+force_install_dir", installPath, "+app_update", rustAppID, } if validate { args = append(args, "validate") } args = append(args, "+quit") log.Printf("Executing: %s %v", sc.path, args) // Create command cmd := exec.Command(sc.path, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr // Run SteamCMD if err := cmd.Run(); err != nil { return fmt.Errorf("steamcmd update failed: %w", err) } duration := time.Since(startTime) log.Printf("SteamCMD update completed in %v", duration) return nil } // CheckSteamCMDInstalled verifies SteamCMD is installed and executable func (sc *SteamCMD) CheckSteamCMDInstalled() error { if _, err := os.Stat(sc.path); os.IsNotExist(err) { return fmt.Errorf("steamcmd not found at: %s", sc.path) } // Try to execute with --help or similar to verify it's executable cmd := exec.Command(sc.path, "+quit") if err := cmd.Run(); err != nil { return fmt.Errorf("steamcmd is not executable or working: %w", err) } return nil } // getServerInstallDir returns the default server installation directory // This should ideally come from configuration, but we provide a fallback func getServerInstallDir() string { // Try to determine from GAME_SERVER_PATH environment variable serverPath := os.Getenv("GAME_SERVER_PATH") if serverPath != "" { return getDirectory(serverPath) } // Default fallback paths by OS return "/home/rustserver/server" }