Веб-панель управления сервером Project Zomboid
Менеджер запускает сервер PZ как дочерний процесс и держит его stdin/stdout: отсюда живая консоль без RCON, стриминг логов через SSE и корректная остановка по цепочке quit -> SIGTERM -> SIGKILL для всей группы процессов. Сам менеджер работает под systemd. Что входит: - управление жизненным циклом сервера, автозапуск и автоподъём после падения; - метрики процесса из /proc и состояние хоста, список игроков онлайн; - редакторы servertest.ini и SandboxVars.lua, сохраняющие исходное форматирование файлов; - моды: списки Workshop ID и Mod ID с порядком загрузки, названия из Steam; - бэкапы мира по расписанию и вручную, с ротацией и восстановлением; - установка и обновление сервера через SteamCMD; - вход по логину и паролю, первичная настройка по одноразовому коду. Веб-интерфейс без сборщика, вшит в бинарник через embed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Duration — time.Duration, который в YAML выглядит как "90s" или "6h", а не
|
||||
// как число наносекунд: конфиг правят руками.
|
||||
type Duration time.Duration
|
||||
|
||||
// Duration возвращает значение в виде time.Duration.
|
||||
func (d Duration) Duration() time.Duration { return time.Duration(d) }
|
||||
|
||||
// Seconds возвращает длительность в секундах — удобно для JSON-ответов API.
|
||||
func (d Duration) Seconds() int64 { return int64(time.Duration(d).Seconds()) }
|
||||
|
||||
// String печатает длительность в том же виде, в каком она пишется в конфиге.
|
||||
func (d Duration) String() string { return time.Duration(d).String() }
|
||||
|
||||
// MarshalYAML пишет длительность строкой.
|
||||
func (d Duration) MarshalYAML() (any, error) { return time.Duration(d).String(), nil }
|
||||
|
||||
// UnmarshalYAML принимает и строку ("90s"), и число — число трактуется как
|
||||
// секунды, потому что так его естественнее всего написать руками.
|
||||
func (d *Duration) UnmarshalYAML(node *yaml.Node) error {
|
||||
var asString string
|
||||
if err := node.Decode(&asString); err == nil {
|
||||
parsed, err := time.ParseDuration(asString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("не разобрана длительность %q: %w", asString, err)
|
||||
}
|
||||
*d = Duration(parsed)
|
||||
return nil
|
||||
}
|
||||
|
||||
var asSeconds int64
|
||||
if err := node.Decode(&asSeconds); err != nil {
|
||||
return fmt.Errorf("длительность должна быть строкой вида 90s или числом секунд")
|
||||
}
|
||||
*d = Duration(time.Duration(asSeconds) * time.Second)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user