完美的Minecraft服务器启动脚本



作者非常喜欢这款游戏,他本人是“纯粹是为了朋友”的小型服务器的管理员。像业余爱好者一样,一切都在服务器上进行调制,这会导致工作不稳定以及由于摔倒而导致的不稳定。由于作者对Powershell的了解远胜于在大街上的商店位置,因此他决定制作“ 启动Minecraft 2020最佳脚本 ”。相同的脚本作为Ruvds市场中模板的基础但是所有来源已经在文章中。现在,一切按顺序进行。

我们需要团队


替代记录


曾经放了几个mod,我发现服务器似乎在没有宣战的情况下崩溃了。服务器未在latest.log或debug中写入错误,并关闭了原本应该写入并停止该错误的控制台。

不想写-不需要。我们拥有带有Tee-Object cmdlet的 Powershell,该cmdlet接受一个对象,并将其同时显示在文件和控制台中。

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

这样,Powershell将拾取StandardOutput并将其写入文件。不要尝试使用Start-Process,因为它将返回System.ComponentModel.Component而不是StandardOutput,并且-RedirectStandardOutput将使它无法进入控制台,这是我们想要避免的。

启动参数


通过放置相同的一对mod,作者注意到服务器还缺少RAM。这需要更改启动参数。无需每次都在每个人都使用的start.bat中更改它们,只需使用此脚本即可。

由于Tee-Object仅在可执行文件名为“ Right So”时才读取StandardOutput,因此您将不得不编写另一个脚本。该脚本将自行运行minecraft。让我们从参数开始。

为了在将来沉迷于最终的懒惰,脚本必须动态收集启动参数。为此,请先查找最新版本的forge

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

在排序对象的帮助下,无论您将它们放到哪里,我们都将始终携带最大位数的对象。最终的懒惰。

现在,您需要为服务器分配内存。为此,请占用系统内存量,并以字符串形式写入其内存量。

$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 files\Oracle\Java\javapath_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:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -Value $Username -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value $Password  -ErrorAction SilentlyContinue
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -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:\minecraft\stdout.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:\minecraft\stdout.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 files\Oracle\Java\javapath_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:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 
    if ($null -eq $i) {
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -Value $Username
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value $Password 
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoAdminLogon -Value 1
        Write-Verbose "Set-Autologon will enable user auto logon."
 
    }
    else {
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -Value $Username
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value $Password
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -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:\minecraft\stdout.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:\minecraft\stdout.txt" -MinecraftPath "C:\minecraft\"'
Register-ScheduledTask -TaskName "StartSSMS" -Trigger $Trigger -User $User -Action $PS -RunLevel Highest

3.打开自动登录到系统,然后重新启动计算机

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

完成时间


作者(包括自己在内)编写了脚本,因此,他很高兴听到您提出的改进脚本的建议。作者希望所有这些代码至少对您有用,并且这篇文章很有趣。


All Articles