Le script de démarrage du serveur Minecraft parfait

Le script de démarrage du serveur Minecraft parfait

L'auteur aime beaucoup le jeu et il est lui-même l'administrateur d'un petit serveur "purement pour les amis". Comme c'est l'habitude chez les amateurs, tout sur le serveur est modifié, ce qui entraîne une instabilité et, par conséquent, des plantages. Puisque l'auteur de Powershell connaît mieux que l'emplacement des magasins dans sa rue, il a décidé de faire "Meilleur script pour lancer Minecraft 2020" Le même script a servi de base au modèle dans Marché Ruvds. Mais toutes les sources sont déjà dans l’article. Maintenant, dans l’ordre, comment tout cela a été fait.

Les commandes dont nous avons besoin

Journalisation alternative

Un jour, après avoir installé quelques mods supplémentaires, j'ai découvert que le serveur, apparemment, plantait sans déclarer la guerre. Le serveur n'a pas écrit d'erreurs dans last.log ou dans debug, et la console, qui en théorie aurait dû écrire cette erreur et s'arrêter, a été fermée.

S’il ne veut pas écrire, il n’en a pas besoin. Nous avons Powershell avec applet de commande Tee-Objet, qui prend un objet et l'envoie dans un fichier et vers la console en même temps.

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

De cette façon, Powershell récupérera le StandardOutput et l’écrira dans un fichier. N'essayez pas d'utiliser Démarrer-Processuscar il renverra System.ComponentModel.Component et non StandardOutput, et -RedirectStandardOutput rendra impossible l'entrée dans la console, ce que nous voulons éviter.

Arguments de lancement

Après avoir installé cette même paire de mods, l’auteur a remarqué que le serveur ne disposait pas non plus de suffisamment de RAM. Et cela nécessite de changer les arguments de lancement. Au lieu de les modifier à chaque fois dans start.bat, que tout le monde utilise, utilisez simplement ce script.

Puisque Tee-Object ne lit StandardOutput que lorsque l'exécutable est appelé "Just Like This", vous devrez créer un autre script. Ce script sera lancé par Minecraft lui-même. Commençons par les arguments.

Afin de s'adonner à la paresse ultime à l'avenir, le script doit collecter les arguments de lancement à la volée. Pour ce faire, commençons par rechercher la dernière version forger.

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

En utilisant sort-object, nous prendrons toujours l'objet avec le plus grand nombre, quel que soit le nombre d'objets que vous y mettez. Paresse ultime.

Vous devez maintenant attribuer de la mémoire au serveur. Pour ce faire, prenez la quantité de mémoire système et écrivez sa quantité sous forme de chaîne.

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

Redémarrage automatique correct

L'auteur a vu des fichiers .bat d'autres personnes, mais ils n'ont pas pris en compte la raison pour laquelle le serveur a été arrêté. Ce n'est pas pratique, que se passe-t-il si vous avez simplement besoin de modifier le fichier mod ou de supprimer quelque chose ?
Faisons maintenant un redémarrage approprié. L'auteur a déjà rencontré d'étranges scripts qui redémarraient le serveur quelle que soit la raison pour laquelle le serveur s'était arrêté. Nous utiliserons le code de sortie. Java utilise 0 comme succès, nous allons donc danser à partir de là.

Tout d'abord, créons une fonction qui redémarrera le serveur en cas d'échec.

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

Le script restera dans la boucle jusqu'à ce que le serveur s'arrête normalement depuis sa propre console à l'aide de la commande /stop.

Si nous décidons de tout automatiser, alors ce serait bien de collecter la date de début, la date de fin, ainsi que la raison de l'achèvement.

Pour ce faire, nous écrivons le résultat de Start-Process dans une variable. Dans le script, cela ressemble à ceci :

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

Et puis nous écrivons les résultats dans un fichier. Voici ce qui nous est renvoyé dans la variable :

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

Tout cela peut être ajouté à un fichier en utilisant Add-Content. Après l'avoir examiné un peu, nous obtenons ce script, et appelons-le 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

Créons maintenant un script qui lance le gestionnaire.

Démarrage correct

L'auteur souhaite exécuter différentes versions de Minecraft à partir de n'importe quel chemin dans un seul module, et également pouvoir stocker les journaux dans un dossier spécifique.

Le problème est que le processus doit être démarré par un utilisateur connecté au système. Cela peut être fait via le bureau ou WinRm. Si vous exécutez le serveur en tant qu'utilisateur système ou même en tant qu'administrateur, mais que vous ne vous connectez pas, Server.jar ne pourra même pas lire eula.txt et démarrer.

Nous pouvons activer la connexion automatique en ajoutant trois entrées au registre.

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

Ce n'est pas sûr. Le login et le mot de passe sont indiqués ici en texte clair, donc pour démarrer le serveur, vous devez créer un utilisateur distinct ayant accès au niveau utilisateur ou dans un groupe encore plus restreint. Il est strictement déconseillé d'utiliser un administrateur standard pour cela.

Nous avons réglé la connexion automatique. Vous devez maintenant enregistrer une nouvelle tâche pour le serveur. Nous allons exécuter la commande depuis Powershell, elle ressemblera donc à ceci :

$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

Assemblage du module

Maintenant, mettons tout dans des modules qui pourront être utilisés plus tard. Tout le code des scripts prêts à l'emploi est ici, importez et utilisez.

Vous pouvez utiliser tout ce qui est décrit ci-dessus séparément si vous ne voulez pas vous embêter avec les modules.

Démarrer-Minecraft

Tout d'abord, créons un module qui ne fera rien d'autre que d'exécuter un script qui écoutera et enregistrera la sortie standard.

Dans le bloc des paramètres, il demande à partir de quel dossier lancer Minecraft et où mettre le journal.

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

Et vous devrez lancer Minecraft comme ceci :

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

Passons maintenant au Handler.ps1 prêt à l'emploi

Pour que notre script accepte les paramètres lorsqu'il est appelé, nous devons également spécifier un bloc de paramètres. Veuillez noter qu'il exécute Oracle Java, si vous utilisez une distribution différente, vous devrez modifier le chemin d'accès au fichier exécutable.

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

S'inscrire-Minecraft

Le script est pratiquement le même que Start-Minecraft, sauf qu'il enregistre uniquement une nouvelle tâche. Accepte les mêmes arguments. Le nom d'utilisateur, s'il n'est pas spécifié, prend le nom actuel.

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

S'inscrire-Connexion automatique

Dans le bloc des paramètres, le script accepte les paramètres Nom d'utilisateur et Mot de passe. Si le nom d'utilisateur n'a pas été spécifié, le nom de l'utilisateur actuel est utilisé.

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."
 
}

L'exécution de ce script ressemble à ceci :

Set-Autologon -Password "PlaintextPassword"

Comment utiliser

Voyons maintenant comment l'auteur lui-même utilise tout cela. Comment déployer correctement un serveur Minecraft public sous Windows. Commençons par le tout début.

1. Créez un utilisateur

$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword

2. Enregistrez la tâche pour exécuter le script

Vous pouvez vous inscrire en utilisant un module comme celui-ci :

Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MInecraftServer" -TaskName "MinecraftStarter"

Ou utilisez des outils standards :

$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. Activez la connexion automatique et redémarrez la machine

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

Achèvement

L'auteur a réalisé le scénario, y compris pour lui-même, il se fera donc un plaisir d'écouter vos suggestions pour améliorer le scénario. L'auteur espère que tout ce code vous a été au moins peu utile et que l'article était intéressant.

Le script de démarrage du serveur Minecraft parfait

Source: habr.com

Ajouter un commentaire