windows: find the Steam error box among all server windows, up to 3 starts

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
esefandClaude Opus 5.5 committed 2026-10-15 21:15:20 +03:00
1 parent 1cf0032927
commit 7d8aa4a029
1 file changed
+30 -8
+30 -8
View File
@@ -334,31 +334,53 @@ function Start-CsServer($root) {
$y = $y -replace '(?m)^yb_difficulty ".*"', ('yb_difficulty "' + [int]$s.CS_BOT_DIFFICULTY + '"')
Write-TextFile $ycfg $y
$hargs = "-console -condebug -game cstrike -port $([int]$s.CS_PORT) +maxplayers $([int]$s.CS_MAXPLAYERS) +map $($s.CS_MAP) +log on"
# On the very first start after an install, the server's Steam part sets itself up (appcache,
# config) and the server stops with a "Fatal error: Unable to initialize Steam" box. The next
# start works, so that one case gets a second try.
for ($try = 1; $try -le 2; $try++) {
# On the first start after an install, the server's Steam part sets itself up and the server
# stops with a "Fatal error: Unable to initialize Steam" box. A new start works, so that box
# gets the server closed and started again.
for ($try = 1; $try -le 3; $try++) {
$p = Start-Process -FilePath (Join-Path $h 'hlds.exe') -WorkingDirectory $h -ArgumentList $hargs -PassThru
if (-not (Test-SteamFailure $p ([int]$s.CS_PORT))) { break }
Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue
if ($try -eq 1) { Write-Host ' (first start: Steam needed a second try)' }
Start-Sleep -Seconds 2
Write-Host " (Steam wasn't ready yet, starting again)"
}
return $true
}
# Waits up to 40 s for the server to answer or to show the "Unable to initialize Steam" box.
# Waits up to 40 s for the server to answer or to show its "Fatal error" box.
# Returns $true for that box.
function Test-SteamFailure($p, [int]$port) {
$end = (Get-Date).AddSeconds(40)
while ((Get-Date) -lt $end -and -not $p.HasExited) {
if (Get-A2SInfo '127.0.0.1' $port 1000) { return $false }
$p.Refresh()
if ($p.MainWindowTitle -like 'Fatal error*') { return $true }
if (@(Get-ProcessWindowTitles $p.Id | Where-Object { $_ -like 'Fatal error*' }).Count) { return $true }
Start-Sleep -Milliseconds 500
}
return $false
}
# Titles of all top-level windows of a process (the error box is not always its main window)
function Get-ProcessWindowTitles([int]$processId) {
if (-not ('Cs16Win' -as [type])) {
Add-Type @'
using System; using System.Text; using System.Collections.Generic; using System.Runtime.InteropServices;
public static class Cs16Win {
delegate bool EnumProc(IntPtr h, IntPtr l);
[DllImport("user32.dll")] static extern bool EnumWindows(EnumProc f, IntPtr l);
[DllImport("user32.dll")] static extern int GetWindowThreadProcessId(IntPtr h, out int pid);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int GetWindowText(IntPtr h, StringBuilder s, int n);
public static string[] Titles(int want) {
var r = new List<string>();
EnumWindows((h, l) => { int pid; GetWindowThreadProcessId(h, out pid);
if (pid == want) { var t = new StringBuilder(256); GetWindowText(h, t, 256); r.Add(t.ToString()); } return true; }, IntPtr.Zero);
return r.ToArray();
}
}
'@
}
[Cs16Win]::Titles($processId)
}
# An earlier version (2026-10-15) hid this Steam setting while starting the server; this puts it
# back if a start was interrupted then. Harmless otherwise.
$Script:SteamKey = 'HKCU:\Software\Valve\Steam\ActiveProcess'