package api import ( "net/http" "os" "strconv" "time" "github.com/mrleo1nid/pzmanager/internal/config" "github.com/mrleo1nid/pzmanager/internal/i18n" "github.com/mrleo1nid/pzmanager/internal/pzconfig" ) // handleGetServerConfig отдаёт содержимое servertest.ini. Файл появляется // только после первого запуска сервера, поэтому его отсутствие — не ошибка. func (s *Server) handleGetServerConfig(w http.ResponseWriter, r *http.Request) { path := s.cfg.ServerConfigPath() ini, err := pzconfig.LoadINI(path) if os.IsNotExist(err) { writeJSON(w, http.StatusOK, map[string]any{ "exists": false, "path": path, "hint": i18n.T(i18n.FromRequest(r), "Файл создаётся при первом запуске сервера"), }) return } if err != nil { writeError(w, r, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, map[string]any{ "exists": true, "path": path, "keys": ini.Keys(), "values": ini.Map(), // Игра сама пишет в конфиг описания параметров на языке сервера — // показываем их, вместо того чтобы придумывать свои. "descriptions": ini.Comments(), }) } // handlePutServerConfig правит только присланные ключи, остальные строки файла // (включая комментарии) остаются нетронутыми. func (s *Server) handlePutServerConfig(w http.ResponseWriter, r *http.Request) { var body struct { Values map[string]string `json:"values"` } if !decodeJSON(w, r, &body) { return } path := s.cfg.ServerConfigPath() ini, err := pzconfig.LoadINI(path) if err != nil { writeError(w, r, http.StatusBadRequest, "конфиг сервера недоступен: "+err.Error()) return } for key, value := range body.Values { ini.Set(key, value) } if err := pzconfig.SaveINI(path, ini); err != nil { writeError(w, r, http.StatusInternalServerError, err.Error()) return } s.sup.AppendLog("manager", "Конфиг сервера сохранён (изменений: "+strconv.Itoa(len(body.Values))+"). Изменения вступят в силу после перезапуска.") writeJSON(w, http.StatusOK, map[string]any{"saved": len(body.Values)}) } func (s *Server) handleGetSandbox(w http.ResponseWriter, r *http.Request) { path := s.cfg.SandboxConfigPath() sb, err := pzconfig.LoadSandbox(path) if os.IsNotExist(err) { writeJSON(w, http.StatusOK, map[string]any{ "exists": false, "path": path, "hint": i18n.T(i18n.FromRequest(r), "Файл создаётся при первом запуске сервера"), }) return } if err != nil { writeError(w, r, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, map[string]any{ "exists": true, "path": path, "entries": sb.Entries(), }) } func (s *Server) handlePutSandbox(w http.ResponseWriter, r *http.Request) { var body struct { Values map[string]string `json:"values"` } if !decodeJSON(w, r, &body) { return } path := s.cfg.SandboxConfigPath() sb, err := pzconfig.LoadSandbox(path) if err != nil { writeError(w, r, http.StatusBadRequest, "настройки песочницы недоступны: "+err.Error()) return } for key, value := range body.Values { if err := sb.Set(key, value); err != nil { writeError(w, r, http.StatusBadRequest, err.Error()) return } } if err := pzconfig.SaveSandbox(path, sb); err != nil { writeError(w, r, http.StatusInternalServerError, err.Error()) return } s.sup.AppendLog("manager", "Настройки песочницы сохранены. Часть параметров применяется только к новому миру.") writeJSON(w, http.StatusOK, map[string]any{"saved": len(body.Values)}) } // managerConfigDTO — вид конфига менеджера, удобный для формы в браузере: // длительности в секундах. Всё, что относится к конкретному серверу (имя, // пароль админа, память JVM), живёт в профилях и правится отдельно. type managerConfigDTO struct { Listen string `json:"listen"` ServerDir string `json:"server_dir"` ZomboidDir string `json:"zomboid_dir"` SteamCMDPath string `json:"steamcmd_path"` AutoStart bool `json:"autostart"` AutoRestart bool `json:"autorestart"` StopTimeoutSec int64 `json:"stop_timeout_sec"` LogBufferLines int `json:"log_buffer_lines"` BackupDir string `json:"backup_dir"` BackupScheduleMin int64 `json:"backup_schedule_min"` BackupKeep int `json:"backup_keep"` BackupStopServer bool `json:"backup_stop_server"` ConfigPath string `json:"config_path"` Version string `json:"version"` } func (s *Server) handleGetManagerConfig(w http.ResponseWriter, r *http.Request) { c := s.cfg writeJSON(w, http.StatusOK, managerConfigDTO{ Listen: c.Listen, ServerDir: c.ServerDir, ZomboidDir: c.ZomboidDir, SteamCMDPath: c.SteamCMDPath, AutoStart: c.AutoStart, AutoRestart: c.AutoRestart, StopTimeoutSec: c.StopTimeout.Seconds(), LogBufferLines: c.LogBufferLines, BackupDir: c.Backup.Dir, BackupScheduleMin: int64(c.Backup.Schedule.Duration().Minutes()), BackupKeep: c.Backup.Keep, BackupStopServer: c.Backup.StopServer, ConfigPath: c.Path(), Version: s.version, }) } // handlePutManagerConfig сохраняет общие настройки менеджера. func (s *Server) handlePutManagerConfig(w http.ResponseWriter, r *http.Request) { var dto managerConfigDTO if !decodeJSON(w, r, &dto) { return } c := s.cfg c.Listen = dto.Listen c.ServerDir = dto.ServerDir c.ZomboidDir = dto.ZomboidDir c.SteamCMDPath = dto.SteamCMDPath c.AutoStart = dto.AutoStart c.AutoRestart = dto.AutoRestart c.LogBufferLines = dto.LogBufferLines c.Backup.Dir = dto.BackupDir c.Backup.Keep = dto.BackupKeep c.Backup.StopServer = dto.BackupStopServer if dto.StopTimeoutSec > 0 { c.StopTimeout = config.Duration(time.Duration(dto.StopTimeoutSec) * time.Second) } c.Backup.Schedule = config.Duration(time.Duration(dto.BackupScheduleMin) * time.Minute) if err := c.Save(); err != nil { writeError(w, r, http.StatusInternalServerError, err.Error()) return } if err := c.EnsureDirs(); err != nil { writeError(w, r, http.StatusInternalServerError, err.Error()) return } s.sup.AppendLog("manager", "Настройки менеджера сохранены") writeJSON(w, http.StatusOK, map[string]any{ "saved": true, "note": i18n.T(i18n.FromRequest(r), "Адрес прослушивания применится после перезапуска pzmanager"), }) }