openvibers/source.openvibe.games Commits

Bootstrap Source SDK for Windows DLL workflow

CO Copilot committed 29 Jun 2026 · f093078cbc · 6 files, +216 −78


Changes

ddiff --git a/.github/workflows/windows-source-sdk-dlls.yml b/.github/workflows/windows-source-sdk-dlls.yml
iindex b8be370..1d7af85 100644
---- a/.github/workflows/windows-source-sdk-dlls.yml
++++ b/.github/workflows/windows-source-sdk-dlls.yml
@@@ -12,6 +12,7 @@ on:
- codex/openvibe-next-steps
paths:
- ".github/workflows/windows-source-sdk-dlls.yml"
++ - "tools/bootstrap-source-sdk-2013-windows.ps1"
- "tools/build-sdk-windows.ps1"
- "tools/build-quickjs-lib-windows.ps1"
- "tools/apply-openvibe-sdk.sh"
@@@ -48,15 +49,21 @@ jobs:
- name: Show toolchain and tree
run: |
$ErrorActionPreference = 'Continue'
++ New-Item -ItemType Directory -Force -Path artifacts/windows-build-debug | Out-Null
Write-Host "pwd=$(Get-Location)"
git rev-parse --short HEAD
where.exe msbuild
where.exe cl
where.exe link
where.exe bash
-- Get-ChildItem -Force | Select-Object Mode,Length,Name
-- if (Test-Path engine) { Get-ChildItem -Force engine | Select-Object Mode,Length,Name } else { Write-Host "[miss] engine directory" }
-- if (Test-Path engine/source-sdk-2013/src) { Get-ChildItem -Force engine/source-sdk-2013/src | Select-Object Mode,Length,Name } else { Write-Host "[miss] engine/source-sdk-2013/src" }
++ where.exe git
++ Get-ChildItem -Force | Select-Object Mode,Length,Name | Tee-Object -FilePath artifacts/windows-build-debug/repo-root-before-build.txt
++ if (Test-Path engine) { Get-ChildItem -Force engine | Select-Object Mode,Length,Name | Tee-Object -FilePath artifacts/windows-build-debug/engine-before-build.txt } else { Write-Host "[miss] engine directory" }
++
++ - name: Bootstrap Source SDK 2013 MP
++ run: |
++ $ErrorActionPreference = 'Stop'
++ powershell -NoProfile -ExecutionPolicy Bypass -File tools/bootstrap-source-sdk-2013-windows.ps1 *>&1 | Tee-Object -FilePath artifacts/windows-build-debug/bootstrap-source-sdk-2013.log
- name: Build Windows Source SDK DLLs
id: build
@@@ -78,40 +85,26 @@ jobs:
Get-ChildItem -Recurse -Force -Include client.dll,server.dll -ErrorAction SilentlyContinue |
Select-Object FullName,Length,LastWriteTime |
Format-List | Out-File artifacts/windows-build-debug/dll-search.txt -Append
-- "=== vc/sln search ===" | Out-File artifacts/windows-build-debug/project-search.txt
++ "=== project/log search ===" | Out-File artifacts/windows-build-debug/project-search.txt
Get-ChildItem -Recurse -Force -Include *.sln,*.vcxproj,*.vcproj,*.log -ErrorAction SilentlyContinue |
Select-Object FullName,Length,LastWriteTime |
Format-List | Out-File artifacts/windows-build-debug/project-search.txt -Append
-- $clientCandidates = @(
-- "game/openvibe.games/bin/client.dll",
-- "engine/source-sdk-2013/game/mod_hl2mp/bin/client.dll",
-- "engine/source-sdk-2013/game/mod_hl2mp/bin/win64/client.dll",
-- "engine/source-sdk-2013/game/mod_hl2mp/bin/Release/client.dll",
-- "engine/source-sdk-2013/src/game/client/Release_hl2mp/client.dll",
-- "engine/source-sdk-2013/src/game/client/Release/client.dll"
-- )
-- $serverCandidates = @(
-- "game/openvibe.games/bin/server.dll",
-- "engine/source-sdk-2013/game/mod_hl2mp/bin/server.dll",
-- "engine/source-sdk-2013/game/mod_hl2mp/bin/win64/server.dll",
-- "engine/source-sdk-2013/game/mod_hl2mp/bin/Release/server.dll",
-- "engine/source-sdk-2013/src/game/server/Release_hl2mp/server.dll",
-- "engine/source-sdk-2013/src/game/server/Release/server.dll"
-- )
--
-- $client = $clientCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1
-- $server = $serverCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1
-- if ($client) { Copy-Item $client artifacts/windows-dlls/client.dll -Force }
-- if ($server) { Copy-Item $server artifacts/windows-dlls/server.dll -Force }
--
-- if (Test-Path artifacts/windows-dlls/client.dll) {
-- $clientText = (Select-String -Path artifacts/windows-dlls/client.dll -Pattern "ov_join|ov_menu|OpenVibe" -Encoding Byte -SimpleMatch -Quiet)
-- Write-Host "client.dll staged"
++ $client = "game/openvibe.games/bin/client.dll"
++ $server = "game/openvibe.games/bin/server.dll"
++ $clientOk = $false
++ if (Test-Path $client) {
++ $text = strings.exe $client 2>$null | Select-String -Pattern "ov_join|ov_menu|OpenVibe" -Quiet
++ if ($text) { $clientOk = $true }
++ }
++ if ($clientOk -and (Test-Path $server)) {
++ Copy-Item $client artifacts/windows-dlls/client.dll -Force
++ Copy-Item $server artifacts/windows-dlls/server.dll -Force
++ Write-Host "[ok] staged patched OpenVibe Windows DLLs"
} else {
-- Write-Host "[miss] no client.dll staged"
++ Write-Host "[miss] not staging DLLs because patched OpenVibe client.dll was not produced"
++ "No patched OpenVibe DLLs staged. Check build logs." | Out-File artifacts/windows-build-debug/no-patched-dlls.txt
}
-- if (Test-Path artifacts/windows-dlls/server.dll) { Write-Host "server.dll staged" } else { Write-Host "[miss] no server.dll staged" }
- name: Upload Windows DLL artifact
if: always()
ddiff --git a/docs/WINDOWS_WORKFLOW_SDK_BOOTSTRAP.md b/docs/WINDOWS_WORKFLOW_SDK_BOOTSTRAP.md
nnew file mode 100644
iindex 0000000..025e23d
---- /dev/null
++++ b/docs/WINDOWS_WORKFLOW_SDK_BOOTSTRAP.md
@@@ -0,0 +1,23 @@
++# Windows DLL workflow bootstrap
++
++The Windows GitHub Actions runner does not have the local `engine/source-sdk-2013` checkout that exists on the Linux workstation.
++
++The workflow now bootstraps Valve's Source SDK 2013 multiplayer tree into:
++
++```text
++engine/source-sdk-2013
++```
++
++Then it applies the OpenVibe SDK patch, skips the Linux QuickJS static-library build, builds QuickJS with MSVC, generates Visual Studio projects, builds `client.dll/server.dll`, and only uploads DLLs when `client.dll` contains OpenVibe command strings such as `ov_join`, `ov_menu`, or `OpenVibe`.
++
++Use:
++
++```bash
++tools/gh-windows-build-and-install.sh
++```
++
++or debug the latest run with:
++
++```bash
++tools/windows-workflow-debug-and-install.sh
++```
ddiff --git a/tools/apply-openvibe-sdk.sh b/tools/apply-openvibe-sdk.sh
iindex 305004d..3b00cea 100755
---- a/tools/apply-openvibe-sdk.sh
++++ b/tools/apply-openvibe-sdk.sh
@@@ -21,7 +21,13 @@ copy_tree() {
local src="$1"
local dst="$2"
mkdir -p "$dst"
-- rsync -a --delete "$src/" "$dst/"
++ if command -v rsync >/dev/null 2>&1; then
++ rsync -a --delete "$src/" "$dst/"
++ else
++ rm -rf "$dst"
++ mkdir -p "$dst"
++ cp -R "$src"/. "$dst"/
++ fi
echo "[openvibe-sdk] copied tree ${dst#$SDK/}"
}
ddiff --git a/tools/bootstrap-source-sdk-2013-windows.ps1 b/tools/bootstrap-source-sdk-2013-windows.ps1
nnew file mode 100644
iindex 0000000..be99448
---- /dev/null
++++ b/tools/bootstrap-source-sdk-2013-windows.ps1
@@@ -0,0 +1,51 @@
++$ErrorActionPreference = 'Stop'
++
++$Root = if ($env:OPENVIBE_ROOT) { (Resolve-Path $env:OPENVIBE_ROOT).Path } else { (Resolve-Path (Join-Path $PSScriptRoot '..')).Path }
++$Sdk = if ($env:OPENVIBE_SDK) { $env:OPENVIBE_SDK } else { Join-Path $Root 'engine/source-sdk-2013' }
++$Src = Join-Path $Sdk 'src'
++$Deps = Join-Path $Root '_deps'
++$ValveRepo = Join-Path $Deps 'source-sdk-2013'
++$LogDir = Join-Path $Root 'artifacts/windows-build-debug'
++New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
++
++function Say($m) { Write-Host "[openvibe-sdk-bootstrap] $m" }
++
++Say "root=$Root"
++Say "sdk=$Sdk"
++
++if ((Test-Path (Join-Path $Src 'game/client/hl2mp')) -and (Test-Path (Join-Path $Src 'game/server/hl2mp'))) {
++ Say "existing SDK tree looks usable"
++ exit 0
++}
++
++New-Item -ItemType Directory -Force -Path $Deps | Out-Null
++
++if (!(Test-Path (Join-Path $ValveRepo '.git'))) {
++ Say "cloning ValveSoftware/source-sdk-2013"
++ if (Test-Path $ValveRepo) { Remove-Item -Recurse -Force $ValveRepo }
++ git clone --depth 1 https://github.com/ValveSoftware/source-sdk-2013.git $ValveRepo 2>&1 | Tee-Object -FilePath (Join-Path $LogDir 'bootstrap-git-clone.log')
++} else {
++ Say "updating cached Valve source-sdk-2013"
++ Push-Location $ValveRepo
++ git fetch --depth 1 origin 2>&1 | Tee-Object -FilePath (Join-Path $LogDir 'bootstrap-git-fetch.log')
++ git reset --hard origin/master 2>&1 | Tee-Object -FilePath (Join-Path $LogDir 'bootstrap-git-reset.log')
++ Pop-Location
++}
++
++$Mp = Join-Path $ValveRepo 'mp'
++if (!(Test-Path (Join-Path $Mp 'src'))) {
++ Get-ChildItem -Force $ValveRepo | Select-Object Mode,Length,Name | Format-Table -AutoSize | Out-File (Join-Path $LogDir 'valve-repo-root.txt')
++ throw "Valve source-sdk-2013 clone does not contain mp/src at $Mp/src"
++}
++
++Say "copying mp branch layout into $Sdk"
++if (Test-Path $Sdk) { Remove-Item -Recurse -Force $Sdk }
++New-Item -ItemType Directory -Force -Path $Sdk | Out-Null
++Copy-Item -Path (Join-Path $Mp '*') -Destination $Sdk -Recurse -Force
++
++if (!(Test-Path (Join-Path $Src 'game/client/hl2mp')) -or !(Test-Path (Join-Path $Src 'game/server/hl2mp'))) {
++ Get-ChildItem -Force $Sdk | Select-Object Mode,Length,Name | Format-Table -AutoSize | Out-File (Join-Path $LogDir 'sdk-root-after-copy.txt')
++ throw "Bootstrapped SDK is missing expected HL2MP folders"
++}
++
++Say "SDK bootstrapped successfully"
ddiff --git a/tools/build-sdk-windows.ps1 b/tools/build-sdk-windows.ps1
iindex 01afdda..3c26262 100644
---- a/tools/build-sdk-windows.ps1
++++ b/tools/build-sdk-windows.ps1
@@@ -1,42 +1,82 @@
++param(
++ [switch]$InDevShell
++)
++
$ErrorActionPreference = "Stop"
$Root = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
--$Sdk = Join-Path $Root "engine/source-sdk-2013"
++$Sdk = if ($env:OPENVIBE_SDK) { $env:OPENVIBE_SDK } else { Join-Path $Root "engine/source-sdk-2013" }
$Src = Join-Path $Sdk "src"
$Mod = Join-Path $Root "game/openvibe.games"
$OutBin = Join-Path $Mod "bin"
--$Qjs = Join-Path $Src "game/shared/openvibe/third_party/quickjs"
$LogDir = Join-Path $Root "artifacts/windows-build-debug"
New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
function Say($m) { Write-Host "[openvibe-win] $m" }
--function Require($p, $msg) {
-- if (!(Test-Path $p)) { throw "$msg`nMissing: $p" }
++function Require($p, $msg) { if (!(Test-Path $p)) { throw "$msg`nMissing: $p" } }
++
++function Enter-MsvcDevShellIfNeeded {
++ if (Get-Command cl.exe -ErrorAction SilentlyContinue) {
++ Say "cl.exe already available"
++ return
++ }
++ if ($InDevShell) { throw "cl.exe still not found after entering MSVC dev shell" }
++
++ $vswhere = Join-Path ${env:ProgramFiles(x86)} "Microsoft Visual Studio/Installer/vswhere.exe"
++ if (!(Test-Path $vswhere)) { throw "vswhere.exe not found; Visual Studio Build Tools are not installed" }
++
++ $install = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
++ if (!$install) { throw "Could not find Visual Studio installation with VC x86/x64 tools" }
++
++ $vcvars = Join-Path $install "VC/Auxiliary/Build/vcvars32.bat"
++ if (!(Test-Path $vcvars)) { throw "vcvars32.bat not found at $vcvars" }
++
++ Say "relaunching through MSVC x86 dev shell: $vcvars"
++ $self = $PSCommandPath
++ $cmd = "call `"$vcvars`" && powershell -NoProfile -ExecutionPolicy Bypass -File `"$self`" -InDevShell"
++ & cmd.exe /d /s /c $cmd
++ exit $LASTEXITCODE
}
Say "root=$Root"
Say "sdk=$Sdk"
Say "src=$Src"
--Require $Src "Source SDK checkout is missing from this runner. The workflow must have engine/source-sdk-2013 available in the repository/submodule before Windows DLLs can build."
--# Apply OpenVibe source files using Git Bash when available. This reuses the Linux patcher on Windows runners.
++$env:OPENVIBE_ROOT = $Root
++$env:OPENVIBE_SDK = $Sdk
++
++if (!(Test-Path $Src)) {
++ Say "SDK src missing; bootstrapping Source SDK 2013 MP"
++ & powershell -NoProfile -ExecutionPolicy Bypass -File (Join-Path $Root "tools/bootstrap-source-sdk-2013-windows.ps1")
++ if ($LASTEXITCODE -ne 0) { throw "bootstrap-source-sdk-2013-windows.ps1 failed with exit code $LASTEXITCODE" }
++}
++
++Require $Src "Source SDK checkout is missing from this runner."
++Require (Join-Path $Src "game/client/hl2mp") "Source SDK HL2MP client tree missing."
++Require (Join-Path $Src "game/server/hl2mp") "Source SDK HL2MP server tree missing."
++
++Enter-MsvcDevShellIfNeeded
++
++# Do not let old/stock repo DLLs get mistaken for a successful new build.
++New-Item -ItemType Directory -Force -Path $OutBin | Out-Null
++Remove-Item (Join-Path $OutBin "client.dll") -Force -ErrorAction SilentlyContinue
++Remove-Item (Join-Path $OutBin "server.dll") -Force -ErrorAction SilentlyContinue
++Remove-Item -Recurse -Force (Join-Path $Sdk "game/mod_hl2mp/bin") -ErrorAction SilentlyContinue
++
++# Apply OpenVibe source files using Git Bash. Skip the Linux QuickJS build inside apply-openvibe-sdk.sh.
$bash = (Get-Command bash -ErrorAction SilentlyContinue)
if ($bash) {
Say "applying OpenVibe SDK patch through bash"
-- & bash "$Root/tools/apply-openvibe-sdk.sh"
++ $env:OPENVIBE_SKIP_QJS_BUILD = "1"
++ & bash "$Root/tools/apply-openvibe-sdk.sh" 2>&1 | Tee-Object -FilePath (Join-Path $LogDir "apply-openvibe-sdk.log")
if ($LASTEXITCODE -ne 0) { throw "apply-openvibe-sdk.sh failed with exit code $LASTEXITCODE" }
} else {
throw "Git Bash is required on the Windows runner to apply the OpenVibe SDK patch."
}
--# Build QuickJS as MSVC objects/lib. The Linux .a cannot be linked into Windows DLLs.
--if (Test-Path (Join-Path $Root "tools/build-quickjs-lib-windows.ps1")) {
-- Say "building QuickJS Windows static library"
-- & powershell -NoProfile -ExecutionPolicy Bypass -File (Join-Path $Root "tools/build-quickjs-lib-windows.ps1")
-- if ($LASTEXITCODE -ne 0) { throw "build-quickjs-lib-windows.ps1 failed with exit code $LASTEXITCODE" }
--} else {
-- Say "no build-quickjs-lib-windows.ps1 found; continuing"
--}
++Say "building QuickJS Windows static library"
++& powershell -NoProfile -ExecutionPolicy Bypass -File (Join-Path $Root "tools/build-quickjs-lib-windows.ps1") 2>&1 | Tee-Object -FilePath (Join-Path $LogDir "quickjs-windows.log")
++if ($LASTEXITCODE -ne 0) { throw "build-quickjs-lib-windows.ps1 failed with exit code $LASTEXITCODE" }
Set-Location $Src
@@@ -53,7 +93,7 @@ if ($solutions.Count -eq 0) {
foreach ($gen in $generators) {
if (Test-Path $gen) {
Say "running $gen"
-- & cmd /c "`"$gen`"" | Tee-Object -FilePath (Join-Path $LogDir "project-generation.log")
++ & cmd /d /s /c "`"$gen`"" 2>&1 | Tee-Object -FilePath (Join-Path $LogDir "project-generation.log")
$ran = $true
break
}
@@@ -63,7 +103,7 @@ if ($solutions.Count -eq 0) {
$vpc = Join-Path $Src "devtools/bin/vpc.exe"
if (Test-Path $vpc) {
Say "running vpc.exe fallback"
-- & $vpc /hl2mp +game /mksln OpenVibe_HL2MP.sln | Tee-Object -FilePath (Join-Path $LogDir "vpc.log")
++ & $vpc /hl2mp +game /mksln OpenVibe_HL2MP.sln 2>&1 | Tee-Object -FilePath (Join-Path $LogDir "vpc.log")
$ran = $true
}
}
@@@ -78,14 +118,12 @@ if ($solutions.Count -eq 0) {
Say "solutions found:"
$solutions | ForEach-Object { Say " $($_.FullName)" }
--# Pick the most likely HL2MP/game solution.
$solution = $solutions |
Where-Object { $_.Name -match "hl2mp|game|sdk|everything|OpenVibe" } |
Select-Object -First 1
if (-not $solution) { $solution = $solutions | Select-Object -First 1 }
Say "selected solution=$($solution.FullName)"
--# Try common project targets/configurations. Source SDK projects vary by branch/version.
$configs = @("Release", "Release_HL2MP", "Release HL2MP")
$platforms = @("Win32", "x86")
$targets = @("client_hl2mp", "server_hl2mp", "client", "server", "Build")
@@@ -95,20 +133,16 @@ foreach ($cfg in $configs) {
foreach ($plat in $platforms) {
foreach ($target in $targets) {
Say "msbuild cfg=$cfg platform=$plat target=$target"
-- & msbuild $solution.FullName /m /p:Configuration=$cfg /p:Platform=$plat /t:$target /v:minimal /nologo 2>&1 | Tee-Object -FilePath (Join-Path $LogDir "msbuild-$($cfg -replace '[^A-Za-z0-9]','_')-$plat-$target.log")
-- if ($LASTEXITCODE -eq 0) {
-- $builtAny = $true
-- break
-- }
++ $log = Join-Path $LogDir "msbuild-$($cfg -replace '[^A-Za-z0-9]','_')-$plat-$target.log"
++ & msbuild $solution.FullName /m /p:Configuration=$cfg /p:Platform=$plat /p:PlatformToolset=v143 /t:$target /v:minimal /nologo 2>&1 | Tee-Object -FilePath $log
++ if ($LASTEXITCODE -eq 0) { $builtAny = $true; break }
}
if ($builtAny) { break }
}
if ($builtAny) { break }
}
--if (-not $builtAny) {
-- throw "MSBuild could not build any known Source SDK HL2MP target. Check uploaded msbuild logs."
--}
++if (-not $builtAny) { throw "MSBuild could not build any known Source SDK HL2MP target. Check uploaded msbuild logs." }
New-Item -ItemType Directory -Force -Path $OutBin | Out-Null
@@@ -129,4 +163,7 @@ Say "copy server=$($server.FullName)"
Copy-Item $client.FullName (Join-Path $OutBin "client.dll") -Force
Copy-Item $server.FullName (Join-Path $OutBin "server.dll") -Force
++$clientText = & strings.exe (Join-Path $OutBin "client.dll") 2>$null | Select-String -Pattern "ov_join|ov_menu|OpenVibe" -Quiet
++if (-not $clientText) { throw "Built client.dll does not contain OpenVibe strings; refusing to publish stale/stock DLL" }
++
Say "done"
ddiff --git a/tools/windows-workflow-debug-and-install.sh b/tools/windows-workflow-debug-and-install.sh
iindex 2f3d84a..0084b53 100755
---- a/tools/windows-workflow-debug-and-install.sh
++++ b/tools/windows-workflow-debug-and-install.sh
@@@ -1,26 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail
++
ROOT="${OPENVIBE_ROOT:-$HOME/src/openvibe-source}"
--REPO="${OPENVIBE_REPO:-OpenVibers/OpenVibe.Games}"
--WORKFLOW="${OPENVIBE_WINDOWS_WORKFLOW:-windows-source-sdk-dlls.yml}"
--BRANCH="$(git -C "$ROOT" rev-parse --abbrev-ref HEAD)"
--OUT="$ROOT/artifacts/windows-workflow-debug"
cd "$ROOT"
++REPO="${OPENVIBE_GITHUB_REPO:-OpenVibers/OpenVibe.Games}"
++WORKFLOW="${OPENVIBE_WINDOWS_WORKFLOW:-windows-source-sdk-dlls.yml}"
++RUN_ID="${1:-}"
++
++if ! command -v gh >/dev/null 2>&1; then
++ echo "[openvibe] missing gh. Install with: sudo apt install gh" >&2
++ exit 1
++fi
++
++if [[ -z "$RUN_ID" ]]; then
++ RUN_ID="$(gh run list --repo "$REPO" --workflow "$WORKFLOW" --branch "$(git rev-parse --abbrev-ref HEAD)" --limit 1 --json databaseId --jq '.[0].databaseId')"
++fi
++
++OUT="$ROOT/artifacts/windows-workflow-debug/run-$RUN_ID-artifacts"
++rm -rf "$OUT"
mkdir -p "$OUT"
--run="$(gh run list --repo "$REPO" --workflow "$WORKFLOW" --branch "$BRANCH" --limit 1 --json databaseId --jq '.[0].databaseId')"
--echo "[openvibe] latest run=$run"
--gh run view "$run" --repo "$REPO" --log > "$OUT/run-${run}.log" 2>&1 || true
--gh run view "$run" --repo "$REPO" --log-failed > "$OUT/run-${run}-failed.log" 2>&1 || true
--gh run download "$run" --repo "$REPO" --dir "$OUT/run-${run}-artifacts" || true
--printf '\n[openvibe] tail of failed log:\n'
--tail -n 160 "$OUT/run-${run}-failed.log" || true
--printf '\n[openvibe] artifacts saved under: %s\n' "$OUT/run-${run}-artifacts"
--if [[ -f "$OUT/run-${run}-artifacts/openvibe-windows-dlls/client.dll" && -f "$OUT/run-${run}-artifacts/openvibe-windows-dlls/server.dll" ]]; then
-- mkdir -p game/openvibe.games/bin
-- cp -f "$OUT/run-${run}-artifacts/openvibe-windows-dlls/client.dll" game/openvibe.games/bin/client.dll
-- cp -f "$OUT/run-${run}-artifacts/openvibe-windows-dlls/server.dll" game/openvibe.games/bin/server.dll
-- echo "[openvibe] installed DLL artifacts"
-- tools/verify-openvibe-dll-content.sh || true
++
++echo "[openvibe] run=$RUN_ID"
++echo "[openvibe] downloading logs/artifacts into $OUT"
++
++gh run view "$RUN_ID" --repo "$REPO" --log > "$OUT/full-run.log" || true
++gh run download "$RUN_ID" --repo "$REPO" --dir "$OUT" || true
++
++find "$OUT" -maxdepth 3 -type f | sort > "$OUT/file-list.txt"
++
++echo
++echo "[openvibe] likely errors:"
++grep -RniE "error MSB|fatal error|undefined reference|unresolved external|LNK[0-9]+|C[0-9]{4}:|throw |Missing:|not found|could not|failed|No Visual Studio solution|No patched" "$OUT" | tail -n 120 || true
++
++echo
++echo "[openvibe] artifact files:"
++sed -n '1,160p' "$OUT/file-list.txt"
++
++DLLDIR="$OUT/openvibe-windows-dlls"
++if [[ -f "$DLLDIR/client.dll" && -f "$DLLDIR/server.dll" ]]; then
++ if strings "$DLLDIR/client.dll" | grep -Eq 'ov_join|ov_menu|OpenVibe'; then
++ mkdir -p game/openvibe.games/bin
++ cp -f "$DLLDIR/client.dll" game/openvibe.games/bin/client.dll
++ cp -f "$DLLDIR/server.dll" game/openvibe.games/bin/server.dll
++ echo "[openvibe] installed patched Windows DLLs"
++ tools/verify-openvibe-dll-content.sh || true
++ else
++ echo "[openvibe] refused to install DLL artifact because client.dll lacks OpenVibe strings" >&2
++ exit 2
++ fi
else
-- echo "[openvibe] no DLL artifact available yet; check debug artifact/logs"
++ echo "[openvibe] no DLL artifact available yet" >&2
++ exit 3
fi