«Работает» — только после строки о готовности сервера
Регистрацию в Steam сервер печатает задолго до того, как мир загружен, и по ней панель показывала «Работает» на сервере, который ещё никого не пустит. Теперь готовность распознаётся только по «*** SERVER STARTED ****», а пока идёт загрузка, состояние остаётся «Запускается» с пояснением под ним и счётчиком времени загрузки. Если строки о готовности так и не будет (своя версия, свои моды), через пятнадцать минут менеджер сочтёт сервер запущенным и скажет об этом в консоли: иначе панель навсегда осталась бы без опроса игроков. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,11 @@ var (
|
||||
// playersPollInterval — как часто менеджер спрашивает у сервера список игроков.
|
||||
const playersPollInterval = 30 * time.Second
|
||||
|
||||
// startupGrace — сколько ждём строку о готовности. Загрузка мира с модами
|
||||
// занимает минуты, поэтому запас большой: раньше времени объявлять сервер
|
||||
// работающим хуже, чем подождать.
|
||||
const startupGrace = 15 * time.Minute
|
||||
|
||||
// restartDelay — пауза перед автоподъёмом упавшего сервера.
|
||||
const restartDelay = 10 * time.Second
|
||||
|
||||
@@ -355,10 +360,13 @@ func (s *Supervisor) handleLine(stream, text string) {
|
||||
}
|
||||
|
||||
// isServerReady распознаёт строку, которой PZ сообщает о готовности принимать
|
||||
// игроков.
|
||||
// игроков: «LOG : Network f:0 st:81,093,763> *** SERVER STARTED ****».
|
||||
//
|
||||
// Других маркеров тут нет намеренно. Регистрацию в Steam сервер печатает
|
||||
// задолго до того, как мир загружен, и по ней панель показывала «Работает» на
|
||||
// сервере, который ещё никого не пустит.
|
||||
func isServerReady(line string) bool {
|
||||
return strings.Contains(line, "SERVER STARTED") ||
|
||||
strings.Contains(line, "Server Steam ID")
|
||||
return strings.Contains(strings.ToUpper(line), "SERVER STARTED")
|
||||
}
|
||||
|
||||
// wait дожидается завершения процесса и решает, поднимать ли его заново.
|
||||
@@ -542,6 +550,23 @@ func (s *Supervisor) WaitStopped(timeout time.Duration) bool {
|
||||
return s.State() == StateStopped
|
||||
}
|
||||
|
||||
// checkStartupGrace страхует от сервера, который так и не напечатал строку о
|
||||
// готовности: со своими модами и своей версией он может назвать её иначе, а
|
||||
// вечное «Запускается» лишило бы панель опроса игроков.
|
||||
func (s *Supervisor) checkStartupGrace() {
|
||||
s.mu.Lock()
|
||||
overdue := s.state == StateStarting && !s.startedAt.IsZero() &&
|
||||
time.Since(s.startedAt) > startupGrace
|
||||
if overdue {
|
||||
s.state = StateRunning
|
||||
}
|
||||
s.mu.Unlock()
|
||||
|
||||
if overdue {
|
||||
s.AppendLog("manager", "Сервер не сообщил о готовности — считаю его запущенным")
|
||||
}
|
||||
}
|
||||
|
||||
// pollPlayers периодически спрашивает у работающего сервера, кто онлайн.
|
||||
func (s *Supervisor) pollPlayers() {
|
||||
ticker := time.NewTicker(playersPollInterval)
|
||||
@@ -551,6 +576,7 @@ func (s *Supervisor) pollPlayers() {
|
||||
case <-s.quit:
|
||||
return
|
||||
case <-ticker.C:
|
||||
s.checkStartupGrace()
|
||||
if s.State() != StateRunning {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user