Perfektní spouštěcí skript serveru Minecraft

Perfektní spouštěcí skript serveru Minecraft

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 Tržiště Ruvds. Ale všechny zdroje jsou již v článku. Nyní popořadě, jak se to všechno udělalo.

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ý.

Perfektní spouštěcí skript serveru Minecraft

Zdroj: www.habr.com

Přidat komentář