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
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.
Fonte: habr.com