Forfatteren elsker virkelig spillet og er selv administrator for en lille server "kun for venner". Som det er sædvanligt blandt entusiaster, er alt modded på serveren, hvilket fører til ustabilitet og som konsekvens nedbrud. Da forfatteren kender Powershell bedre end placeringen af butikkerne på sin gade, besluttede han at lave "Den Bedste Skripte Til At Starte Minecraft 2020". Dette samme skript blev grundlaget for skabelonen i . Men alle kilderne er allerede i artiklen. Nu, i rækkefølge, hvordan det hele blev udført.
De Nødvendige Kommandoer
Alternativ Logging
En gang satte jeg et par mods til, og jeg opdagede, at serveren, tilsyneladende, falder uden forudgående varsel. Serveren skrev ikke fejl i latest.log eller debug, og konsollen, som i teorien burde have skrevet denne fejl og lukket ned, var blevet lukket.
Hvis den ikke vil skrive – så er det ikke nødvendigt. Vi har Powershell med cmdlet'en Tee-Object, som tager et objekt og udskriver det til en fil og til konsollen samtidig.
.handler.ps1 | Tee-Object .StandardOutput.txt -AppendPå den måde vil Powershell hente StandardOutput og skrive det til en fil. Prøv ikke at bruge Start-Process, fordi det vil returnere System.ComponentModel.Component, og ikke StandardOutput, og -RedirectStandardOutput vil gøre det umuligt at skrive ind i konsollen, hvilket vi ønsker at undgå.
Start Argumenter
Da forfatteren satte den samme par mods op, bemærkede han også, at serveren manglede RAM. Derfor skal vi ændre startargumenterne. I stedet for at ændre dem hver gang i start.bat, som alle bruger, kan du blot bruge dette skript.
Da Tee-Object kun læser StandardOutput, når den eksekverbare fil kaldes "direkte sådan", skal vi lave endnu et skript. Dette skript vil starte selve Minecraft. Lad os begynde med argumenterne.
For fremover at kunne slappe helt af, skal skriptet samle startargumenterne i realtid. Til dette vil vi starte med at finde den nyeste version af forge.
$forge = ((Get-ChildItem | Where-Object Name -Like "forge*").Name | Sort-Object -Descending) | Select-Object -last 1Ved hjælp af sort-object vil vi altid tage objektet med det højeste nummer, uanset hvor mange du har lagt ind. Ultimativ dovenskab.
Nu skal vi tildele serveren RAM. For at gøre dette tager vi mængden af systemhukommelse og optager dens samlede beløb i en string.
$ram = ((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb)
$xmx = "-Xms" + $ram + "G"Korrekt Automatisk Genstart
Forfatteren har set .bat-filer fra andre personer, men de tog ikke højde for grunden til, at serveren blev stoppet. Det er upraktisk, når man blot skal ændre en mod-fil eller fjerne noget.
Lad os nu lave en korrekt genstart. Forfatteren har tidligere stødt på mærkelige scripts, der genstartede serveren uanset hvorfor serveren lukkede ned. Vi vil derimod bruge exitcode. Java bruger 0 som en succesfuld afslutning, og det er her, vi vil begynde.
Først opretter vi en funktion, der vil genstarte serveren, hvis den afsluttes uden succes.
function Get-MinecraftExitCode {
do {
if ($global:Process.ExitCode -ne 0) {
Write-Log
Restart-Minecraft
}
else {
Write-Log
}
} until ($global:Process.ExitCode -eq 0)
}
Scriptet forbliver i en loop, indtil serveren afsluttes normalt via sin egen konsol med kommandoen \/stop.
Hvis vi ønsker at automatisere det hele, ville det være godt at indsamle start- og slutdato samt årsagen til afslutningen.
For dette gemmer vi resultatet af Start-Process i en variabel. I scriptet ser det sådan ud:
$global:Process = Start-Process -FilePath "C:Program Files (x86)common filesOracleJavajavapath_target_*java.exe" -ArgumentList "$xmx -server -jar $forge nogui" -Wait -NoNewWindow -PassThruOg derefter gemmer vi resultaterne i en fil. Her er hvad der returneres til vores variabel:
$global:Process.StartTime
$global:Process.ExitCode
$global:Process.ExitTimeAlt dette kan tilføjes til en fil med Add-Content. Efter lidt trimning får vi et script, som vi vil kalde 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
Lad os nu formatere scriptet til at starte handler'en.
Korrekt autostart
Forfatteren ønsker at starte Minecraft i forskellige versioner fra enhver sti med ét modul og have mulighed for at gemme logs i en bestemt mappe.
Problemet er, at processen skal startes af en bruger, der er logget ind i systemet. Dette kan gøres via skrivebordet eller WinRm. Hvis man starter serveren som system- eller endda administrator, men ikke logger ind, kan Server.jar ikke engang læse eula.txt og starte.
Vi kan aktivere automatisk login ved at tilføje tre poster i registreringsdatabasen.
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 SilentlyContinueDet er usikkert. Log ind og adgangskode angives her i klar tekst, så du skal oprette en separat bruger med brugeradgangsniveau, eller i en endnu snævrere gruppe, til serverens drift. Det anbefales helt klart ikke at bruge standardadministrator til dette.
Vi har forstået autologin. Nu skal vi registrere en ny opgave til serveren. Vi vil køre kommandoen fra PowerShell, så det vil se sådan ud:
$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 HighestVi samler modulet
Lad os nu organisere alt i moduler, som kan bruges senere. Al koden til de færdige scripts er her, importer og brug dem.
Alt det, der er beskrevet ovenfor, kan du bruge separat, hvis du ikke ønsker at bøvle med moduler.
Start-Minecraft
Først laver vi et modul, der kun vil køre et script, som lytter og registrerer standardoutput.
I parameterblokken beder den om, hvilken mappe Minecraft skal køres fra, og hvor loggen skal gemmes.
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-MinecraftOg du skal starte Minecraft sådan her:
Start-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft"Lad os nu gå videre til det brugsklare Handler.ps1
For at vores script kan modtage parametre ved opkald, skal der også angives en parameterblok. Bemærk, at det starter Oracle Java, hvis du bruger en anden distribution, skal stien til eksekveringsfilen ændres.
param (
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$type,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$MinecraftPath,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$StandardOutput
)
Set-Location $MinecraftPath
function Restart-Minecraft {
Write-host "=============== Starter 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 "Starttid:" $global:Process.StartTime
Write-host "Exitkode:" $global:Process.ExitCode
Write-host "Exit tid:" $global:Process.ExitTime
Write-host "=============== Stoppet 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
Registrer-Minecraft
Scriptet gentager stort set Start-Minecraft, bortset fra at det kun registrerer en ny opgave. Det tager de samme argumenter. Brugerens navn, hvis det ikke er angivet, tages fra den nuværende bruger.
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-MinecraftRegistrer-Autologon
I parameterblokken tager scriptet parameteren Bruger og Adgangskode. Hvis Bruger ikke er angivet, bruges navnet på den nuværende bruger.
funktion Set-Autologon {
param (
[Parameter(
HelpMessage="Brugernavn til autologon")]
$Username = $env:USERNAME,
[Parameter(Mandatory=$true,
HelpMessage="Brugers 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 vil aktivere brugerens 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 blev indstillet korrekt."
}
Kørsel af dette script ser således ud:
Set-Autologon -Password "PlaintextPassword"Sådan bruger du
Lad os nu se på, hvordan forfatteren selv bruger alt dette. Hvordan man korrekt implementerer en offentlig Minecraft-server på Windows. Vi starter fra begyndelsen.
1. Opretter en bruger
$pass = Get-Credential
New-LocalUser -Name "MinecraftServer" -Password $pass.Password -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword2. Registrerer opgaven for at køre scriptet
Du kan registrere det ved hjælp af modulen, sådan her:
Register-Minecraft -Type Forge -LogFile "C:minecraftstdout.txt" -MinecraftPath "C:minecraft" -User "MinecraftServer" -TaskName "MinecraftStarter"Eller bruge de standardværktøjer:
$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 Highest3. Aktiverer autologon og genstarter maskinen
Set-Autologon -Username "MinecraftServer" -Password "Qw3"Afslutning
Forfatteren har lavet scriptet især til sig selv, så han vil med glæde høre dine forslag til forbedringer af scriptet. Forfatteren håber, at hele denne kode har været enhver minimal nyttig for dig, og at artiklen er interessant.
Kilde: habr.com
