Многие администраторы серверов сталкиваются с проблемой падения или зависания сервера в случае каких-либо ошибок. Для автоматического перезапуска сервера существуют так называемые антикраш скрипты. Пример такого скрипта можно посмотреть здесь. Однако, подобный батник не сможет перезапустить сервер в случае ошибки GetPathName, из-за которой консоль сервера остаётся активной. Зато антикраш скрипт для PowerShell сможет. Основное. Спойлер 1. Переименовываем для удобства (или на случай наличия нескольких серверов) ucc.exe Например, в my_ucc.exe 2. В батнике, с помощью которого мы запускаем сервер, пишем следующее: powershell ./Start_myServer.ps1 3. Открываем Windows PowerShell и вставляем туда такой код: Спойлер Код: $path = "D:\MyServer\System\my_ucc.exe" // Указываем путь к исполняемому файлу. $arg = "server KF-Farm.rom?game=KFMod.KFGameType?VACSecured=false?Mutator=MutLoader.MutLoader -log=server.log" // Указываем параметры запуска сервера. if( -not (get-process | where {$_.ProcessName -eq 'my_ucc'})) { for($i = 0; $i -lt 100; $i++) { 'Starting process' $date = Get-Date -format yyyy_MM_dd_HH_mm $log = [string]::Concat('Log_',$date,'.x') $current_arg=[string]::Concat($arg,$log) Start-Process -FilePath $path -ArgumentList $current_arg $ps=get-process | where-object { $_.Name -eq 'my_ucc' } do {Start-Sleep -s 1} while ($ps.HasExited -eq $false) 'Restarting' Start-Sleep -s 1 $ps.Kill() Start-Sleep -s 1 } } else {'Already exist'} Сохраняем как Start_myServer.ps1. Кладём в папку System. Запуск сервера производится с помощью всё того же батника. Утилита создаёт свои логи с названием, в котором содержится время его создания, то есть логи не будут затираться и вы сможете спокойно просматривать их, следя за работой сервера. Для тех, кому интересно, как это работает. Спойлер Для создания новой переменной или для изменения значения переменной используется инструкция присваивания в следующем формате: Код: $<переменная> = <значение> Для начала создадим переменную, в которой будем хранить путь к исполняемому файлу. Код: $path = "D:\MyServer\System\my_ucc.exe" В этой переменной укажем параметры запуска сервера. Код: $arg = "server KF-Farm.rom?game=KFMod.KFGameType?VACSecured=false?Mutator=MutLoader.MutLoader -log=server.log" Дальше у нас идёт условие. Код: if( -not (get-process | where {$_.ProcessName -eq 'my_ucc'})) Код: -not Логический оператор (Запись операторов начинается знаком "-"). Изменяет результат оценки условия последующей инструкции на противоположный. Код: get-process Командлет получает процессы, выполняющиеся на локальном или удаленном компьютере. Код: | Отделяем один командлет от другого. Тем самым получаем конвейер - последовательность командлетов, записанную в одной строке и выполняемую особым образом. Код: where Результат выполнения любого командлета — это объект. А зачастую не один а объект, а массив объектов. Для фильтрации только определенных объектов в Powershell используется Where. На самом деле Where — это алиас для командлета Where-Object. Код: {} Дальше у нас используется параметр FilterScript. Значение FilterScript представляет собой блок сценария — одну или несколько команд Windows PowerShell, заключенных в фигурные скобки {}, — результатом которого могут быть значения True или False. Такие блоки сценариев могут быть очень простыми, но для их создания требуется понимание другой концепции Windows PowerShell, а именно операторов сравнения. При использовании данного способа после Where в фигурных скобках указывается условие, которое обращается к свойствам объекта через переменную $_. Переменная $_ содержит текущий объект просматриваемый в конвейере. Обращение к свойствам текущего объекта осуществляется через точку. Код: $_.ProcessName Наименование процесса. Код: -eq Оператор сравнения. Равенство. Распространяется на случай совпадения значений. Код: 'my_ucc' Имя нашего процесса. То есть, наше условие будет выглядеть примерно так: Если процесс my_ucc не запущен на компьютере, то... То дальше мы запускаем цикл. Код: for($i = 0; $i -lt 100; $i++) Код: -lt Оператор сравнения. Меньше. В данном случае, цикл может выполнится 100 раз, можно, конечно, выставить число побольше, но это ни к чему, и 100 хватит. Код: 'Starting process' Выводим информацию о том, что процесс запущен. Создаём переменную, в которой будет хранится дата запуска сервера. Код: $date = Get-Date -format yyyy_MM_dd_HH_mm Код: Get-Date Командлет получает объект DateTime, содержащий текущую или заданную дату. Код: -format При использовании параметра Format оболочка Windows PowerShell возвращает только те свойства объекта DateTime, которые требуются для отображения даты в указанном формате. yyyy - год, MM - месяц, dd - день, HH - минута, mm - секунда. Создадим переменную, в которой будем хранить время запуска сервера. Код: $log = [string]::Concat('Log_',$date,'.x') Метод Concat используется для объединения нескольких строк. Методы – это действия, имеющие отношение к данным объекта, такие как удаление или перемещение файла. В качестве примера у нас получится такая строка: Код: Log_2018_04_02_11_55.x Сам файл с логом будет называться так: Код: server.logLog_2018_04_02_11_55.x Создадим переменную, в которой объединим строку запуска сервера и строку, содержащую время запуска сервера. Код: $current_arg=[string]::Concat($arg,$log) Запускаем процесс. Код: Start-Process -FilePath $path -ArgumentList $current_arg Код: Start-Process Запускает один или несколько процессов на локальном компьютере. Код: -FilePath Задает путь и имя файла программы, выполняемой в процессе. Код: -ArgumentList Задает параметры или значения параметров, используемые при запуске процесса. Получаем объект процесса. Код: $ps=get-process | where-object { $_.Name -eq 'my_ucc' } Дальше имеем следующее: Код: do {Start-Sleep -s 1} while ($ps.HasExited -eq $false) Код: do Выполняет список инструкций один или несколько раз в зависимости от условия While. Код: Start-Sleep Командлет приостанавливает выполнение скрипта или сеанса на указанный период времени. Код: -s Секунды, в данном случае - одна. Код: $ps.HasExited Примет значение true, если запущенный процесс операционной системы (в данном случае наш сервер) был завершен; в противном случае — значение false. То есть, наше условие будет выглядеть следующим образом: Приостанавливаем выполнение скрипта на одну секунду (Проще говоря, находимся в спящем режиме), если процесс активен. Если процесс завершится или зависнет, произойдёт выход из while. Код: 'Restarting' Выводим информацию о том, что процесс перезапускается. Код: Start-Sleep -s 1 Спим одну секунду. Код: $ps.Kill() Останавливаем процесс. Код: Start-Sleep -s 1 Спим ещё одну секунду. Код: else {'Already exist'} Eсли процесс уже существует, не выполняем скрипт, выводим информацию о том, что сервер уже запущен. После этого наступит следующий цикл и сервер снова запустится. Автор скрипта: Flame Автор статьи: Essence Ссылка на PowerShell файл: Start_myServer.ps1
Один вопрос: иногда CMD сервера все еще функционируют, но информация сервера не обновляется динамически в реальном времени, а сервер входит в состояние "ложной смерти", как можно автоматически обработать ситуацию?
После смены карты такого же не наблюдается? Есть мутатор, автоматически меняющий карту после некоторого времени простоя сервера без игроков. http://killingfloor.ru/xforum/threads/avtomaticheskaja-smena-karty.2820/