forked from TheSuperHackers/GeneralsGameCode
-
Notifications
You must be signed in to change notification settings - Fork 0
242 lines (205 loc) · 9.29 KB
/
check-replays.yml
File metadata and controls
242 lines (205 loc) · 9.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
name: Check Replays
permissions:
contents: read
pull-requests: write
on:
workflow_call:
inputs:
game:
required: true
type: string
description: "Game to check (only GeneralsMD for now)"
userdata:
required: true
type: string
description: "Path to folder with replays and maps"
preset:
required: true
type: string
description: "CMake preset"
jobs:
build:
name: ${{ inputs.preset }}
runs-on: windows-2022
timeout-minutes: 15
env:
GAME_PATH: C:\GameData
GENERALS_PATH: C:\GameData\Generals
GENERALSMD_PATH: C:\GameData\GeneralsMD
steps:
- name: Checkout Code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: true
- name: Download Game Artifact
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
name: ${{ inputs.game }}-${{ inputs.preset }}
path: build
- name: Cache Game Data
id: cache-gamedata
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ${{ env.GAME_PATH }}
key: gamedata-permanent-cache-v4
- name: Download Game Data from Cloudflare R2
if: ${{ steps.cache-gamedata.outputs.cache-hit != 'true' }}
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
AWS_ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }}
EXPECTED_HASH_GENERALS: "37A351AA430199D1F05DEB9E404857DCE7B461A6AC272C5D4A0B5652CDB06372"
EXPECTED_HASH_GENERALSMD: "6837FE1E3009A4C239406C39B1598216C0943EE8ED46BB10626767029AC05E21"
shell: pwsh
run: |
# Download trimmed gamedata of both Generals 1.08 and Generals Zero Hour 1.04.
# This data cannot be used for playing because it's
# missing textures, audio and gui files. But it's enough for replay checking.
# It's also encrypted because it's not allowed to distribute these files.
if (-not $env:AWS_ACCESS_KEY_ID -or -not $env:AWS_SECRET_ACCESS_KEY -or -not $env:AWS_ENDPOINT_URL) {
$ok1 = [bool]$env:AWS_ACCESS_KEY_ID
$ok2 = [bool]$env:AWS_SECRET_ACCESS_KEY
$ok3 = [bool]$env:AWS_ENDPOINT_URL
Write-Host "One or more required secrets are not set or are empty. R2_ACCESS_KEY_ID: $ok1, R2_SECRET_ACCESS_KEY: $ok2, R2_ENDPOINT_URL: $ok3"
exit 1
}
# Download Generals Game Files
# The archive contains these files:
# BINKW32.DLL
# English.big
# INI.big
# Maps.big
# mss32.dll
# W3D.big
# Data\Scripts\MultiplayerScripts.scb
# Data\Scripts\SkirmishScripts.scb
Write-Host "Downloading Game Data for Generals" -ForegroundColor Cyan
aws s3 cp s3://github-ci/generals108_gamedata_trimmed.7z generals108_gamedata_trimmed.7z --endpoint-url $env:AWS_ENDPOINT_URL
Write-Host "Verifying File Integrity" -ForegroundColor Cyan
$fileHash = (Get-FileHash -Path generals108_gamedata_trimmed.7z -Algorithm SHA256).Hash
Write-Host "Downloaded file SHA256: $fileHash"
Write-Host "Expected file SHA256: $env:EXPECTED_HASH_GENERALS"
if ($fileHash -ne $env:EXPECTED_HASH_GENERALS) {
Write-Error "Hash verification failed! File may be corrupted or tampered with."
exit 1
}
Write-Host "Extracting Archive" -ForegroundColor Cyan
$extractPath = $env:GENERALS_PATH
& 7z x generals108_gamedata_trimmed.7z -o"$extractPath"
Remove-Item generals108_gamedata_trimmed.7z -Verbose
# Download GeneralsMD (ZH) Game Files
# The archive contains these files:
# BINKW32.DLL
# INIZH.big
# MapsZH.big
# mss32.dll
# W3DZH.big
# Data\Scripts\MultiplayerScripts.scb
# Data\Scripts\Scripts.ini
# Data\Scripts\SkirmishScripts.scb
Write-Host "Downloading Game Data for GeneralsMD" -ForegroundColor Cyan
aws s3 cp s3://github-ci/zerohour104_gamedata_trimmed.7z zerohour104_gamedata_trimmed.7z --endpoint-url $env:AWS_ENDPOINT_URL
Write-Host "Verifying File Integrity" -ForegroundColor Cyan
$fileHash = (Get-FileHash -Path zerohour104_gamedata_trimmed.7z -Algorithm SHA256).Hash
Write-Host "Downloaded file SHA256: $fileHash"
Write-Host "Expected file SHA256: $env:EXPECTED_HASH_GENERALSMD"
if ($fileHash -ne $env:EXPECTED_HASH_GENERALSMD) {
Write-Error "Hash verification failed! File may be corrupted or tampered with."
exit 1
}
Write-Host "Extracting Archive" -ForegroundColor Cyan
$extractPath = $env:GENERALSMD_PATH
& 7z x zerohour104_gamedata_trimmed.7z -o"$extractPath"
Remove-Item zerohour104_gamedata_trimmed.7z -Verbose
- name: Set Up Game Data
shell: pwsh
run: |
$source = "$env:GAME_PATH\${{ inputs.game }}"
$destination = "build"
Copy-Item -Path $source\* -Destination $destination -Recurse -Force
- name: Set Generals InstallPath in Registry
shell: pwsh
run: |
# Zero Hour loads some Generals files and needs this registry key to find the
# Generals data files.
$regPath = "HKCU:\SOFTWARE\Electronic Arts\EA Games\Generals"
$installPath = "$env:GENERALS_PATH\"
# Ensure the key exists
if (-not (Test-Path $regPath)) {
New-Item -Path $regPath -Force | Out-Null
}
# Set the InstallPath value
Set-ItemProperty -Path $regPath -Name InstallPath -Value $installPath -Type String
Write-Host "Registry key set: $regPath -> InstallPath = $installPath"
- name: Move Replays and Maps to User Dir
shell: pwsh
run: |
# These files are expected in the user dir, so we move them here.
$source = "${{ inputs.userdata }}\Replays"
$destination = "$env:USERPROFILE\Documents\Command and Conquer Generals Zero Hour Data\Replays"
Write-Host "Move replays to $destination"
New-Item -ItemType Directory -Path $destination -Force | Out-Null
Move-Item -Path "$source\*" -Destination $destination -Force
$source = "${{ inputs.userdata }}\Maps"
$destination = "$env:USERPROFILE\Documents\Command and Conquer Generals Zero Hour Data\Maps"
Write-Host "Move maps to $destination"
New-Item -ItemType Directory -Path $destination -Force | Out-Null
Move-Item -Path "$source\*" -Destination $destination -Force
- name: Run Replay Compatibility Tests
shell: pwsh
run: |
$exePath = "build/generalszh.exe"
$arguments = "-jobs 4 -headless -replay *.rep"
$timeoutSeconds = 10*60
$stdoutPath = "stdout.log"
$stderrPath = "stderr.log"
if (-not (Test-Path $exePath)) {
Write-Host "ERROR: Executable not found at $exePath"
exit 1
}
# Note that the game is a gui application. That means we need to redirect console output to a file
# in order to retrieve it.
# Clean previous logs
Remove-Item $stdoutPath, $stderrPath -ErrorAction SilentlyContinue
# Start the process
Write-Host "Run $exePath $arguments"
$process = Start-Process -FilePath $exePath `
-ArgumentList $arguments `
-RedirectStandardOutput $stdoutPath `
-RedirectStandardError $stderrPath `
-PassThru
# Wait with timeout
$exited = $process.WaitForExit($timeoutSeconds * 1000)
if (-not $exited) {
Write-Host "ERROR: Process still running after $timeoutSeconds seconds. Killing process..."
Stop-Process -Id $process.Id -Force
}
# Read output
Write-Host "=== STDOUT ==="
Get-Content $stdoutPath
if ((Test-Path $stderrPath) -and (Get-Item $stderrPath).Length -gt 0) {
Write-Host "`n=== STDERR ==="
Get-Content $stderrPath
}
if (-not $exited) {
exit 1
}
# Check exit code
$exitCode = $process.ExitCode
# The above doesn't work on all Windows versions. If not, try this: (see https://stackoverflow.com/a/16018287)
#$process.HasExited | Out-Null # Needs to be called for the command below to work correctly
#$exitCode = $process.GetType().GetField('exitCode', 'NonPublic, Instance').GetValue($process)
#Write-Host "exit code $exitCode"
if ($exitCode -ne 0) {
Write-Host "ERROR: Process failed with exit code $exitCode"
exit $exitCode
}
Write-Host "Success!"
- name: Upload Debug Log
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: Replay-Debug-Log-${{ inputs.preset }}
path: build/DebugLogFile*.txt
retention-days: 30
if-no-files-found: ignore