O script ideal de inicialização do servidor Minecraft

O script ideal de inicialização do servidor Minecraft

O autor adora o jogo e ele próprio é administrador de um pequeno servidor “puramente para amigos”. Como é comum entre os amadores, tudo no servidor é modificado, o que acarreta instabilidade e, consequentemente, travamentos. Como o autor do Powershell conhece melhor a localização das lojas em sua rua, ele decidiu fazer "Melhor script para lançar o Minecraft 2020" O mesmo script serviu de base para o modelo em Mercado Ruvds. Mas todas as fontes já estão no artigo. Agora, na ordem, como tudo foi feito.

Os comandos que precisamos

Registro alternativo

Um dia, depois de instalar mais alguns mods, descobri que o servidor, aparentemente, estava travando sem declarar guerra. O servidor não gravou erros no last.log ou no debug, e o console, que em teoria deveria ter escrito esse erro e parado, foi fechado.

Se ele não quer escrever, não precisa. Temos Powershell com cmdlet T-objeto, que pega um objeto e o envia para um arquivo e para o console ao mesmo tempo.

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

Dessa forma, o Powershell irá pegar o StandardOutput e gravá-lo em um arquivo. Não tente usar Iniciar-Processoporque retornará System.ComponentModel.Component e não StandardOutput, e -RedirectStandardOutput impossibilitará a entrada no console, que é o que queremos evitar.

Lançar argumentos

Após instalar o mesmo par de mods, o autor percebeu que o servidor também não tinha RAM suficiente. E isso requer a mudança dos argumentos de lançamento. Em vez de alterá-los sempre no start.bat, que todo mundo usa, basta usar este script.

Como Tee-Object só lê StandardOutput quando o executável é chamado de "Just Like This", você terá que fazer outro script. Este script será lançado pelo próprio Minecraft. Vamos começar com os argumentos.

Para se entregar à preguiça definitiva no futuro, o roteiro deve coletar argumentos de lançamento instantaneamente. Para fazer isso, vamos começar procurando a versão mais recente forjar.

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

Usando sort-object, sempre pegaremos o objeto com o maior número, não importa quantos deles você coloque lá. Preguiça final.

Agora você precisa atribuir memória ao servidor. Para fazer isso, pegue a quantidade de memória do sistema e escreva sua quantidade em uma string.

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

Reinicialização automática correta

O autor viu arquivos .bat de outras pessoas, mas não levou em consideração o motivo pelo qual o servidor foi interrompido. Isso é inconveniente, e se você só precisar alterar o arquivo mod ou excluir algo?
Agora vamos fazer uma reinicialização adequada. O autor já encontrou scripts estranhos que reiniciavam o servidor, independentemente do motivo do desligamento do servidor. Usaremos o código de saída. Java usa 0 como sucesso, então vamos dançar a partir daqui.

Primeiro, vamos criar uma função que irá reiniciar o servidor caso ele falhe.

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 loop até que o servidor seja encerrado normalmente em seu próprio console usando o comando /stop.

Se decidirmos automatizar tudo, seria bom coletar a data de início, a data de conclusão e também o motivo da conclusão.

Para fazer isso, escrevemos o resultado do Start-Process em uma variável. No script fica assim:

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

E então escrevemos os resultados em um arquivo. Isto é o que nos é retornado na variável:

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

Tudo isso pode ser adicionado a um arquivo usando Add-Content. Depois de pentear um pouco, obtemos esse script e vamos chamá-lo de 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 vamos criar um script que inicia o manipulador.

Inicialização correta

O autor deseja executar diferentes versões do Minecraft a partir de qualquer caminho em um módulo e também poder armazenar logs em uma pasta específica.

O problema é que o processo deve ser iniciado por um usuário logado no sistema. Isso pode ser feito através do desktop ou WinRm. Se você executar o servidor como usuário do sistema ou mesmo como administrador, mas não fizer login, o Server.jar nem conseguirá ler o eula.txt e iniciar.

Podemos ativar o login automático adicionando três entradas ao 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

Não é seguro. O login e a senha são indicados aqui em texto simples, portanto, para iniciar o servidor é necessário criar um usuário separado que tenha acesso no nível do usuário, ou em um grupo ainda mais restrito. Não é estritamente recomendado usar um administrador padrão para isso.

Resolvemos o login automático. Agora você precisa registrar uma nova tarefa para o servidor. Executaremos o comando do Powershell, então ficará assim:

$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

Montagem do módulo

Agora vamos colocar tudo em módulos que poderão ser usados ​​posteriormente. Todo o código dos scripts prontos está aqui, importe e use.

Você pode usar tudo descrito acima separadamente se não quiser se preocupar com módulos.

Iniciar-Minecraft

Primeiro, vamos criar um módulo que não fará nada além de executar um script que ouvirá e registrará a saída padrão.

No bloco de parâmetros, ele pergunta de qual pasta iniciar o Minecraft e onde colocar o log.

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 você precisará iniciar o Minecraft assim:

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

Agora vamos passar para o Handler.ps1 pronto para uso

Para que nosso script aceite parâmetros quando chamado, também precisamos especificar um bloco de parâmetros. Observe que ele executa Oracle Java; se você estiver usando uma distribuição diferente, precisará alterar o caminho para o arquivo executável.

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

Registrar-Minecraft

O script é praticamente igual ao Start-Minecraft, exceto que apenas registra uma nova tarefa. Aceita os mesmos argumentos. O nome de usuário, se não for especificado, assume o nome atual.

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

Registro-Autologon

No bloco de parâmetros, o script aceita os parâmetros Nome de usuário e Senha. Se o nome de usuário não for especificado, o nome do usuário atual será usado.

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 execução deste script é semelhante a esta:

Set-Autologon -Password "PlaintextPassword"

Como usar

Agora vejamos como o próprio autor usa tudo isso. Como implantar corretamente um servidor público do Minecraft no Windows. Vamos começar desde o início.

1. Crie um usuário

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

2. Registre a tarefa para executar o script

Você pode se registrar usando um módulo como este:

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

Ou use ferramentas padrão:

$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. Ative o login automático e reinicie a máquina

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

Realização

O autor fez o roteiro, inclusive para si mesmo, portanto, terá prazer em ouvir suas sugestões para melhorar o roteiro. O autor espera que todo esse código tenha sido pelo menos minimamente útil para você e que o artigo seja interessante.

O script ideal de inicialização do servidor Minecraft

Fonte: habr.com

Adicionar um comentário