Das perfekte Startskript für den Minecraft-Server

Das perfekte Startskript für den Minecraft-Server

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 Ruvds-Marktplatz. Aber alle Quellen sind bereits im Artikel. Nun der Reihe nach, wie alles gemacht wurde.

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.

Das perfekte Startskript für den Minecraft-Server

Source: habr.com

Kommentar hinzufügen