Idealny skrypt uruchamiający serwer Minecraft

Idealny skrypt uruchamiający serwer Minecraft

Autor bardzo lubi tę grę i sam jest administratorem niewielkiego serwera "tylko dla przyjaciół". Zwykle wśród miłośników, na serwerze jest wiele modyfikacji, co prowadzi do niestabilności działania i w konsekwencji do zapaści. Ponieważ Powershell zna lepiej niż lokalizację sklepów na swojej ulicy, zdecydował się stworzyć "Najlepszy skrypt do uruchamiania Minecraft 2020" Ten sam skrypt stał się podstawą dla szablonu w rynkach Ruvds. Ale wszystkie źródła są już w artykule. Teraz po kolei, jak to wszystko zostało wykonane.

Potrzebne nam polecenia

Alternatywne logowanie

Pewnego dnia, po dodaniu jeszcze kilku modyfikacji, odkryłem, że serwer, w zasadzie, wyłącza się bez zapowiedzi. Serwer nie pisał błędów w latest.log ani debug, a konsola, która teoretycznie powinna napisać ten błąd i się zatrzymać, była zamknięta.

Nie chce pisać - nie ma potrzeby. Mamy Powershell z poleceniem Tee-Object, które bierze obiekt i wyprowadza go do pliku i konsoli jednocześnie.

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

W ten sposób Powershell pobierze StandardOutput i zapisze go do pliku. Nie próbuj używać Start-Process, ponieważ zwróci System.ComponentModel.Component, a nie StandardOutput, a -RedirectStandardOutput uniemożliwi wprowadzanie do konsoli, czego chcemy uniknąć.

Argumenty uruchamiania

Po zainstalowaniu tych modyfikacji, autor zauważył, że na serwerze brakuje pamięci operacyjnej. Przez to trzeba zmienić argumenty uruchamiania. Zamiast każdy raz zmieniać ich w start.bat, który wszyscy używają, po prostu użyj tego skryptu.

Ponieważ Tee-Object odczytuje StandardOutput tylko wtedy, gdy plik wykonywalny jest wywołany „po prostu tak”, trzeba będzie stworzyć jeszcze jeden skrypt. Ten skrypt uruchomi samego Minecrafta. Zaczniemy od argumentów.

Aby w przyszłości oddać się ostatecznemu lenistwu, skrypt powinien zbierać argumenty uruchamiania w locie. Zaczniemy od wyszukiwania najnowszej wersji forge.

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

Dzięki sort-object zawsze będziemy brali obiekt z największą liczbą, niezależnie od tego, ile ich tam wrzucisz. Ostateczne lenistwo.

Teraz musimy przypisać serwerowi pamięć. W tym celu bierzemy ilość pamięci systemowej i zapisujemy jej sumę w stringu.

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

Poprawne automatyczne ponowne uruchamianie

Autor widział pliki .bat od innych ludzi, ale nie uwzględniali oni powodu, dla którego serwer został zatrzymany. Czy nie byłoby prosto po prostu wymienić plik moda lub usunąć coś?
Teraz zrobimy prawidłowe restartowanie. Autor wcześniej natknął się na dziwne skrypty, które restartowały serwer, nie biorąc pod uwagę, dlaczego serwer zakończył pracę. My użyjemy exitcode. Java wykorzystuje 0 jako zakończenie z sukcesem, stąd będziemy na tym opierać nasze działania.

Najpierw stworzymy funkcję, która będzie restartować serwer w przypadku nieudanej jego pracy.

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, dopóki serwer sam z konsoli nie zakończy pracy poprawnie, używając polecenia /stop.

Jeżeli chcemy to wszystko zautomatyzować, warto również zbierać datę uruchomienia, zakończenia oraz powód zakończenia.

W tym celu zapisujemy wynik Start-Process w 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

A następnie zapisujemy wyniki do pliku. Oto co zwraca nam w zmiennej:

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

To wszystko można dodać do pliku za pomocą Add-Content. Po lekkim uporządkowaniu otrzymujemy taki skrypt, a nazwiemy go handler.ps1.

Add-Content -Value "Czas uruchomienia:" -Path $Logfile 
$global:Process.StartTime
 
Add-Content -Value "Kod zakończenia:" -Path $Logfile 
$global:Process.ExitCode | Add-Content $Logfile
    
Add-Content -Value "Czas zakończenia:" -Path $Logfile 
$global:Process.ExitTime | Add-Content $Logfile

Teraz zaaranżujmy skrypt z uruchomieniem handlera.

Prawidłowe autoładowanie

Autor chce uruchamiać Minecraft różnych wersji z dowolnych ścieżek w jednym module oraz mieć możliwość gromadzenia logów w konkretnej folder.

Problem polega na tym, że proces musi uruchomić użytkownik, który jest zalogowany w systemie. Można to robić przez pulpit lub WinRm. Jeśli uruchomić serwer jako system lub nawet administrator, ale nie być zalogowanym, to Server.jar nie będzie mógł nawet przeczytać eula.txt i się uruchomić.

Włączyć automatyczne logowanie w systemie możemy 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 jest niebezpieczne. Login i hasło są podawane tutaj w czystym tekście, dlatego do uruchomienia serwera powinno się utworzyć osobne konto użytkownika, które ma dostęp na poziomie użytkownika lub w jeszcze węższej grupie. Używanie standardowego administratora do tego jest zdecydowanie odradzane.

Poradziliśmy sobie z autologowaniem. Teraz musimy zarejestrować nowe zadanie dla serwera. Będziemy uruchamiać polecenie z Powershell, więc będzie to 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

Zbieramy moduł

Teraz stwórzmy wszystko w moduły, które można będzie później wykorzystać. Cały kod gotowych skryptów znajduje się tutaj, zaimportuj i korzystaj.

Wszystko, co opisano powyżej, możesz używać oddzielnie, jeśli nie chcesz bawić się modułami.

Start-Minecraft

Najpierw zrobimy moduł, który będzie jedynie uruchamiać skrypt, który będzie nasłuchiwał i zapisywał standardowe wyjście.

W bloku parametrów pyta on, z którego folderu uruchomić Minecraft i gdzie przechować log.

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

A Minecraft należy uruchamiać w ten sposób:

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

Teraz przejdźmy do gotowego do użycia Handler.ps1

Aby nasz skrypt mógł przyjmować parametry podczas wywołania, należy również określić blok parametrów. Zauważ, że uruchamia on Oracle Java, jeśli używasz innej dystrybucji, konieczne będzie zmienienie ścieżki do pliku wykonywalnego.

param (
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$type,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$MinecraftPath,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$StandardOutput
)
 
Set-Location $MinecraftPath
 
function Restart-Minecraft {
 
    Write-host "=============== Rozpoczynanie wyjątkowego serwera gier ============"
 
    $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 "Czas rozpoczęcia:" $global:Process.StartTime
 
    Write-host "Kod wyjścia:" $global:Process.ExitCode
    
    Write-host "Czas zakończenia:" $global:Process.ExitTime
 
    Write-host "=============== Zatrzymano wyjątkowy serwer gier ============="
}
 
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

Register-Minecraft

Skrypt praktycznie powtarza Start-Minecraft, z wyjątkiem tego, że tylko rejestruje nowe zadanie. Przyjmuje te same argumenty. Nazwa użytkownika, jeśli nie została podana, przyjmuje aktualną.

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

Register-Autologon

W bloku parametrów skrypt przyjmuje parametr Username i Password. Jeśli Username nie został podany, używane jest imię bieżącego użytkownika.

function Set-Autologon {
 
    param (
        [Parameter(
        HelpMessage="Nazwa użytkownika do autologowania")]
        $Username = $env:USERNAME,
 
        [Parameter(Mandatory=$true,
        HelpMessage="Hasło użytkownika")]
        [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 włączy auto logowanie użytkownika."
 
    }
    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 "Auto logowanie zostało pomyślnie ustawione."
 
}

Uruchamianie tego skryptu wygląda tak:

Set-Autologon -Password "PlaintextPassword"

Jak korzystać

Teraz przyjrzymy się temu, jak autor korzysta z całego tego procesu. Jak poprawnie ustawić publiczny serwer Minecraft na Windows. Zaczniemy od początku.

1. Tworzymy użytkownika

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

2. Rejestrujemy zadanie uruchamiania skryptu

Możesz zarejestrować za pomocą modułu, tak:

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

Lub skorzystać z 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łączamy autologowanie i restartujemy komputer

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

Zakończenie

Autor stworzył skrypt również dla siebie, więc chętnie wysłucha twoich sugestii dotyczących ulepszenia skryptu. Autor ma nadzieję, że cały ten kod był dla ciebie przynajmniej w minimalnym stopniu przydatny, a artykuł interesujący.

Idealny skrypt uruchamiający serwer Minecraft

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster