Files
pzmanager/internal/config/duration.go
T
mrleo1nidandClaude Opus 5 d0ff64c272 Веб-панель управления сервером 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>
2026-09-03 22:41:11 +03:00

46 lines
1.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}