ผู้เขียนรักเกมนี้เป็นอย่างมาก และตัวเขาเองเป็นผู้ดูแลเซิร์ฟเวอร์ขนาดเล็ก “สำหรับเพื่อนโดยเฉพาะ” ตามปกติในหมู่มือสมัครเล่น ทุกอย่างบนเซิร์ฟเวอร์จะถูกดัดแปลง และสิ่งนี้นำมาซึ่งความไม่เสถียร และเป็นผลให้เกิดปัญหา เนื่องจากผู้เขียน Powershell รู้ดีกว่าที่ตั้งของร้านค้าบนถนน เขาจึงตัดสินใจทำ "สคริปต์ที่ดีที่สุดสำหรับการเปิดตัว Minecraft 2020" สคริปต์เดียวกันนี้ทำหน้าที่เป็นพื้นฐานสำหรับเทมเพลตใน
คำสั่งที่เราต้องการ
การบันทึกทางเลือก
วันหนึ่ง หลังจากติดตั้ง Mod อีกสองสามตัว ฉันพบว่าเซิร์ฟเวอร์ดูเหมือนจะล่มโดยไม่ได้ประกาศสงคราม เซิร์ฟเวอร์ไม่ได้เขียนข้อผิดพลาดใน latest.log หรือในการดีบัก และคอนโซลซึ่งในทางทฤษฎีควรเขียนข้อผิดพลาดนี้และหยุดทำงานแล้วถูกปิด
หากเขาไม่ต้องการเขียนเขาก็ไม่จำเป็นต้องเขียน เรามี Powershell พร้อม cmdlet ที-วัตถุซึ่งนำวัตถุและส่งออกไปยังไฟล์และคอนโซลในเวลาเดียวกัน
.handler.ps1 | Tee-Object .StandardOutput.txt -Append
ด้วยวิธีนี้ Powershell จะรับ StandardOutput และเขียนลงในไฟล์ อย่าพยายามใช้ เริ่มกระบวนการเนื่องจากมันจะส่งคืน System.ComponentModel.Component ไม่ใช่ StandardOutput และ -RedirectStandardOutput จะทำให้ไม่สามารถเข้าสู่คอนโซลได้ซึ่งเป็นสิ่งที่เราต้องการหลีกเลี่ยง
เปิดตัวข้อโต้แย้ง
หลังจากติดตั้งม็อดคู่เดียวกันนั้น ผู้เขียนสังเกตเห็นว่าเซิร์ฟเวอร์มี RAM ไม่เพียงพอเช่นกัน และสิ่งนี้จำเป็นต้องเปลี่ยนข้อโต้แย้งในการเปิดตัว แทนที่จะเปลี่ยนทุกครั้งใน start.bat ที่ใครๆ ก็ใช้ ให้ใช้สคริปต์นี้แทน
เนื่องจาก Tee-Object อ่านเฉพาะ StandardOutput เมื่อไฟล์เรียกทำงานเรียกว่า "Just Like This" คุณจะต้องสร้างสคริปต์อื่น สคริปต์นี้จะเปิดตัวโดย 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 และเริ่มต้นได้
เราสามารถเปิดใช้งานการเข้าสู่ระบบอัตโนมัติโดยเพิ่มสามรายการในรีจิสทรี
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
ลงทะเบียน-Autologon
ในบล็อกพารามิเตอร์ สคริปต์ยอมรับพารามิเตอร์ชื่อผู้ใช้และรหัสผ่าน หากไม่ได้ระบุ 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"
วิธีใช้
ทีนี้มาดูกันว่าผู้เขียนใช้ทั้งหมดนี้อย่างไร วิธีปรับใช้เซิร์ฟเวอร์ 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"
เสร็จ
ผู้เขียนจัดทำบทขึ้นมาเองรวมทั้งตัวเขาเองด้วย ดังนั้น เขายินดีรับฟังข้อเสนอแนะของคุณเพื่อนำไปปรับปรุงบทครับ ผู้เขียนหวังว่าโค้ดทั้งหมดนี้มีประโยชน์กับคุณอย่างน้อยที่สุดและบทความนี้ก็น่าสนใจ
ที่มา: will.com