Το τέλειο σενάριο εκκίνησης διακομιστή Minecraft

Το τέλειο σενάριο εκκίνησης διακομιστή Minecraft

Ο συγγραφέας αγαπά πολύ το παιχνίδι και ο ίδιος είναι ο διαχειριστής ενός μικρού διακομιστή "καθαρά για φίλους". Ως συνήθως στους ερασιτέχνες, τα πάντα στον διακομιστή είναι τροποποιημένα, και αυτό συνεπάγεται αστάθεια της εργασίας και, ως αποτέλεσμα, πτώση. Δεδομένου ότι ο συγγραφέας γνωρίζει το Powershell καλύτερα από την τοποθεσία των καταστημάτων στον δρόμο του, αποφάσισε να κάνει "Καλύτερο σενάριο για την κυκλοφορία του Minecraft 2020". Το ίδιο σενάριο χρησίμευσε ως βάση για το πρότυπο Αγορά Ruvds. Αλλά όλες οι πηγές βρίσκονται ήδη στο άρθρο. Τώρα, με τη σειρά, πώς έγιναν όλα.

Οι εντολές που χρειαζόμαστε

Εναλλακτική υλοτομία

Μόλις εγκατέστησα μερικά ακόμη mods, διαπίστωσα ότι ο διακομιστής, προφανώς, κολλούσε χωρίς να κηρύξει πόλεμο. Ο διακομιστής δεν έγραψε σφάλματα στο latest.log ή εντοπισμό σφαλμάτων και η κονσόλα, η οποία, θεωρητικά, υποτίθεται ότι έγραφε αυτό το σφάλμα και σταματούσε, έκλεισε.

Αν δεν θέλετε να γράψετε, μην το κάνετε. Έχουμε το Powershell με ένα cmdlet Tee-Αντικείμενο, το οποίο παίρνει ένα αντικείμενο και το εξάγει ταυτόχρονα σε ένα αρχείο και στην κονσόλα.

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

Έτσι, το Powershell θα πάρει το StandardOutput και θα το γράψει σε ένα αρχείο. Μην προσπαθήσετε να χρησιμοποιήσετε Έναρξη-Διαδικασία, επειδή θα επιστρέψει ένα System.ComponentModel.Component, όχι ένα StandardOutput, και το -RedirectStandardOutput θα καταστήσει αδύνατη την πληκτρολόγηση στην κονσόλα, κάτι που θέλουμε να αποφύγουμε.

Εκκινήστε τα επιχειρήματα

Έχοντας εγκαταστήσει το ίδιο ζεύγος mods, ο συγγραφέας παρατήρησε ότι ο διακομιστής δεν είχε επίσης αρκετή μνήμη RAM. Και είναι απαραίτητο να αλλάξετε τα επιχειρήματα εκκίνησης. Αντί να τα αλλάζετε κάθε φορά στο start.bat, που χρησιμοποιούν όλοι, απλώς χρησιμοποιήστε αυτό το σενάριο.

Εφόσον το Tee-Object διαβάζει το StandardOutput μόνο όταν το εκτελέσιμο ονομάζεται "Ακριβώς έτσι", θα πρέπει να γίνει ένα ακόμη σενάριο. Αυτό το σενάριο θα τρέξει το ίδιο το minecraft. Ας ξεκινήσουμε με τα επιχειρήματα.

Για να επιδοθεί στην απόλυτη τεμπελιά στο μέλλον, το σενάριο πρέπει να συλλέγει επιχειρήματα εκκίνησης εν κινήσει. Για να το κάνουμε αυτό, ας ξεκινήσουμε αναζητώντας την πιο πρόσφατη έκδοση σιδηρουργείο.

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

Με το sort-object , θα παίρνουμε πάντα το αντικείμενο με τον μεγαλύτερο αριθμό, ανεξάρτητα από το πόσα βάζετε εκεί. Η απόλυτη τεμπελιά.

Τώρα πρέπει να εκχωρήσουμε μνήμη στον διακομιστή. Για να γίνει αυτό, παίρνουμε την ποσότητα της μνήμης του συστήματος και γράφουμε το ποσό της σε συμβολοσειρά.

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

Σωστή αυτόματη επανεκκίνηση

Ο συγγραφέας έχει δει αρχεία .bat από άλλα άτομα, αλλά δεν έλαβε υπόψη τον λόγο για τον οποίο διακόπηκε ο διακομιστής. Δεν είναι βολικό, τι γίνεται αν χρειάζεται απλώς να αλλάξετε το αρχείο mod ή να διαγράψετε κάτι;
Τώρα ας κάνουμε μια σωστή επανεκκίνηση. Ο συντάκτης είχε προηγουμένως συναντήσει περίεργα σενάρια που επανεκκίνησαν τον διακομιστή ανεξάρτητα από το γιατί ο διακομιστής έφυγε. Θα χρησιμοποιήσουμε τον κωδικό εξόδου. Η Java χρησιμοποιεί το 0 ως επιτυχία, οπότε ας χορέψουμε από εκεί.

Αρχικά, ας δημιουργήσουμε μια συνάρτηση που θα επανεκκινήσει τον διακομιστή εάν αποτύχει.

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

Το σενάριο θα παραμείνει στον βρόχο μέχρι ο διακομιστής να βγει κανονικά από τη δική του κονσόλα χρησιμοποιώντας την εντολή /stop.

Εάν αποφασίσαμε να αυτοματοποιήσουμε τα πάντα, τότε θα ήταν ωραίο να συλλέξουμε την ημερομηνία έναρξης, το τέλος, καθώς και τον λόγο για το τέλος.

Για να γίνει αυτό, γράφουμε το αποτέλεσμα του Start-Process σε μια μεταβλητή. Σε ένα σενάριο μοιάζει με αυτό:

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

Και μετά γράψτε τα αποτελέσματα σε ένα αρχείο. Εδώ είναι τι μας επιστρέφεται σε μια μεταβλητή:

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

Όλα αυτά μπορούν να προστεθούν στο αρχείο χρησιμοποιώντας το Add-Content. Έχοντας βουρτσίσει λίγο, παίρνουμε ένα τέτοιο σενάριο, αλλά το λέμε 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

Τώρα ας σχεδιάσουμε το σενάριο με την εκκίνηση του χειριστή.

Σωστή αυτόματη φόρτωση

Ο συγγραφέας θέλει να τρέξει το minecraft διαφόρων εκδόσεων από οποιοδήποτε μονοπάτι με μία ενότητα, και επίσης να μπορεί να βάλει αρχεία καταγραφής σε έναν συγκεκριμένο φάκελο.

Το πρόβλημα είναι ότι η διαδικασία πρέπει να ξεκινήσει από έναν χρήστη που είναι συνδεδεμένος. Αυτό μπορεί να γίνει μέσω της επιφάνειας εργασίας ή του WinRm. Εάν εκτελείτε τον διακομιστή ως σύστημα ή ακόμα και ως διαχειριστής, αλλά δεν συνδεθείτε, τότε το Server.jar δεν θα μπορεί καν να διαβάσει το eula.txt και να ξεκινήσει.

Μπορούμε να ενεργοποιήσουμε το autologon προσθέτοντας τρεις καταχωρήσεις στο μητρώο.

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

Δεν είναι ασφαλές. Η σύνδεση και ο κωδικός πρόσβασης υποδεικνύονται εδώ με το απλό κείμενο, επομένως, για να ξεκινήσετε τον διακομιστή, πρέπει να δημιουργήσετε έναν ξεχωριστό χρήστη που έχει πρόσβαση σε επίπεδο χρήστη ή σε μια ακόμη στενότερη ομάδα. Η χρήση του τυπικού διαχειριστή για αυτό δεν συνιστάται ιδιαίτερα.

Καταλάβαμε την αυτόματη σύνδεση. Τώρα πρέπει να καταχωρήσετε μια νέα εργασία για τον διακομιστή. Θα εκτελέσουμε την εντολή από το Powershell, οπότε θα μοιάζει με αυτό:

$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

Συναρμολόγηση της ενότητας

Τώρα ας τακτοποιήσουμε τα πάντα σε ενότητες που μπορούν να χρησιμοποιηθούν αργότερα. Όλος ο κώδικας των έτοιμων σεναρίων είναι εδώ, εισαγωγή και χρήση.

Μπορείτε να χρησιμοποιήσετε όλα όσα περιγράφονται παραπάνω ξεχωριστά, εάν δεν θέλετε να ασχοληθείτε με τις ενότητες.

ξεκινήστε το minecraft

Αρχικά, ας φτιάξουμε μια ενότητα που δεν θα κάνει τίποτα άλλο από το να τρέξει ένα σενάριο που θα ακούει και θα γράφει στην τυπική έξοδο.

Στο μπλοκ παραμέτρων, ρωτά από ποιον φάκελο να ξεκινήσει το minecraft και πού να τοποθετήσει το αρχείο καταγραφής.

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 ως εξής:

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

Τώρα ας προχωρήσουμε στο έτοιμο προς χρήση Handler.ps1

Προκειμένου το σενάριό μας να δέχεται παραμέτρους όταν καλείται, πρέπει επίσης να καθορίσουμε ένα μπλοκ παραμέτρων. Λάβετε υπόψη ότι εκτελεί Oracle Java, εάν χρησιμοποιείτε διαφορετική διανομή, θα χρειαστεί να αλλάξετε τη διαδρομή προς το εκτελέσιμο αρχείο.

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

εγγραφείτε στο minecraft

Το σενάριο είναι πρακτικά το ίδιο με το Start-Minecraft, με τη διαφορά ότι καταγράφει μόνο μια νέα εργασία. Δέχεται τα ίδια επιχειρήματα. Το όνομα χρήστη, εάν δεν έχει καθοριστεί, παίρνει το τρέχον.

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

Μητρώο-Αυτόλογο

Στο μπλοκ παραμέτρων, το σενάριο δέχεται τις παραμέτρους Όνομα χρήστη και Κωδικός πρόσβασης. Εάν το όνομα χρήστη δεν έχει καθοριστεί, χρησιμοποιείται το όνομα του τρέχοντος χρήστη.

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

Η εκτέλεση αυτού του σεναρίου μοιάζει με αυτό:

Set-Autologon -Password "PlaintextPassword"

Πώς να χρησιμοποιήσετε

Τώρα σκεφτείτε πώς ο ίδιος ο συγγραφέας τα χρησιμοποιεί όλα αυτά. Πώς να αναπτύξετε σωστά έναν δημόσιο διακομιστή Minecraft στα Windows. Ας τα πάρουμε από την αρχή.

1. Δημιουργήστε έναν χρήστη

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

2. Καταχωρίστε την εργασία για να εκτελέσετε το σενάριο

Μπορείτε να εγγραφείτε με μια ενότητα όπως αυτή:

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

Ή χρησιμοποιήστε τα τυπικά εργαλεία:

$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. Ενεργοποιήστε την αυτόματη σύνδεση και επανεκκινήστε το μηχάνημα

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

Ολοκλήρωση

Ο συγγραφέας έκανε το σενάριο, συμπεριλαμβανομένου του εαυτού του, επομένως, θα χαρεί να ακούσει τις προτάσεις σας για τη βελτίωση του σεναρίου. Ο συγγραφέας ελπίζει ότι όλος αυτός ο κώδικας ήταν τουλάχιστον ελάχιστα χρήσιμος για εσάς και το άρθρο είναι ενδιαφέρον.

Το τέλειο σενάριο εκκίνησης διακομιστή Minecraft

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο