Autor hru velmi miluje a sám je správcem malého serveru „čistě pro přátele“. Jak už to mezi amatéry bývá, vše na serveru je modifikováno, což s sebou nese nestabilitu práce a v důsledku toho pád. Protože autor zná Powershell lépe než umístění obchodů ve své ulici, rozhodl se udělat „Nejlepší skript pro spuštění Minecraftu 2020". Stejný skript sloužil jako základ pro šablonu v
Příkazy, které potřebujeme
Alternativní těžba dřeva
Jakmile jsem nainstaloval několik dalších modů, zjistil jsem, že server zjevně padá, aniž by vyhlásil válku. Server nezapsal chyby do last.log ani neladil a konzole, která měla teoreticky tuto chybu zapsat a zastavit, byla uzavřena.
Pokud nechceš psát, tak ne. Máme Powershell s rutinou Tee-Object, který vezme objekt a zároveň jej odešle do souboru a do konzole.
.handler.ps1 | Tee-Object .StandardOutput.txt -Append
Powershell tedy vyzvedne StandardOutput a zapíše jej do souboru. Nesnažte se používat start-proces, protože vrátí System.ComponentModel.Component, nikoli StandardOutput, a -RedirectStandardOutput znemožní psaní do konzole, čemuž se chceme vyhnout.
Spusťte Argumenty
Po instalaci stejného páru modů si autor všiml, že server také nemá dostatek paměti RAM. A je nutné změnit argumenty spuštění. Místo toho, abyste je pokaždé měnili v start.bat, který všichni používají, použijte tento skript.
Vzhledem k tomu, že Tee-Object čte StandardOutput pouze tehdy, když se spustitelný soubor nazývá "Jen tak", bude třeba provést ještě jeden skript. Tento skript spustí samotný minecraft. Začněme s argumenty.
Aby si skript mohl v budoucnu dopřát ultimátní lenost, musí za běhu sbírat argumenty pro spuštění. Chcete-li to provést, začněme hledáním nejnovější verze vytvořit.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1
Pomocí sort-object vždy vezmeme objekt s největším číslem, bez ohledu na to, kolik jich tam vložíte. Konečná lenost.
Nyní musíme přiřadit paměť serveru. Za tímto účelem vezmeme velikost systémové paměti a zapíšeme její množství do řetězce.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"
Správný automatický restart
Autor viděl soubory .bat od jiných lidí, ale nevzali v úvahu důvod, proč byl server zastaven. Je to nepohodlné, co když potřebujete jen změnit soubor modu nebo něco smazat?
Nyní provedeme pořádný restart. Autor dříve narazil na podivné skripty, které restartovaly server bez ohledu na to, proč server skončil. Použijeme výstupní kód. Java používá 0 jako úspěch, takže pojďme tančit odtud.
Nejprve vytvořte funkci, která restartuje server, pokud selže.
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Write-Log
Restart-Minecraft
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
Skript zůstane ve smyčce, dokud server normálně neopustí svou vlastní konzolu pomocí příkazu /stop.
Pokud bychom se rozhodli vše automatizovat, pak by bylo fajn sesbírat datum spuštění, ukončení a také důvod konce.
K tomu zapíšeme výsledek Start-Process do proměnné. Ve skriptu to vypadá takto:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru
A pak zapište výsledky do souboru. Zde je to, co se nám vrací v proměnné:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTime
To vše lze do souboru přidat pomocí Add-Content. Když jsme trochu oprášili, dostaneme takový skript, ale říkáme mu 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
Nyní pojďme navrhnout skript se spuštěním handleru.
Správné automatické nabíjení
Autor chce spouštět minecraft různých verzí z libovolné cesty s jedním modulem a také mít možnost vkládat protokoly do konkrétní složky.
Problém je v tom, že proces musí spustit přihlášený uživatel. To lze provést přes plochu nebo WinRm. Pokud server provozujete jako systém nebo dokonce jako správce, ale nepřihlásíte se, pak Server.jar nebude schopen číst eula.txt a spustit se.
Automatické přihlášení můžeme povolit přidáním tří položek do registru.
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
Není to bezpečné. Přihlašovací jméno a heslo jsou zde označeny prostým textem, takže pro spuštění serveru je třeba vytvořit samostatného uživatele, který má přístup na uživatelské úrovni nebo v ještě užší skupině. Důrazně se nedoporučuje používat k tomu standardního správce.
Přišli jsme na automatické přihlášení. Nyní musíte pro server zaregistrovat novou úlohu. Příkaz spustíme z Powershell, takže bude vypadat takto:
$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
Sestavení modulu
Nyní si vše uspořádejme do modulů, které lze použít později. Veškerý kód hotových skriptů je zde, importujte a používejte.
Vše popsané výše můžete použít samostatně, pokud se nechcete trápit s moduly.
spustit minecraft
Nejprve udělejme modul, který nebude dělat nic jiného než spouštět skript, který bude naslouchat a zapisovat na standardní výstup.
V bloku parametrů se zeptá, ze které složky má spustit minecraft a kam umístit 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
A budete muset spustit minecraft takto:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"
Nyní přejdeme na připravený Handler.ps1
Aby náš skript při volání akceptoval parametry, musíme také zadat blok parametrů. Upozorňujeme, že běží na Oracle Java, pokud používáte jinou distribuci, budete muset změnit cestu ke spustitelnému souboru.
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
zaregistrovat minecraft
Skript je prakticky stejný jako Start-Minecraft, až na to, že pouze zaregistruje nový úkol. Přijímá stejné argumenty. Uživatelské jméno, pokud není uvedeno, přebírá aktuální.
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
Registrovat-automatické přihlášení
V bloku parametrů skript přijímá parametry Uživatelské jméno a Heslo. Pokud není zadáno Uživatelské jméno, použije se jméno aktuálního uživatele.
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."
}
Spuštění tohoto skriptu vypadá takto:
Set-Autologon -Password "PlaintextPassword"
Jak používat
Nyní zvažte, jak toho všeho využívá sám autor. Jak správně nasadit veřejný server Minecraft na Windows. Začněme úplně od začátku.
1. Vytvořte uživatele
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword
2. Zaregistrujte úlohu ke spuštění skriptu
Můžete se zaregistrovat pomocí modulu, jako je tento:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"
Nebo použijte standardní nástroje:
$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. Zapněte automatické přihlášení a restartujte počítač
Set-Autologon -Username "MinecraftServer" -Password "Qw3"
Dokončení
Autor vytvořil scénář i pro sebe, proto si rád vyslechne vaše návrhy na vylepšení scénáře. Autor doufá, že pro vás byl celý tento kód alespoň minimálně užitečný a článek je zajímavý.
Zdroj: www.habr.com