O autor realmente ama o jogo e é administrador de um pequeno servidor "apenas para amigos". Como é comum entre os entusiastas, o servidor possui várias mods, o que resulta em instabilidade e, consequentemente, quedas. Como o Powershell é mais familiar para ele do que a localização das lojas na sua rua, ele decidiu criar "O Melhor Script Para Iniciar Minecraft 2020". Este mesmo script serviu como base para um modelo no . Mas todos os códigos-fonte já estão no artigo. Agora, vamos passo a passo, como tudo isso foi feito.
Os comandos necessários para nós
Registro alternativo
Certa vez, ao instalar mais alguns mods, percebi que o servidor, aparentemente, estava caindo sem aviso prévio. O servidor não registrou erros no latest.log ou no debug, e o console, que deveria imprimir esse erro e parar, estava fechado.
Se ele não quer reportar – não precisa. Temos o Powershell com o cmdlet Tee-Object, que pega um objeto e o envia para um arquivo e para o console ao mesmo tempo.
.handler.ps1 | Tee-Object .StandardOutput.txt -AppendAssim, o Powershell irá capturar o StandardOutput e gravá-lo em um arquivo. Não tente usar Start-Process, pois ele retornará System.ComponentModel.Component, não o StandardOutput, e -RedirectStandardOutput tornará impossível a entrada no console, o que queremos evitar.
Argumentos de inicialização
Depois de instalar aqueles mods, o autor notou que o servidor também estava sem memória RAM suficiente. Isso significa que é necessário alterar os argumentos de inicialização. Em vez de mudar isso toda vez no start.bat, que todo mundo usa, basta usar este script.
Como o Tee-Object lê o StandardOutput apenas quando o arquivo executável é chamado "Assim", precisaremos criar mais um script. Este script irá iniciar o próprio Minecraft. Vamos começar com os argumentos.
Para no futuro se entregar à total preguiça, o script deve reunir os argumentos de inicialização dinamicamente. Para isso, vamos começar procurando a última versão do forge.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1Com o sort-object, sempre pegaremos o objeto com o número mais alto, não importa quantos você tenha ali. Total preguiça.
Agora precisamos alocar memória para o servidor. Para isso, pegamos a quantidade de memória do sistema e somamos isso em uma string.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"Reinício automático correto
O autor viu arquivos .bat de outras pessoas, mas eles não consideravam o motivo pelo qual o servidor havia sido encerrado. É inconveniente, não é? E se precisar apenas trocar o arquivo do mod ou remover algo?
Agora vamos realizar o reinício corretamente. O autor anteriormente encontrou scripts estranhos que reiniciavam o servidor independentemente de como o servidor havia parado. Vamos usar o exitcode. O Java utiliza 0 para uma finalização bem-sucedida, e é a partir disso que trabalharemos.
Primeiro, vamos criar uma função que reiniciará o servidor em caso de falha na sua finalização.
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á em um loop até que o servidor se encerre corretamente a partir de sua própria console, usando o comando /stop.
Se decidirmos automatizar tudo, seria bom também coletar a data de início, término, e a razão para a finalização.
Para isso, gravamos o resultado de Start-Process em uma variável. No script, isso se parece com:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThruEm seguida, gravamos os resultados em um arquivo. Aqui está o que é retornado para a variável:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeTudo isso pode ser adicionado a um arquivo usando Add-Content. Após uma pequena organização, temos este script, que chamaremos de handler.ps1.
Add-Content -Value "Hora de início:" -Path $Logfile
$global:Process.StartTime
Add-Content -Value "Código de saída:" -Path $Logfile
$global:Process.ExitCode | Add-Content $Logfile
Add-Content -Value "Hora de saída:" -Path $Logfile
$global:Process.ExitTime | Add-Content $Logfile
Agora vamos organizar o script com a execução do handler.
Inicialização automática correta
O autor deseja usar um único módulo para executar diferentes versões do Minecraft a partir de quaisquer caminhos, além de ter a capacidade de armazenar logs em uma pasta específica.
O problema é que o processo deve ser iniciado por um usuário que esteja no sistema. Isso pode ser feito através da área de trabalho ou WinRm. Se o servidor for executado sob a conta do sistema ou até mesmo como administrador, mas o usuário não estiver logado, então o Server.jar não conseguirá ler o eula.txt e não iniciará.
Podemos habilitar o login automático no sistema 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 SilentlyContinueIsso não é seguro. O login e a senha são informados aqui em texto simples, por isso, para rodar o servidor, você deve criar um usuário separado que tenha acesso no nível de usuário ou em um grupo ainda mais restrito. Usar o administrador padrão para isso é fortemente desaconselhado.
Já entendemos o login automático. Agora precisamos registrar uma nova tarefa para o servidor. Vamos executar um 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 HighestVamos compilar o módulo
Agora vamos organizar tudo em módulos que poderão ser utilizados depois. Todo o código dos scripts prontos está aqui, importe e utilize.
Tudo o que foi descrito acima pode ser usado separadamente, caso você não queira se preocupar com módulos.
Start-Minecraft
Primeiro, faremos um módulo que apenas executará o script, que ouvirá e registrará a saída padrão.
No bloco de parâmetros, ele solicita de qual pasta iniciar o Minecraft e onde armazenar 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-MinecraftE o Minecraft deve ser iniciado assim:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"Agora vamos para o Handler.ps1 pronto para uso
Para que nosso script possa aceitar parâmetros quando chamado, também precisamos especificar o bloco de parâmetros. Observe que ele executa o Oracle Java; se você estiver usando outra distribuição, precisará alterar o caminho para o executável.
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$type,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$MinecraftPath,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$StandardOutput
)
Set-Location $MinecraftPath
function Restart-Minecraft {
Write-host "=============== Iniciando o servidor de jogo incrível ============"
$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 "Hora de início:" $global:Process.StartTime
Write-host "Código de saída:" $global:Process.ExitCode
Write-host "Hora de saída:" $global:Process.ExitTime
Write-host "=============== Servidor de jogo incrível parado ============="
}
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 uma duplicata de 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 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-MinecraftRegistrar-Autologon
No bloco de parâmetros, o script aceita os parâmetros Username e Password. Se o Username não for especificado, usa o nome do usuário atual.
function Set-Autologon {
param (
[Parameter(
HelpMessage="Nome de usuário para autologon")]
$Username = $env:USERNAME,
[Parameter(Mandatory=$true,
HelpMessage="Senha do usuário")]
[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 ativará o logon automático do usuário."
}
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 foi configurado com sucesso."
}
A execução deste script se parece com isto:
Set-Autologon -Password "SenhaEmTextoClaro"Como usar
Agora vamos ver como o autor usa tudo isso. Como corretamente configurar um servidor público Minecraft no Windows. Vamos começar do começo.
1. Criar o usuário
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword2. Registrar a tarefa para executar o script
Você pode registrar usando o módulo assim:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MinecraftServer" -TaskName "MinecraftStarter"Ou usar os recursos padrões:
$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 Highest3. Ativar o logon automático e reiniciar a máquina
Set-Autologon -Username "MinecraftServer" -Password "Qw3"Conclusão
O autor fez o script, inclusive para si mesmo, portanto, ficará feliz em ouvir suas sugestões de melhorias. O autor espera que todo esse código tenha sido minimamente útil para você e que o artigo seja interessante.
Fonte: habr.com
