Radicade Public Code

This commit is contained in:
JogmansonReal
2026-10-16 23:33:13 -07:00
commit 55175acdf6
832 changed files with 363261 additions and 0 deletions
+215
View File
@@ -0,0 +1,215 @@
<#
Builds a friend-ready Radicade August 2023 client bundle from a WORKING install.
It reads the source install, verifies every required piece against the reference
hashes, copies them to -OutDir, drops the triage script and a README in with them,
and optionally zips the result. Nothing in -GameDir is ever modified.
Usage:
powershell -ExecutionPolicy Bypass -File make-august-client-pack.ps1 -OutDir "D:\radicade-pack"
powershell -ExecutionPolicy Bypass -File make-august-client-pack.ps1 -OutDir "D:\radicade-pack" -Zip
Verification is fail-closed: if a piece is unpatched or a different build, the script
stops and names it instead of producing a bundle that cannot work.
#>
[CmdletBinding()]
param(
[string]$GameDir,
[Parameter(Mandatory = $true)][string]$OutDir,
[switch]$Zip,
[switch]$Force
)
$ErrorActionPreference = 'Stop'
# Reference values: the install that logs in and loads rooms.
$expected = @{
AssemblySize = 167390208
AssemblyMd5 = '11e14eb35671e2725bd0c78a6a91bb48'
MetadataSize = 38654794
MetadataMd5 = 'cc9c32014b5fc3dd1a2a8fb12376be15'
InteropSize = 38654794
InteropMd5 = '4a1a28078f957af470f3b31951b32648'
BootSize = 173
BootMd5 = 'dc2e5f7af7d5df736a4cc3477b4b1a1f'
WinhttpSize = 26112
WinhttpMd5 = 'b2a4d0cb04bf8f5a27ccab237ecc2586'
LoaderSize = 60928
LoaderMd5 = '9430bb84349d52b753a181788a86c5e2'
PluginSize = 62464
PluginMd5 = '8718a45dd42d7cb72b3e46e04b744d91'
InteropCount = 335
}
function Get-Md5 {
param([string]$Path)
return (Get-FileHash -LiteralPath $Path -Algorithm MD5).Hash.ToLower()
}
function Assert-Piece {
param(
[string]$Label,
[string]$Path,
[long]$Size,
[string]$Md5
)
if (-not (Test-Path -LiteralPath $Path)) {
throw "$Label is missing: $Path"
}
$info = Get-Item -LiteralPath $Path
$actual = Get-Md5 $Path
if ($info.Length -ne $Size -or $actual -ne $Md5) {
$detail = "$Label does not match the reference: {0} b md5 {1} (expected {2} b md5 {3})" -f $info.Length, $actual, $Size, $Md5
if ($Force) { Write-Host ("WARNING: " + $detail) }
else { throw ($detail + ' - fix it or pass -Force if you know this build is fine.') }
} else {
Write-Host (" ok {0}" -f $Label)
}
}
# --- locate the source install ------------------------------------------------
if (-not $GameDir) {
$candidates = @(
(Join-Path $env:USERPROFILE 'Downloads\2023-08-29T06-53-33Z')
)
$downloads = Join-Path $env:USERPROFILE 'Downloads'
if (Test-Path -LiteralPath $downloads) {
$candidates += (Get-ChildItem -LiteralPath $downloads -Directory -ErrorAction SilentlyContinue |
Where-Object { Test-Path -LiteralPath (Join-Path $_.FullName 'RecRoom.exe') } |
ForEach-Object { $_.FullName })
}
foreach ($c in $candidates) {
if (Test-Path -LiteralPath (Join-Path $c 'BepInEx\plugins\RadicadeAugustClient.dll')) { $GameDir = $c; break }
}
}
if (-not $GameDir) { $GameDir = Read-Host 'Path to the patched Rec Room folder (the one that works)' }
$GameDir = $GameDir.TrimEnd('\')
$metadataDir = Join-Path $GameDir 'Recroom_Data\il2cpp_data\Metadata'
$bepInEx = Join-Path $GameDir 'BepInEx'
Write-Host 'Verifying the source install against the reference hashes...'
Assert-Piece 'GameAssembly.dll (build identity)' (Join-Path $GameDir 'GameAssembly.dll') $expected.AssemblySize $expected.AssemblyMd5
Assert-Piece 'global-metadata.dat (host literals patched)' (Join-Path $metadataDir 'global-metadata.dat') $expected.MetadataSize $expected.MetadataMd5
Assert-Piece 'global-metadata.interop.dat' (Join-Path $metadataDir 'global-metadata.interop.dat') $expected.InteropSize $expected.InteropMd5
Assert-Piece 'Recroom_Data\boot.config' (Join-Path $GameDir 'Recroom_Data\boot.config') $expected.BootSize $expected.BootMd5
Assert-Piece 'winhttp.dll (Doorstop 4.3.0)' (Join-Path $GameDir 'winhttp.dll') $expected.WinhttpSize $expected.WinhttpMd5
Assert-Piece 'BepInEx.Unity.IL2CPP.dll (patched loader)' (Join-Path $bepInEx 'core\BepInEx.Unity.IL2CPP.dll') $expected.LoaderSize $expected.LoaderMd5
Assert-Piece 'RadicadeAugustClient.dll' (Join-Path $bepInEx 'plugins\RadicadeAugustClient.dll') $expected.PluginSize $expected.PluginMd5
if (-not (Test-Path -LiteralPath (Join-Path $GameDir 'doorstop_config.ini'))) { throw 'doorstop_config.ini is missing' }
$interopCount = (Get-ChildItem -LiteralPath (Join-Path $bepInEx 'interop') -File -ErrorAction SilentlyContinue).Count
if ($interopCount -lt $expected.InteropCount) {
throw ("BepInEx\interop holds {0} assemblies, expected at least {1} - interop generation was incomplete" -f $interopCount, $expected.InteropCount)
}
Write-Host (" ok BepInEx\interop ({0} assemblies)" -f $interopCount)
Write-Host 'Source install verified.'
Write-Host ''
# --- assemble the bundle ------------------------------------------------------
$bundleRoot = Join-Path $OutDir 'RadicadeAugustClient'
if (Test-Path -LiteralPath $bundleRoot) {
if ($Force) { Remove-Item -LiteralPath $bundleRoot -Recurse -Force }
else { throw "$bundleRoot already exists - delete it or pass -Force to replace it." }
}
New-Item -ItemType Directory -Path $bundleRoot -Force | Out-Null
Write-Host ("Copying into {0} ..." -f $bundleRoot)
# Root-level loader pieces and the patched data files.
Copy-Item -LiteralPath (Join-Path $GameDir 'winhttp.dll') -Destination $bundleRoot
Copy-Item -LiteralPath (Join-Path $GameDir 'doorstop_config.ini') -Destination $bundleRoot
foreach ($name in @('.doorstop_version', 'changelog.txt')) {
$p = Join-Path $GameDir $name
if (Test-Path -LiteralPath $p) { Copy-Item -LiteralPath $p -Destination $bundleRoot }
}
$dataTarget = Join-Path $bundleRoot 'Recroom_Data'
New-Item -ItemType Directory -Path $dataTarget -Force | Out-Null
Copy-Item -LiteralPath (Join-Path $GameDir 'Recroom_Data\boot.config') -Destination $dataTarget
foreach ($name in @('radicade-patch.json')) {
$p = Join-Path $GameDir ('Recroom_Data\' + $name)
if (Test-Path -LiteralPath $p) { Copy-Item -LiteralPath $p -Destination $dataTarget }
}
$metaTarget = Join-Path $dataTarget 'il2cpp_data\Metadata'
New-Item -ItemType Directory -Path $metaTarget -Force | Out-Null
foreach ($name in @('global-metadata.dat', 'global-metadata.interop.dat')) {
Copy-Item -LiteralPath (Join-Path $metadataDir $name) -Destination $metaTarget
}
# The whole BepInEx tree, minus logs, sidecar backups and caches.
$bepTarget = Join-Path $bundleRoot 'BepInEx'
# Excluded: logs, sidecar backups of previous builds, and the diagnostic RVA map the
# plugin writes (18 MB of local crash-analysis output).
robocopy $bepInEx $bepTarget /E /NFL /NDL /NJH /NJS /NP `
/XF 'LogOutput.log' '*.log' '*.before-*' '*.tracer-*' '*.march-backup' '*.baseline-disabled' `
'radicade-addr-map.txt' | Out-Null
if ($LASTEXITCODE -ge 8) { throw ("robocopy failed with exit code {0}" -f $LASTEXITCODE) }
$global:LASTEXITCODE = 0
# The triage script travels with the bundle so the friend can produce a report.
$triage = Join-Path $PSScriptRoot 'august-client-triage.ps1'
if (Test-Path -LiteralPath $triage) { Copy-Item -LiteralPath $triage -Destination $bundleRoot }
$assemblyInfo = Get-Item -LiteralPath (Join-Path $GameDir 'GameAssembly.dll')
$readme = @()
$readme += 'Radicade August 2023 client patch'
$readme += ''
$readme += 'This bundle carries the client half of a Rec Room 2023-08-29 (game version 20230825,'
$readme += 'Unity 2020.3.33f1) setup pointed at a Radicade server on YOUR OWN machine.'
$readme += ''
$readme += 'It only works on the identical game build. Check yours before copying anything:'
$readme += (" GameAssembly.dll must be {0} bytes, md5 {1}" -f $assemblyInfo.Length, $expected.AssemblyMd5)
$readme += ''
$readme += 'Install, into the folder that holds RecRoom.exe:'
$readme += ' 1. copy winhttp.dll, doorstop_config.ini and .doorstop_version into the game root'
$readme += ' 2. copy BepInEx\ next to them'
$readme += ' 3. copy Recroom_Data\boot.config and Recroom_Data\il2cpp_data\Metadata\*.dat over the'
$readme += ' existing files (keep copies of the originals; global-metadata.dat.orig is the'
$readme += ' patcher''s own backup and must stay untouched)'
$readme += ' 4. rename any winhttp.dll.baseline-disabled you already have out of the way'
$readme += ' 5. start your Radicade server first - https://localhost:3030 plus http://127.0.0.1:3031,'
$readme += ' ASPNETCORE_ENVIRONMENT=Development - and only then launch the game'
$readme += ''
$readme += 'Why the server has to be local: the patched global-metadata.dat rewrites the client''s'
$readme += 'bootstrap literals to https://localhost:3030, so a remote server cannot answer them.'
$readme += ''
$readme += 'Then check the install with the bundled triage script:'
$readme += ' powershell -ExecutionPolicy Bypass -File august-client-triage.ps1'
$readme += 'It prints one PASS/MISSING line per required piece and writes august-client-report.txt.'
$readme += ''
$readme += 'The line "Failed to load Type RecRoom.Analytics.Statsig.StatsigDebugOverrides" in'
$readme += 'Player.log is NORMAL and appears in a completely unpatched launch of this build too.'
$readme += 'It is never the reason a patched install fails.'
$readme += ''
$readme += 'Pieces and their reference hashes (the triage script checks these for you):'
$readme += ' GameAssembly.dll 167390208 b 11e14eb35671e2725bd0c78a6a91bb48'
$readme += ' Recroom_Data/il2cpp_data/Metadata/global-metadata.dat'
$readme += ' 38654794 b cc9c32014b5fc3dd1a2a8fb12376be15'
$readme += ' Recroom_Data/il2cpp_data/Metadata/global-metadata.interop.dat'
$readme += ' 38654794 b 4a1a28078f957af470f3b31951b32648'
$readme += ' Recroom_Data/boot.config 173 b dc2e5f7af7d5df736a4cc3477b4b1a1f'
$readme += ' winhttp.dll 26112 b b2a4d0cb04bf8f5a27ccab237ecc2586'
$readme += ' BepInEx/core/BepInEx.Unity.IL2CPP.dll'
$readme += ' 60928 b 9430bb84349d52b753a181788a86c5e2'
$readme += ' BepInEx/plugins/RadicadeAugustClient.dll'
$readme += ' 62464 b 8718a45dd42d7cb72b3e46e04b744d91'
$readme += ' BepInEx/interop/ 335 assemblies'
$readme += ''
Set-Content -LiteralPath (Join-Path $bundleRoot 'README-FRIEND.txt') -Value ($readme -join "`r`n") -Encoding UTF8
$size = (Get-ChildItem -LiteralPath $bundleRoot -Recurse -File | Measure-Object -Property Length -Sum).Sum
Write-Host ('Bundle assembled: {0} ({1:N1} MB)' -f $bundleRoot, ($size / 1MB))
if ($Zip) {
$zipPath = $bundleRoot.TrimEnd('\') + '.zip'
if (Test-Path -LiteralPath $zipPath) { Remove-Item -LiteralPath $zipPath -Force }
Write-Host ('Compressing to {0} (this takes a while)...' -f $zipPath)
Compress-Archive -Path (Join-Path $bundleRoot '*') -DestinationPath $zipPath -CompressionLevel Optimal
Write-Host ('Zip written: {0} ({1:N1} MB)' -f $zipPath, ((Get-Item -LiteralPath $zipPath).Length / 1MB))
}
Write-Host ''
Write-Host 'Remind the friend that he still needs the game build above and his own Radicade server.'