Den perfekte oppstartscripten for Minecraft-server

Den perfekte oppstartscripten for Minecraft-server

Forfatteren elsker virkelig spillet og er selv administrator på en lille server 'kun for venner'. Som det plejer blandt entusiaster, er serveren modded, hvilket medfører ustabil drift og dermed nedbrud. Da forfatteren kender PowerShell bedre end placeringen af butikkerne på sin gade, besluttede han sig for at lave 'Den Bedste Script Til At Køre Minecraft 2020'. Denne samme script var grundlaget for skabelonen i markedet Ruvds. Men alle kildekoder er allerede i artiklen. Nu vil vi i rækkefølge se, hvordan det hele blev lavet.

De nødvendige kommandoer

Alternativ logging

En dag, efter at have installeret et par moduler, opdagede jeg, at serveren, tilsyneladende, faldt uden videre. Serveren skrev ikke fejl i latest.log eller debug, og konsollen, der i teorien burde have skrevet denne fejl og stoppet, var lukket.

Vil ikke skrive – så behøver det ikke. 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å denne måde vil PowerShell hente StandardOutput og gemme det i en fil. Forsøg ikke at bruge Start-Process, fordi det vil returnere System.ComponentModel.Component og ikke StandardOutput, og -RedirectStandardOutput vil gøre det umuligt at indtaste i konsollen, hvilket vi ønsker at undgå.

Startup-argumenter

Efter at have installeret de samme moduler, bemærkede forfatteren, at serveren desuden manglede RAM. Dette kræver, at startup-argumenterne ændres. I stedet for at ændre dem hver gang i start.bat, som alle bruger, kunne man bare bruge dette script.

Da Tee-Object kun læser StandardOutput, når den udførte fil kaldes "Bare sådan", bliver vi nødt til at lave endnu et script. Dette script vil starte selve Minecraft. Lad os begynde med argumenterne.

For fremover at kunne være ultrafaul, skal scriptet indsamle startup-argumenterne on-the-fly. For dette begynder vi med at finde den nyeste version 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 største tal, uanset hvor mange du har lagt derind. Ultimativt dovenskab.

Nu skal vi tildele serveren RAM. For dette tager vi mængden af systemhukommelse og gemmer summen i en streng.

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

Korrekt automatisk genstart

Forfatteren har sett .bat-filer fra andre, men de tok ikke hensyn til årsaken til at serveren ble stoppet. Det er problematisk at vi kanskje bare må endre mod-filen eller fjerne noe?
La oss nå gjøre en riktig omstart. Forfatteren har tidligere støtt på merkelige skript som startet serveren på nytt uansett hvorfor serveren avsluttet. Vi skal bruke exitcode. Java bruker 0 som vellykket avslutning, og vi skal derfor ta utgangspunkt i det.

Først skal vi opprette en funksjon som vil starte serveren på nytt dersom den avsluttes på en feil måte.

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

Skriptet vil forbli i en løkke til serveren avslutter seg selv ordentlig fra konsollen, ved hjelp av kommandoen /stop.

Hvis vi skal automatisere alt, kan det også være greit å samle dato for oppstart, avslutning, samt årsaken til avslutningen.

For dette lagrer vi resultatet av Start-Process i en variabel. I skriptet ser det slik ut:

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

Deretter lagrer vi resultatene i en fil. Dette er hva som returneres i variabelen:

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

Alt dette kan vi legge til i en fil ved hjelp av Add-Content. Etter å ha ryddet litt opp, får vi et slikt skript, som vi kaller 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

La oss nå ordne skriptet med oppstart av handler'en.

Riktig automatisk oppstart

Forfatteren ønsker å starte Minecraft i forskjellige versjoner fra hvilke som helst stier med ett modul, samt ha mulighet til å lagre logger i en bestemt mappe.

Problemet er at prosessen må startes av en bruker som er logget inn på systemet. Dette kan gjøres via skrivebordet eller WinRm. Hvis serveren kjøres av systemet eller til og med administratoren uten innlogging, kan ikke Server.jar engang lese eula.txt og starte.

Vi kan aktivere automatisk pålogging ved å legge til tre oppføringer i registret.

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 ikke sikkert. Brukernavn og passord oppgis her i klartekst, så under serverdrift bør man opprette en egen bruker som har tilgangsnivå for brukere, eller i en enda smalere gruppe. Det anbefales kategorisk ikke å bruke standardadministrator for dette.

Vi har fått avtaleforbindelsen til å fungere. Nå må vi registrere en ny oppgave for serveren. Vi skal kjøre kommandoen fra Powershell, så det vil se slik ut:

$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 modulen.

La oss nå organisere alt i moduler som kan brukes senere. Hele koden for de ferdige skriptene er her, importer og bruk den.

Alt det ovenfor kan brukes separat hvis du ikke ønsker å bruke moduler.

Start-Minecraft

Først lager vi en modul som bare skal starte et skript som lytter og skriver standardoutput.

I parameterblokken spør den hvilken mappe Minecraft skal startes fra og hvor loggen skal lagres.

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 for å starte Minecraft må det gjøres slik:

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

La oss nå gå til den bruksklare Handler.ps1.

For at skriptet vårt skal kunne ta imot parametere ved anrop, må vi også angi en parameterblokk. Vær oppmerksom på at den starter Oracle Java; hvis du bruker en annen distribusjon, må banen til den kjørbare filen endres.

param (
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$type,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$MinecraftPath,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$StandardOutput
)
 
Set-Location $MinecraftPath
 
function Restart-Minecraft {
 
    Write-host "=============== Starter legendarisk spelserver ============"
 
    $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 "Utgångskod:" $global:Process.ExitCode
    
    Write-host "Avslutningstid:" $global:Process.ExitTime
 
    Write-host "=============== Stoppad legendarisk spelserver ============="
}
 
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

Skriptet upprepar i stort sett Start-Minecraft, med undantag för att det bara registrerar en ny uppgift. Den tar emot samma argument. Användarnamnet, om det inte anges, tas från den aktuella användaren.

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

I parameterblocket tar skriptet emot parameter Username och Password. Om Username inte angavs, används det aktuella användarnamnet.

function Set-Autologon {
 
    param (
        [Parameter(
        HelpMessage="Brukernavn for autologon")]
        $Username = $env:USERNAME,
 
        [Parameter(Mandatory=$true,
        HelpMessage="Brukerpassord")]
        [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 automatisk innlogging for brukeren."
 
    }
    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 ble satt opp vellykket."
 
}

Å kjøre dette skriptet ser slik ut:

Set-Autologon -Password "PlaintextPassword"

Hvordan bruke

Nå skal vi se hvordan forfatteren selv bruker alt dette. Hvordan man skal sette opp en offentlig Minecraft-server på Windows. La oss begynne fra starten.

1. Oppretter en bruker

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

2. Registrerer oppgave for å kjøre skriptet

Du kan registrere ved hjelp av modulen, slik:

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

Eller bruke standardverktøyene:

$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 autologin og starter maskinen på nytt

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

Fullføring

Forfatteren laget skriptet, blant annet for seg selv, så han vil gjerne høre forslag til forbedringer av skriptet. Forfatteren håper at hele denne koden har vært nyttig for deg, og at artikkelen var interessant.

Den perfekte oppstartscripten for Minecraft-server

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster