O script de inicio do servidor Minecraft ideal

O script de inicio do servidor Minecraft ideal

O autor adora moito o xogo e el mesmo é o administrador dun pequeno servidor "puramente para amigos". Como é habitual entre os afeccionados, todo o servidor está modificado, e isto implica inestabilidade e, como resultado, fallos. Dado que o autor de Powershell coñece mellor que a localización das tendas na súa rúa, decidiu facer "Mellor guión para lanzar Minecraft 2020" O mesmo script serviu de base para o modelo en Mercado Ruvds. Pero todas as fontes xa están no artigo. Agora, por orde, como se fixo todo.

Os comandos que necesitamos

Rexistro alternativo

Un día, despois de instalar un par de modificacións máis, descubrín que o servidor, ao parecer, fallaba sen declarar a guerra. O servidor non escribiu erros en latest.log nin en debug, e a consola, que en teoría debería escribir este erro e deterse, pechouse.

Se non quere escribir, non fai falta. Temos Powershell con cmdlet Tee-Obxecto, que toma un obxecto e envíao a un ficheiro e á consola ao mesmo tempo.

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

Deste xeito, Powershell recollerá o StandardOutput e escribirá nun ficheiro. Non intente usar Inicio-Procesoporque devolverá System.ComponentModel.Component e non StandardOutput, e -RedirectStandardOutput fará imposible entrar na consola, que é o que queremos evitar.

Lanzar argumentos

Despois de instalar ese mesmo par de modificacións, o autor notou que o servidor tampouco tiña suficiente memoria RAM. E iso require cambiar os argumentos de lanzamento. En lugar de cambialos cada vez en start.bat, que todos usan, só tes que usar este script.

Dado que Tee-Object só le StandardOutput cando o executable se chama "Just Like This", terás que facer outro script. Este script será lanzado polo propio Minecraft. Comecemos polos argumentos.

Para gozar da preguiza definitiva no futuro, o guión debe recoller argumentos de lanzamento sobre a marcha. Para iso, imos comezar a buscar a última versión forxar.

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

Usando sort-object, colleremos sempre o obxecto con maior número, sen importar cantos poña alí. Preguiza definitiva.

Agora cómpre asignar memoria ao servidor. Para iso, tome a cantidade de memoria do sistema e escriba a súa cantidade en cadea.

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

Reinicio automático correcto

O autor viu ficheiros .bat doutras persoas, pero non tiveron en conta o motivo polo que se detivo o servidor. Isto é un inconveniente, e se só precisas cambiar o ficheiro mod ou eliminar algo?
Agora imos facer un reinicio axeitado. O autor atopouse con scripts estraños que reiniciaban o servidor independentemente do motivo polo que se apagou. Usaremos o código de saída. Java usa 0 como un éxito, así que bailaremos desde aquí.

Primeiro, imos crear unha función que reinicie o servidor se falla.

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

O script permanecerá no bucle ata que o servidor se apague normalmente desde a súa propia consola mediante o comando /stop.

Se decidimos automatizar todo, sería bo recoller a data de inicio, a data de finalización e tamén o motivo da finalización.

Para iso, escribimos o resultado de Start-Process nunha variable. No guión vese así:

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

E despois escribimos os resultados nun ficheiro. Isto é o que se nos devolve na variable:

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

Todo isto pódese engadir a un ficheiro usando Add-Content. Peiteado un pouco, obtemos este script e chamémoslle 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

Agora imos crear un script que lance o controlador.

Arranque correcto

O autor quere executar diferentes versións de Minecraft desde calquera ruta nun módulo e tamén poder almacenar rexistros nun cartafol específico.

O problema é que o proceso debe ser iniciado por un usuario que estea iniciado sesión no sistema. Isto pódese facer a través do escritorio ou WinRm. Se executa o servidor como usuario do sistema ou mesmo como administrador, pero non inicia sesión, Server.jar nin sequera poderá ler eula.txt e iniciar.

Podemos activar o inicio de sesión automático engadindo tres entradas ao rexistro.

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 é seguro. O inicio de sesión e o contrasinal indícanse aquí en texto plano, polo que para iniciar o servidor cómpre crear un usuario separado que teña acceso a nivel de usuario ou nun grupo aínda máis reducido. Non se recomenda estrictamente utilizar un administrador estándar para iso.

Resolvemos o inicio de sesión automático. Agora cómpre rexistrar unha nova tarefa para o servidor. Executaremos o comando desde Powershell, polo que quedará así:

$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

Montaxe do módulo

Agora imos poñer todo en módulos que se poden usar máis tarde. Todo o código para scripts listos está aquí, importa e utiliza.

Podes usar todo o descrito anteriormente por separado se non queres molestarte cos módulos.

Inicio - Minecraft

En primeiro lugar, imos crear un módulo que non fará máis que executar un script que escoitará e gravará a saída estándar.

No bloque de parámetros, pregunta desde que cartafol lanzar Minecraft e onde poñer o rexistro.

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 terás que lanzar Minecraft así:

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

Agora imos pasar ao Handler.ps1 listo para usar

Para que o noso script acepte parámetros cando se chame, tamén necesitamos especificar un bloque de parámetros. Teña en conta que executa Oracle Java, se está a usar unha distribución diferente, terá que cambiar o camiño ao ficheiro executable.

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

Rexistro-Minecraft

O script é practicamente o mesmo que Start-Minecraft, agás que só rexistra unha tarefa nova. Acepta os mesmos argumentos. O nome de usuario, se non se especifica, toma o actual.

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

Rexistro-Autologon

No bloque de parámetros, o script acepta os parámetros Nome de usuario e Contrasinal. Se non se especificou o nome de usuario, utilízase o nome do usuario actual.

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

A execución deste script é así:

Set-Autologon -Password "PlaintextPassword"

Como usar

Vexamos agora como utiliza todo isto o propio autor. Como implementar correctamente un servidor público de Minecraft en Windows. Comecemos dende o principio.

1. Crea un usuario

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

2. Rexistra a tarefa para executar o script

Podes rexistrarte usando un módulo como este:

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

Ou use ferramentas estándar:

$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. Active o inicio de sesión automático e reinicie a máquina

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

Realización

O autor fixo o guión, incluso para si mesmo, polo tanto, estará encantado de escoitar as túas suxestións para mellorar o guión. O autor espera que todo este código fose polo menos mínimamente útil para vostede e que o artigo fose interesante.

O script de inicio do servidor Minecraft ideal

Fonte: www.habr.com

Engadir un comentario