Ideálny skript na spustenie servera Minecraft

Ideálny skript na spustenie servera Minecraft

Autor hry má hru veľmi rád a sám je administrátorom malého servera „len pre priateľov“. Ako to býva medzi nadšencami, na serveri je všetko modifikované, čo vedie k nestabilite a následným pádov. Pretože Powershell pozná lepšie, než umiestnenie obchodov na svojej ulici, rozhodol sa vytvoriť „Najlepší skript na spustenie Minecraftu 2020„ Tento skript tiež poslúžil ako základ pre šablónu v marketplace Ruvds. Všetky zdrojové kódy sú už uvedené v článku. Teraz sa pozrime na to, ako to celé prebiehalo.

Potrebné príkazy

Alternatívne logovanie

Raz, keď som nainštaloval ďalšie módy, zistil som, že server zjavne padá bez varovania. Server nezaznamenal chyby v latest.log alebo v debug, a konzola, ktorá by túto chybu mala zaznamenať a zastaviť sa, bola zatvorená.

Ak nechce písať – netreba. Máme Powershell s príkazom Tee-Object, ktorý vezme objekt a súčasne ho vypíše do súboru a do konzoly.

.handler.ps1 | Tee-Object .StandardOutput.txt -Append

Týmto spôsobom Powershell zoberie StandardOutput a zapíše ho do súboru. Nepokúšajte sa použiť Start-Process, pretože on vráti System.ComponentModel.Component, a nie StandardOutput, a -RedirectStandardOutput znemožní vstup do konzoly, čo chceme sa vyhnúť.

Argumenty spustenia

Po nainštalovaní tých pár módov si autor všimol, že serveru navyše chýba operačná pamäť. To si vyžaduje zmenu argumentov spustenia. Namiesto toho, aby ste zakaždým menili ich v start.bat, ktorý všetci používajú, jednoducho použite tento skript.

Pretože Tee-Object číta StandardOutput len keď je spustiteľný súbor zavolaný „Príliš tak“, musíme vytvoriť ďalší skript. Tento skript spustí samotný Minecraft. Začneme s argumentmi.

Aby sme v budúcnosti mohli venovať ultimátnej lenivosti, skript by mal naletku zbierať argumenty spustenia. Na to začneme vyhľadávaním najnovšej verzie forge.

$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1

Pomocou sort-object vždy vezmeme objekt s najvyšším číslom, koľko z nich tam nedáte. Ultimátna lenivosť.

Teraz je potrebné serveru priradiť pamäť. Na to získame množstvo systémovej pamäte a zapíšeme jej súčet do reťazca.

$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"

Správny automatický reštart

Autor videl .bat súbory od iných ľudí, ale nezohľadnili dôvod, prečo server zastavil svoju činnosť. Je nepríjemné, že ak treba len zmeniť súbor módu alebo niečo odstrániť?
Teraz urobíme správne reštartovanie. Autor sa predtým stretol s podivnými skriptami, ktoré reštartovali server bez ohľadu na to, prečo server skončil. My však použijeme exitcode. Java používa 0 ako úspešné ukončenie, odtiaľ sa budeme odrážať.

Najprv vytvoríme funkciu, ktorá bude reštartovať server v prípade, že jeho činnosť neskončila úspešne.

function Get-MinecraftExitCode {
   
    do {
        
        if ($global:Process.ExitCode -ne 0) {
            Write-Log
            Restart-Minecraft
        }
        else {
            Write-Log
        }
 
    } until ($global:Process.ExitCode -eq 0)
    
}

Skript zostane v cykle, kým server zo svojej vlastnej konzoly neskončí normálne s pomocou príkazu /stop.

Ak sme sa rozhodli všetko automatizovať, bolo by dobré zaznamenávať dátum spustenia, ukončenia a tiež dôvod ukončenia.

Na to zapisujeme výsledok Start-Process do premennej. V skripte to vyzerá 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 ďalej zapisujeme výsledky do súboru. Toto je to, čo sa nám vráti do premennej:

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

Všetko toto môžeme pomocou Add-Content pridať do súboru. Trochu upravené, dostávame takýto 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

Teraz si upevníme skript na spustenie handler’a.

Správne automatické spúšťanie

Autor chce jedným modulom spúšťať Minecraft rôznych verzií z akýchkoľvek ciest a mal by tiež možnosť ukladať logy do konkrétneho priečinka.

Problém spočíva v tom, že proces musí spustiť používateľ, ktorý je v systéme. To je možné urobiť prostredníctvom pracovnej plochy alebo WinRm. Ak server spúšťate v mene systému alebo dokonca administrátora, ale nie ste prihlásení v systéme, server.jar nebude schopný ani prečítať eula.txt a spustiť sa.

Povolením automatického prihlásenia do systému môžeme pridať tri záznamy do registra.

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

Toto nie je bezpečné. Prihlasovacie meno a heslo sú uvedené v plain texte, preto je potrebné vytvoriť samostatného používateľa, ktorý má prístup na úrovni používateľa, alebo v ešte užšej skupine. Používanie štandardného administrátora na tento účel je striktne zakázané.

S automatickým prihlásením sme sa vyrovnali. Teraz potrebujeme zaregistrovať novú úlohu pre server. Spustíme príkaz z Powershell, takže to bude vyzerať 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

Zostavujeme modul

Teraz dajme všetko dohromady do modulov, ktoré budeme môcť neskôr použiť. Celý kód hotových skriptov je tu, naimportujte ho a používajte.

Všetko vyššie uvedené môžete používať samostatne, ak sa nechcete zaoberať modulmi.

Start-Minecraft

Najprv vytvoríme modul, ktorý bude len spúšťať skript, ktorý bude počúvať a zaznamenávať standardoutput.

V bloku parametrov sa pýta, z ktorej zložky sa má Minecraft spustiť a kam umiestniť 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 Minecraft sa bude musieť spustiť takto:

Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"

Teraz prejdeme k hotovému Handler.ps1

Aby náš skript mohol prijímať parametre pri volaní, je tiež potrebné uviesť blok parametrov. Všimnite si, že spúšťa Oracle Java, ak používate iný disitribútor, bude potrebné zmeniť cestu k vykonateľnému súboru.

param (
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$type,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$MinecraftPath,
 
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$StandardOutput
)
 
Set-Location $MinecraftPath
 
function Restart-Minecraft {
 
    Write-host "=============== Spúšťanie božskej hernej servera ============"
 
    $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 začiatku:" $global:Process.StartTime
 
    Write-host "Kód ukončenia:" $global:Process.ExitCode
    
    Write-host "Čas ukončenia:" $global:Process.ExitTime
 
    Write-host "=============== Zastavenie božskej hernej servera ============="
}
 
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

Skript takmer úplne kopíruje Start-Minecraft, s výnimkou toho, že len registruje novú úlohu. Prijíma tie isté argumenty. Meno používateľa, ak nebolo uvedené, berie aktuálny.

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

V bloku parametrov skript prijíma parameter Username a Password. Ak Username nebol uvedený, používa sa meno aktuálneho používateľa.

funkcia Set-Autologon {
 
    param (
        [Parameter(
        HelpMessage="Užívateľské meno pre autologon")]
        $Username = $env:USERNAME,
 
        [Parameter(Mandatory=$true,
        HelpMessage="Heslo používateľa")]
        [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 umožní automatické prihlásenie používateľa."
 
    }
    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 bol úspešne nastavený."
 
}

Spustenie tohto skriptu vyzerá takto:

Set-Autologon -Password "PlaintextPassword"

Ako používať

Teraz sa pozrieme na to, ako s týmto všetkým autor sám narába. Ako správne nasadiť verejný server Minecraft na Windows. Začneme od začiatku.

1. Vytvoříme používateľa

$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword

2. Zaregistrujeme úlohu na spustenie skriptu

Môžete zaregistrovať pomocou modulu, takto:

Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MinecraftServer" -TaskName "MinecraftStarter"

Alebo využiť štandardné 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. Zapneme automatické prihlásenie do systému a reštartujeme stroj

Set-Autologon -Username "MinecraftServer" -Password "Qw3"

Dokončenie

Autor vytvoril skript predovšetkým pre seba, a tak rád prijme vaše návrhy na zlepšenie skriptu. Dúfa, že tento kód bol pre vás aspoň minimálne užitočný a článok zaujímavý.

Ideálny skript na spustenie servera Minecraft

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster