Den perfekte serverstart script til Minecraft

Den perfekte serverstart script til Minecraft

Forfatteren elsker virkelig spillet og er selv administrator for en lille server "kun for venner". Som det er sædvanligt blandt entusiaster, er alt modded på serveren, hvilket fører til ustabilitet og som konsekvens nedbrud. Da forfatteren kender Powershell bedre end placeringen af butikkerne på sin gade, besluttede han at lave "Den Bedste Skripte Til At Starte Minecraft 2020". Dette samme skript blev grundlaget for skabelonen i marketplace Ruvds. Men alle kilderne er allerede i artiklen. Nu, i rækkefølge, hvordan det hele blev udført.

De Nødvendige Kommandoer

Alternativ Logging

En gang satte jeg et par mods til, og jeg opdagede, at serveren, tilsyneladende, falder uden forudgående varsel. Serveren skrev ikke fejl i latest.log eller debug, og konsollen, som i teorien burde have skrevet denne fejl og lukket ned, var blevet lukket.

Hvis den ikke vil skrive – så er det ikke nødvendigt. Vi har Powershell med cmdlet'en Tee-Object, som tager et objekt og udskriver det til en fil og til konsollen samtidig.

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

På den måde vil Powershell hente StandardOutput og skrive det til en fil. Prøv ikke at bruge Start-Process, fordi det vil returnere System.ComponentModel.Component, og ikke StandardOutput, og -RedirectStandardOutput vil gøre det umuligt at skrive ind i konsollen, hvilket vi ønsker at undgå.

Start Argumenter

Da forfatteren satte den samme par mods op, bemærkede han også, at serveren manglede RAM. Derfor skal vi ændre startargumenterne. I stedet for at ændre dem hver gang i start.bat, som alle bruger, kan du blot bruge dette skript.

Da Tee-Object kun læser StandardOutput, når den eksekverbare fil kaldes "direkte sådan", skal vi lave endnu et skript. Dette skript vil starte selve Minecraft. Lad os begynde med argumenterne.

For fremover at kunne slappe helt af, skal skriptet samle startargumenterne i realtid. Til dette vil vi starte med at finde den nyeste version af forge.

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

Ved hjælp af sort-object vil vi altid tage objektet med det højeste nummer, uanset hvor mange du har lagt ind. Ultimativ dovenskab.

Nu skal vi tildele serveren RAM. For at gøre dette tager vi mængden af systemhukommelse og optager dens samlede beløb i en string.

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

Korrekt Automatisk Genstart

Forfatteren har set .bat-filer fra andre personer, men de tog ikke højde for grunden til, at serveren blev stoppet. Det er upraktisk, når man blot skal ændre en mod-fil eller fjerne noget.
Lad os nu lave en korrekt genstart. Forfatteren har tidligere stødt på mærkelige scripts, der genstartede serveren uanset hvorfor serveren lukkede ned. Vi vil derimod bruge exitcode. Java bruger 0 som en succesfuld afslutning, og det er her, vi vil begynde.

Først opretter vi en funktion, der vil genstarte serveren, hvis den afsluttes uden succes.

function Get-MinecraftExitCode {
   
    do {
        
        if ($global:Process.ExitCode -ne 0) {
            Write-Log
            Restart-Minecraft
        }
        else {
            Write-Log
        }
 
    } until ($global:Process.ExitCode -eq 0)
    
}

Scriptet forbliver i en loop, indtil serveren afsluttes normalt via sin egen konsol med kommandoen \/stop.

Hvis vi ønsker at automatisere det hele, ville det være godt at indsamle start- og slutdato samt årsagen til afslutningen.

For dette gemmer vi resultatet af Start-Process i en variabel. I scriptet ser det sådan ud:

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

Og derefter gemmer vi resultaterne i en fil. Her er hvad der returneres til vores variabel:

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

Alt dette kan tilføjes til en fil med Add-Content. Efter lidt trimning får vi et script, som vi vil kalde 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

Lad os nu formatere scriptet til at starte handler'en.

Korrekt autostart

Forfatteren ønsker at starte Minecraft i forskellige versioner fra enhver sti med ét modul og have mulighed for at gemme logs i en bestemt mappe.

Problemet er, at processen skal startes af en bruger, der er logget ind i systemet. Dette kan gøres via skrivebordet eller WinRm. Hvis man starter serveren som system- eller endda administrator, men ikke logger ind, kan Server.jar ikke engang læse eula.txt og starte.

Vi kan aktivere automatisk login ved at tilføje tre poster i registreringsdatabasen.

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

Det er usikkert. Log ind og adgangskode angives her i klar tekst, så du skal oprette en separat bruger med brugeradgangsniveau, eller i en endnu snævrere gruppe, til serverens drift. Det anbefales helt klart ikke at bruge standardadministrator til dette.

Vi har forstået autologin. Nu skal vi registrere en ny opgave til serveren. Vi vil køre kommandoen fra PowerShell, så det vil se sådan ud:

$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

Vi samler modulet

Lad os nu organisere alt i moduler, som kan bruges senere. Al koden til de færdige scripts er her, importer og brug dem.

Alt det, der er beskrevet ovenfor, kan du bruge separat, hvis du ikke ønsker at bøvle med moduler.

Start-Minecraft

Først laver vi et modul, der kun vil køre et script, som lytter og registrerer standardoutput.

I parameterblokken beder den om, hvilken mappe Minecraft skal køres fra, og hvor loggen skal gemmes.

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

Og du skal starte Minecraft sådan her:

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

Lad os nu gå videre til det brugsklare Handler.ps1

For at vores script kan modtage parametre ved opkald, skal der også angives en parameterblok. Bemærk, at det starter Oracle Java, hvis du bruger en anden distribution, skal stien til eksekveringsfilen ændres.

param (
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$type,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$MinecraftPath,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$StandardOutput
)
 
Set-Location $MinecraftPath
 
function Restart-Minecraft {
 
    Write-host "=============== Starter 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 "Starttid:" $global:Process.StartTime
 
    Write-host "Exitkode:" $global:Process.ExitCode
    
    Write-host "Exit tid:" $global:Process.ExitTime
 
    Write-host "=============== Stoppet 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

Registrer-Minecraft

Scriptet gentager stort set Start-Minecraft, bortset fra at det kun registrerer en ny opgave. Det tager de samme argumenter. Brugerens navn, hvis det ikke er angivet, tages fra den nuværende bruger.

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

Registrer-Autologon

I parameterblokken tager scriptet parameteren Bruger og Adgangskode. Hvis Bruger ikke er angivet, bruges navnet på den nuværende bruger.

funktion Set-Autologon {
 
    param (
        [Parameter(
        HelpMessage="Brugernavn til autologon")]
        $Username = $env:USERNAME,
 
        [Parameter(Mandatory=$true,
        HelpMessage="Brugers 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 vil aktivere brugerens 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 blev indstillet korrekt."
 
}

Kørsel af dette script ser således ud:

Set-Autologon -Password "PlaintextPassword"

Sådan bruger du

Lad os nu se på, hvordan forfatteren selv bruger alt dette. Hvordan man korrekt implementerer en offentlig Minecraft-server på Windows. Vi starter fra begyndelsen.

1. Opretter en bruger

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

2. Registrerer opgaven for at køre scriptet

Du kan registrere det ved hjælp af modulen, sådan her:

Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MinecraftServer" -TaskName "MinecraftStarter"

Eller bruge de standardværktøjer:

$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. Aktiverer autologon og genstarter maskinen

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

Afslutning

Forfatteren har lavet scriptet især til sig selv, så han vil med glæde høre dine forslag til forbedringer af scriptet. Forfatteren håber, at hele denne kode har været enhver minimal nyttig for dig, og at artiklen er interessant.

Den perfekte serverstart script til Minecraft

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster