Das perfekte Startskript für den Minecraft-Server



Der Autor mag das Spiel sehr und er selbst ist der Administrator eines kleinen Servers "nur für Freunde". Wie bei Amateuren üblich, wird alles auf dem Server moduliert, was zu Instabilität der Arbeit und infolge des Sturzes führt. Da der Autor Powershell besser kennt als die Geschäfte in seiner Straße, entschied er sich für "The Best Minecraft 2020 Launch Script ". Das gleiche Skript diente als Grundlage für die Vorlage auf dem Ruvds-Marktplatz . Aber alle Quellen sind bereits im Artikel enthalten. Nun, in der Reihenfolge, wie alles passiert ist.

Wir brauchen Teams


Alternative Protokollierung


Nachdem ich ein paar weitere Mods eingebaut hatte, stellte ich fest, dass der Server anscheinend abstürzt, ohne den Krieg zu erklären. Der Server hat keine Fehler in latest.log oder debug geschrieben, und die Konsole, die diesen Fehler schreiben und stoppen sollte, wurde geschlossen.

Will nicht schreiben - keine Notwendigkeit. Wir haben Powershell mit dem Cmdlet Tee-Object , das ein Objekt nimmt und es gleichzeitig in einer Datei und in der Konsole anzeigt.

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

Auf diese Weise nimmt Powershell StandardOutput auf und schreibt es in eine Datei. Versuchen Sie nicht, Start-Process zu verwenden , da System.ComponentModel.Component und nicht StandardOutput zurückgegeben werden und -RedirectStandardOutput das Aufrufen der Konsole unmöglich macht, was wir vermeiden möchten.

Argumente starten


Der Autor stellte fest, dass dem Server auch RAM fehlt. Und dies muss die Startargumente ä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 "Right So" heißt, müssen Sie ein anderes Skript erstellen. Dieses Skript führt Minecraft selbst aus. Beginnen wir mit den Argumenten.

Um sich in Zukunft der ultimativen Faulheit hinzugeben, muss das Skript sofort Startargumente sammeln. Suchen Sie dazu zunächst nach der neuesten Schmiede .

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

Mit Hilfe von sort-object nehmen wir immer das Objekt mit der größten Ziffer, egal wie viel Sie dort ablegen. Die ultimative Faulheit.

Jetzt müssen Sie dem Server Speicher zuweisen. Nehmen Sie dazu den Systemspeicher und schreiben Sie ihn in eine Zeichenfolge.

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

Korrigieren Sie den automatischen Neustart


Der Autor hat .bat-Dateien von anderen Personen gesehen, aber sie haben den Grund, warum der Server gestoppt wurde, nicht berücksichtigt. Ist es unpraktisch, wenn Sie nur die Mod-Datei ändern oder etwas löschen müssen?
Jetzt machen wir den richtigen Neustart. Der Autor stieß zuvor auf seltsame Skripte, mit denen der Server neu gestartet wurde, obwohl der Server heruntergefahren wurde. Wir werden den Exitcode verwenden. Java verwendet 0 als erfolgreichen Abschluss, daher werden wir tanzen.

Erstellen Sie zunächst eine Funktion, die den Server neu startet, wenn er nicht abgeschlossen werden kann.

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 von seiner eigenen Konsole mit dem Befehl / stop normal heruntergefahren wird.

Wenn wir uns alle für eine Automatisierung entscheiden würden, wäre es schön, das Startdatum, die Fertigstellung sowie den Grund für die Fertigstellung zu erfassen.

Dazu schreiben wir das Start-Process-Ergebnis in eine Variable. Im Skript sieht es so aus:

$global:Process = Start-Process -FilePath  "C:\Program Files (x86)\common files\Oracle\Java\javapath_target_*\java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru

Und dann schreiben wir die Ergebnisse in eine Datei. Folgendes kehrt in der Variablen zu uns zurück:

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

All dies kann mithilfe von Add-Content zur Datei hinzugefügt werden. Nachdem wir ein wenig gekämmt haben, erhalten wir ein solches Skript und 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 ausführen.

Richtiger Start


Der Autor möchte, dass ein Modul Minecraft verschiedener Versionen von beliebigen Pfaden aus startet und Protokolle in einem bestimmten Ordner ablegen kann.

Das Problem ist, dass der Prozess von dem Benutzer gestartet werden muss, der sich auf dem System befindet. Dies kann über den Desktop oder WinRm erfolgen. Wenn Sie den Server im Namen des Systems oder sogar des Administrators starten, sich jedoch nicht anmelden, kann Server.jar nicht einmal eula.txt lesen und starten.

Wir können die automatische Anmeldung am System aktivieren, indem wir der Registrierung drei Einträge hinzufügen.

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 SilentlyContinue

Es ist nicht sicher. Das Login und das Passwort werden hier im Klartext angezeigt. Sie müssen also einen einzelnen Benutzer starten, der Zugriff auf Benutzerebene oder in einer noch engeren Gruppe hat, um den Server zu starten. Es wird dringend davon abgeraten, einen Standardadministrator zu verwenden.

Mit automatischer Eingabe aussortiert. Jetzt müssen Sie eine neue Aufgabe unter dem Server registrieren. Wir werden den Befehl von Powershell aus ausführen, also sieht es so aus:

$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 Highest

Modul zusammenbauen


Lassen Sie uns nun alles zu Modulen machen, die später verwendet werden können. Der gesamte Code der vorgefertigten Skripte ist hier, importiert und verwendet.

Sie können alles oben Beschriebene separat verwenden, wenn Sie sich nicht mit Modulen beschäftigen möchten.

Starten Sie Minecraft


Zuerst erstellen wir ein Modul, das nur dies erledigt, führen ein Skript aus, das die Standardausgabe abhört und aufzeichnet.

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 so ausführen:

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

Fahren

wir nun mit dem gebrauchsfertigen Handler.ps1 fort. Damit unser Skript beim Aufruf Parameter akzeptieren kann, müssen wir auch einen Parameterblock angeben. Beachten Sie, dass Oracle Java gestartet 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 files\Oracle\Java\javapath_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

Register-Minecraft


Das Skript wiederholt praktisch Start-Minecraft, außer dass nur eine neue Aufgabe registriert wird. Akzeptiert die gleichen Argumente. Wenn der Benutzername nicht angegeben ist, 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

Register-Autologon


Im Parameterblock akzeptiert das Skript die Parameter Benutzername und Passwort. Wenn Benutzername nicht angegeben wurde, 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:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 
    if ($null -eq $i) {
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -Value $Username
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value $Password 
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoAdminLogon -Value 1
        Write-Verbose "Set-Autologon will enable user auto logon."
 
    }
    else {
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -Value $Username
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value $Password
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoAdminLogon -Value 1
    }
 
    
    Write-Verbose "Autologon was set successfully."
 
}

Das Ausführen dieses Skripts sieht folgendermaßen aus:

Set-Autologon -Password "PlaintextPassword"

Wie benutzt man


Nun werden wir uns überlegen, wie der Autor selbst all dies verwendet. So stellen Sie den öffentlichen Minecraft-Server unter Windows bereit. Beginnen wir von vorne.

1. Erstellen Sie einen Benutzer

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

2. Registrieren Sie die Aufgabe zum Ausführen des Skripts.

Sie können sich mit dem Modul wie folgt registrieren:

Register-Minecraft -Type Forge -LogFile "C:\minecraft\stdout.txt" -MinecraftPath "C:\minecraft\" -User "MInecraftServer" -TaskName "MinecraftStarter"

Oder verwenden Sie die Standardwerkzeuge:

$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 Highest

3. Aktivieren Sie die automatische Anmeldung am System und starten Sie den Computer neu

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

Fertigstellung


Der Autor hat das Skript erstellt, auch für sich selbst. Daher freut er sich über Ihre Vorschläge zur Verbesserung des Skripts. Der Autor hofft, dass all dieser Code für Sie zumindest minimal nützlich war, und der Artikel ist interessant.


All Articles