Scriptul ideal de pornire a serverului Minecraft

Scriptul ideal de pornire a serverului Minecraft

Autorul iubește foarte mult jocul și el însuși este administratorul unui server mic „doar pentru prieteni”. După cum este de obicei în rândul amatorilor, totul de pe server este modificat, iar acest lucru implică instabilitate și, ca urmare, blocări. Întrucât autorul cărții Powershell știe mai bine decât locația magazinelor de pe strada sa, a decis să facă "Cel mai bun script pentru a lansa Minecraft 2020" Același script a servit ca bază pentru șablonul în Piața Ruvds. Dar toate sursele sunt deja în articol. Acum, în ordine, cum s-a făcut totul.

Comenzile de care avem nevoie

Înregistrare alternativă

Într-o zi, după ce am instalat încă câteva moduri, am descoperit că serverul, aparent, se prăbușește fără să declare război. Serverul nu a scris erori în latest.log sau în debug, iar consola, care în teorie ar fi trebuit să scrie această eroare și să se oprească, a fost închisă.

Dacă nu vrea să scrie, nu are nevoie. Avem Powershell cu cmdlet Tee-Obiect, care preia un obiect și îl trimite într-un fișier și în consolă în același timp.

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

În acest fel, Powershell va prelua StandardOutput și îl va scrie într-un fișier. Nu încercați să utilizați Start-Procesdeoarece va returna System.ComponentModel.Component și nu StandardOutput, iar -RedirectStandardOutput va face imposibilă intrarea în consolă, ceea ce vrem să evităm.

Lansați argumente

După ce a instalat aceeași pereche de moduri, autorul a observat că și serverul nu avea suficientă memorie RAM. Și asta necesită schimbarea argumentelor de lansare. În loc să le schimbi de fiecare dată în start.bat, pe care toată lumea îl folosește, folosește doar acest script.

Deoarece Tee-Object citește StandardOutput doar atunci când executabilul se numește „La fel ca acesta”, va trebui să faci un alt script. Acest script va fi lansat chiar de Minecraft. Să începem cu argumentele.

Pentru a se răsfăța cu lenea supremă în viitor, scenariul trebuie să adune argumente de lansare din mers. Pentru a face acest lucru, să începem prin a căuta cea mai recentă versiune falsifica.

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

Folosind sort-object, vom lua întotdeauna obiectul cu cel mai mare număr, indiferent cât de multe dintre ele ai pune acolo. Lene supremă.

Acum trebuie să atribuiți memorie serverului. Pentru a face acest lucru, luați cantitatea de memorie de sistem și scrieți cantitatea acesteia în șir.

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

Repornire automată corectă

Autorul a văzut fișiere .bat de la alte persoane, dar nu au ținut cont de motivul pentru care serverul a fost oprit. Acest lucru este incomod, ce se întâmplă dacă trebuie doar să schimbați fișierul mod sau să ștergeți ceva?
Acum să facem o repornire corectă. Autorul a întâlnit anterior scripturi ciudate care reporneau serverul, indiferent de motivul pentru care acesta s-a închis. Vom folosi codul de ieșire. Java folosește 0 ca un succes, așa că vom dansa de aici.

Mai întâi, să creăm o funcție care va reporni serverul dacă nu reușește.

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

Scriptul va rămâne în buclă până când serverul se oprește în mod normal din propria sa consolă folosind comanda /stop.

Dacă decidem să automatizăm totul, atunci ar fi bine să colectăm data de începere, data de finalizare și, de asemenea, motivul finalizării.

Pentru a face acest lucru, scriem rezultatul Start-Process într-o variabilă. În script arată așa:

$global:Process = Start-Process -FilePath  "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThru

Și apoi scriem rezultatele într-un fișier. Aceasta este ceea ce ne este returnat în variabila:

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

Toate acestea pot fi adăugate la un fișier utilizând Add-Content. După ce l-am pieptănat puțin, obținem acest script și să-l numim 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

Acum să creăm un script care lansează handler.

Pornire corectă

Autorul dorește să ruleze versiuni diferite de Minecraft din orice cale dintr-un singur modul și, de asemenea, să poată stoca jurnalele într-un anumit folder.

Problema este că procesul trebuie pornit de un utilizator care este conectat la sistem. Acest lucru se poate face prin desktop sau WinRm. Dacă rulați serverul ca utilizator de sistem sau chiar administrator, dar nu vă autentificați, atunci Server.jar nu va putea nici măcar să citească eula.txt și să pornească.

Putem activa autentificarea automată adăugând trei intrări în 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

Nu este sigur. Login-ul și parola sunt indicate aici în text simplu, așa că pentru a porni serverul trebuie să creați un utilizator separat care să aibă acces la nivel de utilizator sau într-un grup și mai restrâns. Nu este strict recomandat să folosiți un administrator standard pentru aceasta.

Am rezolvat autentificarea automată. Acum trebuie să înregistrați o nouă sarcină pentru server. Vom rula comanda din Powershell, așa că va arăta astfel:

$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

Asamblarea modulului

Acum să punem totul în module care pot fi folosite mai târziu. Tot codul pentru scripturile gata făcute este aici, importați și utilizați.

Puteți folosi totul descris mai sus separat dacă nu doriți să vă deranjați cu modulele.

Start-Minecraft

Mai întâi, să creăm un modul care nu va face altceva decât să ruleze un script care va asculta și înregistra ieșirea standard.

În blocul de parametri, el întreabă din ce folder să lanseze Minecraft și unde să pună jurnalul.

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

Și va trebui să lansați Minecraft astfel:

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

Acum să trecem la Handler.ps1 gata de utilizare

Pentru ca scriptul nostru să accepte parametri atunci când este apelat, trebuie să specificăm și un bloc de parametri. Vă rugăm să rețineți că rulează Oracle Java, dacă utilizați o distribuție diferită, va trebui să schimbați calea către fișierul executabil.

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

Înregistrare-Minecraft

Scriptul este practic același cu Start-Minecraft, cu excepția faptului că înregistrează doar o sarcină nouă. Acceptă aceleași argumente. Numele de utilizator, dacă nu este specificat, îl ia pe cel curent.

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

Înregistrare-Autentificare automată

În blocul de parametri, scriptul acceptă parametrii Username și Password. Dacă Nume de utilizator nu a fost specificat, este folosit numele utilizatorului curent.

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."
 
}

Rularea acestui script arată astfel:

Set-Autologon -Password "PlaintextPassword"

Cum să utilizați

Acum să ne uităm la modul în care autorul însuși folosește toate acestea. Cum să implementați corect un server Minecraft public pe Windows. Să începem de la bun început.

1. Creați un utilizator

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

2. Înregistrați sarcina pentru a rula scriptul

Vă puteți înregistra folosind un modul ca acesta:

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

Sau folosiți instrumente standard:

$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. Activați autentificarea automată și reporniți mașina

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

Completare

Autorul a realizat scenariul, inclusiv pentru el însuși, prin urmare, va fi bucuros să vă asculte sugestiile pentru îmbunătățirea scenariului. Autorul speră că tot acest cod ți-a fost cel puțin util și că articolul a fost interesant.

Scriptul ideal de pornire a serverului Minecraft

Sursa: www.habr.com

Adauga un comentariu