Det perfekte Minecraft-serveroppstartsskriptet

Det perfekte Minecraft-serveroppstartsskriptet

Forfatteren elsker spillet veldig mye, og han er selv administrator for en liten server "rent for venner." Som vanlig blant amatører er alt på serveren modifisert, og dette medfører ustabilitet og som et resultat krasjer. Siden forfatteren av Powershell vet bedre enn plasseringen av butikkene i gaten hans, bestemte han seg for å lage "Beste skript for å lansere Minecraft 2020" Det samme manuset fungerte som grunnlag for malen i Ruvds markedsplass. Men alle kildene er allerede i artikkelen. Nå, i rekkefølge, hvordan det hele ble gjort.

Kommandoene vi trenger

Alternativ logging

En dag, etter å ha installert et par mods til, oppdaget jeg at serveren tilsynelatende krasjet uten å erklære krig. Serveren skrev ikke feil i latest.log eller i debug, og konsollen, som i teorien skulle ha skrevet denne feilen og stoppet, ble stengt.

Hvis han ikke vil skrive, trenger han ikke det. Vi har Powershell med cmdlet Tee-objekt, som tar et objekt og sender det til en fil og til konsollen samtidig.

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

På denne måten vil Powershell plukke opp StandardOutput og skrive den til en fil. Ikke prøv å bruke Start-prosessfordi det vil returnere System.ComponentModel.Component og ikke StandardOutput, og -RedirectStandardOutput vil gjøre det umulig å gå inn i konsollen, som er det vi ønsker å unngå.

Start argumenter

Etter å ha installert det samme paret med mods, la forfatteren merke til at serveren heller ikke hadde nok RAM. Og dette krever at lanseringsargumentene endres. I stedet for å endre dem hver gang i start.bat, som alle bruker, bare bruk dette skriptet.

Siden Tee-Object bare leser StandardOutput når den kjørbare filen heter "Just Like This", må du lage et annet skript. Dette skriptet vil bli lansert av Minecraft selv. La oss starte med argumentene.

For å hengi seg til ultimat latskap i fremtiden, må manuset samle lanseringsargumenter i farten. For å gjøre dette, la oss starte med å søke etter den nyeste versjonen smi.

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

Ved å bruke sorter-objekt vil vi alltid ta objektet med det største tallet, uansett hvor mange av dem du legger der. Ultimativ latskap.

Nå må du tilordne minne til serveren. For å gjøre dette, ta mengden systemminne og skriv mengden i streng.

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

Riktig automatisk omstart

Forfatteren har sett .bat-filer fra andre personer, men de tok ikke hensyn til årsaken til at serveren ble stoppet. Dette er upraktisk, hva om du bare trenger å endre mod-filen eller slette noe?
La oss nå gjøre en skikkelig omstart. Forfatteren kom tidligere over merkelige skript som startet serveren på nytt uavhengig av hvorfor serveren ble stengt. Vi vil bruke exitcode. Java bruker 0 som en suksess, så vi danser herfra.

La oss først lage en funksjon som vil starte serveren på nytt hvis den mislykkes.

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 løkken til serveren slår seg av normalt fra sin egen konsoll ved å bruke /stop-kommandoen.

Hvis vi bestemmer oss for å automatisere alt, ville det være fint å samle startdatoen, ferdigstillelsesdatoen og også årsaken til ferdigstillelsen.

For å gjøre dette skriver vi resultatet av Start-Process inn i en variabel. I manuset 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

Og så skriver vi resultatene til en fil. Dette er det som returneres til oss i variabelen:

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

Alt dette kan legges til en fil ved hjelp av Add-Content. Etter å ha finkjemmet det litt, får vi dette skriptet, og la oss kalle det 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å lage et skript som starter handler.

Riktig oppstart

Forfatteren ønsker å kjøre forskjellige versjoner av Minecraft fra hvilken som helst bane i én modul, og også kunne lagre logger i en bestemt mappe.

Problemet er at prosessen må startes av en bruker som er pålogget systemet. Dette kan gjøres via skrivebordet eller WinRm. Hvis du kjører serveren som en systembruker eller til og med en administrator, men ikke logger på, vil ikke Server.jar engang kunne lese eula.txt og starte.

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

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 trygt. Innlogging og passord er angitt her i klartekst, så for å starte serveren må du opprette en egen bruker som har tilgang på brukernivå, eller i en enda smalere gruppe. Det er strengt tatt ikke anbefalt å bruke en standard administrator for dette.

Vi ordnet opp i auto-påloggingen. Nå må du registrere en ny oppgave for serveren. Vi kjører kommandoen fra Powershell, så den 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

Montering av modulen

La oss nå legge alt inn i moduler som kan brukes senere. All koden for ferdige skript er her, importer og bruk.

Du kan bruke alt beskrevet ovenfor separat hvis du ikke vil bry deg med moduler.

Start-Minecraft

Først, la oss lage en modul som ikke gjør noe mer enn å kjøre et skript som vil lytte til og ta opp standardutdata.

I parameterblokken spør han fra hvilken mappe han skal starte Minecraft og hvor han skal plassere loggen.

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 må starte Minecraft slik:

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

La oss nå gå videre til den klare til bruk Handler.ps1

For at skriptet vårt skal akseptere parametere når det kalles, må vi også spesifisere en parameterblokk. Vær oppmerksom på at den kjører Oracle Java, hvis du bruker en annen distribusjon, må du endre banen til den kjørbare filen.

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

Register-Minecraft

Skriptet er praktisk talt det samme som Start-Minecraft, bortsett fra at det bare registrerer en ny oppgave. Godtar de samme argumentene. Brukernavnet, hvis det ikke er spesifisert, tar det gjeldende.

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-Autopålogging

I parameterblokken godtar skriptet parameterne Brukernavn og Passord. Hvis brukernavn ikke ble spesifisert, brukes gjeldende brukers navn.

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."
 
}

Å kjøre dette skriptet ser slik ut:

Set-Autologon -Password "PlaintextPassword"

Hvordan bruke

La oss nå se på hvordan forfatteren selv bruker alt dette. Slik distribuerer du en offentlig Minecraft-server på Windows. La oss starte helt fra begynnelsen.

1. Opprett en bruker

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

2. Registrer oppgaven for å kjøre skriptet

Du kan registrere deg ved å bruke en modul som denne:

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

Eller bruk standardverktøy:

$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. Aktiver automatisk pålogging og start maskinen på nytt

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

Ferdigstillelse

Forfatteren laget manuset, inkludert for seg selv, derfor vil han gjerne lytte til forslagene dine for å forbedre manuset. Forfatteren håper at all denne koden i det minste var minimalt nyttig for deg, og at artikkelen var interessant.

Det perfekte Minecraft-serveroppstartsskriptet

Kilde: www.habr.com

Legg til en kommentar