Ideální skript pro spuštění serveru Minecraft

Ideální skript pro spuštění serveru Minecraft

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 marketplace Ruvds. 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 -Append

Tí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 1

Pomocí 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 -PassThru

A poté zapisujeme výsledky do souboru. Takhle to vrací proměnné:

$global:Process.StartTime
$global:Process.ExitCode	
$global:Process.ExitTime

Vš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 SilentlyContinue

To 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 Highest

Sestavujeme 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-Minecraft

Minecraft 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-Minecraft

Register-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 -UserMayNotChangePassword

2. 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 Highest

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

Ideální skript pro spuštění serveru Minecraft

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster