Update AFSM.ps1

This commit is contained in:
2026-05-10 14:49:25 +00:00
parent f834258179
commit 8b26da805a
+600 -192
View File
@@ -5,6 +5,24 @@ Add-Type -AssemblyName System.Drawing
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$configPath = "$scriptDir\server_config.json" $configPath = "$scriptDir\server_config.json"
$script:serverProcess = $null $script:serverProcess = $null
$script:configChanged = $false
# Get local IP address
function Get-LocalIP {
$ip = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notlike "*Loopback*" -and $_.InterfaceAlias -notlike "*Virtual*" -and $_.IPAddress -notlike "169.254.*" } | Select-Object -First 1
if ($ip) { return $ip.IPAddress }
return "127.0.0.1"
}
# Get public IP (WAN)
function Get-PublicIP {
try {
$wanIP = (Invoke-WebRequest -Uri "https://api.ipify.org" -UseBasicParsing -TimeoutSec 3).Content
return $wanIP
} catch {
return "Unavailable"
}
}
# Load/Save Config # Load/Save Config
function Load-Config { function Load-Config {
@@ -19,8 +37,8 @@ function Load-Config {
$txtServerPassword.Text = $cfg.ServerPassword $txtServerPassword.Text = $cfg.ServerPassword
$txtAdminPassword.Text = $cfg.AdminPassword $txtAdminPassword.Text = $cfg.AdminPassword
$txtServerName.Text = $cfg.ServerName $txtServerName.Text = $cfg.ServerName
$chkUseLogin.Checked = $cfg.UseLogin $script:configChanged = $false
$txtSteamUser.Text = $cfg.SteamUser $btnSave.BackColor = [System.Drawing.Color]::FromArgb(240, 240, 240)
} catch { } catch {
Set-Defaults Set-Defaults
} }
@@ -28,10 +46,11 @@ function Load-Config {
Set-Defaults Set-Defaults
} }
Update-SteamCMDStatus Update-SteamCMDStatus
Update-GameDirStatus
} }
function Set-Defaults { function Set-Defaults {
$txtSteamCMDDir.Text = "$env:ProgramFiles\SteamCMD" $txtSteamCMDDir.Text = ""
$txtInstallDir.Text = "" $txtInstallDir.Text = ""
$txtMaxPlayers.Text = "6" $txtMaxPlayers.Text = "6"
$txtPort.Text = "7777" $txtPort.Text = "7777"
@@ -39,9 +58,8 @@ function Set-Defaults {
$txtServerPassword.Text = "" $txtServerPassword.Text = ""
$txtAdminPassword.Text = "" $txtAdminPassword.Text = ""
$txtServerName.Text = "My Abiotic Factor Server" $txtServerName.Text = "My Abiotic Factor Server"
$chkUseLogin.Checked = $false $script:configChanged = $false
$txtSteamUser.Text = "" $btnSave.BackColor = [System.Drawing.Color]::FromArgb(240, 240, 240)
$txtSteamPass.Text = ""
} }
function Save-Config { function Save-Config {
@@ -54,27 +72,62 @@ function Save-Config {
ServerPassword = $txtServerPassword.Text ServerPassword = $txtServerPassword.Text
AdminPassword = $txtAdminPassword.Text AdminPassword = $txtAdminPassword.Text
ServerName = $txtServerName.Text ServerName = $txtServerName.Text
UseLogin = $chkUseLogin.Checked
SteamUser = $txtSteamUser.Text
} }
$cfg | ConvertTo-Json | Out-File $configPath -Encoding UTF8 -Force $cfg | ConvertTo-Json | Out-File $configPath -Encoding UTF8 -Force
$script:configChanged = $false
$btnSave.BackColor = [System.Drawing.Color]::FromArgb(240, 240, 240)
Update-SteamCMDStatus
Update-GameDirStatus
}
function Mark-ConfigChanged {
if (-not $script:configChanged) {
$script:configChanged = $true
$btnSave.BackColor = [System.Drawing.Color]::LightBlue
}
} }
function Update-SteamCMDStatus { function Update-SteamCMDStatus {
$exe = "$($txtSteamCMDDir.Text)\steamcmd.exe" $exe = "$($txtSteamCMDDir.Text)\steamcmd.exe"
if (Test-Path $exe) { if (Test-Path $exe) {
$lblStatus.Text = "SteamCMD: Ready" $lblSteamCMDStatus.Text = "SteamCMD: Ready"
$lblStatus.ForeColor = "Green" $lblSteamCMDStatus.ForeColor = "Green"
$btnInstallSteamCMD.Enabled = $false $btnInstallSteamCMD.Enabled = $false
$btnInstallSteamCMD.Text = "SteamCMD Installed" $btnInstallSteamCMD.Text = "SteamCMD Installed"
} else { } else {
$lblStatus.Text = "SteamCMD: Not Found" $lblSteamCMDStatus.Text = "SteamCMD: Not Found"
$lblStatus.ForeColor = "Red" $lblSteamCMDStatus.ForeColor = "Red"
$btnInstallSteamCMD.Enabled = $true $btnInstallSteamCMD.Enabled = $true
$btnInstallSteamCMD.Text = "Install SteamCMD" $btnInstallSteamCMD.Text = "Install SteamCMD"
} }
} }
function Update-GameDirStatus {
$installDir = $txtInstallDir.Text
if (-not $installDir) {
$lblGameDirStatus.Text = "Game Directory: Not Set"
$lblGameDirStatus.ForeColor = "Red"
return
}
$serverExe = Join-Path $installDir "AbioticFactor\Binaries\Win64\AbioticFactorServer-Win64-Shipping.exe"
if (Test-Path $serverExe) {
$lblGameDirStatus.Text = "Game Directory: Ready"
$lblGameDirStatus.ForeColor = "Green"
} else {
$lblGameDirStatus.Text = "Game Directory: Not Found (Run Update Server)"
$lblGameDirStatus.ForeColor = "Red"
}
}
function Check-ServerSetupComplete {
$installDir = $txtInstallDir.Text
if (-not $installDir) { return $false }
$serverExe = Join-Path $installDir "AbioticFactor\Binaries\Win64\AbioticFactorServer-Win64-Shipping.exe"
return (Test-Path $serverExe)
}
function Install-SteamCMD { function Install-SteamCMD {
$path = $txtSteamCMDDir.Text $path = $txtSteamCMDDir.Text
if (-not $path) { return } if (-not $path) { return }
@@ -118,29 +171,47 @@ function Update-Server {
$scriptFile = [System.IO.Path]::GetTempFileName() + ".txt" $scriptFile = [System.IO.Path]::GetTempFileName() + ".txt"
$scriptContent = "force_install_dir `"$installDir`"`n" $scriptContent = "@ShutdownOnFailedCommand 0`n"
$scriptContent += "@NoPromptForPassword 1`n"
if ($chkUseLogin.Checked -and $txtSteamUser.Text) { $scriptContent += "force_install_dir `"$installDir`"`n"
$scriptContent += "login `"$($txtSteamUser.Text)`" `"$($txtSteamPass.Text)`"`n"
} else {
$scriptContent += "login anonymous`n" $scriptContent += "login anonymous`n"
} $scriptContent += "app_update $appId`n"
$scriptContent += "app_update $appId validate`n"
$scriptContent += "app_update $appId validate`nquit`n" $scriptContent += "quit`n"
$scriptContent | Out-File $scriptFile -Encoding ASCII $scriptContent | Out-File $scriptFile -Encoding ASCII
$batchFile = [System.IO.Path]::GetTempFileName() + ".bat" $steamCMDExe = "$($txtSteamCMDDir.Text)\steamcmd.exe"
$cmdContent = "@echo off`ncd /d `"$($txtSteamCMDDir.Text)`"`n`"$($txtSteamCMDDir.Text)\steamcmd.exe`" +runscript `"$scriptFile`"`necho Update complete`ntimeout /t 3 /nobreak > nul" $arguments = "+runscript `"$scriptFile`""
$cmdContent | Out-File $batchFile -Encoding ASCII
Start-Process "cmd.exe" -ArgumentList "/c `"$batchFile`"" -Wait -NoNewWindow Write-Host "Updating server. Please wait..."
Start-Sleep -Seconds 1 $process = Start-Process -FilePath $steamCMDExe -ArgumentList $arguments -Wait -PassThru -NoNewWindow
$process.WaitForExit()
Start-Sleep -Seconds 2
try {
Remove-Item $scriptFile -Force -ErrorAction SilentlyContinue Remove-Item $scriptFile -Force -ErrorAction SilentlyContinue
Remove-Item $batchFile -Force -ErrorAction SilentlyContinue } catch {}
Write-Host "Update complete!"
Update-GameDirStatus
[System.Windows.Forms.MessageBox]::Show("Server update completed!", "Success", "OK", "Information")
} }
function Start-Server { function Start-Server {
if ($script:configChanged) {
$result = [System.Windows.Forms.MessageBox]::Show("You have unsaved configuration changes.`n`nDo you want to save them before starting the server?", "Unsaved Changes", "YesNoCancel", "Question")
if ($result -eq "Cancel") {
return
}
if ($result -eq "Yes") {
Save-Config
}
}
$installDir = $txtInstallDir.Text $installDir = $txtInstallDir.Text
if (-not $installDir) { if (-not $installDir) {
[System.Windows.Forms.MessageBox]::Show("Please set Game Install Directory first!", "Error", "OK", "Error") [System.Windows.Forms.MessageBox]::Show("Please set Game Install Directory first!", "Error", "OK", "Error")
@@ -168,7 +239,7 @@ function Start-Server {
$btnStop.Enabled = $true $btnStop.Enabled = $true
$btnStart.Enabled = $false $btnStart.Enabled = $false
$btnUpdate.Enabled = $false $btnUpdate.Enabled = $false
$lblStatusValue.Text = "Server: RUNNING" $lblStatusValue.Text = "RUNNING"
$lblStatusValue.ForeColor = "Green" $lblStatusValue.ForeColor = "Green"
} catch { } catch {
[System.Windows.Forms.MessageBox]::Show("Failed to start server: $_", "Error", "OK", "Error") [System.Windows.Forms.MessageBox]::Show("Failed to start server: $_", "Error", "OK", "Error")
@@ -189,7 +260,7 @@ function Stop-Server {
$btnStop.Enabled = $false $btnStop.Enabled = $false
$btnStart.Enabled = $true $btnStart.Enabled = $true
$btnUpdate.Enabled = $true $btnUpdate.Enabled = $true
$lblStatusValue.Text = "Server: STOPPED" $lblStatusValue.Text = "STOPPED"
$lblStatusValue.ForeColor = "Red" $lblStatusValue.ForeColor = "Red"
} }
@@ -199,287 +270,624 @@ function Browse-Directory {
if ($dlg.ShowDialog() -eq "OK") { if ($dlg.ShowDialog() -eq "OK") {
$txtBox.Text = $dlg.SelectedPath $txtBox.Text = $dlg.SelectedPath
if ($txtBox.Name -eq "txtSteamCMDDir") { Update-SteamCMDStatus } if ($txtBox.Name -eq "txtSteamCMDDir") { Update-SteamCMDStatus }
Save-Config if ($txtBox.Name -eq "txtInstallDir") { Update-GameDirStatus }
Mark-ConfigChanged
}
}
function Show-Password {
param($txtBox)
if ($txtBox.PasswordChar -eq '*') {
$txtBox.PasswordChar = $null
} else {
$txtBox.PasswordChar = '*'
} }
} }
# Create Form # Create Form
$form = New-Object System.Windows.Forms.Form $form = New-Object System.Windows.Forms.Form
$form.Text = "Abiotic Factor Server Manager" $form.Text = "Abiotic Factor Server Manager"
$form.Size = New-Object System.Drawing.Size(850, 600) $form.Size = New-Object System.Drawing.Size(920, 780)
$form.StartPosition = "CenterScreen" $form.StartPosition = "CenterScreen"
$form.MinimumSize = New-Object System.Drawing.Size(920, 780)
$form.MaximumSize = New-Object System.Drawing.Size(920, 780)
$form.FormBorderStyle = "FixedDialog"
$form.MaximizeBox = $false
$stdButtonWidth = 120
$stdButtonHeight = 32
# Status Panel # Status Panel
$statusPanel = New-Object System.Windows.Forms.Panel $statusPanel = New-Object System.Windows.Forms.Panel
$statusPanel.BackColor = "Control" $statusPanel.BackColor = [System.Drawing.Color]::FromArgb(240, 240, 240)
$statusPanel.Location = New-Object System.Drawing.Point(0, 0) $statusPanel.Location = New-Object System.Drawing.Point(0, 0)
$statusPanel.Size = New-Object System.Drawing.Size(850, 80) $statusPanel.Size = New-Object System.Drawing.Size(920, 100)
$statusPanel.BorderStyle = "FixedSingle" $statusPanel.BorderStyle = "FixedSingle"
# Logo/Image Area with embedded image
$logoBox = New-Object System.Windows.Forms.PictureBox
$logoBox.Location = New-Object System.Drawing.Point(15, 15)
$logoBox.Size = New-Object System.Drawing.Size(70, 70)
$logoBox.Width = 70
$logoBox.Height = 70
$logoBox.BackColor = [System.Drawing.Color]::Transparent
$logoBox.BorderStyle = "None"
$logoBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::Zoom
# Embedded image (replace YOUR_BASE64_STRING_HERE with your actual base64 string)
$base64String = "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"
if ($base64String) {
$imageBytes = [System.Convert]::FromBase64String($base64String)
$ms = New-Object System.IO.MemoryStream($imageBytes, 0, $imageBytes.Length)
$ms.Write($imageBytes, 0, $imageBytes.Length)
$logoBox.Image = [System.Drawing.Image]::FromStream($ms)
$ms.Close()
}
$statusPanel.Controls.Add($logoBox)
$lblStatusLabel = New-Object System.Windows.Forms.Label
$lblStatusLabel.Text = "Server Status:"
$lblStatusLabel.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold)
$lblStatusLabel.Location = New-Object System.Drawing.Point(100, 15)
$lblStatusLabel.Size = New-Object System.Drawing.Size(100, 20)
$statusPanel.Controls.Add($lblStatusLabel)
$lblStatusValue = New-Object System.Windows.Forms.Label $lblStatusValue = New-Object System.Windows.Forms.Label
$lblStatusValue.Text = "Server: STOPPED" $lblStatusValue.Text = "STOPPED"
$lblStatusValue.ForeColor = "Red" $lblStatusValue.ForeColor = "Red"
$lblStatusValue.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 10, [System.Drawing.FontStyle]::Bold) $lblStatusValue.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold)
$lblStatusValue.Location = New-Object System.Drawing.Point(10, 10) $lblStatusValue.Location = New-Object System.Drawing.Point(200, 15)
$lblStatusValue.Size = New-Object System.Drawing.Size(200, 25) $lblStatusValue.Size = New-Object System.Drawing.Size(100, 20)
$statusPanel.Controls.Add($lblStatusValue) $statusPanel.Controls.Add($lblStatusValue)
$lblPortValue = New-Object System.Windows.Forms.Label $lblServerNameLabel = New-Object System.Windows.Forms.Label
$lblPortValue.Text = "Port: 7777" $lblServerNameLabel.Text = "Server Name:"
$lblPortValue.Location = New-Object System.Drawing.Point(10, 35) $lblServerNameLabel.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblPortValue.Size = New-Object System.Drawing.Size(200, 20) $lblServerNameLabel.Location = New-Object System.Drawing.Point(100, 40)
$statusPanel.Controls.Add($lblPortValue) $lblServerNameLabel.Size = New-Object System.Drawing.Size(80, 18)
$statusPanel.Controls.Add($lblServerNameLabel)
$lblServerNameValue = New-Object System.Windows.Forms.Label $lblServerNameValue = New-Object System.Windows.Forms.Label
$lblServerNameValue.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 9, [System.Drawing.FontStyle]::Bold) $lblServerNameValue.Font = New-Object System.Drawing.Font("Segoe UI", 8, [System.Drawing.FontStyle]::Bold)
$lblServerNameValue.Location = New-Object System.Drawing.Point(250, 10) $lblServerNameValue.Location = New-Object System.Drawing.Point(180, 40)
$lblServerNameValue.Size = New-Object System.Drawing.Size(400, 25) $lblServerNameValue.Size = New-Object System.Drawing.Size(400, 18)
$lblServerNameValue.AutoEllipsis = $true
$statusPanel.Controls.Add($lblServerNameValue) $statusPanel.Controls.Add($lblServerNameValue)
$lblPortLabel = New-Object System.Windows.Forms.Label
$lblPortLabel.Text = "Game Port:"
$lblPortLabel.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblPortLabel.Location = New-Object System.Drawing.Point(100, 63)
$lblPortLabel.Size = New-Object System.Drawing.Size(70, 18)
$statusPanel.Controls.Add($lblPortLabel)
$lblPortValue = New-Object System.Windows.Forms.Label
$lblPortValue.Text = "7777"
$lblPortValue.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblPortValue.Location = New-Object System.Drawing.Point(170, 63)
$lblPortValue.Size = New-Object System.Drawing.Size(60, 18)
$statusPanel.Controls.Add($lblPortValue)
$lblPasswordLabel = New-Object System.Windows.Forms.Label
$lblPasswordLabel.Text = "Password:"
$lblPasswordLabel.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblPasswordLabel.Location = New-Object System.Drawing.Point(250, 63)
$lblPasswordLabel.Size = New-Object System.Drawing.Size(65, 18)
$statusPanel.Controls.Add($lblPasswordLabel)
$lblPasswordValue = New-Object System.Windows.Forms.Label $lblPasswordValue = New-Object System.Windows.Forms.Label
$lblPasswordValue.Location = New-Object System.Drawing.Point(250, 35) $lblPasswordValue.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblPasswordValue.Size = New-Object System.Drawing.Size(200, 20) $lblPasswordValue.Location = New-Object System.Drawing.Point(315, 63)
$lblPasswordValue.Size = New-Object System.Drawing.Size(80, 18)
$statusPanel.Controls.Add($lblPasswordValue) $statusPanel.Controls.Add($lblPasswordValue)
$lblLocalLabel = New-Object System.Windows.Forms.Label
$lblLocalLabel.Text = "Local IP:"
$lblLocalLabel.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblLocalLabel.Location = New-Object System.Drawing.Point(590, 15)
$lblLocalLabel.Size = New-Object System.Drawing.Size(60, 18)
$statusPanel.Controls.Add($lblLocalLabel)
$lblLocalValue = New-Object System.Windows.Forms.Label
$lblLocalValue.Text = (Get-LocalIP)
$lblLocalValue.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblLocalValue.Location = New-Object System.Drawing.Point(650, 15)
$lblLocalValue.Size = New-Object System.Drawing.Size(230, 18)
$statusPanel.Controls.Add($lblLocalValue)
$lblWANLabel = New-Object System.Windows.Forms.Label
$lblWANLabel.Text = "WAN IP:"
$lblWANLabel.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblWANLabel.Location = New-Object System.Drawing.Point(590, 40)
$lblWANLabel.Size = New-Object System.Drawing.Size(60, 18)
$statusPanel.Controls.Add($lblWANLabel)
$lblWANValue = New-Object System.Windows.Forms.Label
$lblWANValue.Text = (Get-PublicIP)
$lblWANValue.Font = New-Object System.Drawing.Font("Segoe UI", 8)
$lblWANValue.Location = New-Object System.Drawing.Point(650, 40)
$lblWANValue.Size = New-Object System.Drawing.Size(230, 18)
$statusPanel.Controls.Add($lblWANValue)
$form.Controls.Add($statusPanel) $form.Controls.Add($statusPanel)
# Button Panel # Server Controls GroupBox
$buttonPanel = New-Object System.Windows.Forms.Panel $controlsGroup = New-Object System.Windows.Forms.GroupBox
$buttonPanel.Location = New-Object System.Drawing.Point(0, 85) $controlsGroup.Text = "Server Controls"
$buttonPanel.Size = New-Object System.Drawing.Size(850, 45) $controlsGroup.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold)
$form.Controls.Add($buttonPanel) $controlsGroup.Location = New-Object System.Drawing.Point(15, 110)
$controlsGroup.Size = New-Object System.Drawing.Size(880, 70)
$btnUpdate = New-Object System.Windows.Forms.Button $form.Controls.Add($controlsGroup)
$btnUpdate.Text = "1. Update"
$btnUpdate.Size = New-Object System.Drawing.Size(100, 35)
$btnUpdate.Location = New-Object System.Drawing.Point(10, 5)
$btnUpdate.Add_Click({ Update-Server })
$buttonPanel.Controls.Add($btnUpdate)
$btnStart = New-Object System.Windows.Forms.Button
$btnStart.Text = "2. Start"
$btnStart.Size = New-Object System.Drawing.Size(100, 35)
$btnStart.Location = New-Object System.Drawing.Point(120, 5)
$btnStart.BackColor = "LightGreen"
$btnStart.Add_Click({ Start-Server })
$buttonPanel.Controls.Add($btnStart)
$btnStop = New-Object System.Windows.Forms.Button
$btnStop.Text = "3. Stop"
$btnStop.Size = New-Object System.Drawing.Size(100, 35)
$btnStop.Location = New-Object System.Drawing.Point(230, 5)
$btnStop.BackColor = "LightCoral"
$btnStop.Enabled = $false
$btnStop.Add_Click({ Stop-Server })
$buttonPanel.Controls.Add($btnStop)
$btnSave = New-Object System.Windows.Forms.Button $btnSave = New-Object System.Windows.Forms.Button
$btnSave.Text = "Save Config" $btnSave.Text = "Save Config"
$btnSave.Size = New-Object System.Drawing.Size(80, 35) $btnSave.Size = New-Object System.Drawing.Size($stdButtonWidth, $stdButtonHeight)
$btnSave.Location = New-Object System.Drawing.Point(340, 5) $btnSave.Location = New-Object System.Drawing.Point(20, 25)
$btnSave.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnSave.Add_Click({ Save-Config }) $btnSave.Add_Click({ Save-Config })
$buttonPanel.Controls.Add($btnSave) $controlsGroup.Controls.Add($btnSave)
$btnUpdate = New-Object System.Windows.Forms.Button
$btnUpdate.Text = "Update Server"
$btnUpdate.Size = New-Object System.Drawing.Size($stdButtonWidth, $stdButtonHeight)
$btnUpdate.Location = New-Object System.Drawing.Point(155, 25)
$btnUpdate.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnUpdate.Add_Click({ Update-Server })
$controlsGroup.Controls.Add($btnUpdate)
$btnStart = New-Object System.Windows.Forms.Button
$btnStart.Text = "Start Server"
$btnStart.Size = New-Object System.Drawing.Size($stdButtonWidth, $stdButtonHeight)
$btnStart.Location = New-Object System.Drawing.Point(290, 25)
$btnStart.BackColor = [System.Drawing.Color]::LightGreen
$btnStart.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnStart.Add_Click({ Start-Server })
$controlsGroup.Controls.Add($btnStart)
$btnStop = New-Object System.Windows.Forms.Button
$btnStop.Text = "Stop Server"
$btnStop.Size = New-Object System.Drawing.Size($stdButtonWidth, $stdButtonHeight)
$btnStop.Location = New-Object System.Drawing.Point(425, 25)
$btnStop.BackColor = [System.Drawing.Color]::LightCoral
$btnStop.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnStop.Enabled = $false
$btnStop.Add_Click({ Stop-Server })
$controlsGroup.Controls.Add($btnStop)
# Settings Panel # Settings Panel
$settingsPanel = New-Object System.Windows.Forms.Panel $settingsPanel = New-Object System.Windows.Forms.Panel
$settingsPanel.Location = New-Object System.Drawing.Point(0, 135) $settingsPanel.Location = New-Object System.Drawing.Point(15, 190)
$settingsPanel.Size = New-Object System.Drawing.Size(850, 450) $settingsPanel.Size = New-Object System.Drawing.Size(880, 540)
$settingsPanel.AutoScroll = $true $settingsPanel.AutoScroll = $true
$form.Controls.Add($settingsPanel) $form.Controls.Add($settingsPanel)
# SteamCMD # SteamCMD Group
$steamCMDGroup = New-Object System.Windows.Forms.GroupBox
$steamCMDGroup.Text = "SteamCMD Configuration"
$steamCMDGroup.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold)
$steamCMDGroup.Location = New-Object System.Drawing.Point(5, 5)
$steamCMDGroup.Size = New-Object System.Drawing.Size(855, 90)
$settingsPanel.Controls.Add($steamCMDGroup)
$lbl1 = New-Object System.Windows.Forms.Label $lbl1 = New-Object System.Windows.Forms.Label
$lbl1.Text = "SteamCMD Dir:" $lbl1.Text = "SteamCMD Directory:"
$lbl1.Location = New-Object System.Drawing.Point(10, 10) $lbl1.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lbl1.Size = New-Object System.Drawing.Size(100, 25) $lbl1.Location = New-Object System.Drawing.Point(15, 30)
$settingsPanel.Controls.Add($lbl1) $lbl1.Size = New-Object System.Drawing.Size(135, 22)
$steamCMDGroup.Controls.Add($lbl1)
$txtSteamCMDDir = New-Object System.Windows.Forms.TextBox $txtSteamCMDDir = New-Object System.Windows.Forms.TextBox
$txtSteamCMDDir.Location = New-Object System.Drawing.Point(120, 8) $txtSteamCMDDir.Location = New-Object System.Drawing.Point(155, 28)
$txtSteamCMDDir.Size = New-Object System.Drawing.Size(500, 25) $txtSteamCMDDir.Size = New-Object System.Drawing.Size(450, 23)
$settingsPanel.Controls.Add($txtSteamCMDDir) $txtSteamCMDDir.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$txtSteamCMDDir.Name = "txtSteamCMDDir"
$steamCMDGroup.Controls.Add($txtSteamCMDDir)
$btnBrowse1 = New-Object System.Windows.Forms.Button $btnBrowse1 = New-Object System.Windows.Forms.Button
$btnBrowse1.Text = "Browse" $btnBrowse1.Text = "Browse"
$btnBrowse1.Location = New-Object System.Drawing.Point(630, 7) $btnBrowse1.Location = New-Object System.Drawing.Point(615, 27)
$btnBrowse1.Size = New-Object System.Drawing.Size(70, 27) $btnBrowse1.Size = New-Object System.Drawing.Size(90, 26)
$btnBrowse1.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnBrowse1.Add_Click({ Browse-Directory $txtSteamCMDDir }) $btnBrowse1.Add_Click({ Browse-Directory $txtSteamCMDDir })
$settingsPanel.Controls.Add($btnBrowse1) $steamCMDGroup.Controls.Add($btnBrowse1)
$btnInstallSteamCMD = New-Object System.Windows.Forms.Button $btnInstallSteamCMD = New-Object System.Windows.Forms.Button
$btnInstallSteamCMD.Location = New-Object System.Drawing.Point(710, 7) $btnInstallSteamCMD.Location = New-Object System.Drawing.Point(715, 27)
$btnInstallSteamCMD.Size = New-Object System.Drawing.Size(100, 27) $btnInstallSteamCMD.Size = New-Object System.Drawing.Size(125, 26)
$btnInstallSteamCMD.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnInstallSteamCMD.Add_Click({ Install-SteamCMD }) $btnInstallSteamCMD.Add_Click({ Install-SteamCMD })
$settingsPanel.Controls.Add($btnInstallSteamCMD) $steamCMDGroup.Controls.Add($btnInstallSteamCMD)
$lblStatus = New-Object System.Windows.Forms.Label $lblSteamCMDStatus = New-Object System.Windows.Forms.Label
$lblStatus.Location = New-Object System.Drawing.Point(120, 40) $lblSteamCMDStatus.Location = New-Object System.Drawing.Point(155, 60)
$lblStatus.Size = New-Object System.Drawing.Size(300, 25) $lblSteamCMDStatus.Size = New-Object System.Drawing.Size(450, 20)
$settingsPanel.Controls.Add($lblStatus) $lblSteamCMDStatus.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$steamCMDGroup.Controls.Add($lblSteamCMDStatus)
# Install Dir Group
$installGroup = New-Object System.Windows.Forms.GroupBox
$installGroup.Text = "Game Installation"
$installGroup.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold)
$installGroup.Location = New-Object System.Drawing.Point(5, 105)
$installGroup.Size = New-Object System.Drawing.Size(855, 90)
$settingsPanel.Controls.Add($installGroup)
# Install Dir
$lbl2 = New-Object System.Windows.Forms.Label $lbl2 = New-Object System.Windows.Forms.Label
$lbl2.Text = "Game Install Dir:" $lbl2.Text = "Game Install Directory:"
$lbl2.Location = New-Object System.Drawing.Point(10, 75) $lbl2.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lbl2.Size = New-Object System.Drawing.Size(100, 25) $lbl2.Location = New-Object System.Drawing.Point(15, 30)
$settingsPanel.Controls.Add($lbl2) $lbl2.Size = New-Object System.Drawing.Size(135, 22)
$installGroup.Controls.Add($lbl2)
$txtInstallDir = New-Object System.Windows.Forms.TextBox $txtInstallDir = New-Object System.Windows.Forms.TextBox
$txtInstallDir.Location = New-Object System.Drawing.Point(120, 73) $txtInstallDir.Location = New-Object System.Drawing.Point(155, 28)
$txtInstallDir.Size = New-Object System.Drawing.Size(600, 25) $txtInstallDir.Size = New-Object System.Drawing.Size(540, 23)
$settingsPanel.Controls.Add($txtInstallDir) $txtInstallDir.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$installGroup.Controls.Add($txtInstallDir)
$btnBrowse2 = New-Object System.Windows.Forms.Button $btnBrowse2 = New-Object System.Windows.Forms.Button
$btnBrowse2.Text = "Browse" $btnBrowse2.Text = "Browse"
$btnBrowse2.Location = New-Object System.Drawing.Point(730, 72) $btnBrowse2.Location = New-Object System.Drawing.Point(705, 27)
$btnBrowse2.Size = New-Object System.Drawing.Size(70, 27) $btnBrowse2.Size = New-Object System.Drawing.Size(90, 26)
$btnBrowse2.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnBrowse2.Add_Click({ Browse-Directory $txtInstallDir }) $btnBrowse2.Add_Click({ Browse-Directory $txtInstallDir })
$settingsPanel.Controls.Add($btnBrowse2) $installGroup.Controls.Add($btnBrowse2)
# Steam Login $lblGameDirStatus = New-Object System.Windows.Forms.Label
$loginGroup = New-Object System.Windows.Forms.GroupBox $lblGameDirStatus.Location = New-Object System.Drawing.Point(155, 60)
$loginGroup.Text = "Steam Login (optional)" $lblGameDirStatus.Size = New-Object System.Drawing.Size(540, 20)
$loginGroup.Location = New-Object System.Drawing.Point(10, 115) $lblGameDirStatus.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$loginGroup.Size = New-Object System.Drawing.Size(800, 80) $installGroup.Controls.Add($lblGameDirStatus)
$settingsPanel.Controls.Add($loginGroup)
$chkUseLogin = New-Object System.Windows.Forms.CheckBox # Server Settings Group
$chkUseLogin.Text = "Use Login"
$chkUseLogin.Location = New-Object System.Drawing.Point(10, 20)
$chkUseLogin.Size = New-Object System.Drawing.Size(80, 25)
$chkUseLogin.Add_CheckStateChanged({
$txtSteamUser.Enabled = $chkUseLogin.Checked
$txtSteamPass.Enabled = $chkUseLogin.Checked
})
$loginGroup.Controls.Add($chkUseLogin)
$lblUser = New-Object System.Windows.Forms.Label
$lblUser.Text = "Username:"
$lblUser.Location = New-Object System.Drawing.Point(100, 23)
$lblUser.Size = New-Object System.Drawing.Size(70, 20)
$loginGroup.Controls.Add($lblUser)
$txtSteamUser = New-Object System.Windows.Forms.TextBox
$txtSteamUser.Location = New-Object System.Drawing.Point(175, 20)
$txtSteamUser.Size = New-Object System.Drawing.Size(150, 25)
$txtSteamUser.Enabled = $false
$loginGroup.Controls.Add($txtSteamUser)
$lblPass = New-Object System.Windows.Forms.Label
$lblPass.Text = "Password:"
$lblPass.Location = New-Object System.Drawing.Point(340, 23)
$lblPass.Size = New-Object System.Drawing.Size(70, 20)
$loginGroup.Controls.Add($lblPass)
$txtSteamPass = New-Object System.Windows.Forms.TextBox
$txtSteamPass.Location = New-Object System.Drawing.Point(415, 20)
$txtSteamPass.Size = New-Object System.Drawing.Size(150, 25)
$txtSteamPass.PasswordChar = '*'
$txtSteamPass.Enabled = $false
$loginGroup.Controls.Add($txtSteamPass)
# Server Config
$serverGroup = New-Object System.Windows.Forms.GroupBox $serverGroup = New-Object System.Windows.Forms.GroupBox
$serverGroup.Text = "Server Settings" $serverGroup.Text = "Server Settings"
$serverGroup.Location = New-Object System.Drawing.Point(10, 210) $serverGroup.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold)
$serverGroup.Size = New-Object System.Drawing.Size(800, 160) $serverGroup.Location = New-Object System.Drawing.Point(5, 205)
$serverGroup.Size = New-Object System.Drawing.Size(855, 185)
$settingsPanel.Controls.Add($serverGroup) $settingsPanel.Controls.Add($serverGroup)
$lblMax = New-Object System.Windows.Forms.Label $lblMax = New-Object System.Windows.Forms.Label
$lblMax.Text = "Max Players:" $lblMax.Text = "Max Players:"
$lblMax.Location = New-Object System.Drawing.Point(15, 25) $lblMax.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lblMax.Size = New-Object System.Drawing.Size(85, 25) $lblMax.Location = New-Object System.Drawing.Point(15, 32)
$lblMax.Size = New-Object System.Drawing.Size(90, 22)
$serverGroup.Controls.Add($lblMax) $serverGroup.Controls.Add($lblMax)
$txtMaxPlayers = New-Object System.Windows.Forms.TextBox $txtMaxPlayers = New-Object System.Windows.Forms.TextBox
$txtMaxPlayers.Location = New-Object System.Drawing.Point(105, 23) $txtMaxPlayers.Location = New-Object System.Drawing.Point(110, 30)
$txtMaxPlayers.Size = New-Object System.Drawing.Size(80, 25) $txtMaxPlayers.Size = New-Object System.Drawing.Size(100, 23)
$txtMaxPlayers.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$serverGroup.Controls.Add($txtMaxPlayers) $serverGroup.Controls.Add($txtMaxPlayers)
$lblPort = New-Object System.Windows.Forms.Label $lblPort = New-Object System.Windows.Forms.Label
$lblPort.Text = "Game Port:" $lblPort.Text = "Game Port:"
$lblPort.Location = New-Object System.Drawing.Point(220, 25) $lblPort.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lblPort.Size = New-Object System.Drawing.Size(70, 25) $lblPort.Location = New-Object System.Drawing.Point(235, 32)
$lblPort.Size = New-Object System.Drawing.Size(80, 22)
$serverGroup.Controls.Add($lblPort) $serverGroup.Controls.Add($lblPort)
$txtPort = New-Object System.Windows.Forms.TextBox $txtPort = New-Object System.Windows.Forms.TextBox
$txtPort.Location = New-Object System.Drawing.Point(295, 23) $txtPort.Location = New-Object System.Drawing.Point(320, 30)
$txtPort.Size = New-Object System.Drawing.Size(80, 25) $txtPort.Size = New-Object System.Drawing.Size(100, 23)
$txtPort.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$serverGroup.Controls.Add($txtPort) $serverGroup.Controls.Add($txtPort)
$lblQuery = New-Object System.Windows.Forms.Label $lblQuery = New-Object System.Windows.Forms.Label
$lblQuery.Text = "Query Port:" $lblQuery.Text = "Query Port:"
$lblQuery.Location = New-Object System.Drawing.Point(410, 25) $lblQuery.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lblQuery.Size = New-Object System.Drawing.Size(80, 25) $lblQuery.Location = New-Object System.Drawing.Point(445, 32)
$lblQuery.Size = New-Object System.Drawing.Size(85, 22)
$serverGroup.Controls.Add($lblQuery) $serverGroup.Controls.Add($lblQuery)
$txtQueryPort = New-Object System.Windows.Forms.TextBox $txtQueryPort = New-Object System.Windows.Forms.TextBox
$txtQueryPort.Location = New-Object System.Drawing.Point(495, 23) $txtQueryPort.Location = New-Object System.Drawing.Point(535, 30)
$txtQueryPort.Size = New-Object System.Drawing.Size(80, 25) $txtQueryPort.Size = New-Object System.Drawing.Size(100, 23)
$txtQueryPort.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$serverGroup.Controls.Add($txtQueryPort) $serverGroup.Controls.Add($txtQueryPort)
$lblPassServer = New-Object System.Windows.Forms.Label $lblPassServer = New-Object System.Windows.Forms.Label
$lblPassServer.Text = "Server PW:" $lblPassServer.Text = "Server Password:"
$lblPassServer.Location = New-Object System.Drawing.Point(15, 60) $lblPassServer.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lblPassServer.Size = New-Object System.Drawing.Size(85, 25) $lblPassServer.Location = New-Object System.Drawing.Point(15, 75)
$lblPassServer.Size = New-Object System.Drawing.Size(115, 22)
$serverGroup.Controls.Add($lblPassServer) $serverGroup.Controls.Add($lblPassServer)
$txtServerPassword = New-Object System.Windows.Forms.TextBox $txtServerPassword = New-Object System.Windows.Forms.TextBox
$txtServerPassword.Location = New-Object System.Drawing.Point(105, 58) $txtServerPassword.Location = New-Object System.Drawing.Point(135, 73)
$txtServerPassword.Size = New-Object System.Drawing.Size(150, 25) $txtServerPassword.Size = New-Object System.Drawing.Size(200, 23)
$txtServerPassword.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$txtServerPassword.PasswordChar = '*'
$serverGroup.Controls.Add($txtServerPassword) $serverGroup.Controls.Add($txtServerPassword)
$btnViewServerPass = New-Object System.Windows.Forms.Button
$btnViewServerPass.Text = "V"
$btnViewServerPass.Location = New-Object System.Drawing.Point(340, 72)
$btnViewServerPass.Size = New-Object System.Drawing.Size(30, 25)
$btnViewServerPass.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnViewServerPass.Add_Click({ Show-Password $txtServerPassword })
$serverGroup.Controls.Add($btnViewServerPass)
$lblAdmin = New-Object System.Windows.Forms.Label $lblAdmin = New-Object System.Windows.Forms.Label
$lblAdmin.Text = "Admin PW:" $lblAdmin.Text = "Admin Password:"
$lblAdmin.Location = New-Object System.Drawing.Point(280, 60) $lblAdmin.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lblAdmin.Size = New-Object System.Drawing.Size(85, 25) $lblAdmin.Location = New-Object System.Drawing.Point(410, 75)
$lblAdmin.Size = New-Object System.Drawing.Size(120, 22)
$serverGroup.Controls.Add($lblAdmin) $serverGroup.Controls.Add($lblAdmin)
$txtAdminPassword = New-Object System.Windows.Forms.TextBox $txtAdminPassword = New-Object System.Windows.Forms.TextBox
$txtAdminPassword.Location = New-Object System.Drawing.Point(370, 58) $txtAdminPassword.Location = New-Object System.Drawing.Point(535, 73)
$txtAdminPassword.Size = New-Object System.Drawing.Size(150, 25) $txtAdminPassword.Size = New-Object System.Drawing.Size(200, 23)
$txtAdminPassword.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$txtAdminPassword.PasswordChar = '*'
$serverGroup.Controls.Add($txtAdminPassword) $serverGroup.Controls.Add($txtAdminPassword)
$btnViewAdminPass = New-Object System.Windows.Forms.Button
$btnViewAdminPass.Text = "V"
$btnViewAdminPass.Location = New-Object System.Drawing.Point(740, 72)
$btnViewAdminPass.Size = New-Object System.Drawing.Size(30, 25)
$btnViewAdminPass.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$btnViewAdminPass.Add_Click({ Show-Password $txtAdminPassword })
$serverGroup.Controls.Add($btnViewAdminPass)
$lblName = New-Object System.Windows.Forms.Label $lblName = New-Object System.Windows.Forms.Label
$lblName.Text = "Server Name:" $lblName.Text = "Server Name:"
$lblName.Location = New-Object System.Drawing.Point(15, 95) $lblName.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$lblName.Size = New-Object System.Drawing.Size(85, 25) $lblName.Location = New-Object System.Drawing.Point(15, 118)
$lblName.Size = New-Object System.Drawing.Size(115, 22)
$serverGroup.Controls.Add($lblName) $serverGroup.Controls.Add($lblName)
$txtServerName = New-Object System.Windows.Forms.TextBox $txtServerName = New-Object System.Windows.Forms.TextBox
$txtServerName.Location = New-Object System.Drawing.Point(105, 93) $txtServerName.Location = New-Object System.Drawing.Point(135, 116)
$txtServerName.Size = New-Object System.Drawing.Size(350, 25) $txtServerName.Size = New-Object System.Drawing.Size(650, 23)
$txtServerName.Font = New-Object System.Drawing.Font("Segoe UI", 9)
$serverGroup.Controls.Add($txtServerName) $serverGroup.Controls.Add($txtServerName)
# Event handlers # Event handlers
$txtPort.Add_TextChanged({ $txtPort.Add_TextChanged({
$lblPortValue.Text = "Port: $($txtPort.Text)" $lblPortValue.Text = $txtPort.Text
Save-Config Mark-ConfigChanged
}) })
$txtServerName.Add_TextChanged({ $txtServerName.Add_TextChanged({
$lblServerNameValue.Text = $txtServerName.Text $lblServerNameValue.Text = $txtServerName.Text
Save-Config Mark-ConfigChanged
}) })
$txtServerPassword.Add_TextChanged({ $txtServerPassword.Add_TextChanged({
if ($txtServerPassword.Text) { if ($txtServerPassword.Text) {
$lblPasswordValue.Text = "PW: Set" $lblPasswordValue.Text = "Set"
$lblPasswordValue.ForeColor = "Green"
} else { } else {
$lblPasswordValue.Text = "PW: None" $lblPasswordValue.Text = "None"
$lblPasswordValue.ForeColor = "Gray"
} }
Save-Config Mark-ConfigChanged
}) })
$txtMaxPlayers.Add_TextChanged({ Save-Config }) $txtMaxPlayers.Add_TextChanged({ Mark-ConfigChanged })
$txtQueryPort.Add_TextChanged({ Save-Config }) $txtQueryPort.Add_TextChanged({ Mark-ConfigChanged })
$txtAdminPassword.Add_TextChanged({ Save-Config }) $txtAdminPassword.Add_TextChanged({ Mark-ConfigChanged })
$txtSteamCMDDir.Add_TextChanged({
Mark-ConfigChanged
Update-SteamCMDStatus
})
$txtInstallDir.Add_TextChanged({
Mark-ConfigChanged
Update-GameDirStatus
})
# Initialize display values # Initialize display values
$lblPortValue.Text = "Port: $($txtPort.Text)" $lblPortValue.Text = "7777"
$lblServerNameValue.Text = $txtServerName.Text $lblServerNameValue.Text = "My Abiotic Factor Server"
$lblPasswordValue.Text = "PW: None" $lblPasswordValue.Text = "None"
$lblPasswordValue.ForeColor = "Gray"
# Load config and show # Load config and check setup
Load-Config Load-Config
# Check for missing directories and show helpful startup popup if needed
$steamCMDMissing = [string]::IsNullOrWhiteSpace($txtSteamCMDDir.Text) -or -not (Test-Path "$($txtSteamCMDDir.Text)\steamcmd.exe")
$gameDirMissing = [string]::IsNullOrWhiteSpace($txtInstallDir.Text) -or -not (Check-ServerSetupComplete)
if ($steamCMDMissing -or $gameDirMissing) {
$message = "Welcome to Abiotic Factor Server Manager!`n`nTo get your server running, please follow these simple steps:"
$message += "`n`n1. Set SteamCMD Directory (where steamcmd.exe will be installed)"
$message += "`n2. Click 'Install SteamCMD' to download SteamCMD"
$message += "`n3. Set Game Install Directory (where the server will be installed)"
$message += "`n4. Click 'Update Server' to download the game server files"
$message += "`n5. Configure your server settings (name, passwords, ports)"
$message += "`n6. Click 'Save Config' to save your settings"
$message += "`n7. Click 'Start Server' to launch your server!`n"
$message += "`nNote: You can also browse to existing directories if you already have them."
[System.Windows.Forms.MessageBox]::Show($message, "Setup Required", "OK", "Information")
}
# Silently check server setup - updates UI status without popup
$null = Check-ServerSetupComplete
$form.ShowDialog() $form.ShowDialog()