Перфектният скрипт за стартиране на Minecraft сървър

Перфектният скрипт за стартиране на Minecraft сървър

Авторът много обича играта и самият той е администратор на малък сървър „чисто за приятели“. Както обикновено сред любителите, всичко на сървъра е модифицирано и това води до нестабилност на работата и в резултат на това падане. Тъй като авторът познава Powershell по-добре от местоположението на магазините на неговата улица, той реши да направи "Най-добрият скрипт за стартиране на Minecraft 2020". Същият скрипт послужи като основа за шаблона в Ruvds пазар. Но всички източници вече са в статията. Сега, по ред, как беше направено всичко.

Командите, от които се нуждаем

Алтернативен дърводобив

След като инсталирах още няколко модификации, открих, че сървърът очевидно се срива, без да обявява война. Сървърът не записа грешки в latest.log или debug и конзолата, която на теория трябваше да напише тази грешка и да спре, беше затворена.

Ако не искаш да пишеш, недей. Имаме Powershell с cmdlet Tee-Object, който взема обект и го извежда във файл и в конзолата едновременно.

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

Така Powershell ще вземе StandardOutput и ще го запише във файл. Не се опитвайте да използвате Старт-процес, защото ще върне System.ComponentModel.Component, а не StandardOutput, и -RedirectStandardOutput ще направи невъзможно въвеждането в конзолата, което искаме да избегнем.

Стартиране на аргументи

След като инсталира същата двойка модове, авторът забеляза, че сървърът също няма достатъчно 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 файлове от други хора, но те не са взели предвид причината, поради която сървърът е спрян. Неудобно е, какво ще стане, ако просто трябва да промените модния файл или да изтриете нещо?
Сега нека направим правилно рестартиране. Авторът преди това се натъкна на странни скриптове, които рестартираха сървъра, независимо от причината, поради която сървърът излезе. Ще използваме изходен код. 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 и да стартира.

Можем да активираме автоматично влизане, като добавим три записа в регистъра.

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

Първо, нека направим модул, който няма да прави нищо, освен да изпълнява скрипт, който ще слуша и ще пише на standardoutput.

В блока с параметри той пита от коя папка да стартира 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

Регистриране-автоматично влизане

В блока с параметри скриптът приема параметрите Username и Password. Ако потребителското име не е указано, се използва името на текущия потребител.

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

Добавяне на нов коментар