Lo script di avvio del server Minecraft perfetto

Lo script di avvio del server Minecraft perfetto

L'autore ama moltissimo il gioco e lui stesso è l'amministratore di un piccolo server “puramente per amici”. Come al solito tra i dilettanti, tutto sul server è modificato e ciò comporta instabilità e, di conseguenza, arresti anomali. Poiché l'autore di Powershell conosce meglio l'ubicazione dei negozi nella sua strada, ha deciso di creare "Miglior script per avviare Minecraft 2020" Lo stesso script è servito come base per il modello in Il mercato di Ruvds. Ma tutte le fonti sono già nell'articolo. Ora, in ordine, come è stato fatto tutto.

I comandi di cui abbiamo bisogno

Registrazione alternativa

Un giorno, dopo aver installato un altro paio di mod, ho scoperto che il server, a quanto pare, stava andando in crash senza dichiarare guerra. Il server non ha scritto errori in latest.log o in debug e la console, che in teoria avrebbe dovuto scrivere questo errore e arrestarsi, è stata chiusa.

Se non vuole scrivere, non ne ha bisogno. Abbiamo Powershell con cmdlet Tee-Oggetto, che prende un oggetto e lo invia contemporaneamente a un file e alla console.

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

In questo modo, Powershell preleverà lo StandardOutput e lo scriverà in un file. Non provare a usare Inizio-Processoperché restituirà System.ComponentModel.Component e non StandardOutput e -RedirectStandardOutput renderà impossibile l'accesso alla console, che è ciò che vogliamo evitare.

Lanciare argomentazioni

Dopo aver installato la stessa coppia di mod, l'autore ha notato che anche il server non aveva abbastanza RAM. E ciò richiede la modifica degli argomenti di lancio. Invece di cambiarli ogni volta in start.bat, che tutti usano, usa semplicemente questo script.

Poiché Tee-Object legge StandardOutput solo quando l'eseguibile si chiama "Just Like This", dovrai creare un altro script. Questo script verrà lanciato da Minecraft stesso. Cominciamo con le argomentazioni.

Per concedersi la massima pigrizia in futuro, lo script deve raccogliere al volo gli argomenti di lancio. Per fare ciò, iniziamo cercando la versione più recente forgiare.

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

Usando sort-object, prenderemo sempre l'oggetto con il numero più grande, non importa quanti ne metti lì. Pigrizia estrema.

Ora devi assegnare la memoria al server. Per fare ciò, prendi la quantità di memoria di sistema e scrivila in una stringa.

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

Riavvio automatico corretto

L'autore ha visto file .bat di altre persone, ma non ha tenuto conto del motivo per cui il server è stato arrestato. Questo è scomodo, cosa succede se hai solo bisogno di cambiare il file mod o eliminare qualcosa?
Ora facciamo un riavvio corretto. L'autore in precedenza si era imbattuto in strani script che riavviavano il server indipendentemente dal motivo per cui il server si era spento. Utilizzeremo il codice di uscita. Java usa 0 come successo, quindi balleremo da qui.

Innanzitutto, creiamo una funzione che riavvierà il server se fallisce.

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

Lo script rimarrà nel ciclo finché il server non si spegnerà normalmente dalla propria console utilizzando il comando /stop.

Se decidiamo di automatizzare tutto, allora sarebbe bello raccogliere la data di inizio, la data di completamento e anche il motivo del completamento.

Per fare ciò, scriviamo il risultato di Start-Process in una variabile. Nello script appare così:

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

E poi scriviamo i risultati in un file. Questo è ciò che ci viene restituito nella variabile:

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

Tutto questo può essere aggiunto a un file utilizzando Add-Content. Dopo averlo setacciato un po', otteniamo questo script e chiamiamolo 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

Ora creiamo uno script che avvii il gestore.

Avvio corretto

L'autore desidera eseguire diverse versioni di Minecraft da qualsiasi percorso in un modulo ed essere anche in grado di archiviare i registri in una cartella specifica.

Il problema è che il processo deve essere avviato da un utente che ha effettuato l'accesso al sistema. Questo può essere fatto tramite il desktop o WinRm. Se esegui il server come utente di sistema o anche come amministratore, ma non accedi, Server.jar non sarà nemmeno in grado di leggere eula.txt e avviarsi.

Possiamo abilitare l'accesso automatico aggiungendo tre voci al registro.

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

Non è sicuro. Il login e la password sono indicati qui in chiaro, quindi per avviare il server è necessario creare un utente separato che abbia accesso a livello utente o in un gruppo ancora più ristretto. È severamente sconsigliato utilizzare un amministratore standard per questo.

Abbiamo risolto il login automatico. Ora devi registrare una nuova attività per il server. Eseguiremo il comando da Powershell, quindi sarà simile a questo:

$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

Assemblaggio del modulo

Ora inseriamo tutto nei moduli che possono essere utilizzati in seguito. Tutto il codice per gli script già pronti è qui, importalo e usalo.

Puoi utilizzare tutto quanto descritto sopra separatamente se non vuoi preoccuparti dei moduli.

Inizio-Minecraft

Per prima cosa creiamo un modulo che non farà altro che eseguire uno script che ascolterà e registrerà l'output standard.

Nel blocco dei parametri chiede da quale cartella avviare Minecraft e dove inserire il registro.

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

E dovrai avviare Minecraft in questo modo:

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

Passiamo ora all'Handler.ps1 pronto all'uso

Affinché il nostro script accetti i parametri quando viene chiamato, dobbiamo anche specificare un blocco di parametri. Tieni presente che esegue Oracle Java, se stai utilizzando una distribuzione diversa dovrai modificare il percorso del file eseguibile.

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

Registrati-Minecraft

Lo script è praticamente lo stesso di Start-Minecraft, tranne per il fatto che registra solo una nuova attività. Accetta le stesse argomentazioni. Il nome utente, se non specificato, assume quello attuale.

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

Registrati-Accesso automatico

Nel blocco parametri, lo script accetta i parametri Nome utente e Password. Se Nome utente non è stato specificato, verrà utilizzato il nome dell'utente corrente.

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

L'esecuzione di questo script è simile alla seguente:

Set-Autologon -Password "PlaintextPassword"

Come usare

Ora diamo un'occhiata a come l'autore stesso usa tutto questo. Come distribuire correttamente un server Minecraft pubblico su Windows. Cominciamo dall'inizio.

1. Crea un utente

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

2. Registrare l'attività per eseguire lo script

Puoi registrarti utilizzando un modulo come questo:

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

Oppure utilizza strumenti standard:

$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. Abilita l'accesso automatico e riavvia la macchina

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

Completamento

L'autore ha realizzato la sceneggiatura, anche per se stesso, quindi sarà felice di ascoltare i tuoi suggerimenti per migliorare la sceneggiatura. L'autore spera che tutto questo codice ti sia stato almeno minimamente utile e che l'articolo sia stato interessante.

Lo script di avvio del server Minecraft perfetto

Fonte: habr.com

Aggiungi un commento