理想的 Minecraft 服务器启动脚本

理想的 Minecraft 服务器启动脚本

作者非常喜欢这个游戏,他本人是一个“纯粹为了朋友”的小服务器的管理员。 正如业余爱好者中常见的那样,服务器上的所有内容都经过修改,这会导致不稳定,从而导致崩溃。 由于 Powershell 的作者比他所在街道上商店的位置更了解,因此他决定制作“启动 Minecraft 2020 的最佳脚本” 相同的脚本作为模板的基础 Ruvds 市场。 但所有的来源都已经在文章中了。 现在,按照顺序,这一切是如何完成的。

我们需要的命令

替代日志记录

有一天,在安装了几个模组后,我发现服务器显然在没有宣战的情况下崩溃了。 服务器没有在latest.log或debug中写入错误,理论上应该写入此错误并停止的控制台被关闭。

如果他不想写,他就不需要写。 我们有带 cmdlet 的 Powershell 三通对象,它获取一个对象并将其同时输出到文件和控制台。

.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 服务器启动脚本

来源: habr.com

添加评论