diff --git a/configs/global.psm1 b/configs/global.psm1 index 0910008..60fb385 100644 --- a/configs/global.psm1 +++ b/configs/global.psm1 @@ -8,6 +8,9 @@ $GlobalDetails = @{ #SteamCMD SteamCMD = ".\tools\SteamCMD\steamcmd.exe" + #Java Directory + JavaDirectory =".\tools\java" + #Path of the logs folder. LogFolder = ".\logs" diff --git a/functions/Backup-Server.psm1 b/functions/Backup-Server.psm1 index 9315dbb..3557aa8 100644 --- a/functions/Backup-Server.psm1 +++ b/functions/Backup-Server.psm1 @@ -3,17 +3,13 @@ function Backup-Server { #Create backup name from date and time $BackupName = Get-TimeStamp #Check if Backups Destination directory exist and create it. - if (-not (Test-Path -Path "$($Backups.Path)\$Type" -PathType "Container")){ + if (-not (Test-Path -Path "$($Backups.Path)\$Type" -PathType "Container" -ErrorAction SilentlyContinue)){ New-Item -Path "$($Backups.Path)\$Type" -ItemType "directory" -ErrorAction SilentlyContinue } #Check if Backups Source directory exist and create it. - if (-not (Test-Path -Path $Backups.Saves -PathType "Container")){ + if (-not (Test-Path -Path $Backups.Saves -PathType "Container" -ErrorAction SilentlyContinue)){ New-Item -Path $Backups.Saves -ItemType "directory" -ErrorAction SilentlyContinue } - #Resolve Server Saves Path - $Backups.Saves = Resolve-Path -Path $Backups.Saves -ErrorAction SilentlyContinue - #Resolve Backup Path - $Backups.Path = Resolve-Path -Path $Backups.Path -ErrorAction SilentlyContinue #Check if it's friday (Sunday is 0) if ((Get-Date -UFormat %u) -eq 5){ $Type = "Weekly" diff --git a/functions/Get-WebFile.psm1 b/functions/Get-WebFile.psm1 new file mode 100644 index 0000000..7e20dfd --- /dev/null +++ b/functions/Get-WebFile.psm1 @@ -0,0 +1,26 @@ +function Invoke-Download { + [CmdletBinding()] + param ( + [Parameter(Mandatory)] + $Uri, + $OutFile + ) + + # Create the HTTP client download request + $httpClient = New-Object System.Net.Http.HttpClient + $response = $httpClient.GetAsync($Uri) + $response.Wait() + + # Create a file stream to pointed to the output file destination + $outputFileStream = [System.IO.FileStream]::new($OutFile, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write) + + # Stream the download to the destination file stream + $downloadTask = $response.Result.Content.CopyToAsync($outputFileStream) + $downloadTask.Wait() + + # Close the file stream + $outputFileStream.Close() + +} + +Export-ModuleMember -Function Invoke-Download \ No newline at end of file diff --git a/functions/Install-Dependency.psm1 b/functions/Install-Dependency.psm1 new file mode 100644 index 0000000..ecc1581 --- /dev/null +++ b/functions/Install-Dependency.psm1 @@ -0,0 +1,34 @@ +function Install-Dependency { + #Define variables + Write-ScriptMsg "Verifying Dependencies..." + $Dependencies = @{ + SevenZip = $Global.SevenZip + Mcrcon = $Global.Mcrcon + SteamCMD = $Global.SteamCMD + } + + [System.Collections.ArrayList]$MissingDependencies = @() + + #For each dependency check if the excutable exist, if not, add the key of the dependency to the MissingDependencies list. + foreach ($Key in $Dependencies.keys) { + if (-not (Test-Path -Path $Dependencies[$Key] -ErrorAction SilentlyContinue)) { + $null = $MissingDependencies.Add($Key) + } + } + + #If there is missing dependencies, create the download folder and for each missing dependency, run the installation script. + if ($MissingDependencies.Count -gt 0){ + #Create Temporary Download Folder + New-Item -Path ".\downloads" -ItemType "directory" -ErrorAction SilentlyContinue + + foreach ($Item in $MissingDependencies) { + $Cmd = "Install-$Item" + &$Cmd -Application $Dependencies[$Item] + } + + #Cleanup + Remove-Item -Path ".\downloads" -Recurse -Force -ErrorAction SilentlyContinue + } +} + +Export-ModuleMember -Function Install-Dependency \ No newline at end of file diff --git a/functions/Install-Mcrcon.psm1 b/functions/Install-Mcrcon.psm1 index 0054657..d17ad9e 100644 --- a/functions/Install-Mcrcon.psm1 +++ b/functions/Install-Mcrcon.psm1 @@ -8,7 +8,7 @@ function Install-Mcrcon { #Create Install Directory. New-Item -Path (Split-Path -Path $Application) -ItemType "directory" #Download zip file. - Invoke-WebRequest -Uri "https://github.com/Tiiffi/mcrcon/releases/download/v0.7.1/mcrcon-0.7.1-windows-x86-32.zip" -OutFile ".\downloads\mcrcon.zip" -ErrorAction SilentlyContinue + Invoke-Download -Uri "https://github.com/Tiiffi/mcrcon/releases/download/v0.7.1/mcrcon-0.7.1-windows-x86-32.zip" -OutFile ".\downloads\mcrcon.zip" -ErrorAction SilentlyContinue #Unzip file. Expand-Archive -Path ".\downloads\mcrcon.zip" -DestinationPath ".\downloads\mcrcon\" -Force #Copy executable to install directory. diff --git a/functions/Install-SevenZip.psm1 b/functions/Install-SevenZip.psm1 index 6d0e67d..8ee76fd 100644 --- a/functions/Install-SevenZip.psm1 +++ b/functions/Install-SevenZip.psm1 @@ -7,12 +7,12 @@ function Install-SevenZip { Write-ServerMsg "Installing 7Zip Portable." Write-ServerMsg "Downloading 7zip 9.20 to extract 7zip 19.00" #Download 7zip 9.20 - Invoke-WebRequest -Uri "https://www.7-zip.org/a/7za920.zip" -OutFile ".\downloads\7za920.zip" + Invoke-Download -Uri "https://www.7-zip.org/a/7za920.zip" -OutFile ".\downloads\7za920.zip" #Unzip 7zip 9.20 Expand-Archive -Path ".\downloads\7za920.zip" -DestinationPath ".\downloads\7z920\" -Force Write-ServerMsg "Downloading 7zip 19.00" #Download 7zip 19.00 - Invoke-WebRequest -Uri "https://www.7-zip.org/a/7z1900-extra.7z" -OutFile ".\downloads\7z1900-extra.7z" -ErrorAction SilentlyContinue + Invoke-Download -Uri "https://www.7-zip.org/a/7z1900-extra.7z" -OutFile ".\downloads\7z1900-extra.7z" -ErrorAction SilentlyContinue #Use 7zip 9.20 to unzip 7zip 19.00 & ".\downloads\7z920\7za.exe" x ".\downloads\7z1900-extra.7z" -o".\downloads\7z1900\" -y #Copy the executable and dll to the 7zip directory. diff --git a/functions/Install-SteamCMD.psm1 b/functions/Install-SteamCMD.psm1 index 2a00414..2ac31c4 100644 --- a/functions/Install-SteamCMD.psm1 +++ b/functions/Install-SteamCMD.psm1 @@ -6,7 +6,7 @@ function Install-SteamCMD { ) Write-ServerMsg "Downloading SteamCMD." #Download file - Invoke-WebRequest -Uri "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip" -OutFile ".\downloads\steamcmd.zip" -ErrorAction SilentlyContinue + Invoke-Download -Uri "https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip" -OutFile ".\downloads\steamcmd.zip" -ErrorAction SilentlyContinue #Unzip file in installation directory Expand-Archive -Path ".\downloads\steamcmd.zip" -DestinationPath (Split-Path -Path $Application) -Force Write-ServerMsg "SteamCMD Installed." diff --git a/functions/Optimize-ArgumentList.psm1 b/functions/Optimize-ArgumentList.psm1 new file mode 100644 index 0000000..9653635 --- /dev/null +++ b/functions/Optimize-ArgumentList.psm1 @@ -0,0 +1,19 @@ +function Optimize-ArgumentList { + [OutputType([string])] + param ( + [Parameter(Mandatory)] + [array] $Arguments + ) + + #Create Server.Arguments from cleaned ArgumentList. + [System.Collections.ArrayList]$CleanedArguments=@() + + foreach($Argument in $Arguments){ + if (-not ($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ + $null = $CleanedArguments.Add($Argument) + } + } + return ($CleanedArguments -join "") +} + +Export-ModuleMember -Function Optimize-ArgumentList \ No newline at end of file diff --git a/functions/Read-Config.psm1 b/functions/Read-Config.psm1 new file mode 100644 index 0000000..7e11168 --- /dev/null +++ b/functions/Read-Config.psm1 @@ -0,0 +1,21 @@ +function Read-Config { + #Read configuration data and improve it by parsing full paths and cleaning arguments + + #Create Long Paths + $Server.Exec = (Resolve-CompletePath -Path $Server.Exec -ParentPath ".\servers\") + $Server.Path = (Resolve-CompletePath -Path $Server.Path -ParentPath ".\servers\") + $Server.ConfigFolder = (Resolve-CompletePath -Path $Server.ConfigFolder -ParentPath ".\servers\") + $Backups.Path = (Resolve-CompletePath -Path $Backups.Path -ParentPath ".\backups\") + $Backups.Saves = (Resolve-CompletePath -Path $Backups.Saves -ParentPath ".\servers\") + $Global.SevenZip = (Resolve-CompletePath -Path $Global.SevenZip -ParentPath ".\tools\") + $Global.Mcrcon = (Resolve-CompletePath -Path $Global.Mcrcon -ParentPath ".\tools\") + $Global.SteamCMD = (Resolve-CompletePath -Path $Global.SteamCMD -ParentPath ".\tools\") + $Global.JavaDirectory = (Resolve-CompletePath -Path $Global.JavaDirectory -ParentPath ".\tools\") + $Global.LogFolder = (Resolve-CompletePath -Path $Global.LogFolder -ParentPath ".\") + + #Create Arguments + if ($Server.ArgumentList.length -gt 0) { + Add-Member -InputObject $Server -Name "Arguments" -Type NoteProperty -Value (Optimize-ArgumentList -Arguments $Server.ArgumentList) + } +} +Export-ModuleMember -Function Read-Config \ No newline at end of file diff --git a/functions/Resolve-CompletePath.psm1 b/functions/Resolve-CompletePath.psm1 new file mode 100644 index 0000000..1ab537f --- /dev/null +++ b/functions/Resolve-CompletePath.psm1 @@ -0,0 +1,21 @@ + +function Resolve-CompletePath { + [CmdletBinding()] + [OutputType([string])] + param ( + [Parameter(Mandatory)] + [string] $Path, + [string] $ParentPath + ) + #Add the full path to the path from the config file. + if ($Path.StartsWith($ParentPath)){ + return "$(Get-Location)$($Path.substring(1))" + } + $ReturnPath = Resolve-Path -LiteralPath $Path -ErrorAction SilentlyContinue + if ($null -eq $ReturnPath) { + $ReturnPath = $Path + } + return $ReturnPath +} + +Export-ModuleMember -Function Resolve-CompletePath \ No newline at end of file diff --git a/functions/Send-RestartWarning.psm1 b/functions/Send-RestartWarning.psm1 index 762fd66..d6e23f8 100644 --- a/functions/Send-RestartWarning.psm1 +++ b/functions/Send-RestartWarning.psm1 @@ -60,7 +60,7 @@ function Send-RestartWarning { } #if the process is still running, if allowed, stop process. if(-not ($ServerProcess.HasExited) -and ($Server.AllowForceClose)){ - $Stopped = Stop-Server -ServerProcess $ServerProcess + $Stopped = Stop-ServerProcess -ServerProcess $ServerProcess } return $Stopped } diff --git a/functions/Set-IP.psm1 b/functions/Set-IP.psm1 new file mode 100644 index 0000000..2137a9f --- /dev/null +++ b/functions/Set-IP.psm1 @@ -0,0 +1,18 @@ +function Set-IP { + #Get current internal ip from active network interface. + Write-ScriptMsg "Finding server IPs..." + $InternalIP = ( + Get-NetIPConfiguration | Where-Object {(($null -ne $_.IPv4DefaultGateway) -and ($_.NetAdapter.Status -ne "Disconnected"))} + ).IPv4Address.IPAddress + + #Get current external ip from ifconfig.me + $ExternalIP = (Invoke-WebRequest ifconfig.me/ip).Content.Trim() + + Write-ScriptMsg "Server local IP : $InternalIP" + Write-ScriptMsg "Server external IP : $ExternalIP" + + #Add propreties to global. + Add-Member -InputObject $Global -Name "InternalIP" -Type NoteProperty -Value $InternalIP + Add-Member -InputObject $Global -Name "ExternalIP" -Type NoteProperty -Value $ExternalIP +} +Export-ModuleMember -Function Set-IP \ No newline at end of file diff --git a/functions/Start-Server.psm1 b/functions/Start-Server.psm1 new file mode 100644 index 0000000..63b50f1 --- /dev/null +++ b/functions/Start-Server.psm1 @@ -0,0 +1,28 @@ +function Start-Server { + try { + Write-ScriptMsg "Starting Server Preparation..." + Start-ServerPrep + Write-ScriptMsg "Starting Server..." + if ($Server.Arguments.length -gt 0){ + $App = Start-Process -FilePath $Server.Launcher -WorkingDirectory $($Server.WorkingDirectory) -ArgumentList $Server.Arguments -PassThru + } else { + $App = Start-Process -FilePath $Server.Launcher -WorkingDirectory $($Server.WorkingDirectory) -PassThru + } + #Wait to see if the server is stable. + Start-Sleep -Seconds $Server.StartupWaitTime + if (($null -eq $App) -or ($App.HasExited)){ + Exit-WithError "Server Failed to launch." + } else { + Write-ServerMsg "Server Started." + Set-Priority -ServerProcess $App + } + if (-not (Register-PID -ServerProcess $App)){ + Write-ServerMsg "Failed to Register PID file." + } + } + catch { + Write-Error $_ + Exit-WithError -ErrorMsg "Unable to start server." + } +} +Export-ModuleMember -Function Start-Server \ No newline at end of file diff --git a/functions/Stop-Server.psm1 b/functions/Stop-Server.psm1 index b1acc3c..9df83c0 100644 --- a/functions/Stop-Server.psm1 +++ b/functions/Stop-Server.psm1 @@ -1,41 +1,55 @@ function Stop-Server { - [CmdletBinding()] - [OutputType([boolean])] - param ( - [Parameter(Mandatory)] - $ServerProcess - ) - #if the server is still running - - Write-ServerMsg "Closing main window..." - #Close the main windows. - $ServerProcess.CloseMainWindow() - #Wait for exit for at most 30 seconds. - $ServerProcess.WaitForExit(30000) - #if the process exited send success message - if ($ServerProcess.HasExited) { - Write-ServerMsg "Server succesfully stopped." - }else{ - Write-Warning "Trying again to stop the server..." - #else try to stop server with stop-process. - Stop-Process $ServerProcess - #Wait for exit for at most 30 seconds. - $ServerProcess.WaitForExit(30000) - #If process is still running, force stop-process. - if ($ServerProcess.HasExited) { - Write-Warning "Server succesfully stopped on second try." - }else{ - Write-Warning "Forcefully stopping server..." - Stop-Process $ServerProcess -Force + if ($Server.UsePID){ + #Get the PID from the .PID market file. + $ServerPID = Get-PID + #If it returned 0, it failed to get a PID + if ($null -ne $ServerPID) { + $ServerProcess = Get-Process -ID $ServerPID -ErrorAction SilentlyContinue } } - - #Safety timer for allowing the files to unlock before backup. - Start-Sleep -Seconds 10 - if ($ServerProcess.HasExited) { - return $true + #If the server process is none-existent, Get the process from the server process name. + if ($null -eq $ServerProcess) { + $ServerProcess = Get-Process -Name $Server.ProcessName -ErrorAction SilentlyContinue + } + #Check if the process was found. + if ($null -eq $ServerProcess) { + Write-ServerMsg "Server is not running." } else { - return $false + #Check if it's the right server via RCON if possible. + $Success = $false + if ($Warnings.Use){ + $Success = Send-Command("help") + if ($Success) { + Write-ServerMsg "Server is responding to remote messages." + } else { + Write-ServerMsg "Server is not responding to remote messages." + } + } + #If Rcon worked, send stop warning. + if ($Success) { + Write-ServerMsg "Server is running, warning users about upcomming restart." + $Stopped = Send-RestartWarning -ServerProcess $ServerProcess + } else { + #If Server is allow to be closed, close it. + if ($Server.AllowForceClose){ + Write-ServerMsg "Server is running, stopping server." + $Stopped = Stop-ServerProcess -ServerProcess $ServerProcess + } + } + #If the server stopped, send messages, if not check if it's normal, then stopped it, if it fails, exit with error. + if ($Stopped) { + Write-ServerMsg "Server stopped." + } else { + if ($Server.AllowForceClose) { + Exit-WithError "Failed to stop server." + } else { + Write-ServerMsg "Server not stopped." + } + } + } + #Unregister the PID + if (-not $(Unregister-PID)) { + Write-ServerMsg "Failed to remove PID file." } } Export-ModuleMember -Function Stop-Server \ No newline at end of file diff --git a/functions/Stop-ServerProcess.psm1 b/functions/Stop-ServerProcess.psm1 new file mode 100644 index 0000000..e5021dd --- /dev/null +++ b/functions/Stop-ServerProcess.psm1 @@ -0,0 +1,40 @@ +function Stop-ServerProcess { + [CmdletBinding()] + [OutputType([boolean])] + param ( + [Parameter(Mandatory)] + $ServerProcess + ) + #if the server is still running + + Write-ServerMsg "Closing main window..." + #Close the main windows. + $ServerProcess.CloseMainWindow() + #Wait for exit for at most 30 seconds. + $ServerProcess.WaitForExit($Warnings.SaveDelay * 1000) + #if the process exited send success message + if ($ServerProcess.HasExited) { + Write-ServerMsg "Server succesfully stopped." + }else{ + Write-Warning "Trying again to stop the server..." + #else try to stop server with stop-process. + Stop-Process $ServerProcess + #Wait for exit for at most 30 seconds. + $ServerProcess.WaitForExit($Warnings.SaveDelay * 1000) + #If process is still running, force stop-process. + if ($null -eq (Get-Process -ID ($ServerProcess.Id) -ErrorAction SilentlyContinue)) { + Write-Warning "Server succesfully stopped on second try." + }else{ + Write-Warning "Forcefully stopping server..." + Stop-Process $ServerProcess -Force + } + } + #Safety timer for allowing the files to unlock before backup. + Start-Sleep -Seconds 10 + if ($ServerProcess.HasExited) { + return $true + } else { + return $false + } +} +Export-ModuleMember -Function Stop-ServerProcess \ No newline at end of file diff --git a/functions/Update-Server.psm1 b/functions/Update-Server.psm1 index 5858837..94972a5 100644 --- a/functions/Update-Server.psm1 +++ b/functions/Update-Server.psm1 @@ -5,36 +5,61 @@ function Update-Server { [string]$UpdateType ) #Create server directory if not found. - if (-not (Test-Path -Path $Server.Path)){ + if (-not (Test-Path -Path $Server.Path -ErrorAction SilentlyContinue)){ New-Item -ItemType "directory" -Path $Server.Path -ErrorAction SilentlyContinue } - #Resolve complete path of the server folder. - $Server.Path = Resolve-Path -Path $Server.Path - #Run steam the correct steam command based on context. - if($Server.Beta){ - Write-ServerMsg "$UpdateType Beta Build." - try { - if ($Server.Validate) { - $Task = Start-Process $Global.SteamCMD -ArgumentList "+@ShutdownOnFailedCommand 1 +@NoPromptForPassword 1 +login anonymous +force_install_dir $($Server.Path) `"+app_update $($Server.AppID) -beta $($Server.BetaBuild) -betapassword $($Server.BetaBuildPassword)`" -validate +quit" -Wait -PassThru -NoNewWindow - } else { - $Task = Start-Process $Global.SteamCMD -ArgumentList "+@ShutdownOnFailedCommand 1 +@NoPromptForPassword 1 +login anonymous +force_install_dir $($Server.Path) `"+app_update $($Server.AppID) -beta $($Server.BetaBuild) -betapassword $($Server.BetaBuildPassword)`" +quit" -Wait -PassThru -NoNewWindow - } - } catch { - Exit-WithError -ErrorMsg "SteamCMD failed to complete." - } - } else { - Write-ServerMsg "$UpdateType Regular Build." - try { - if ($Server.Validate){ - $Task = Start-Process $Global.SteamCMD -ArgumentList "+@ShutdownOnFailedCommand 1 +@NoPromptForPassword 1 +login anonymous +force_install_dir $($Server.Path) +app_update $($Server.AppID) -validate +quit" -Wait -PassThru -NoNewWindow - } else { - $Task = Start-Process $Global.SteamCMD -ArgumentList "+@ShutdownOnFailedCommand 1 +@NoPromptForPassword 1 +login anonymous +force_install_dir $($Server.Path) +app_update $($Server.AppID) +quit" -Wait -PassThru -NoNewWindow - } - } catch { - Exit-WithError -ErrorMsg "SteamCMD failed to complete." - } - } - #Update Server.Exec value with the full path. - $Server.Exec = Resolve-Path -Path $Server.Exec + #Skip install if AppID is 0 + if ($Server.AppID -eq 0){ + return + } + <# + String Part if value is null or false or empty string + if () { + String Part if value is defined + } + #> + #Login String + $LoginString = "+@ShutdownOnFailedCommand 1 +@NoPromptForPassword 1 +login anonymous " + if ($Server.Login -ne "anonymous") { + $LoginString = "+login $($Server.Login) " + } + #Validation String + $ValidateString = " " + $ValidatingString = "" + if ($Server.Validate -ne $false){ + $ValidateString = "validate " + $ValidatingString = "and Validating" + } + #Beta Build String + $BetaBuildString = " " + $VersionString = "Regular" + if ($Server.BetaBuild -ne ""){ + $BetaBuildString = "-beta $($Server.BetaBuild) " + $VersionString = "Beta" + } + #Beta Password String + $BetaPasswordString = " " + if ($Server.BetaBuildPassword -ne ""){ + $BetaPasswordString = "-betapassword $($Server.BetaBuildPassword)" + } + #Generate String + $ArgumentList = @( + "$LoginString", + "+force_install_dir `"$($Server.Path)`" ", + "+app_update $($Server.AppID)", + "$BetaBuildString", + "$BetaPasswordString", + " $ValidateString", + "+quit" + ) + $Arguments = Optimize-ArgumentList -Arguments $ArgumentList + #Run the update String + Write-ServerMsg "$UpdateType $ValidatingString $VersionString Build." + try { + $Task = Start-Process $Global.SteamCMD -ArgumentList $Arguments -Wait -PassThru -NoNewWindow + } + catch { + Exit-WithError -ErrorMsg "SteamCMD failed to complete." + } } Export-ModuleMember -Function Update-Server \ No newline at end of file diff --git a/launchers/run.cmd b/launchers/run.cmd index 1465e1f..0904e89 100644 --- a/launchers/run.cmd +++ b/launchers/run.cmd @@ -1,2 +1,2 @@ cd .. -start powershell.exe -noprofile -executionpolicy bypass -file ".\main.ps1" -ServerCfg "squad" \ No newline at end of file +start powershell.exe -noprofile -executionpolicy bypass -file ".\main.ps1" -ServerCfg "valheim" \ No newline at end of file diff --git a/main.ps1 b/main.ps1 index 4e357a5..b03de78 100644 --- a/main.ps1 +++ b/main.ps1 @@ -47,60 +47,13 @@ Write-ScriptMsg "Working Directory : $(Get-Location)" # Get server IPs #--------------------------------------------------------- -#Get current internal ip from active network interface. -Write-ScriptMsg "Finding server IPs..." -$InternalIP = ( - Get-NetIPConfiguration | - Where-Object { - $_.IPv4DefaultGateway -ne $null -and - $_.NetAdapter.Status -ne "Disconnected" - } -).IPv4Address.IPAddress - -#Get current external ip from ifconfig.me -$ExternalIP = (Invoke-WebRequest ifconfig.me/ip).Content.Trim() - -Write-ScriptMsg "Server local IP : $InternalIP" -Write-ScriptMsg "Server external IP : $ExternalIP" - -#Add propreties to global. -Add-Member -InputObject $Global -Name "InternalIP" -Type NoteProperty -Value $InternalIP -Add-Member -InputObject $Global -Name "ExternalIP" -Type NoteProperty -Value $ExternalIP +Set-IP #--------------------------------------------------------- # Install Dependencies #--------------------------------------------------------- -#Define variables -Write-ScriptMsg "Verifying Dependencies..." -$Dependencies = @{ - SevenZip = $Global.SevenZip - Mcrcon = $Global.Mcrcon - SteamCMD = $Global.SteamCMD -} - -[System.Collections.ArrayList]$MissingDependencies = @() - -#For each dependency check if the excutable exist, if not, add the key of the dependency to the MissingDependencies list. -foreach ($Key in $Dependencies.keys) { - if (-not (Test-Path -Path $Dependencies[$Key])) { - $null = $MissingDependencies.Add($Key) - } -} - -#If there is missing dependencies, create the download folder and for each missing dependency, run the installation script. -if ($MissingDependencies.Count -gt 0){ - #Create Temporary Download Folder - New-Item -Path ".\downloads" -ItemType "directory" -ErrorAction SilentlyContinue - - foreach ($Item in $MissingDependencies) { - $Cmd = "Install-$Item" - &$Cmd -Application $Dependencies[$Item] - } - - #Cleanup - Remove-Item -Path ".\downloads" -Recurse -Force -ErrorAction SilentlyContinue -} +Install-Dependency #--------------------------------------------------------- # Importing server configuration. @@ -108,8 +61,8 @@ if ($MissingDependencies.Count -gt 0){ Write-ScriptMsg "Importing Server Configuration..." #Check if requested config exist in the config folder, if not, copy it from the templates. Exit if fails. -if (-not (Test-Path -Path ".\configs\$ServerCfg.psm1" -PathType "Leaf")) { - if (Test-Path -Path ".\templates\$ServerCfg.psm1" -PathType "Leaf"){ +if (-not (Test-Path -Path ".\configs\$ServerCfg.psm1" -PathType "Leaf" -ErrorAction SilentlyContinue)) { + if (Test-Path -Path ".\templates\$ServerCfg.psm1" -PathType "Leaf" -ErrorAction SilentlyContinue){ Copy-Item -Path ".\templates\$ServerCfg.psm1" -Destination ".\configs\$ServerCfg.psm1" -ErrorAction SilentlyContinue } else { Exit-WithError -ErrorMsg "Unable to find configuration file." @@ -121,19 +74,21 @@ try { Import-Module -Name ".\configs\$ServerCfg.psm1" } catch { - Exit-WithError -ErrorMsg "Unable to server configuration." - exit + Exit-WithError -ErrorMsg "Unable to import server configuration." } +#Parse configuration +Read-Config + #--------------------------------------------------------- # Install Server #--------------------------------------------------------- Write-ScriptMsg "Verifying Server installation..." #Flag of a fresh installation in the current instance. -[boolean]$FreshInstall = $false +$FreshInstall = $false #If the server executable is missing, run SteamCMD and install the server. -if (-not(Test-Path -Path $Server.Exec)){ +if (-not (Test-Path -Path $Server.Exec -ErrorAction SilentlyContinue)){ Write-ServerMsg "Server is not installed : Installing $($Server.Name) Server." Update-Server -UpdateType "Installing" Write-ServerMsg "Server successfully installed." @@ -145,59 +100,8 @@ if (-not(Test-Path -Path $Server.Exec)){ #--------------------------------------------------------- Write-ScriptMsg "Verifying Server State..." #If the server is not freshly installed. -if (-not ($FreshInstall)) { - #Get the PID from the .PID market file. - $ServerPID = Get-PID - #If it returned 0, it failed to get a PID - if ($null -ne $ServerPID) { - $ServerProcess = Get-Process -ID $ServerPID -ErrorAction SilentlyContinue - } - #If the server process is none-existent, Get the process from the server process name. - if ($null -ne $ServerProcess) { - $ServerProcess = Get-Process -Name $Server.ProcessName -ErrorAction SilentlyContinue - } - #Check if the process was found. - if ($null -eq $ServerProcess) { - Write-ServerMsg "Server is not running." - } else { - #Check if it's the right server via RCON if possible. - $Success = $false - if ($Warnings.Use){ - $Success = Send-Command("help") - if ($Success) { - Write-ServerMsg "Server is responding to remote messages." - } else { - Write-ServerMsg "Server is not responding to remote messages." - } - } - - #If Rcon worked, send stop warning. - if ($Success) { - Write-ServerMsg "Server is running, warning users about upcomming restart." - $Stopped = Send-RestartWarning -ServerProcess $ServerProcess - } else { - #If Server is allow to be closed, close it. - if ($Server.AllowForceClose){ - Write-ServerMsg "Server is running, stopping server." - $Stopped = Stop-Server -ServerProcess $ServerProcess - } - } - - #If the server stopped, send messages, if not check if it's normal, then stopped it, if it fails, exit with error. - if ($Stopped) { - Write-ServerMsg "Server stopped." - } else { - if ($Server.AllowForceClose) { - Exit-WithError "Failed to stop server." - } else { - Write-ServerMsg "Server not stopped." - } - } - } - #Unregister the PID - if (-not $(Unregister-PID)) { - Write-ServerMsg "Failed to remove PID file." - } +if (-not $FreshInstall) { + Stop-Server } #--------------------------------------------------------- @@ -205,7 +109,7 @@ if (-not ($FreshInstall)) { #--------------------------------------------------------- #If not a fresh install and Backups are enabled, run backups. -if ($Backups.Use -and -not ($FreshInstall)) { +if ($Backups.Use -and -not $FreshInstall) { Write-ScriptMsg "Verifying Backups..." Backup-Server } @@ -215,9 +119,9 @@ if ($Backups.Use -and -not ($FreshInstall)) { #--------------------------------------------------------- #If not a fresh install, update and/or validate server. -if (-not ($FreshInstall)) { +if (-not $FreshInstall -and $Server.AutoUpdates) { Write-ScriptMsg "Updating Server..." - Update-Server -UpdateType "Updating / Validating" + Update-Server -UpdateType "Updating" Write-ServerMsg "Server successfully updated and/or validated." } @@ -226,25 +130,16 @@ if (-not ($FreshInstall)) { #--------------------------------------------------------- #Try to start the server, then if it's stable, set the priority and affinity then register the PID. Exit with Error if it fails. -try { - Write-ScriptMsg "Starting Server..." - Start-ServerPrep - $App = Start-Process -FilePath $Server.Launcher -WorkingDirectory $Server.WorkingDirectory -ArgumentList $Server.ArgumentList -PassThru - #Wait to see if the server is stable. - Start-Sleep -Seconds $Server.StartupWaitTime - if (-not ($App) -or $App.HasExited){ - Exit-WithError "Server Failed to launch." - } else { - Write-ServerMsg "Server Started." - Set-Priority -ServerProcess $App - } - if (-not $(Register-PID -ServerProcess $App)){ - Write-ServerMsg "Failed to Register PID file." - } -} -catch { - Write-Error $_ - Exit-WithError -ErrorMsg "Unable to start server." +Start-Server + +#--------------------------------------------------------- +# Open FreshInstall Configuration folder +#--------------------------------------------------------- + +if ($FreshInstall -and (Test-Path -Path $Server.ConfigFolder -PathType "Container" -ErrorAction SilentlyContinue)) { + & explorer.exe $Server.ConfigFolder + #Stop Server because configuration is probably bad anyway + Stop-Server } #--------------------------------------------------------- diff --git a/templates/7daystodie.psm1 b/templates/7daystodie.psm1 index 04c280e..df4290e 100644 --- a/templates/7daystodie.psm1 +++ b/templates/7daystodie.psm1 @@ -5,7 +5,6 @@ #Server Name, use the same name to share game files. $Name = "7DaysToDie" - #--------------------------------------------------------- # Server Configuration #--------------------------------------------------------- @@ -13,7 +12,10 @@ $Name = "7DaysToDie" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 7 + UID = "7DaysToDie_1" + + #Login username used by SteamCMD + Login = "anonymous" #Server Configuration ConfigFile = "$Env:userprofile\AppData\Roaming\7DaysToDie\Saves\serverconfig.xml" @@ -40,22 +42,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server configuration folder + ConfigFolder = "$Env:userprofile\AppData\Roaming\7DaysToDie\Saves\" + #Steam Server App Id AppID = 294420 - - #Use Beta builds $true or $false - Beta = $false - + #Name of the Beta Build BetaBuild = "" #Beta Build Password BetaBuildPassword = "" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "7DaysToDieServer" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\7DaysToDieServer.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -156,7 +164,7 @@ $Warnings = New-Object -TypeName PsObject -Property $WarningsDetails #--------------------------------------------------------- #Launch Arguments -$Arguments = @( +$ArgumentList = @( "-logfile $($Server.LogFile) ", "-configfile=$($Server.ConfigFile) ", "-batchmode ", @@ -165,23 +173,9 @@ $Arguments = @( "-quit" ) -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. @@ -193,11 +187,11 @@ function Start-ServerPrep { #Copy Config File if not created. Do not modify the one in the server directory, it will be overwriten on updates. $ConfigFilePath = Split-Path -Path $Server.ConfigFile - if (-not (Test-Path -Path $ConfigFilePath)){ + if (-not (Test-Path -Path $ConfigFilePath -ErrorAction SilentlyContinue)){ New-Item -ItemType "directory" -Path $ConfigFilePath -Force -ErrorAction SilentlyContinue } - If(-not (Test-Path -Path $Server.ConfigFile -PathType "leaf")){ - Copy-Item -Path "$($Server.Path)\serverconfig.xml" -Destination $Server.ConfigFile -Force + If(-not (Test-Path -Path $Server.ConfigFile -PathType "leaf" -ErrorAction SilentlyContinue)){ + Copy-Item -Path "$($Server.Path)\serverconfig.xml" -Destination $Server.ConfigFile -Force -ErrorAction SilentlyContinue } } diff --git a/templates/astroneer.psm1 b/templates/astroneer.psm1 new file mode 100644 index 0000000..7c5948f --- /dev/null +++ b/templates/astroneer.psm1 @@ -0,0 +1,186 @@ +<# + Edit your configuration in .\servers\Astroneer\Astro\Saved\Config\WindowsServer + + https://blog.astroneer.space/p/astroneer-dedicated-server-details/ +#> + +#Server Name, use the same name to share game files. +$Name = "Astroneer" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "Astroneer_1" + + #Login username used by SteamCMD + Login = "anonymous" + + #Rcon IP (not supported by astroneer yet.) + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = "" + + #Rcon Password + ManagementPassword = "" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name" + + #Server configuration folder + ConfigFolder = ".\servers\Astroneer\Astro\Saved\Config\WindowsServer" + + #Steam Server App Id + AppID = 728470 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + + #Process name in the task manager + ProcessName = "AstroServer-Win64-Shipping" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $false + + #Server Executable + Exec = ".\servers\$Name\AstroServer.exe" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $false + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $true + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + Saves = ".\servers\$($Server.Name)\Astro\Saved" + +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $false + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Rcon" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "say" + + #command to save the server + CmdSave = "saveworld" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "shutdown" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Launch Arguments +$ArgumentList = @() +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +function Start-ServerPrep { + + Write-ScriptMsg "`nPort Forward : 8777 in TCP and UDP to $($Global.InternalIP)" + Write-ScriptMsg "`nAdd the following lines to engine.ini `n`n[URL]`nPort=8777" + Write-ScriptMsg "`nIn AstroServerSettings.ini change the following lines`n` + `nPublicIP=$($Global.ExternalIP)` + `nServerName=Your server Name` + `nOwnerName=Your Steam Username` + `nOwnerGuid=Your SteamID 64` + `nServerPassword=CHANGEME` + `nConsolePassword=CHANGEMETOO`n" +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/insurgencysandstorm.psm1 b/templates/insurgencysandstorm.psm1 index 49bb171..b6af074 100644 --- a/templates/insurgencysandstorm.psm1 +++ b/templates/insurgencysandstorm.psm1 @@ -13,7 +13,10 @@ $Name = "InsurgencySandstorm" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 2 + UID = "InsurgencySandstorm_1" + + #Login username used by SteamCMD + Login = "anonymous" #Name of the server in the Server Browser SessionName = "My Insurgency Server" @@ -60,9 +63,6 @@ $ServerDetails = @{ #Official RuleSet OfficialRulesSet = "OfficialRules" - #Enable Rcon $true or $false - EnableRcon = $true - #Rcon IP, usually localhost ManagementIP = "127.0.0.1" @@ -82,22 +82,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server configuration folder + ConfigFolder = ".\servers\$Name\Saved\Config\WindowsServer" + #Steam Server App Id AppID = 581330 - #Use Beta builds $true or $false - Beta = $false - #Name of the Beta Build BetaBuild = "" #Beta Build Password BetaBuildPassword = "" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "InsurgencyServer" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\InsurgencyServer.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -197,7 +203,7 @@ $Warnings = New-Object -TypeName PsObject -Property $WarningsDetails # Launch Arguments #--------------------------------------------------------- -$Arguments = @( +$ArgumentList = @( "$($Server.Map)", "?Scenario=$($Server.Scenario)", "?MaxPlayers=$($Server.MaxPlayers)", @@ -214,32 +220,12 @@ $Arguments = @( "-ruleset=`"$($Server.OfficialRulesSet)`" ", "-CmdModList=`"$($Server.Mods)`" ", "-mutators=`"$($Server.Mutators)`" ", + "-Rcon -RconListenPort=`"$($Server.ManagementPort)`" -RconPassword=`"$($Server.ManagementPassword)`" ", "-log" ) - -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -if ($Server.EnableRcon){ - $CleanedArguments.Add(" -Rcon") - $CleanedArguments.Add(" -RconPassword=`"$($Server.ManagementPassword)`"") - $CleanedArguments.Add(" -RconListenPort=`"$($Server.ManagementPort)`"") -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. @@ -247,7 +233,7 @@ Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Val function Start-ServerPrep { - Write-ScriptMsg "Port Forward : $($server.Port) and $($server.QueryPort) in TCP and UDP to $($Global.InternalIP)" + Write-ScriptMsg "Port Forward : $($Server.Port) and $($Server.QueryPort) in TCP and UDP to $($Global.InternalIP)" } diff --git a/templates/killingfloor2.psm1 b/templates/killingfloor2.psm1 index e12fd2a..de0d1c5 100644 --- a/templates/killingfloor2.psm1 +++ b/templates/killingfloor2.psm1 @@ -14,7 +14,10 @@ $Name = "KillingFloor2" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 6 + UID = "KillingFloor2_1" + + #Login username used by SteamCMD + Login = "anonymous" #This is the admin username for WebAdmin if you're configuring WebAdmin via Commandline AdminName = "admin" @@ -62,22 +65,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server Configuration + ConfigFolder = ".\servers\$Name\KFGame\Config\" + #Steam Server App Id AppID = 232130 - #Use Beta builds $true or $false - Beta = $false - #Name of the Beta Build BetaBuild = "" #Beta Build Password BetaBuildPassword = "" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "KFServer" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\Binaries\Win64\KFServer.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -133,7 +142,7 @@ $BackupsDetails = @{ Weeks = 4 #Folder to include in backup - Saves = ".\servers\$Name\KFGame\Config\" + Saves = ".\servers\$($Server.Name)\KFGame\Config\" } #Create the object $Backups = New-Object -TypeName PsObject -Property $BackupsDetails @@ -178,7 +187,7 @@ $Warnings = New-Object -TypeName PsObject -Property $WarningsDetails #--------------------------------------------------------- #Launch Arguments -$Arguments = @( +$ArgumentList = @( "$($Server.Map)", "?Game=$($Server.GameMode)", "?MaxPlayers=$($Server.MaxPlayers)", @@ -189,24 +198,9 @@ $Arguments = @( "-Multihome=$($Global.InternalIP) ", "-ConfigSubDir=KF$($Server.UID)" ) - -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. @@ -214,8 +208,8 @@ Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Val function Start-ServerPrep { - Write-ScriptMsg "Port Forward : $($server.Port), $($server.QueryPort), 20560, 123 in UDP and $($server.WebAdminPort) in TCP to $($Global.InternalIP)" - Write-ScriptMsg "Once Webadmin enabled, go to http://$($Global.InternalIP):$($server.WebAdminPort) to administer this server." + Write-ScriptMsg "Port Forward : $($Server.Port), $($Server.QueryPort), 20560, 123 in UDP and $($Server.WebAdminPort) in TCP to $($Global.InternalIP)" + Write-ScriptMsg "Once Webadmin enabled, go to http://$($Global.InternalIP):$($Server.WebAdminPort) to administer this server." } diff --git a/templates/left4dead2.psm1 b/templates/left4dead2.psm1 new file mode 100644 index 0000000..77662b2 --- /dev/null +++ b/templates/left4dead2.psm1 @@ -0,0 +1,254 @@ +<# + Edit configuration in : .\servers\Left4Dead2\left4dead2\cfg\server.cfg +#> + +#Server Name, use the same name to share game files. +$Name = "Left4Dead2" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "Left4Dead2_1" + + #Login username used by SteamCMD + Login = "anonymous" + + #Server Host Name + SessionName = "My Left 4 Dead 2 Server" + + #Game Port + Port = 27015 + + #Query Port + QueryPort = 27005 + + #Max number of players + MaxPlayers = 4 + + #Server Password + Password = "" + + #Map + Map = "c1m1_hotel" + + #Configuration File + ConfigFile = "server.cfg" + + #Rcon IP + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = "9000" + + #Rcon Password + ManagementPassword = "" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name" + + #Server configuration folder + ConfigFolder = ".\servers\$Name\left4dead2\cfg\" + + #Steam Server App Id + AppID = 222860 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + + #Process name in the task manager + ProcessName = "srcds" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable + Exec = ".\servers\$Name\srcds.exe" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $true + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $false + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + Saves = ".\servers\$($Server.Name)\left4dead2\cfg" +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $true + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Telnet" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "say" + + #command to save the server + CmdSave = "save" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "quit" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Launch Arguments +$ArgumentList = @( + "-console ", + "-game left4dead2 ", + "-secure ", + "-nohltv ", + "-netconport $($Server.ManagementPort) ", + "-netconpassword $($Server.ManagementPassword) ", + "+map $($Server.Map) ", + "+log on ", + "+maxplayers $($Server.MaxPlayers) ", + "+hostport $($Server.Port) ", + "+clientport $($Server.QueryPort) ", + "-ip $($Global.InternalIP) ", + "+hostip $($Global.ExternalIP) ", + "+exec $($Server.ConfigFile)" +) +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +$FileContentList = @( + "hostname `"$($Server.SessionName)`"", + "rcon_password `"$($Server.ManagementPassword)`"", + "sv_password `"$($Server.Password)`"", + "sv_contact `"contact@example.com`"", + "hostport $($Server.Port)", + "sv_lan 0", + "sv_region 0", + "sv_allow_lobby_connect_only 0", + "mp_disable_autokick 1", + "sv_allow_wait_command 0", + "sv_alternateticks 0", + "sv_clearhinthistory 0", + "sv_consistency 0", + "sv_pausable 0", + "sv_forcepreload 1", + "sv_pure_kick_clients 0", + "sv_pure 0", + "sv_voiceenable 1", + "sv_alltalk 1", + "log on", + "sv_logecho 0", + "sv_logfile 1", + "sv_log_onefile 0", + "sv_logbans 1", + "sv_logflush 0", + "sv_logsdir logs", + "exec banned_user.cfg", + "exec banned_ip.cfg", + "writeip", + "writeid" +) + +$FileContent = ($FileContentList -join "`n") + +function Start-ServerPrep { + + + #Copy Config File if not created. Do not modify the one in the server directory, it will be overwriten on updates. + if (-not (Test-Path -Path ".\servers\$($Server.Name)\left4dead2\cfg\$($Server.ConfigFile)" -ErrorAction SilentlyContinue)){ + Write-Host "Creating Config File" + New-Item -Path ".\servers\$($Server.Name)\left4dead2\cfg\" -Name "$($Server.ConfigFile)" -ItemType "file" -Value $FileContent + } + + Write-ScriptMsg "Port Forward : $($Server.Port) in TCP and UDP to $($Global.InternalIP)" + +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/mordhau.psm1 b/templates/mordhau.psm1 new file mode 100644 index 0000000..c976b1c --- /dev/null +++ b/templates/mordhau.psm1 @@ -0,0 +1,206 @@ +<# + Edit configuration in : .\servers\Mordhau\Mordhau\Saved\Config\WindowsServer + Modify Game.ini and Engine.ini + Instructions here + https://mordhau.fandom.com/wiki/Dedicated_Server_Hosting_Guide#Configuring_and_Running_the_Server +#> + +#Server Name, use the same name to share game files. +$Name = "Mordhau" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "Mordhau_1" + + #Login username used by SteamCMD + Login = "anonymous" + + #Server Port + Port = 7778 + + #Query Port + QueryPort = 27016 + + #Beacon Port + Beaconport = 15000 + + #Modified Game.ini + GameIni = ".\servers\Mordhau\Mordhau\Saved\Config\WindowsServer\Game2.ini" + + #Modified Engine.ini + EngineIni = ".\servers\Mordhau\Mordhau\Saved\Config\WindowsServer\Engine2.ini" + + #Rcon IP + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = 15002 + + #Rcon Password + ManagementPassword = "CHANGEME" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name" + + #Server configuration folder + ConfigFolder = ".\servers\Mordhau\Mordhau\Saved\Config\WindowsServer" + + #Steam Server App Id + AppID = 629800 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + + #Process name in the task manager + ProcessName = "MordhauServer-Win64-Shipping" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $false + + #Server Executable + Exec = ".\servers\$Name\MordhauServer.exe" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $false + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $true + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + Saves = ".\servers\$($Server.Name)\Mordhau\Saved\Config\WindowsServer" +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $true + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Rcon" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "say" + + #command to save the server + CmdSave = "stats" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "shutdown" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Address parsing and slash flipping +$Server.GameIni = (Resolve-CompletePath -Path $Server.GameIni -ParentPath ".\servers\") -replace '\\','/' +$Server.EngineIni = (Resolve-CompletePath -Path $Server.EngineIni -ParentPath ".\servers\") -replace '\\','/' + +#Launch Arguments +$ArgumentList = @( + "-Port=$($Server.Port) ", + "-QueryPort=$($Server.QueryPort) ", + "-Beaconport=$($Server.Beaconport) ", + "-GAMEINI=`"$($Server.GameIni)`" ", + "-ENGINEINI=`"$($Server.EngineIni)`" ", + "-log" + +) +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +function Start-ServerPrep { + + Write-ScriptMsg "Port Forward : $($Server.Port), $($Server.QueryPort), $($Server.Beaconport) in TCP and UDP to $($Global.InternalIP)" + +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/paperclip.psm1 b/templates/paperclip.psm1 new file mode 100644 index 0000000..e1c1cde --- /dev/null +++ b/templates/paperclip.psm1 @@ -0,0 +1,285 @@ +<# + Edit .\servers\Paperclip\server.properties +#> + +#Server Name, use the same name to share game files. +$Name = "Paperclip" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "Paperclip_1" + + #Login username used by SteamCMD + Login = "anonymous" + + # Server Name + SessionName = "My Minecraft Server" + + # Message of the day, also shows in server browser + MOTD = "\u00A76My Server - \u00A7AMinecraft 1.17.1" + + # Specifies the port to listen on. + Port = 25565 + + # Specifies the port to listen on. + QueryPort = 25565 + + # Sets the max number of players + MaxPlayers = 64 + + # Sets the server Game Mode + GameMode = "survival" + + #Level Name + World = "world" + + #Level Type + LevelType = "default" + + #Specifies the world seed when using -autocreate + Seed = 1234 + + #Difficulty + Difficulty = "normal" + + #Amount of ram dedicated to the server in Go + Ram = 2 + + #Rcon IP + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = 25575 + + #Rcon Password + ManagementPassword = "CHANGEME" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name" + + #Server configuration folder + ConfigFolder = ".\servers\$Name" + + #Server Version https://adoptopenjdk.net/releases.html?variant=openjdk16&jvmVariant=hotspot + JavaVersionLink = "https://github.com/AdoptOpenJDK/openjdk16-binaries/releases/download/jdk-16.0.1%2B9/OpenJDK16U-jre_x64_windows_hotspot_16.0.1_9.msi" + + #Server Version https://papermc.io/downloads#Paper-1.17 + PaperclipVersionLink = "https://papermc.io/api/v2/projects/paper/versions/1.17.1/builds/265/downloads/paper-1.17.1-265.jar" + + #Steam Server App Id *0 Skip SteamCMD Installation + AppID = 0 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $false + + #Process name in the task manager + ProcessName = "java" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable + Exec = ".\servers\$Name\paperclip.jar" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $true + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $true + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + Saves = "$Env:userprofile\Documents\My Games\Terraria\Worlds" +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $true + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Rcon" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "say" + + #command to save the server + CmdSave = "save-all" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "stop" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Launch Arguments +$ArgumentList = @( + "-Xms$($Server.Ram)G ", + "-Xmx$($Server.Ram)G ", + "-jar paperclip.jar ", + "--nogui" +) +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Global.JavaDirectory)\OpenJDK16\bin\java.exe" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" + +#--------------------------------------------------------- +# server.properties +#--------------------------------------------------------- + +$FileContentList = @( + "difficulty=$($Server.Difficulty)", + "gamemode=$($Server.GameMode)", + "level-name=$($Server.World)", + "level-seed=$($Server.Seed)", + "level-type=$($Server.LevelType)", + "max-players=$($Server.MaxPlayers)", + "motd=$($Server.MOTD)", + "enable-rcon=true", + "rcon.password=$($Server.ManagementPassword)", + "rcon.port=$($Server.ManagementPort)", + "server-name=$($Server.SessionName)", + "server-port=$($Server.Port)", + "query.port=$($Server.QueryPort)" +) + +$FileContent = ($FileContentList -join "`n") + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +function Start-ServerPrep { + + #Create Config File if not created. + if (-not (Test-Path -Path ".\servers\$($Server.Name)\server.properties" -ErrorAction SilentlyContinue)){ + Write-Host "Creating Config File" + New-Item -Path ".\servers\$($Server.Name)\" -Name "server.properties" -ItemType "file" -Value $FileContent + } + #Create eula File if not created. + if (-not (Test-Path -Path ".\servers\$($Server.Name)\eula.txt" -ErrorAction SilentlyContinue)){ + Write-Host "Creating Config File" + New-Item -Path ".\servers\$($Server.Name)\" -Name "eula.txt" -ItemType "file" -Value "eula=true" + } + #If server is not installed, install it. + $JavaVersion = Get-Content -Path ".\servers\$($Server.Name)\JavaVersion.txt" -ErrorAction SilentlyContinue + if (-not (Test-Path -Path $Server.Exec -PathType "leaf" -ErrorAction SilentlyContinue) -or ($Version -ne $Server.Version)) { + Write-ScriptMsg "Installing Java..." + #Create Temporary Download Folder + New-Item -Path ".\downloads" -ItemType "directory" -ErrorAction SilentlyContinue + #Download Adopt Openjdk-16.0.2+7 + Invoke-Download -Uri $($Server.JavaVersionLink) -OutFile ".\downloads\OpenJDK16.msi" -ErrorAction SilentlyContinue + #Install Adopt Openjdk-16.0.2+7 + $Package = Resolve-Path -Path ".\downloads\OpenJDK16.msi" + Start-Process -FilePath msiexec.exe -ArgumentList "/qn /i $Package ADDLOCAL=FeatureMain,FeatureEnvironment,FeatureJarFileRunWith,FeatureJavaHome INSTALLDIR=`"$($Global.JavaDirectory)\OpenJDK16`" /passive" -Verb "RunAs" -Wait + #Cleanup + Remove-Item -Path ".\downloads" -Recurse -Force -ErrorAction SilentlyContinue + #Remove old version file + Remove-Item -Path ".\servers\$($Server.Name)\JavaVersion.txt" -Confirm:$false -ErrorAction SilentlyContinue + #Write new Version File + New-Item -Path ".\servers\$($Server.Name)\" -Name "JavaVersion.txt" -ItemType "file" -Value "$($Server.JavaVersionLink)" -Force -ErrorAction SilentlyContinue + } + $PaperclipVersion = Get-Content -Path ".\servers\$($Server.Name)\PaperVersion.txt" -ErrorAction SilentlyContinue + if (-not (Test-Path -Path $Server.Exec -PathType "leaf" -ErrorAction SilentlyContinue) -or ($Version -ne $Server.Version)) { + Write-ScriptMsg "Installing Paperclip..." + #Create Temporary Download Folder + New-Item -Path ".\downloads" -ItemType "directory" -ErrorAction SilentlyContinue + #Download Paperclip + Invoke-Download -Uri $($Server.PaperclipVersionLink) -OutFile ".\downloads\paperclip.jar" -ErrorAction SilentlyContinue + #Copy Server Files to Server Directory + Copy-Item -Path ".\downloads\paperclip.jar" -Destination $Server.Path -Force + #Cleanup + Remove-Item -Path ".\downloads" -Recurse -Force -ErrorAction SilentlyContinue + #Remove old version file + Remove-Item -Path ".\servers\$($Server.Name)\PaperVersion.txt" -Confirm:$false -ErrorAction SilentlyContinue + #Write new Version File + New-Item -Path ".\servers\$($Server.Name)\" -Name "PaperVersion.txt" -ItemType "file" -Value "$($Server.PaperclipVersionLink)" -Force -ErrorAction SilentlyContinue + } + Write-ScriptMsg "Port Forward : $($Server.Port) in TCP and UDP to $($Global.InternalIP)" +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/pixark.psm1 b/templates/pixark.psm1 index dfa64c9..9e6e7b0 100644 --- a/templates/pixark.psm1 +++ b/templates/pixark.psm1 @@ -33,7 +33,10 @@ $Name = "PixArk" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 3 + UID = "PixArk_1" + + #Login username used by SteamCMD + Login = "anonymous" #Name of the server in the Server Browser SessionName = "My Pixark Server" @@ -90,22 +93,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server configuration folder + ConfigFolder = ".\servers\$Name\ShooterGame\Saved\Config\WindowsServer\" + #Steam Server App Id AppID = 824360 - #Use Beta builds $true or $false - Beta = $false - #Name of the Beta Build BetaBuild = "" #Beta Build Password BetaBuildPassword = "" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "PixArkServer" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\ShooterGame\Binaries\Win64\PixARKServer.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -206,7 +215,7 @@ $Warnings = New-Object -TypeName PsObject -Property $WarningsDetails #--------------------------------------------------------- #Launch Arguments -$Arguments = @( +$ArgumentList = @( "$($Server.WorldType)", "?listen", "?Multihome=$($Server.InternalIP)", @@ -230,24 +239,9 @@ $Arguments = @( "-server ", "-log" ) - -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. @@ -255,7 +249,7 @@ Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Val function Start-ServerPrep { - Write-ScriptMsg "Port Forward : $($server.Port), $($server.QueryPort) And $($server.CubePort) in TCP and UDP to $($Global.InternalIP)" + Write-ScriptMsg "Port Forward : $($Server.Port), $($Server.QueryPort) And $($Server.CubePort) in TCP and UDP to $($Global.InternalIP)" } diff --git a/templates/projectzomboid.psm1 b/templates/projectzomboid.psm1 index 0f48bc8..471775a 100644 --- a/templates/projectzomboid.psm1 +++ b/templates/projectzomboid.psm1 @@ -40,7 +40,10 @@ $Name = "ProjectZomboid" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 4 + UID = "ProjectZomboid_1" + + #Login username used by SteamCMD + Login = "anonymous" #Rcon IP, usually localhost ManagementIP = "127.0.0.1" @@ -61,22 +64,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server configuration folder + ConfigFolder = "$Env:userprofile\Zomboid\Server\" + #Steam Server App Id AppID = 380870 - #Use Beta builds $true or $false - Beta = $false - #Name of the Beta Build BetaBuild = "iwillbackupmysave" #Beta Build Password BetaBuildPassword = "iaccepttheconsequences" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "java" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\ProjectZomboid64.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -189,7 +198,7 @@ $PZ_CLASSPATH_LIST = @( $PZ_CLASSPATH = $PZ_CLASSPATH_LIST -join "" #Launch Arguments -$Arguments = @( +$ArgumentList = @( "-Dzomboid.steam=1 ", "-Dzomboid.znetlog=1 ", "-XX:+UseConcMarkSweepGC ", @@ -200,24 +209,9 @@ $Arguments = @( "-Djava.library.path=natives/;. ", "-cp $PZ_CLASSPATH zombie.network.GameServer" ) - -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Path)\jre64\bin\java.exe" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. diff --git a/templates/rust.psm1 b/templates/rust.psm1 index 732a9b5..36275a0 100644 --- a/templates/rust.psm1 +++ b/templates/rust.psm1 @@ -5,6 +5,9 @@ Edit configuration in ".\servers\Rust\server\[Identity]\cfg\serverauto.cfg" #Server Name, use the same name to share game files. $Name = "Rust" +#Identity of the server +$Identity = "RustServer01" + #--------------------------------------------------------- # Server Configuration #--------------------------------------------------------- @@ -12,13 +15,16 @@ $Name = "Rust" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 8 + UID = "Rust_1" + + #Login username used by SteamCMD + Login = "anonymous" #Name of the server Hostname = "My Rust Server" #Identity of the server - Identity = "RustServer01" + Identity = $Identity #Description of the server \n for new line Description = "Welcome to my server" @@ -93,22 +99,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server configuration folder + ConfigFolder = ".\servers\$Name\server\$Identity\cfg\" + #Steam Server App Id AppID = 258550 - #Use Beta builds $true or $false - Beta = $false - #Name of the Beta Build BetaBuild = "" #Beta Build Password BetaBuildPassword = "" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "RustDedicated" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\RustDedicated.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -138,7 +150,7 @@ $ServerDetails = @{ AppAffinity = 15 #Should the server validate install after installation or update *(recommended) - Validate = $false + Validate = $true #How long should it wait to check if the server is stable StartupWaitTime = 0 @@ -164,7 +176,7 @@ $BackupsDetails = @{ Weeks = 4 #Folder to include in backup - Saves = ".\servers\$Name\server\$($Server.Identity)" + Saves = ".\servers\$($Server.Name)\server\$($Server.Identity)" } #Create the object $Backups = New-Object -TypeName PsObject -Property $BackupsDetails @@ -209,7 +221,7 @@ $Warnings = New-Object -TypeName PsObject -Property $WarningsDetails #--------------------------------------------------------- #Launch Arguments -$Arguments = @( +$ArgumentList = @( "-batchmode ", "-nographics ", "+server.ip $($Global.InternalIP) ", @@ -239,24 +251,9 @@ $Arguments = @( "+rcon.web $($Server.rconVersion) ", "-logfile $($Server.Identity).txt " ) - -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. @@ -264,7 +261,7 @@ Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Val function Start-ServerPrep { - Write-ScriptMsg "Port Forward : $($server.Port), $($server.ManagementPort), $($Server.Port + 69) in TCP and UDP to $($Global.InternalIP)" + Write-ScriptMsg "Port Forward : $($Server.Port), $($Server.ManagementPort), $($Server.Port + 69) in TCP and UDP to $($Global.InternalIP)" } diff --git a/templates/squad.psm1 b/templates/squad.psm1 index 3e03914..d7ed920 100644 --- a/templates/squad.psm1 +++ b/templates/squad.psm1 @@ -11,7 +11,10 @@ $Name = "Squad" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 1 + UID = "Squad_1" + + #Login username used by SteamCMD + Login = "anonymous" #Randomize First Map NONE OR ALWAYS RandomMap = "ALWAYS" @@ -44,22 +47,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server configuration folder + ConfigFolder = + #Steam Server App Id AppID = 403240 - #Use Beta builds $true or $false - Beta = $false - #Name of the Beta Build BetaBuild = "" #Beta Build Password BetaBuildPassword = "" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "SquadGameServer" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\SquadGameServer.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -115,7 +124,7 @@ $BackupsDetails = @{ Weeks = 4 #Folder to include in backup - Saves = ".\servers\$Name\SquadGame\ServerConfig\" + Saves = ".\servers\$($Server.Name)\SquadGame\ServerConfig\" } #Create the object $Backups = New-Object -TypeName PsObject -Property $BackupsDetails @@ -160,7 +169,7 @@ $Warnings = New-Object -TypeName PsObject -Property $WarningsDetails #--------------------------------------------------------- #Launch Arguments -$Arguments = @( +$ArgumentList = @( "Multihome=$($Global.InternalIP) ", "Port=$($Server.Port) ", "QueryPort=$($Server.QueryPort) ", @@ -168,24 +177,9 @@ $Arguments = @( "RANDOM $($Server.RandomMap) ", "-log" ) - -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. @@ -193,7 +187,7 @@ Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Val function Start-ServerPrep { - Write-ScriptMsg "Port Forward : $($server.Port) in TCP and UDP to $($Global.InternalIP)" + Write-ScriptMsg "Port Forward : $($Server.Port) and $($Server.QueryPort) in TCP and UDP to $($Global.InternalIP)" } diff --git a/templates/starbound.psm1 b/templates/starbound.psm1 new file mode 100644 index 0000000..3f6d934 --- /dev/null +++ b/templates/starbound.psm1 @@ -0,0 +1,178 @@ +<# + Edit : .\servers\Starbound\storage\starbound_server.config + https://starbounder.org/Guide:Setting_Up_Multiplayer +#> + +#Server Name, use the same name to share game files. +$Name = "Starbound" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "Starbound_1" + + #Login username used by SteamCMD + Login = "Username" + + #Rcon IP (not supported by valheim yet.) + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = 21026 + + #Rcon Password + ManagementPassword = "Changeme" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name" + + #Server configuration folder + ConfigFolder = ".\servers\$Name\storage" + + #Steam Server App Id + AppID = 533830 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $false + + #Process name in the task manager + ProcessName = "starbound_server" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable + Exec = ".\servers\$Name\win64\starbound_server.exe" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $true + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $true + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + Saves = ".\servers\$($Server.Name)\storage" +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $false + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Rcon" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "say" + + #command to save the server + CmdSave = "saveworld" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "shutdown" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Launch Arguments +$ArgumentList = @() +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)\win64" + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +function Start-ServerPrep { + + Write-ScriptMsg "Port Forward : 21025 and 21026 in TCP and UDP to $($Global.InternalIP)" + Write-ScriptMsg "Edit Server Configuration in .\servers\$Name\storage\starbound_server.config" + +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/stationeers.psm1 b/templates/stationeers.psm1 new file mode 100644 index 0000000..a077f7b --- /dev/null +++ b/templates/stationeers.psm1 @@ -0,0 +1,238 @@ +<# + Not tested but should work. + Edit .\servers\$Name\default.ini to configure this server +#> + +#Server Name, use the same name to share game files. +$Name = "Stationeers" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "Stationeers_1" + + #Login username used by SteamCMD + Login = "anonymous" + + #Server Name + SessionName = "My Stationeers Server" + + #Auto Save Interval in seconds + AutoSaveInterval = 300 + + #Server Owner SteamID64 https://steamid.io/ + Creator = 76561197993918508 + + #World Type + WorldType = "Mars" + + #World Name *(Save name) + WorldName = "Mars1" + + #World that will be loaded + LoadWorld = "MyWorld" + + #Game Port + Port = 27500 + + #Steam Query Port + QueryPort = 27015 + + #Server Password + Password = "Changeme" + + #Max Players + MaxPlayers = 16 + + #Clear All Interval (Will delete disconnected players) + ClearAllInterval = 0 + + #Mod Folder Path + ModPath = ".\servers\$Name\mods" + + #Rcon IP + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = 27500 + + #Rcon Password + ManagementPassword = "stationeers" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name" + + #Server configuration folder + ConfigFolder = ".\servers\$Name" + + #Steam Server App Id + AppID = 600760 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + + #Process name in the task manager + ProcessName = "rocketstation_DedicatedServer" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable + Exec = ".\servers\$Name\rocketstation_DedicatedServer.exe" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $true + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $true + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + Saves = ".\servers\$($Server.Name)\saves" +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $false #Not quite supported. + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Rcon" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "notice" + + #command to save the server + CmdSave = "save $($Server.WorldName)" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "shutdown" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Address parsing +if ($Server.ModPath -ne ""){ + $Server.ModPath = (Resolve-CompletePath -Path $Server.ModPath -ParentPath ".\servers\") +} +$LogFilePath = (Resolve-CompletePath -Path "$($Server.Path)\$($Server.UID).txt" -ParentPath ".\servers\") +Add-Member -InputObject $Server -Name "LogFile" -Type NoteProperty -Value $LogFilePath + +#Launch Arguments +$ArgumentList = @( + "-batchmode ", + "-nographics ", + "-autostart ", + "-logfile=$($Server.LogFile) ", + "-servername=$($Server.SessionName) ", + "-autosaveinterval=$($Server.AutoSaveInterval) ", + "-creator=$($Server.Creator) ", + "-worldtype=$($Server.WorldType) ", + "-worldname=$($Server.WorldName) ", + "-loadworld=$($Server.LoadWorld) ", + "-gameport=$($Server.Port) ", + "-updateport=$($Server.QueryPort) ", + "-password=$($Server.Password) ", + "-maxplayer=$($Server.MaxPlayers) ", + "-clearallinterval=$($Server.ClearAllInterval) ", + "-modpath=$($Server.ModPath) ", + "-bindip=$($Global.InternalIP)" +) +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +function Start-ServerPrep { + + Write-ScriptMsg "Port Forward : $($Server.Port) and $($Server.QueryPort) in TCP and UDP to $($Global.InternalIP)" + +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/terraria.psm1 b/templates/terraria.psm1 new file mode 100644 index 0000000..ac33dcb --- /dev/null +++ b/templates/terraria.psm1 @@ -0,0 +1,242 @@ +<# + ".\servers\$Name\serverconfig.txt" +#> + +#Server Name, use the same name to share game files. +$Name = "Terraria" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "Terraria_1" + + #Login username used by SteamCMD + Login = "anonymous" + + # Specifies the configuration file to use *(relative the the game) + ConfigFile = "serverconfig.txt" + + # Specifies the port to listen on. + Port = 7777 + + # Sets the max number of players + MaxPlayers = 8 + + # Sets the server password + Password = "CHANGEME" + + #Choose the world to load. Do not try to save it somewhere else, it won't work. + World = "$Env:userprofile\Documents\My Games\Terraria\Worlds\ServerWorld.wld" + + #Should match the above world. + WorldName = "ServerWorld" + + #Specifies the world seed when using -autocreate + Seed = "1234" + + #Creates a world if none is found in the path specified by World. + #World size is specified by: 1(small), 2(medium), and 3(large). + AutoCreate = 2 + + #Rcon IP + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = "" + + #Rcon Password + ManagementPassword = "" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name" + + #Server configuration folder + ConfigFolder = ".\servers\$Name" + + #Server Version + Version = "1423" + + #Steam Server App Id *0 Skip SteamCMD Installation + AppID = 0 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + + #Process name in the task manager + ProcessName = "TerrariaServer" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable + Exec = ".\servers\$Name\TerrariaServer.exe" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $true + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $true + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + Saves = "$Env:userprofile\Documents\My Games\Terraria\Worlds" +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $false + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Rcon" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "say" + + #command to save the server + CmdSave = "saveworld" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "shutdown" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Launch Arguments +$ArgumentList = @( + "-config `"$($Server.ConfigFile)`" ", + "-port $($Server.Port) ", + "-maxplayers $($Server.MaxPlayers) ", + "-password `"$($Server.Password)`" ", + "-world `"$($Server.World)`" ", + "-worldname `"$($Server.WorldName)`" ", + "-seed `"$($Server.Seed)`" ", + "-autocreate $($Server.AutoCreate) ", + "-secure ", + "-noupnp ", + "-steam " +) +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +function Start-ServerPrep { + #If server is not installed, install it. + $Version = Get-Content -Path ".\servers\$($Server.Name)\Version.txt" -ErrorAction SilentlyContinue + if (-not (Test-Path -Path $Server.Exec -PathType "leaf" -ErrorAction SilentlyContinue) -or ($Version -ne $Server.Version)) { + Write-ScriptMsg "Installing Server..." + #Create Temporary Download Folder + New-Item -Path ".\downloads" -ItemType "directory" -ErrorAction SilentlyContinue + #Download Microsoft XNA Framework + Invoke-Download -Uri "https://download.microsoft.com/download/5/3/A/53A804C8-EC78-43CD-A0F0-2FB4D45603D3/xnafx40_redist.msi" -OutFile ".\downloads\xna.msi" -ErrorAction SilentlyContinue + #Install Microsoft XNA + $Package = Resolve-Path -Path ".\downloads\xna.msi" + Start-Process -FilePath msiexec.exe -ArgumentList "/qn /i $Package" -Verb "RunAs" -Wait + #Download Server Zip + Invoke-Download -Uri "https://terraria.org/api/download/pc-dedicated-server/terraria-server-$($Server.Version).zip" -OutFile ".\downloads\terraria.zip" -ErrorAction SilentlyContinue + #Extract Server to Temporary Folder + Expand-Archive -Path ".\downloads\terraria.zip" -DestinationPath ".\downloads\terraria\" -Force + #Copy Server Files to Server Directory + Copy-Item -Path ".\downloads\terraria\$($Server.Version)\Windows\TerrariaServer.exe" -Destination $Server.Path -Force + Copy-Item -Path ".\downloads\terraria\$($Server.Version)\Windows\ReLogic.Native.dll" -Destination $Server.Path -Force + if (-not (Test-Path -Path $Server.ConfigFile -PathType "leaf" -ErrorAction SilentlyContinue)) { + Copy-Item -Path ".\downloads\terraria\$($Server.Version)\Windows\serverconfig.txt" -Destination $Server.Path + } + #Cleanup + Remove-Item -Path ".\downloads" -Recurse -Force -ErrorAction SilentlyContinue + #Remove old version file + Remove-Item -Path ".\servers\$($Server.Name)\Version.txt" -Confirm:$false -ErrorAction SilentlyContinue + #Write new Version File + New-Item -Path ".\servers\$($Server.Name)\" -Name "Version.txt" -ItemType "file" -Value "$($Server.Version)" -Force -ErrorAction SilentlyContinue + } + Write-ScriptMsg "Port Forward : $($Server.Port) in TCP and UDP to $($Global.InternalIP)" +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/theforest.psm1 b/templates/theforest.psm1 new file mode 100644 index 0000000..0af5c6f --- /dev/null +++ b/templates/theforest.psm1 @@ -0,0 +1,232 @@ +<# + ".\servers\TheForest\Multiplayer\config.cfg" +#> + +#Server Name, use the same name to share game files. +$Name = "TheForest" + +#--------------------------------------------------------- +# Server Configuration +#--------------------------------------------------------- + +$ServerDetails = @{ + + #Unique Identifier used to track processes. Must be unique to each servers. + UID = "TheForest_1" + + #Login username used by SteamCMD + Login = "anonymous" + + #Configuration File #Command line parameters overwrite matching entries defined in the config file. + ConfigFile = ".\Multiplayer\config.cfg" + + #Steam Port + SteamPort = 8766 + + #Game Port + GamePort = 27015 + + #Query Port + QueryPort = 27016 + + #Set the server display name + SessionName = "My Server" + + #Maximum number of players + MaxPlayers = 8 + + #Join Password + Password = "CHANGEME" + + #Admin Password + AdminPassword = "CHANGEMETOO" + + #Set the autosave interval in minutes, default is 15 + AutoSaveInterval = 5 + + #Set Save Slot ( 1 | 2 | 3 | 4 | 5 ) + SaveSlot = 1 + + #Set Continue State ("New" | "Continue") + InitType = "Continue" + + #Set the game difficult level, default is Normal ("Peaceful" | "Normal" | "Hard") + Difficulty = "Normal" + + #Rcon IP + ManagementIP = "127.0.0.1" + + #Rcon Port + ManagementPort = "" + + #Rcon Password + ManagementPassword = "" + +#--------------------------------------------------------- +# Server Installation Details +#--------------------------------------------------------- + + #Name of the Server Instance + Name = $Name + + #Server Installation Path + Path = ".\servers\$Name\" + + #Server configuration folder + ConfigFolder = ".\servers\$Name\Multiplayer" + + #Steam Server App Id + AppID = 556450 + + #Name of the Beta Build + BetaBuild = "" + + #Beta Build Password + BetaBuildPassword = "" + + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $false + + #Process name in the task manager + ProcessName = "TheForestDedicatedServer" + + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable + Exec = ".\servers\$Name\TheForestDedicatedServer.exe" + + #Allow force close, usefull for server without RCON and Multiple instances. + AllowForceClose = $true + + #Process Priority Realtime, High, Above normal, Normal, Below normal, Low + UsePriority = $true + AppPriority = "High" + + <# + Process Affinity (Core Assignation) + Core 1 = > 00000001 = > 1 + Core 2 = > 00000010 = > 2 + Core 3 = > 00000100 = > 4 + Core 4 = > 00001000 = > 8 + Core 5 = > 00010000 = > 16 + Core 6 = > 00100000 = > 32 + Core 7 = > 01000000 = > 64 + Core 8 = > 10000000 = > 128 + ---------------------------- + 8 Cores = > 11111111 = > 255 + 4 Cores = > 00001111 = > 15 + 2 Cores = > 00000011 = > 3 + #> + + UseAffinity = $false + AppAffinity = 15 + + #Should the server validate install after installation or update *(recommended) + Validate = $true + + #How long should it wait to check if the server is stable + StartupWaitTime = 10 +} +#Create the object +$Server = New-Object -TypeName PsObject -Property $ServerDetails + +#--------------------------------------------------------- +# Backups +#--------------------------------------------------------- + +$BackupsDetails = @{ + #Do Backups + Use = $true + + #Backup Folder + Path = ".\backups\$($Server.Name)" + + #Number of days of backups to keep. + Days = 7 + + #Number of weeks of weekly backups to keep. + Weeks = 4 + + #Folder to include in backup + #Saves = "$Env:userprofile\AppData\LocalLow\SKS\TheForestDedicatedServer" + Saves = ".\servers\$($Server.Name)\Multiplayer" +} +#Create the object +$Backups = New-Object -TypeName PsObject -Property $BackupsDetails + +#--------------------------------------------------------- +# Restart Warnings (Require RCON, Telnet or WebSocket API) +#--------------------------------------------------------- + +$WarningsDetails = @{ + #Use Rcon to restart server softly. + Use = $false + + #What protocol to use : Rcon, Telnet, Websocket + Protocol = "Rcon" + + #Times at which the servers will warn the players that it is about to restart. (in seconds between each timers) + Timers = [System.Collections.ArrayList]@(240,50,10) #Total wait time is 240+50+10 = 300 seconds or 5 minutes + + #message that will be sent. % is a wildcard for the timer. + MessageMin = "The server will restart in % minutes !" + + #message that will be sent. % is a wildcard for the timer. + MessageSec = "The server will restart in % seconds !" + + #command to send a message. + CmdMessage = "say" + + #command to save the server + CmdSave = "saveworld" + + #How long to wait in seconds after the save command is sent. + SaveDelay = 15 + + #command to stop the server + CmdStop = "shutdown" +} +#Create the object +$Warnings = New-Object -TypeName PsObject -Property $WarningsDetails + +#--------------------------------------------------------- +# Launch Arguments +#--------------------------------------------------------- + +#Launch Arguments +$ArgumentList = @( + "-batchmode ", + "-dedicated ", + "-nographics ", + "-nosteamclient ", + "-serverip $($Global.InternalIP) ", + "-serversteamport $($Server.SteamPort) ", + "-servergameport $($Server.GamePort) ", + "-serverqueryport $($Server.QueryPort) ", + "-servername `"$($Server.SessionName)`" ", + "-serverplayers $($Server.maxPlayers) ", + "-serverpassword `"$($Server.Password)`" ", + "-serverpassword_admin `"$($Server.AdminPassword)`" ", + "-serverautosaveinterval $($Server.AutoSaveInterval) ", + "-slot $($Server.SaveSlot) ", + "-serverautosaveinterval $($Server.InitType) ", + "-difficulty `"$($Server.Difficulty)`" ", + "-configfilepath `"$($Server.ConfigFile)`" ", + "-savefolderpath .\" +) +Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" + +#--------------------------------------------------------- +# Function that runs just before the server starts. +#--------------------------------------------------------- + +function Start-ServerPrep { + + Write-ScriptMsg "Port Forward : 8766, 27015, 27016 in TCP and UDP to $($Global.InternalIP)" + +} + +Export-ModuleMember -Function Start-ServerPrep -Variable @("Server","Backups","Warnings") \ No newline at end of file diff --git a/templates/valheim.psm1 b/templates/valheim.psm1 index 9d3712f..fd7d132 100644 --- a/templates/valheim.psm1 +++ b/templates/valheim.psm1 @@ -1,4 +1,3 @@ - #Server Name, use the same name to share game files. $Name = "Valheim" @@ -9,7 +8,10 @@ $Name = "Valheim" $ServerDetails = @{ #Unique Identifier used to track processes. Must be unique to each servers. - UID = 5 + UID = "Valheim_1" + + #Login username used by SteamCMD + Login = "anonymous" #Name of the server in the Server Browser SessionName = "My Valheim Server" @@ -24,7 +26,7 @@ $ServerDetails = @{ Port = 2459 #Rcon IP (not supported by valheim yet.) - ManagementIP = "" + ManagementIP = "127.0.0.1" #Rcon Port ManagementPort = "" @@ -42,22 +44,28 @@ $ServerDetails = @{ #Server Installation Path Path = ".\servers\$Name" + #Server configuration folder + ConfigFolder = "$Env:userprofile\AppData\LocalLow\IronGate\Valheim" + #Steam Server App Id AppID = 896660 - #Use Beta builds $true or $false - Beta = $false - #Name of the Beta Build BetaBuild = "" #Beta Build Password BetaBuildPassword = "" + #Auto-Update Enable or Disable Auto-Updates, some games don't work well with SteamCMD + AutoUpdates = $true + #Process name in the task manager ProcessName = "valheim_server" - #ProjectZomboid64.exe + #Use PID instead of Process Name, Will still use processname if the PID fails to find anything. + UsePID = $true + + #Server Executable Exec = ".\servers\$Name\valheim_server.exe" #Allow force close, usefull for server without RCON and Multiple instances. @@ -158,7 +166,7 @@ $Warnings = New-Object -TypeName PsObject -Property $WarningsDetails #--------------------------------------------------------- #Launch Arguments -$Arguments = @( +$ArgumentList = @( "-batchmode ", "-nographics ", "-name $($Server.SessionName) ", @@ -167,24 +175,9 @@ $Arguments = @( "-password $($Server.Password) ", "-public 1" ) - -[System.Collections.ArrayList]$CleanedArguments=@() - -foreach($Argument in $Arguments){ - if (!($Argument.EndsWith('=""') -or $Argument.EndsWith('=') -or $Argument.EndsWith(' '))){ - $CleanedArguments.Add($Argument) - } -} - -$ArgumentList = $CleanedArguments -join "" - -#Server Launcher -$Launcher = "$(Get-Location)$($Server.Exec.substring(1))" -$WorkingDirectory = "$(Get-Location)$($Server.Path.substring(1))" - Add-Member -InputObject $Server -Name "ArgumentList" -Type NoteProperty -Value $ArgumentList -Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value $Launcher -Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value $WorkingDirectory +Add-Member -InputObject $Server -Name "Launcher" -Type NoteProperty -Value "$($Server.Exec)" +Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Value "$($Server.Path)" #--------------------------------------------------------- # Function that runs just before the server starts. @@ -192,7 +185,7 @@ Add-Member -InputObject $Server -Name "WorkingDirectory" -Type NoteProperty -Val function Start-ServerPrep { - Write-ScriptMsg "Port Forward : $($server.Port) in TCP and UDP to $($Global.InternalIP)" + Write-ScriptMsg "Port Forward : $($Server.Port) in TCP and UDP to $($Global.InternalIP)" }