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 . 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 -AppendW 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 1Dzię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 -PassThruA następnie zapisujemy wyniki do pliku. Oto co zwraca nam w zmiennej:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeTo 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 SilentlyContinueTo 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 HighestZbieramy 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-MinecraftA 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-MinecraftRegister-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 -UserMayNotChangePassword2. 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 Highest3. 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.
Źródło: habr.com
