Popoln zagon strežnika Minecraft

Popoln zagon strežnika Minecraft

Avtor zelo uživa v igri in je tudi administrator majhnega strežnika „samo za prijatelje“. Kot je običajno med ljubitelji, je na strežniku vse modifikirano, kar prinaša nestabilnost delovanja in s tem padce. Ker PowerShell avtor pozna bolje kot lokacijo trgovin na svoji ulici, se je odločil narediti „Najboljši skript za zagon Minecrafta 2020‘. Ta skript je služil tudi kot osnova za predlogo v tržnici Ruvds. Vendar so vsi izvorni podatki že vključeni v članku. Zdaj po vrsti, kako je to vse potekalo.

Potrebni ukazi

Alternativno beleženje

Nekega dne, ko sem dodal še nekaj modov, sem ugotovil, da strežnik, po vsej verjetnosti, pade brez napovedi vojne. Strežnik ni pisal napak v latest.log ali debug, konzola, ki bi morale to napako zabeležiti in se ustaviti, pa je bila zaprta.

Če noče pisati – ni potrebe. Imamo PowerShell z ukazom Tee-Object, ki vzame objekt in ga izpiše hkrati v datoteko in v konzolo.

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

Tako bo PowerShell pobiral StandardOutput in ga zapisoval v datoteko. Ne poskušajte uporabiti Start-Process, ker bo vrnil System.ComponentModel.Component, ne pa StandardOutput, medtem ko -RedirectStandardOutput onemogoči vnos v konzolo, kar želimo zagotoviti.

Argumenti za zagon

Ko je avtor namestil tiste modove, je opazil, da strežniku primanjkuje tudi pomnilnika. Zato je potrebno spremeniti argumente za zagon. Namesto da bi jih vsakokrat spreminjali v start.bat, katerega vsi uporabljajo, preprosto uporabite ta skript.

Ker Tee-Object bere StandardOutput le, ko se izvršljivo datoteko pokliče „tako brez predsodkov“, bomo morali narediti še en skript. Ta skript bo zagnal sam Minecraft. Začnimo z argumenti.

Da bi se v prihodnje prepustili ultimativni lenobi, mora skript dinamično zbirati argumente za zagon. Za to začnemo s iskanjem zadnje različice forge.

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

S pomočjo sort-object bomo vedno vzeli objekt z največjim številom, ne glede na to, koliko jih tam postavite. Ultimativna lenoba.

Zdaj moramo dodeliti strežniku pomnilnik. Za to vzamemo količino sistemskega pomnilnika in zapišemo njegovo vsoto v niz.

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

Pravilno samodejno ponovno zagon

Autor je videl .bat datoteke od drugih ljudi, vendar niso upoštevali razloga, zakaj je bil strežnik ustavljen. Je nevšečno, da če je treba le zamenjati mod datoteko ali odstraniti kaj?
Zdaj bomo izvedli pravilen ponovni zagon. Avtor je prej naletel na čudne skripte, ki so ponovno zagnali strežnik ne glede na to, zakaj je strežnik prenehal delovati. Mi pa uporabimo exitcode. Java uporablja 0 za uspešen izhod, od tod tudi plešemo.

Najprej bomo ustvarili funkcijo, ki bo ponovno zagnala strežnik v primeru, da se ni uspešno izklopil.

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

Skripta bo ostala v zanki, dokler strežnik ne konča delovanja normalno, z ukazom \/stop iz svoje konzole.

Če smo vse želeli avtomatizirati, bi bilo dobro tudi zbrati datum začetka, konca ter razlog za zaključek.

Zato zapišemo rezultat Start-Process v spremenljivko. V skripti to izgleda takole:

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

Nato rezultate zapišemo v datoteko. To je, kar se vrača v spremenljivko:

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

Vse to lahko dodamo v datoteko z Add-Content. S nekoliko boljšo obliko dobimo to skripto, ki jo poimenujemo 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

Zdaj uredimo skripto za zagon handlerja.

Pravilna samodejna napoved

Avtor želi, da en modul zažene Minecraft različnih različic iz katerega koli mesta, ter da ima možnost shranjevanja logov v določeno mapo.

Težava je, da mora postopek zagnati uporabnik, ki je v sistemu. To lahko storimo prek delovne površine ali WinRm. Če zaženemo strežnik v imenu sistema ali celo skrbnika, vendar se ne prijavimo v sistem, strežnik.jar ne bo mogel niti prebrati eula.txt in se zagnati.

Omogočimo samodejni prijavo v sistem z dodajanjem treh zapisov v register.

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 ni varno. Tukaj se prijava in geslo navedeta v prostem besedilu, zato je treba za zagon strežnika ustvariti ločenega uporabnika, ki ima dostop na ravni uporabnika ali v še užem skupini. Uporaba privzetega skrbnika za to je kategorično odsvetovana.

Avtomatsko prijavo smo uredili. Zdaj je treba registrirati novo nalogo za strežnik. Zagnali bomo ukaz iz Powershell, zato bo to videti tako:

$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

Sestavljamo modul

Zdaj se vse skupaj uredimo v module, ki jih lahko nato uporabimo. Celotna koda končnih skript je tukaj, uvozite in uporabljajte.

Vse zgoraj opisano lahko uporabite ločeno, če se ne želite ukvarjati z moduli.

Start-Minecraft

Najprej bomo naredili modul, ki bo samo zagnal skript, ki bo poslušal in zapisoval standardni izhod.

V bloku parametrov se sprašuje, iz katere mape naj se zažene Minecraft in kam naj se shrani 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 bo zagnal tako:

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

Zdaj preidimo na pripravljen Handler.ps1

Da lahko naš skript sprejema parametre ob klicu, je treba tudi navesti blok parametrov. Upoštevajte, da zažene Oracle Java; če uporabljate drugo različico, bo treba spremeniti pot do izvršljive datoteke.

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

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

Register-Autologon

В блоке параметров скрипт принимает параметры Username и Password. Если Username не был указан, используется имя текущего пользователя.

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"

Kako uporabljati

Сейчас рассмотрим, как сам автор использует этот скрипт. Как правильно развернуть публичный сервер 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"

Zaključek

Автор сделал скрипт, в том числе и для себя, и будет рад услышать ваши предложения по его улучшению. Он надеется, что этот код был хотя бы немного полезен вам, а статья вызвала интерес.

Popoln zagon strežnika Minecraft

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster