理想的 Minecraft 伺服器啟動腳本

理想的 Minecraft 伺服器啟動腳本

作者非常喜歡這個遊戲,他本人是一個「純粹為了朋友」的小伺服器的管理員。 正如業餘愛好者中常見的那樣,伺服器上的所有內容都經過修改,這會導致不穩定,從而導致崩潰。 由於 Powershell 的作者比他所在街道上商店的位置更了解,因此他決定製作“啟動 Minecraft 2020 的最佳腳本」 相同的腳本作為模板的基礎 Ruvds 市場。 但所有的來源都已經在文章中了。 現在,按照順序,這一切是如何完成的。

我們需要的命令

替代日誌記錄

有一天,在安裝了幾個模組後,我發現伺服器顯然在沒有宣戰的情況下崩潰了。 伺服器沒有在latest.log或debug中寫入錯誤,理論上應該寫入此錯誤並停止的控制台被關閉。

如果他不想寫,他就不需要寫。 我們有 cmdlet 的 Powershell T卹對象,它獲取一個物件並將其同時輸出到文件和控制台。

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

這樣,Powershell 將獲取標準輸出並將其寫入檔案。 不要嘗試使用 啟動進程因為它會回傳System.ComponentModel.Component而不是StandardOutput,而-RedirectStandardOutput將導致無法進入控制台,這是我們想要避免的。

啟動參數

安裝同一對模組後,作者註意到伺服器也沒有足夠的 RAM。 這需要更改啟動參數。 不必每次都在每個人都使用的 start.bat 中更改它們,只需使用此腳本即可。

由於 Tee-Object 僅在呼叫「Just Like This」執行檔時讀取 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

所有這些都可以使用新增內容新增到文件中。 稍微梳理了一下,我們得到了這個腳本,我們稱之為 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 以及將日誌放在哪裡。

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

註冊-我的世界

該腳本實際上與 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"

如何使用

現在讓我們看看作者本人是如何使用這一切的。 如何在 Windows 上正確部署公用 Minecraft 伺服器。 讓我們從頭開始。

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

添加評論