package main import ( "encoding/json" "fmt" "io" "os" "path/filepath" "strings" ) type VsServerConfigOptions struct { ServerName string `json:"ServerName"` Port int `json:"Port"` IpAddress string `json:"IpAddress"` MaxClients int `json:"MaxClients"` Password string `json:"Password"` DefaultRole string `json:"DefaultRole"` GuestRole string `json:"GuestRole"` PreApprovedRole string `json:"PreApprovedRole"` } // func WriteInstanceConfig(instanceDir string, settings VsServerConfig) error { // configPath := filepath.Join(instanceDir, "serverconfig.json") // if settings.IpAddress == "" { // settings.IpAddress = "0.0.0.0" // } // if settings.MaxClients == 0 { // settings.MaxClients = 16 // } // data, err := json.MarshalIndent(settings, "", " ") // if err != nil { // return fmt.Errorf("failed to marshal server configuration: %w", err) // } // err = os.WriteFile(configPath, data, 0644) // if err != nil { // return fmt.Errorf("failed writing serverconfig.json to instance: %w", err) // } // return nil // } func PrepareInstanceConfig(templateVersion string, instanceConfigPath string, config VsServerConfigOptions, cfg *AppConfig) error { templatePath := filepath.Join(cfg.Storage.ConfigTemplatesDir, templateVersion, "serverconfig.json") if _, err := os.Stat(instanceConfigPath); err == nil { return nil } if err := os.MkdirAll(filepath.Dir(instanceConfigPath), 0755); err != nil { return fmt.Errorf("failed creating instance directory tree: %w", err) } source, err := os.Open(templatePath) if err != nil { return fmt.Errorf("failed opening baseline template file: %w", err) } defer source.Close() destination, err := os.Create(instanceConfigPath) if err != nil { return fmt.Errorf("failed creating target instance configuration: %w", err) } defer destination.Close() if _, err := io.Copy(destination, source); err != nil { return fmt.Errorf("failed cloning configuration template payload: %w", err) } destination.Close() data, err := os.ReadFile(instanceConfigPath) if err != nil { return fmt.Errorf("failed reading cloned configuration data: %w", err) } var rawConfig map[string]interface{} if err := json.Unmarshal(data, &rawConfig); err != nil { return fmt.Errorf("failed parsing configuration JSON payload: %w", err) } rawConfig["ServerName"] = config.ServerName rawConfig["Port"] = config.Port rawConfig["MaxClients"] = config.MaxClients if config.Password != "" { rawConfig["Password"] = config.Password } else { rawConfig["Password"] = nil } instanceDir := filepath.Dir(instanceConfigPath) if worldConfig, ok := rawConfig["WorldConfig"].(map[string]interface{}); ok { worldConfig["SaveFileLocation"] = filepath.Join(instanceDir, "Saves", "default.vcdbs") } if modPaths, ok := rawConfig["ModPaths"].([]interface{}); ok { for i, pathVal := range modPaths { if strPath, ok := pathVal.(string); ok && (strings.Contains(strPath, "/vs-manager/instances/") || filepath.IsAbs(strPath)) && strPath != "Mods" { modPaths[i] = filepath.Join(instanceDir, "Mods") } } } updatedData, err := json.MarshalIndent(rawConfig, "", " ") if err != nil { return fmt.Errorf("failed marshaling updated configuration adjustments: %w", err) } if err := os.WriteFile(instanceConfigPath, updatedData, 0644); err != nil { return fmt.Errorf("failed committing updated configuration to disk: %w", err) } return nil }