112 lines
4.6 KiB
PowerShell
112 lines
4.6 KiB
PowerShell
param(
|
|
[Parameter(Mandatory)]
|
|
[string]$GameDir,
|
|
|
|
[Parameter(Mandatory)]
|
|
[string]$LocalClientDir,
|
|
|
|
[string]$SharedDataDir,
|
|
|
|
[switch]$Wait
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$GameDir = [IO.Path]::GetFullPath($GameDir)
|
|
$LocalClientDir = [IO.Path]::GetFullPath($LocalClientDir)
|
|
if (-not $SharedDataDir) {
|
|
$localAppData = [Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)
|
|
$SharedDataDir = Join-Path (Split-Path -Parent $localAppData) 'LocalLow\Gamfs\BrownDust II'
|
|
}
|
|
$SharedDataDir = [IO.Path]::GetFullPath($SharedDataDir)
|
|
|
|
$exe = Join-Path $GameDir 'BrownDust II.exe'
|
|
$pluginDir = Join-Path $GameDir 'BepInEx\plugins'
|
|
$localRes = Join-Path $pluginDir 'PluginLocalRes.dll'
|
|
$capturePlugin = Join-Path $pluginDir 'BD2CaptureEnvironment.dll'
|
|
$identityPlugin = Join-Path $pluginDir 'BD2LocalIdentity.dll'
|
|
$doorstop = Join-Path $GameDir 'doorstop_config.ini'
|
|
$isolatedData = Join-Path $GameDir 'IsolatedUserData'
|
|
$sharedGameData = Join-Path $SharedDataDir 'Data\t'
|
|
$stagedCapturePlugin = Join-Path $PSScriptRoot '..\..\plugins\CaptureEnvironment\bin\Release\netstandard2.1\BD2CaptureEnvironment.dll'
|
|
|
|
if (Get-Process -Name 'BrownDust II' -ErrorAction SilentlyContinue) {
|
|
throw 'BrownDust II is already running. Exit it before starting the isolated official client.'
|
|
}
|
|
|
|
foreach ($requiredDirectory in @($GameDir, $LocalClientDir, $SharedDataDir, $sharedGameData)) {
|
|
if (-not (Test-Path -LiteralPath $requiredDirectory -PathType Container)) {
|
|
throw "Required directory is missing: $requiredDirectory"
|
|
}
|
|
}
|
|
|
|
if (Test-Path -LiteralPath $stagedCapturePlugin -PathType Leaf) {
|
|
$installedHash = if (Test-Path -LiteralPath $capturePlugin -PathType Leaf) {
|
|
(Get-FileHash -LiteralPath $capturePlugin -Algorithm SHA256).Hash
|
|
}
|
|
$stagedHash = (Get-FileHash -LiteralPath $stagedCapturePlugin -Algorithm SHA256).Hash
|
|
if ($installedHash -ne $stagedHash) {
|
|
New-Item -ItemType Directory -Force -Path $pluginDir | Out-Null
|
|
Copy-Item -LiteralPath $stagedCapturePlugin -Destination $capturePlugin -Force
|
|
Write-Host "Updated capture plugin from staged build ($stagedHash)."
|
|
}
|
|
}
|
|
|
|
foreach ($required in @($exe, $doorstop, $localRes, $capturePlugin)) {
|
|
if (-not (Test-Path -LiteralPath $required -PathType Leaf)) {
|
|
throw "Required file is missing: $required"
|
|
}
|
|
}
|
|
|
|
if (Test-Path -LiteralPath $identityPlugin) {
|
|
throw "Unsafe plugin found in official environment: $identityPlugin"
|
|
}
|
|
|
|
$unexpectedIdentity = Get-ChildItem -LiteralPath (Join-Path $GameDir 'BepInEx') `
|
|
-Recurse -File -Filter 'BD2LocalIdentity.dll' -ErrorAction SilentlyContinue
|
|
if ($unexpectedIdentity) {
|
|
throw "BD2LocalIdentity.dll must not exist anywhere in the official environment."
|
|
}
|
|
|
|
$sharedStaticPaths = @{
|
|
(Join-Path $isolatedData 'SoundData') = (Join-Path $SharedDataDir 'SoundData')
|
|
(Join-Path $isolatedData 'com.unity.addressables') = (Join-Path $SharedDataDir 'com.unity.addressables')
|
|
(Join-Path $isolatedData 'VideoData') = (Join-Path $SharedDataDir 'VideoData')
|
|
(Join-Path $GameDir 'BrownDust II_Data\StreamingAssets\aa') = (Join-Path $LocalClientDir 'BrownDust II_Data\StreamingAssets\aa')
|
|
}
|
|
foreach ($link in $sharedStaticPaths.GetEnumerator()) {
|
|
$item = Get-Item -LiteralPath $link.Key -Force -ErrorAction SilentlyContinue
|
|
if (-not $item -or $item.LinkType -ne 'Junction') {
|
|
throw "Shared static-data junction is missing: $($link.Key)"
|
|
}
|
|
$actualTarget = [IO.Path]::GetFullPath([string]$item.Target)
|
|
$expectedTarget = [IO.Path]::GetFullPath([string]$link.Value)
|
|
if ($actualTarget -ne $expectedTarget) {
|
|
throw "Unexpected junction target for $($link.Key): $actualTarget"
|
|
}
|
|
}
|
|
|
|
New-Item -ItemType Directory -Force -Path $isolatedData | Out-Null
|
|
$unityLog = Join-Path $isolatedData 'Player.log'
|
|
$process = Start-Process -FilePath $exe -WorkingDirectory $GameDir `
|
|
-ArgumentList @(
|
|
'-logFile', ('"' + $unityLog + '"'),
|
|
'-bd2SharedGameData', ('"' + $sharedGameData + '"')
|
|
) -PassThru
|
|
Write-Host "Started isolated official client (PID $($process.Id))."
|
|
Write-Host "BepInEx log: $(Join-Path $GameDir 'BepInEx\LogOutput.log')"
|
|
Write-Host "Capture root: $(Join-Path $GameDir 'Capture')"
|
|
Write-Host "Isolated data: $isolatedData"
|
|
|
|
if ($Wait) {
|
|
$process.WaitForExit()
|
|
Write-Host "Client exited with code $($process.ExitCode)."
|
|
$latest = Get-ChildItem -LiteralPath (Join-Path $GameDir 'Capture') `
|
|
-Directory -ErrorAction SilentlyContinue |
|
|
Sort-Object LastWriteTime -Descending |
|
|
Select-Object -First 1
|
|
if ($latest) {
|
|
Write-Host "Latest capture: $($latest.FullName)"
|
|
}
|
|
}
|