Avtor zelo uživa v igri in je tudi administrator majhnega strežnika „samo za prijatelje“. Kot je običajno med ljubitelji, je na strežniku vse modifikirano, kar prinaša nestabilnost delovanja in s tem padce. Ker PowerShell avtor pozna bolje kot lokacijo trgovin na svoji ulici, se je odločil narediti „Najboljši skript za zagon Minecrafta 2020‘. Ta skript je služil tudi kot osnova za predlogo v . Vendar so vsi izvorni podatki že vključeni v članku. Zdaj po vrsti, kako je to vse potekalo.
Potrebni ukazi
Alternativno beleženje
Nekega dne, ko sem dodal še nekaj modov, sem ugotovil, da strežnik, po vsej verjetnosti, pade brez napovedi vojne. Strežnik ni pisal napak v latest.log ali debug, konzola, ki bi morale to napako zabeležiti in se ustaviti, pa je bila zaprta.
Če noče pisati – ni potrebe. Imamo PowerShell z ukazom Tee-Object, ki vzame objekt in ga izpiše hkrati v datoteko in v konzolo.
.handler.ps1 | Tee-Object .StandardOutput.txt -AppendTako bo PowerShell pobiral StandardOutput in ga zapisoval v datoteko. Ne poskušajte uporabiti Start-Process, ker bo vrnil System.ComponentModel.Component, ne pa StandardOutput, medtem ko -RedirectStandardOutput onemogoči vnos v konzolo, kar želimo zagotoviti.
Argumenti za zagon
Ko je avtor namestil tiste modove, je opazil, da strežniku primanjkuje tudi pomnilnika. Zato je potrebno spremeniti argumente za zagon. Namesto da bi jih vsakokrat spreminjali v start.bat, katerega vsi uporabljajo, preprosto uporabite ta skript.
Ker Tee-Object bere StandardOutput le, ko se izvršljivo datoteko pokliče „tako brez predsodkov“, bomo morali narediti še en skript. Ta skript bo zagnal sam Minecraft. Začnimo z argumenti.
Da bi se v prihodnje prepustili ultimativni lenobi, mora skript dinamično zbirati argumente za zagon. Za to začnemo s iskanjem zadnje različice forge.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1S pomočjo sort-object bomo vedno vzeli objekt z največjim številom, ne glede na to, koliko jih tam postavite. Ultimativna lenoba.
Zdaj moramo dodeliti strežniku pomnilnik. Za to vzamemo količino sistemskega pomnilnika in zapišemo njegovo vsoto v niz.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"Pravilno samodejno ponovno zagon
Autor je videl .bat datoteke od drugih ljudi, vendar niso upoštevali razloga, zakaj je bil strežnik ustavljen. Je nevšečno, da če je treba le zamenjati mod datoteko ali odstraniti kaj?
Zdaj bomo izvedli pravilen ponovni zagon. Avtor je prej naletel na čudne skripte, ki so ponovno zagnali strežnik ne glede na to, zakaj je strežnik prenehal delovati. Mi pa uporabimo exitcode. Java uporablja 0 za uspešen izhod, od tod tudi plešemo.
Najprej bomo ustvarili funkcijo, ki bo ponovno zagnala strežnik v primeru, da se ni uspešno izklopil.
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Write-Log
Restart-Minecraft
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
Skripta bo ostala v zanki, dokler strežnik ne konča delovanja normalno, z ukazom \/stop iz svoje konzole.
Če smo vse želeli avtomatizirati, bi bilo dobro tudi zbrati datum začetka, konca ter razlog za zaključek.
Zato zapišemo rezultat Start-Process v spremenljivko. V skripti to izgleda takole:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThruNato rezultate zapišemo v datoteko. To je, kar se vrača v spremenljivko:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeVse to lahko dodamo v datoteko z Add-Content. S nekoliko boljšo obliko dobimo to skripto, ki jo poimenujemo 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
Zdaj uredimo skripto za zagon handlerja.
Pravilna samodejna napoved
Avtor želi, da en modul zažene Minecraft različnih različic iz katerega koli mesta, ter da ima možnost shranjevanja logov v določeno mapo.
Težava je, da mora postopek zagnati uporabnik, ki je v sistemu. To lahko storimo prek delovne površine ali WinRm. Če zaženemo strežnik v imenu sistema ali celo skrbnika, vendar se ne prijavimo v sistem, strežnik.jar ne bo mogel niti prebrati eula.txt in se zagnati.
Omogočimo samodejni prijavo v sistem z dodajanjem treh zapisov v register.
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 SilentlyContinueTo ni varno. Tukaj se prijava in geslo navedeta v prostem besedilu, zato je treba za zagon strežnika ustvariti ločenega uporabnika, ki ima dostop na ravni uporabnika ali v še užem skupini. Uporaba privzetega skrbnika za to je kategorično odsvetovana.
Avtomatsko prijavo smo uredili. Zdaj je treba registrirati novo nalogo za strežnik. Zagnali bomo ukaz iz Powershell, zato bo to videti tako:
$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 HighestSestavljamo modul
Zdaj se vse skupaj uredimo v module, ki jih lahko nato uporabimo. Celotna koda končnih skript je tukaj, uvozite in uporabljajte.
Vse zgoraj opisano lahko uporabite ločeno, če se ne želite ukvarjati z moduli.
Start-Minecraft
Najprej bomo naredili modul, ki bo samo zagnal skript, ki bo poslušal in zapisoval standardni izhod.
V bloku parametrov se sprašuje, iz katere mape naj se zažene Minecraft in kam naj se shrani 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-MinecraftMinecraft se bo zagnal tako:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"Zdaj preidimo na pripravljen Handler.ps1
Da lahko naš skript sprejema parametre ob klicu, je treba tudi navesti blok parametrov. Upoštevajte, da zažene Oracle Java; če uporabljate drugo različico, bo treba spremeniti pot do izvršljive datoteke.
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
Register-Minecraft
Скрипт почти полностью повторяет Start-Minecraft, за исключением того, что он только регистрирует новую задачу. Принимает те же аргументы. Имя пользователя, если не указано, берется текущее.
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-MinecraftRegister-Autologon
В блоке параметров скрипт принимает параметры Username и Password. Если Username не был указан, используется имя текущего пользователя.
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."
}
Запуск этого скрипта выглядит так:
Set-Autologon -Password "PlaintextPassword"Kako uporabljati
Сейчас рассмотрим, как сам автор использует этот скрипт. Как правильно развернуть публичный сервер Minecraft на Windows. Начнем с самого начала.
1. Создаем пользователя
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword2. Регистрируем задание по запуску скрипта
Вы можете зарегистрировать это с помощью модуля следующим образом:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MinecraftServer" -TaskName "MinecraftStarter"Или воспользоваться стандартными средствами:
$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. Включаем автовход в систему и перезагружаем машину
Set-Autologon -Username "MinecraftServer" -Password "Qw3"Zaključek
Автор сделал скрипт, в том числе и для себя, и будет рад услышать ваши предложения по его улучшению. Он надеется, что этот код был хотя бы немного полезен вам, а статья вызвала интерес.
Izvor: habr.com
