AutoChangeMapMut: смена карты, если на сервер Killing Floor никто не может зайти
Иногда после рестарта выделенного сервера Killing Floor на него никто не может зайти, хотя сервер работает. В логе при этом:
RecvFrom returned SOCKET_ERROR 111
RecvFrom returned SOCKET_ERROR 113
В Linux 111 означает «соединение отклонено», 113 — «нет маршрута до узла». Flame с killingfloor.ru столкнулся с этим на Linux-серверах в 2012 году, возможно после очередного патча игры, и заметил, что помогает смена карты. Чтобы не ждать админа, он написал мутатор, который делает это автоматически.
Что делает мутатор
- После старта карты раз в минуту проверяет, подключился ли хотя бы один игрок.
- Как только кто-то зашёл, до конца карты проверки прекращаются.
- Если матч всё ещё ждёт старта, а ожидание превысило
waitingInterval, мутатор вызываетRestartGame()с разрешённой сменой уровня, и сервер переходит на следующую карту по списку.
Переход не мгновенный: прибавьте до минуты на таймер и примерно 48 секунд на саму смену карты.
Установка
- Скомпилируйте исходник ниже (см. ucc make) или возьмите оригинальный пакет.
- Добавьте мутатор в список мутаторов сервера как
AutoChangeMapMut.AutoChangeMapMut. - Задайте время ожидания в секундах в
AutoChangeMapMut.ini:
[AutoChangeMapMut.AutoChangeMapMut]
waitingInterval=600
В посте на форуме сказано, что по умолчанию 10 минут, но в опубликованном исходнике стоит waitingInterval=7200 (два часа). Пропишите значение явно.
Исходный код
class AutoChangeMapMut extends Mutator config(AutoChangeMapMut);
var config int waitingInterval;
var int startWaiting;
var bool playersCanConnect;
function PostBeginPlay()
{
startWaiting = Level.TimeSeconds;
playersCanConnect = false;
SetTimer(60.0, true);
}
function Timer()
{
local int playersN;
// once at least one player got in, stop checking
if (playersCanConnect)
return;
// only act while the match is waiting to start
if (!Level.Game.bWaitingToStartMatch)
return;
playersN = PlayersNumber();
if (playersN > 0)
{
playersCanConnect = true;
return;
}
if (Level.TimeSeconds - startWaiting >= waitingInterval)
{
Level.Game.bChangeLevels = true;
Level.Game.bAlreadyChanged = false;
Level.Game.RestartGame();
}
}
function int PlayersNumber()
{
local int N;
local Controller C;
for (C = Level.ControllerList; C != None; C = C.NextController)
{
if (C.IsA('PlayerController') && C.PlayerReplicationInfo.PlayerID > 0)
N++;
}
return N;
}
defaultproperties
{
waitingInterval=7200
bAddToServerPackages=True
GroupName="AutoChangeMapMut"
FriendlyName="AutoChangeMapMut"
Description="Changes the map if nobody plays on current map for a period of time"
}
Как это работает
bChangeLevels = trueиbAlreadyChanged = falseзаставляютRestartGame()переключить карту по ротации, а не перезапустить текущую.PlayersNumber()считает всеPlayerControllerс валиднымPlayerID, то есть зрителей тоже. Если зашёл хотя бы зритель, значит подключения работают.bAddToServerPackages=Trueдля чисто серверного мутатора не нужен: на клиентах он ничего не делает. Можно поставитьFalse, чтобы клиенты не скачивали пакет.
Побочные эффекты
- На тихом сервере мутатор сменит карту и тогда, когда сервер просто пустой: «никто не может зайти» и «никто не пришёл» он не различает. С длинным интервалом это безвредно.
- Саму сетевую проблему он не исправляет. Если ошибки повторяются после каждого рестарта, проверьте файрвол и порты (7707 UDP для игры, 7708 UDP для запросов, 28852 для мастер-сервера) и на каком сетевом интерфейсе слушает сервер.
Что ещё помогало
У другого админа тот же симптом был в локальной сети, где сервер стоял сразу в двух сетях (роутер плюс обычный LAN). После смены карты одна сеть подключалась без проблем, а вторая не видела сервер до следующей смены. Сервер работал на Windows 7, и после перехода на Windows Server 2008 проблема исчезла.
Ещё два случая с форума killingfloor.ru:
- Пускает только одного игрока или вечное подключение. В теме «Проблема: "Не удается установить соединение"» (2013) сервер после выхода единственного игрока считал его ещё на сервере (1/30) и не пускал никого до смены карты; помогло увеличение числа зрителей. В теме «Не заходит на сервер» (2012) DominatorRUS решил вечное подключение к Linux-серверу так: в
KillingFloor.iniстоялоMaxSpectators=0, после замены наMaxSpectators=2всё заработало. - Виноват мутатор. В той же теме у другого админа
MaxSpectatorsне помог: сервер переставал пускать игроков через одну-две смены карты, пока админ не переключал карту вручную. Отключив все мутаторы и включая их по одному, он нашёл виновников: мутатор Kill Message и мутатор, выбрасывающий весь инвентарь. По его словам, с Kill Message сервер работал на версии 1032 и начал сбоить с 1033.