Idealny skrypt startowy serwera Minecraft

Idealny skrypt startowy serwera Minecraft

Autor bardzo kocha tę grę i sam jest administratorem małego serwera „tylko dla znajomych”. Jak zwykle wśród amatorów, wszystko na serwerze jest modowane, co pociąga za sobą niestabilność i w rezultacie awarie. Ponieważ autor Powershella wie lepiej niż lokalizacja sklepów na jego ulicy, postanowił zrobić „Najlepszy skrypt do uruchomienia Minecrafta 2020" Ten sam skrypt posłużył jako podstawa szablonu w Rynek w Ruvds. Ale wszystkie źródła są już w artykule. A teraz w kolejności jak to wszystko zostało zrobione.

Polecenia, których potrzebujemy

Logowanie alternatywne

Pewnego dnia, po zainstalowaniu kilku kolejnych modów, odkryłem, że serwer najwyraźniej zawieszał się bez wypowiedzenia wojny. Serwer nie zapisał błędów w najnowszym.log ani w debugowaniu, a konsola, która teoretycznie powinna była zapisać ten błąd i się zatrzymać, została zamknięta.

Jeśli nie chce pisać, nie musi. Mamy PowerShell z poleceniem cmdlet Tee-Obiekt, który pobiera obiekt i wysyła go jednocześnie do pliku i konsoli.

.handler.ps1 | Tee-Object .StandardOutput.txt -Append

W ten sposób Powershell pobierze StandardOutput i zapisze go w pliku. Nie próbuj używać Rozpocznij procesponieważ zwróci System.ComponentModel.Component, a nie StandardOutput, a -RedirectStandardOutput uniemożliwi wejście do konsoli, a tego chcemy uniknąć.

Uruchom argumenty

Po zainstalowaniu tej samej pary modów autor zauważył, że serwer również nie miał wystarczającej ilości pamięci RAM. A to wymaga zmiany argumentów uruchamiania. Zamiast zmieniać je za każdym razem w pliku start.bat, z którego wszyscy korzystają, po prostu użyj tego skryptu.

Ponieważ Tee-Object czyta StandardOutput tylko wtedy, gdy plik wykonywalny nazywa się „Just Like This”, będziesz musiał utworzyć inny skrypt. Ten skrypt zostanie uruchomiony przez sam Minecraft. Zacznijmy od argumentów.

Aby w przyszłości pozwolić sobie na skrajne lenistwo, skrypt musi na bieżąco zbierać argumenty uruchomienia. Aby to zrobić, zacznijmy od wyszukania najnowszej wersji wykuć.

$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1

Używając obiektu sortującego, zawsze weźmiemy obiekt o największej liczbie, niezależnie od tego, ile ich tam umieścisz. Ostateczne lenistwo.

Teraz musisz przypisać pamięć do serwera. Aby to zrobić, weź ilość pamięci systemowej i zapisz jej ilość w ciągu znaków.

$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"

Prawidłowy automatyczny restart

Autor widział pliki .bat od innych osób, ale nie wziął pod uwagę powodu zatrzymania serwera. Jest to niewygodne. A co jeśli po prostu musisz zmienić plik moda lub coś usunąć?
Teraz wykonajmy właściwy restart. Autor natknął się wcześniej na dziwne skrypty, które restartowały serwer niezależnie od przyczyny jego zamknięcia. Użyjemy kodu wyjścia. Java używa 0 jako sukcesu, więc odtąd będziemy tańczyć.

Najpierw utwórzmy funkcję, która w przypadku awarii zrestartuje serwer.

function Get-MinecraftExitCode {
   
    do {
        
        if ($global:Process.ExitCode -ne 0) {
            Write-Log
            Restart-Minecraft
        }
        else {
            Write-Log
        }
 
    } until ($global:Process.ExitCode -eq 0)
    
}

Skrypt pozostanie w pętli do czasu normalnego zamknięcia serwera z własnej konsoli za pomocą polecenia /stop.

Jeśli zdecydujemy się na automatyzację wszystkiego, dobrze byłoby zebrać datę rozpoczęcia, datę zakończenia, a także powód zakończenia.

Aby to zrobić, zapisujemy wynik Start-Process do zmiennej. W skrypcie wygląda to tak:

$global:Process = Start-Process -FilePath  "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru

Następnie zapisujemy wyniki do pliku. Oto, co jest nam zwracane w zmiennej:

$global:Process.StartTime
$global:Process.ExitCode	
$global:Process.ExitTime

Wszystko to można dodać do pliku za pomocą Add-Content. Po lekkim przeczesaniu otrzymujemy ten skrypt i nazwijmy go handler.ps1.

Add-Content -Value "Start time:" -Path $Logfile 
$global:Process.StartTime
 
Add-Content -Value "Exit code:" -Path $Logfile 
$global:Process.ExitCode | Add-Content $Logfile
    
Add-Content -Value "Exit time:" -Path $Logfile 
$global:Process.ExitTime | Add-Content $Logfile

Stwórzmy teraz skrypt uruchamiający moduł obsługi.

Prawidłowe uruchomienie

Autor chce uruchamiać różne wersje Minecrafta z dowolnej ścieżki w jednym module, a także mieć możliwość przechowywania logów w określonym folderze.

Problem w tym, że proces musi rozpocząć użytkownik zalogowany do systemu. Można to zrobić za pomocą pulpitu lub programu WinRm. Jeśli uruchomisz serwer jako użytkownik systemu lub nawet administrator, ale się nie zalogujesz, Server.jar nie będzie mógł nawet odczytać eula.txt i uruchomić.

Automatyczne logowanie możemy włączyć poprzez dodanie trzech wpisów do rejestru.

New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultUserName -Value $Username -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultPassword -Value $Password  -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name AutoAdminLogon -Value 1 -ErrorAction SilentlyContinue

To nie jest bezpieczne. Login i hasło podane są tutaj jawnym tekstem, dlatego aby uruchomić serwer należy stworzyć osobnego użytkownika mającego dostęp na poziomie użytkownika lub w jeszcze węższej grupie. Zdecydowanie nie zaleca się korzystania w tym celu ze standardowego administratora.

Rozwiązaliśmy problem automatycznego logowania. Teraz musisz zarejestrować nowe zadanie dla serwera. Polecenie uruchomimy z Powershell, więc będzie wyglądać tak:

$Trigger = New-ScheduledTaskTrigger -AtLogOn
$User = "ServerAdmin"
$PS = New-ScheduledTaskAction -Execute 'PowerShell.exe" -Argument "Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"'
Register-ScheduledTask -TaskName "StartSSMS" -Trigger $Trigger -User $User -Action $PS -RunLevel Highest

Montaż modułu

Teraz złóżmy wszystko w moduły, które można wykorzystać później. Cały kod gotowych skryptów jest tutaj, zaimportuj i użyj.

Możesz użyć wszystkiego, co opisano powyżej, osobno, jeśli nie chcesz zawracać sobie głowy modułami.

Uruchom-Minecraft

Najpierw utwórzmy moduł, który nie zrobi nic więcej, jak tylko uruchomi skrypt, który będzie nasłuchiwał i nagrywał standardowe wyjście.

W bloku parametrów pyta z jakiego folderu uruchomić Minecrafta i gdzie umieścić logi.

Set-Location (Split-Path $MyInvocation.MyCommand.Path)
function Start-Minecraft {
    [CmdletBinding()]
    param (
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]
        $LogFile,
 
        [Parameter(Mandatory)]  
        [ValidateSet('Vanilla', 'Forge')]
        [ValidateNotNullOrEmpty()]
        [string]
        $Type,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $MinecraftPath
 
    )
    powershell.exe -file .handler.ps1 -type $type -MinecraftPath $MinecraftPath | Tee-Object $LogFile -Append
}
Export-ModuleMember -Function Start-Minecraft

Będziesz musiał uruchomić Minecraft w ten sposób:

Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"

Przejdźmy teraz do gotowego do użycia Handler.ps1

Aby nasz skrypt akceptował parametry po wywołaniu, musimy również określić blok parametrów. Pamiętaj, że działa na nim Oracle Java, jeśli używasz innej dystrybucji, będziesz musiał zmienić ścieżkę do pliku wykonywalnego.

param (
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$type,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$MinecraftPath,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$StandardOutput
)
 
Set-Location $MinecraftPath
 
function Restart-Minecraft {
 
    Write-host "=============== Starting godlike game server ============"
 
    $forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -first 1
 
    $ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
    $xmx = "-Xms" + $ram + "G"
    $global:Process = Start-Process -FilePath  "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru
    
}
 
function Write-Log {
    Write-host "Start time:" $global:Process.StartTime
 
    Write-host "Exit code:" $global:Process.ExitCode
    
    Write-host "Exit time:" $global:Process.ExitTime
 
    Write-host "=============== Stopped godlike game server ============="
}
 
function Get-MinecraftExitCode {
   
    do {
        
        if ($global:Process.ExitCode -ne 0) {
            Restart-Minecraft
            Write-Log
        }
        else {
            Write-Log
        }
 
    } until ($global:Process.ExitCode -eq 0)
    
}
 
Get-MinecraftExitCode

Zarejestruj się-Minecraft

Skrypt jest praktycznie taki sam jak Start-Minecraft, z tą różnicą, że rejestruje jedynie nowe zadanie. Akceptuje te same argumenty. Nazwa użytkownika, jeśli nie zostanie określona, ​​przyjmuje nazwę bieżącą.

function Register-Minecraft {
    [CmdletBinding()]
    param (
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]
        $LogFile,
 
        [Parameter(Mandatory)]  
        [ValidateSet('Vanilla', 'Forge')]
        [ValidateNotNullOrEmpty()]
        [string]$Type,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$MinecraftPath,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$User,
 
        [Parameter(Mandatory)]
        [string]$TaskName = $env:USERNAME
    )
 
    $Trigger = New-ScheduledTaskTrigger -AtLogOn
    $arguments = "Start-Minecraft -Type $Type -LogFile $LogFile -MinecraftPath $MinecraftPath"
    $PS = New-ScheduledTaskAction -Execute "PowerShell" -Argument "-noexit -command $arguments"
    Register-ScheduledTask -TaskName $TaskName -Trigger $Trigger -User $User -Action $PS -RunLevel Highest
    
}
 
Export-ModuleMember -Function Register-Minecraft

Zarejestruj się-Autologon

W bloku parametrów skrypt akceptuje parametry Nazwa użytkownika i Hasło. Jeśli nazwa użytkownika nie została określona, ​​zostanie użyta nazwa bieżącego użytkownika.

function Set-Autologon {
 
    param (
        [Parameter(
        HelpMessage="Username for autologon")]
        $Username = $env:USERNAME,
 
        [Parameter(Mandatory=$true,
        HelpMessage="User password")]
        [ValidateNotNullOrEmpty()]
        $Password
    )
 
    $i = Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon"
 
    if ($null -eq $i) {
        New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultUserName -Value $Username
        New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultPassword -Value $Password 
        New-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name AutoAdminLogon -Value 1
        Write-Verbose "Set-Autologon will enable user auto logon."
 
    }
    else {
        Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultUserName -Value $Username
        Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name DefaultPassword -Value $Password
        Set-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionWinlogon" -Name AutoAdminLogon -Value 1
    }
 
    
    Write-Verbose "Autologon was set successfully."
 
}

Uruchomienie tego skryptu wygląda następująco:

Set-Autologon -Password "PlaintextPassword"

Jak korzystać

Przyjrzyjmy się teraz, jak sam autor wykorzystuje to wszystko. Jak poprawnie wdrożyć publiczny serwer Minecraft w systemie Windows. Zacznijmy od samego początku.

1. Utwórz użytkownika

$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword

2. Zarejestruj zadanie, aby uruchomić skrypt

Rejestracji możesz dokonać korzystając z takiego modułu:

Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"

Lub użyj standardowych narzędzi:

$Trigger = New-ScheduledTaskTrigger -AtLogOn
$User = "ServerAdmin"
$PS = New-ScheduledTaskAction -Execute 'PowerShell.exe" -Argument "Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"'
Register-ScheduledTask -TaskName "StartSSMS" -Trigger $Trigger -User $User -Action $PS -RunLevel Highest

3. Włącz automatyczne logowanie i uruchom ponownie komputer

Set-Autologon -Username "MinecraftServer" -Password "Qw3"

Ukończenie

Autor stworzył scenariusz, także dla siebie, dlatego chętnie wysłucha Waszych sugestii dotyczących ulepszenia scenariusza. Autor ma nadzieję, że cały ten kod był dla Ciebie choć w minimalnym stopniu przydatny, a artykuł był interesujący.

Idealny skrypt startowy serwera Minecraft

Źródło: www.habr.com

Dodaj komentarz