Autor opravdu miluje hru a je také správcem malé serveru "čistě pro přátele". Jak to bývá mezi nadšenci, na serveru je uděláno spoustu modifikací, což vede k nestabilitě a následným pádům. Protože Powershell zná lépe než umístění obchodů na své ulici, rozhodl se vytvořit "Nejlepší skript pro spuštění Minecraftu 2020". Tento skript byl také základem pro šablonu v . Ale všechny zdrojové kódy už najdete v článku. Teď se podívejme na to, jak se to všechno dělalo.
Potřebné příkazy
Alternativní logování
Jednou, když jsem nainstaloval další pár modů, jsem si všiml, že server, podle všeho, padá bez varování. Server nenapsal chyby do latest.log nebo do debug, a konzole, která by tuto chybu měla napsat a zastavit se, byla zavřená.
Pokud nechce psát – nemusí. Máme Powershell s cmdletem Tee-Object, který vezme objekt a zároveň ho zapíše do souboru i na konzoli.
.handler.ps1 | Tee-Object .StandardOutput.txt -AppendTímto způsobem bude Powershell brát StandardOutput a zapisovat ho do souboru. Nepokoušejte se použít Start-Process, protože vrátí System.ComponentModel.Component, a ne StandardOutput, a -RedirectStandardOutput zablokuje vstup do konzole, čemuž se chceme vyhnout.
Argumenty spuštění
Po nainstalování těch pár modů si autor všiml, že serveru také chybí operační paměť. To je potřeba změnit argumenty spuštění. Místo toho, abyste je pokaždé měnili ve start.bat, který všichni používají, jednoduše použijte tento skript.
Protože Tee-Object čte StandardOutput pouze tehdy, když je spustitelný soubor volán "Přímo“, bude potřeba vytvořit ještě jeden skript. Tento skript spustí samotný Minecraft. Začněme s argumenty.
Abychom se v budoucnu oddávali ultimátní lenosti, skript by měl shromažďovat argumenty spuštění za běhu. Začneme hledáním poslední verze forge.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1Pomocí sort-object vždy vezmeme objekt s největším číslem, ať už jich tam dáte kolik chcete. Ultimátní lenost.
Nyní je potřeba přiřadit serveru paměť. Proto vezmeme množství systémové paměti a zapíšeme jeho součet do string.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"Správný automatický restart
Autor viděl .bat soubory od jiných lidí, ale nezohlednili důvod, proč byl server zastaven. Je nepříjemné, že pokud je potřeba pouze vyměnit soubor módu nebo něco odebrat?
Nyní provedeme správné restartování. Autor dříve narazil na podivné skripty, které restartovaly server, ať už byl důvod jakýkoli. My budeme používat exitcode. Java používá 0 jako úspěšné ukončení, odtud budeme vycházet.
Nejprve vytvoříme funkci, která bude restartovat server v případě, že dojde k neúspěšnému ukončení jeho činnosti.
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 v cyklu, dokud server nezastaví svou činnost správně prostřednictvím příkazu /stop ze své konzole.
Pokud chceme všechno automatizovat, bylo by dobré také shromažďovat datum spuštění, ukončení a také důvod ukončení.
K tomu zapisujeme výsledek Start-Process do proměnné. V 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 -PassThruA poté zapisujeme výsledky do souboru. Takhle to vrací proměnné:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeVšechny tyto informace lze pomocí Add-Content přidat do souboru. Po úpravě dostáváme takový skript a nazveme ho 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í vytvořme skript spouštějící handler.
Správné automatické spuštění
Autor chce pomocí jednoho modulu spouštět Minecraft různých verzí z libovolných cest a mít možnost ukládat logy do konkrétní složky.
Problém spočívá v tom, že proces musí spustit uživatel, který je přihlášen do systému. To lze udělat přes pracovní plochu nebo WinRm. Pokud spouštíte server pod uživatelským účtem systému nebo dokonce administrátora, ale nejste přihlášeni, Server.jar nebude moci ani přečíst eula.txt a spustit se.
Automatické přihlášení můžeme umožnit 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 SilentlyContinueTo není bezpečné. Přihlašovací jméno a heslo jsou uvedeny v prostém textu, proto je nutné pro spuštění serveru vytvořit samostatného uživatele, který má přístup na úrovni uživatele, nebo ještě užší skupiny. Používat standardního administrátora pro tuto operaci se důrazně nedoporučuje.
S automatickým přihlášením jsme si poradili. Nyní je potřeba zaregistrovat nový úkol pro server. Příkaz spustíme z PowerShellu, takže to 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 HighestSestavujeme modul
Nyní zabalíme vše do modulů, které pak budeme moci použít. Celý kód hotových skriptů je zde, importujte a využijte ho.
Vše, co bylo popsáno výše, můžete použít samostatně, pokud se nechcete zabývat moduly.
Start-Minecraft
Nejprve vytvoříme modul, který pouze spustí skript, jenž bude poslouchat a zapisovat standardní výstup.
V bloku parametrů se ptá, z jaké složky má Minecraft spustit a kam ukládat 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 musí spouštět takto:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"Nyní se dostáváme k hotovému skriptu Handler.ps1
Aby náš skript mohl přijímat parametry při volání, je také třeba určit blok parametrů. Všimněte si, že spouští Oracle Java; pokud používáte jinou distribuci, bude nutné změnit cestu k spustitelnému souboru.
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$type,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$MinecraftPath,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$StandardOutput
)
Set-Location $MinecraftPath
function Restart-Minecraft {
Write-host "=============== Spouštění herního serveru ============"
$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 "Čas spuštění:" $global:Process.StartTime
Write-host "Kód ukončení:" $global:Process.ExitCode
Write-host "Čas ukončení:" $global:Process.ExitTime
Write-host "=============== Zastavení herního serveru ============="
}
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
Tento skript se v podstatě shoduje se Start-Minecraft, kromě toho, že pouze registruje novou úlohu. Přijímá stejné argumenty. Pokud není uvedeno uživatelské jméno, použije se 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-MinecraftRegister-Autologon
Ve skupině parametrů skript přijímá parametry Uživatelské jméno a Heslo. Pokud nebylo Uživatelské jméno uvedeno, použije se jméno aktuálního uživatele.
function Set-Autologon {
param (
[Parameter(
HelpMessage="Uživatelské jméno pro automatické přihlášení")]
$Username = $env:USERNAME,
[Parameter(Mandatory=$true,
HelpMessage="Heslo uživatele")]
[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 povolí automatické přihlášení uživatele."
}
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 "Automatické přihlášení bylo úspěšně nastaveno."
}
Spuštění tohoto skriptu vypadá takto:
Set-Autologon -Password "PlaintextPassword"Jak používat
Nyní se podíváme na to, jak s tímto autoři pracují. Jak správně nasadit veřejný server Minecraft na Windows. Začneme od začátku.
1. Vytvoření uživatele
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword2. Registrace úkolu pro spuštění skriptu
Můžete registrovat pomocí modulu, takto:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"Nebo použít standardní prostředky:
$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. Povolení automatického přihlášení do systému a restartování stroje
Set-Autologon -Username "MinecraftServer" -Password "Qw3"Závěr
Autor vytvořil skript také pro sebe, a proto rád uvítá vaše návrhy na zlepšení skriptu. Doufá, že celý tento kód byl pro vás alespoň minimálně užitečný a článek zajímavý.
Zdroj: habr.com
