Der Autor liebt das Spiel sehr und ist selbst Administrator eines kleinen Servers "nur für Freunde". Wie es unter Enthusiasten Brauch ist, ist der Server komplett modifiziert, was mit Instabilität und somit Abstürzen einhergeht. Da der Autor PowerShell besser kennt als die Lage der Geschäfte in seiner Straße, entschloss er sich, "Das beste Skript zum Starten von Minecraft 2020" zu erstellen. Dieses Skript diente als Grundlage für eine Vorlage auf . Alle Quelldateien sind bereits im Artikel verfügbar. Lassen Sie uns nun der Reihenfolge nach erklären, wie alles umgesetzt wurde.
Die benötigten Befehle
Alternatives Logging
Nachdem ich noch ein paar Mods installiert hatte, entdeckte ich, dass der Server anscheinend ohne Vorwarnung abstürzt. Der Server schrieb keine Fehler in latest.log oder in debug, und die Konsole, die diesen Fehler theoretisch melden und stoppen sollte, war geschlossen.
Will nichts schreiben – muss auch nicht. Wir haben PowerShell mit dem Cmdlet Tee-Object, das ein Objekt nimmt und es gleichzeitig in eine Datei und in die Konsole ausgibt.
.handler.ps1 | Tee-Object .StandardOutput.txt -AppendSomit wird PowerShell die Standardausgabe abrufen und in eine Datei schreiben. Versuchen Sie nicht, dies zu verwenden. Starten-Prozess, da es System.ComponentModel.Component zurückgibt und nicht StandardOutput, und -RedirectStandardOutput die Eingabe in die Konsole unmöglich macht, was wir vermeiden möchten.
Start-Argumente
Nachdem das entsprechende Mod-Paar installiert wurde, bemerkte der Autor, dass dem Server auch der Arbeitsspeicher fehlt. Aufgrund dessen müssen die Start-Argumente geändert werden. Statt sie jedes Mal im start.bat zu ändern, der von allen verwendet wird, nutzen Sie einfach dieses Skript.
Da Tee-Object StandardOutput nur liest, wenn die ausführbare Datei „direkt so“ aufgerufen wird, müssen wir ein weiteres Skript erstellen. Dieses Skript wird Minecraft selbst starten. Lassen Sie uns mit den Argumenten beginnen.
Um in Zukunft der ultimativen Faulheit nachzugehen, sollte das Skript die Start-Argumente zur Laufzeit sammeln. Daher beginnen wir mit der Suche nach der neuesten Version forge.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -Last 1Mit sort-object werden wir immer das Objekt mit der höchsten Zahl nehmen, egal wie viele Sie dort platzieren. Ultimative Faulheit.
Jetzt müssen wir dem Server Arbeitsspeicher zuweisen. Dafür nehmen wir die Menge an Systemspeicher und speichern deren Summe in einer Zeichenkette.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"Richtige automatische Neustart
Der Autor hat .bat Dateien von anderen gesehen, aber diese haben nicht berücksichtigt, warum der Server gestoppt wurde. Es ist unpraktisch, wenn man einfach eine Mod-Datei austauschen oder etwas löschen möchte.
Jetzt führen wir einen richtigen Neustart durch. Der Autor ist auf seltsame Skripte gestoßen, die den Server unabhängig von den Gründen für das Herunterfahren neu gestartet haben. Wir hingegen verwenden den exitcode. Java verwendet 0 als erfolgreiche Beendigung, darauf basierend gehen wir vor.
Zuerst erstellen wir eine Funktion, die den Server im Falle eines unerwarteten Abbruchs neu startet.
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Write-Log
Restart-Minecraft
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
Das Skript bleibt in einer Schleife, bis der Server über die Konsole normal mit dem Befehl /stop beendet wird.
Wenn wir alles automatisieren, wäre es auch sinnvoll, das Start- und Enddatum sowie den Grund für das Herunterfahren zu protokollieren.
Dafür speichern wir das Ergebnis von Start-Process in einer Variablen. Im Skript sieht es so aus:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThruIm Anschluss speichern wir die Ergebnisse in einer Datei. Das erhalten wir in der Variablen:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeAll dies kann mit Add-Content in die Datei hinzugefügt werden. Nach etwas Aufbereitung erhalten wir folgendes Skript, das wir handler.ps1 nennen werden.
Add-Content -Value "Startzeit:" -Path $Logfile
$global:Process.StartTime
Add-Content -Value "Exit-Code:" -Path $Logfile
$global:Process.ExitCode | Add-Content $Logfile
Add-Content -Value "Austrittszeit:" -Path $Logfile
$global:Process.ExitTime | Add-Content $Logfile
Lassen Sie uns nun das Skript zum Starten des Handlers anpassen.
Korrekte Autostart-Einstellung
Der Autor möchte, dass ein Modul verschiedene Minecraft-Versionen aus beliebigen Pfaden startet und gleichzeitig die Möglichkeit hat, Protokolle in einem bestimmten Ordner zu speichern.
Das Problem ist, dass der Prozess von einem Benutzer gestartet werden muss, der im System angemeldet ist. Dies kann über den Desktop oder WinRm erfolgen. Wenn der Server im Namen des Systems oder sogar des Administrators, jedoch ohne Anmeldung, gestartet wird, kann Server.jar nicht einmal die eula.txt lesen und sich nicht starten.
Wir können die automatische Anmeldung durch das Hinzufügen von drei Einträgen in die Registrierung aktivieren.
New-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -Value $Username -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value $Password -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoAdminLogon -Value 1 -ErrorAction SilentlyContinueDas ist unsicher. Der Benutzername und das Passwort werden hier im Klartext angegeben, weshalb für den Serverstart ein separater Benutzer angelegt werden sollte, der über Benutzerzugriffsrechte verfügt oder in einer noch engeren Gruppe ist. Die Verwendung des Standardadministrators wird dringend abgeraten.
Die automatische Anmeldung haben wir jetzt geklärt. Jetzt müssen wir eine neue Aufgabe für den Server registrieren. Wir werden den Befehl aus PowerShell ausführen, sodass es folgendermaßen aussieht:
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$User = "ServerAdmin"
$PS = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument 'Start-Minecraft -Type Forge -LogFile "C:\minecraft\stdout.txt" -MinecraftPath "C:\minecraft"'
Register-ScheduledTask -TaskName "StartSSMS" -Trigger $Trigger -User $User -Action $PS -RunLevel HighestModul aufbauen
Lassen Sie uns jetzt alles in Module umwandeln, die später wiederverwendet werden können. Der gesamte Code für die Skripte befindet sich hier, importieren Sie ihn und nutzen Sie ihn.
Alles, was oben beschrieben wurde, können Sie auch separat verwenden, wenn Sie sich nicht mit Modulen beschäftigen möchten.
Start-Minecraft
Zuerst erstellen wir ein Modul, das lediglich das Skript starten wird, welches den Standardausgabestrom abfragt und aufzeichnet.
Im Parameterblock fragt er nach dem Ordner, aus dem Minecraft gestartet werden soll, und wo das Log gespeichert werden soll.
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-MinecraftMinecraft wird dann wie folgt gestartet:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"Jetzt wechseln wir zu dem einsatzbereiten Handler.ps1
Damit unser Skript Parameter bei der Ausführung akzeptieren kann, müssen auch die Parameterblöcke angegeben werden. Beachten Sie, dass es Oracle Java startet; wenn Sie eine andere Distribution verwenden, müssen Sie den Pfad zur ausführbaren Datei ändern.
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$type,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$MinecraftPath,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$StandardOutput
)
Set-Location $MinecraftPath
function Restart-Minecraft {
Write-host "=============== Start des großartigen Spieles ============"
$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 "Startzeit:" $global:Process.StartTime
Write-host "Exit-Code:" $global:Process.ExitCode
Write-host "Endzeit:" $global:Process.ExitTime
Write-host "=============== Großartiges Spiel gestoppt ============="
}
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
Das Skript ist fast identisch mit Start-Minecraft, unterscheidet sich jedoch darin, dass es nur eine neue Aufgabe registriert. Es akzeptiert dieselben Argumente. Der Benutzername wird, falls nicht angegeben, vom aktuellen Benutzer übernommen.
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
Im Parameterblock akzeptiert das Skript die Parameter Username und Password. Wenn der Username nicht angegeben wurde, wird der aktuelle Benutzername verwendet.
function Set-Autologon {
param (
[Parameter(
HelpMessage="Benutzername für die Autoanmeldung")]
$Username = $env:USERNAME,
[Parameter(Mandatory=$true,
HelpMessage="Benutzerpasswort")]
[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 wird die automatische Anmeldung des Benutzers aktivieren."
}
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 "Die Autologin-Einstellungen wurden erfolgreich gesetzt."
}
Der Start dieses Skripts sieht folgendermaßen aus:
Set-Autologon -Password "PlaintextPassword"So verwenden Sie es
Nun betrachten wir, wie der Autor selbst all dies verwendet. So richten Sie einen öffentlichen Minecraft-Server unter Windows richtig ein. Beginnen wir am Anfang.
1. Benutzer erstellen
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword2. Aufgabe zur Ausführung des Skripts registrieren
Sie können sich mit dem Modul wie folgt registrieren:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MinecraftServer" -TaskName "MinecraftStarter"Oder nutzen Sie die Standardmittel:
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$User = "ServerAdmin"
$PS = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument 'Start-Minecraft -Type Forge -LogFile "C:\minecraft\stdout.txt" -MinecraftPath "C:\minecraft"'
Register-ScheduledTask -TaskName "StartSSMS" -Trigger $Trigger -User $User -Action $PS -RunLevel Highest3. Aktivieren Sie den automatischen Login und starten Sie die Maschine neu.
Set-Autologon -Username "MinecraftServer" -Password "Qw3"Abschluss
Der Autor hat das Skript unter anderem für sich selbst erstellt und freut sich daher über Ihre Vorschläge zur Verbesserung des Skripts. Der Autor hofft, dass dieser gesamte Code für Sie zumindest minimal nützlich war und der Artikel interessant ist.
Quelle: habr.com
