Der Autor liebt das Spiel sehr und ist selbst Administrator eines kleinen Servers „rein für Freunde“. Wie bei Amateuren üblich, ist alles auf dem Server modifiziert, was zu Instabilität der Arbeit und in der Folge zu einem Absturz führt. Da der Autor Powershell besser kennt als die Lage der Geschäfte in seiner Straße, entschied er sich für „Bestes Skript zum Starten von Minecraft 2020". Das gleiche Skript diente als Grundlage für die Vorlage in
Die Befehle, die wir brauchen
Alternative Protokollierung
Nachdem ich ein paar weitere Mods installiert hatte, stellte ich fest, dass der Server offenbar zusammenbrach, ohne den Krieg zu erklären. Der Server hat keine Fehler in „latest.log“ oder „debug“ geschrieben und die Konsole, die theoretisch diesen Fehler schreiben und stoppen sollte, wurde geschlossen.
Wenn Sie nicht schreiben möchten, tun Sie es nicht. Wir haben Powershell mit einem Cmdlet Tee-Objekt, das ein Objekt nimmt und es gleichzeitig in eine Datei und an die Konsole ausgibt.
.handler.ps1 | Tee-Object .StandardOutput.txt -Append
Daher greift Powershell die StandardAusgabe auf und schreibt sie in eine Datei. Versuchen Sie nicht, es zu verwenden Start-Prozess, da es ein System.ComponentModel.Component und kein StandardOutput zurückgibt und -RedirectStandardOutput die Eingabe in die Konsole unmöglich macht, was wir vermeiden möchten.
Argumente starten
Nachdem der Autor das gleiche Mod-Paar installiert hatte, stellte er fest, dass der Server auch nicht über genügend RAM verfügte. Und es ist notwendig, die Startargumente zu ändern. Anstatt sie jedes Mal in start.bat zu ändern, das jeder verwendet, verwenden Sie einfach dieses Skript.
Da Tee-Object StandardOutput nur liest, wenn die ausführbare Datei „Just like that“ heißt, muss ein weiteres Skript erstellt werden. Dieses Skript führt Minecraft selbst aus. Beginnen wir mit den Argumenten.
Um in Zukunft der ultimativen Faulheit frönen zu können, muss das Skript Startargumente im Handumdrehen sammeln. Beginnen wir dazu mit der Suche nach der neuesten Version schmieden.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1
Mit sort-object nehmen wir immer das Objekt mit der größten Nummer, egal wie viele Sie dort ablegen. Ultimative Faulheit.
Jetzt müssen wir dem Server Speicher zuweisen. Dazu nehmen wir die Größe des Systemspeichers und schreiben diese in einen String.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"
Korrekter automatischer Neustart
Der Autor hat .bat-Dateien von anderen Leuten gesehen, aber sie haben den Grund, warum der Server gestoppt wurde, nicht berücksichtigt. Es ist unpraktisch, was ist, wenn Sie nur die Mod-Datei ändern oder etwas löschen müssen?
Lassen Sie uns nun einen ordnungsgemäßen Neustart durchführen. Der Autor ist zuvor auf seltsame Skripte gestoßen, die den Server neu starteten, unabhängig davon, warum der Server beendet wurde. Wir werden Exitcode verwenden. Java verwendet 0 als Erfolg, also lasst uns von dort aus weitermachen.
Erstellen wir zunächst eine Funktion, die den Server neu startet, wenn er ausfällt.
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 der Schleife, bis der Server seine eigene Konsole mit dem Befehl /stop normal beendet.
Wenn wir uns dafür entscheiden würden, alles zu automatisieren, wäre es schön, das Startdatum, das Ende und auch den Grund für das Ende zu erfassen.
Dazu schreiben wir das Ergebnis von Start-Process in eine Variable. In einem 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 -PassThru
Und dann schreiben Sie die Ergebnisse in eine Datei. Folgendes wird uns in einer Variablen zurückgegeben:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTime
All dies kann mit Add-Content zur Datei hinzugefügt werden. Nachdem wir ein wenig gebürstet haben, erhalten wir ein solches Skript, aber wir nennen es 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
Lassen Sie uns nun das Skript mit dem Start des Handlers entwerfen.
Richtiges automatisches Laden
Der Autor möchte Minecraft verschiedener Versionen von jedem Pfad aus mit einem Modul ausführen und außerdem Protokolle in einem bestimmten Ordner ablegen können.
Das Problem besteht darin, dass der Prozess von einem angemeldeten Benutzer gestartet werden muss. Dies kann über den Desktop oder WinRm erfolgen. Wenn Sie den Server als System oder sogar als Administrator ausführen, sich aber nicht anmelden, kann Server.jar nicht einmal eula.txt lesen und starten.
Wir können die automatische Anmeldung aktivieren, indem wir der Registrierung drei Einträge hinzufügen.
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
Es ist nicht sicher. Login und Passwort werden hier im Klartext angezeigt, daher müssen Sie zum Starten des Servers einen separaten Benutzer erstellen, der Zugriff auf Benutzerebene oder in einer noch engeren Gruppe hat. Von der Verwendung des Standardadministrators wird dringend abgeraten.
Wir haben das Autologin herausgefunden. Jetzt müssen Sie eine neue Aufgabe für den Server registrieren. Wir werden den Befehl über Powershell ausführen, er sieht also so aus:
$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
Zusammenbau des Moduls
Ordnen wir nun alles in Modulen an, die später verwendet werden können. Der gesamte Code vorgefertigter Skripte kann hier importiert und verwendet werden.
Sie können alles, was oben beschrieben wurde, auch einzeln verwenden, wenn Sie sich nicht mit Modulen herumschlagen möchten.
Minecraft starten
Lassen Sie uns zunächst ein Modul erstellen, das nichts weiter tut, als ein Skript auszuführen, das die Standardausgabe abhört und darauf schreibt.
Im Parameterblock fragt er, aus welchem Ordner Minecraft gestartet werden soll und wo das Protokoll abgelegt 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-Minecraft
Und Sie müssen Minecraft wie folgt ausführen:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"
Kommen wir nun zum gebrauchsfertigen Handler.ps1
Damit unser Skript beim Aufruf Parameter akzeptiert, müssen wir auch einen Parameterblock angeben. Bitte beachten Sie, dass Oracle Java ausgeführt wird. 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 "=============== 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
Minecraft registrieren
Das Skript ist praktisch das gleiche wie Start-Minecraft, außer dass es nur eine neue Aufgabe registriert. Akzeptiert die gleichen Argumente. Wenn kein Benutzername angegeben wird, wird der aktuelle verwendet.
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
Registrieren-Autologon
Im Parameterblock akzeptiert das Skript die Parameter Benutzername und Passwort. Wenn kein Benutzername angegeben ist, wird der Name des aktuellen Benutzers verwendet.
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."
}
Das Ausführen dieses Skripts sieht folgendermaßen aus:
Set-Autologon -Password "PlaintextPassword"
Wie zu verwenden
Überlegen Sie nun, wie der Autor selbst dies alles nutzt. So stellen Sie einen öffentlichen Minecraft-Server unter Windows ordnungsgemäß bereit. Fangen wir ganz von vorne an.
1. Erstellen Sie einen Benutzer
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword
2. Registrieren Sie die Aufgabe, um das Skript auszuführen
Sie können sich wie folgt für ein Modul anmelden:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"
Oder nutzen Sie die Standardtools:
$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. Aktivieren Sie die automatische Anmeldung und starten Sie den Computer neu
Set-Autologon -Username "MinecraftServer" -Password "Qw3"
Abschluss
Der Autor hat das Drehbuch auch für sich selbst erstellt und nimmt daher gerne Ihre Vorschläge zur Verbesserung des Drehbuchs entgegen. Der Autor hofft, dass der gesamte Code für Sie zumindest minimal nützlich war und der Artikel interessant ist.
Source: habr.com