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 . 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 -AppendDessa 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 1Usando 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 -PassThruE então escrevemos os resultados em um arquivo. Isto é o que nos é retornado na variável:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeTudo 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 SilentlyContinueNã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 HighestMontagem 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-MinecraftE 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-MinecraftRegistro-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 vamos ver como o próprio autor usa tudo isso. Como implantar corretamente um servidor público de Minecraft em WindowsVamos começar do princípio.
1. Crie um usuário
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword2. 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 Highest3. 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.
Fonte: habr.com
