- version.dll proxy (6 exports GetFileVersionInfoA/W etc, runtime forwarding to C:\Windows\System32\version.dll, less flagged than winhttp) built via CMake version SHARED - install.sh: platform detector (Linux/Darwin/Windows), --install/--uninstall/--update/--repair, detects Steam via libraryfolders.vdf, pulls version.dll+winhttp.dll+DevourUnlocker.dll per OS, backs up, patches collectables.json via devour_unlocker.py, handles Forgejo vs GitHub API, no BepInEx required but BepInEx still built as fallback, macOS note (no GameAssembly.dylib available) - install.ps1: same for Windows (Find-GameDir, backup, version.dll primary) - check_offsets.py: verifies GameAssembly sha1 and IsRobeUpdated/UpdateLockedPets still in global-metadata, warns if GameAssembly changed since last install
102 lines
4.9 KiB
PowerShell
102 lines
4.9 KiB
PowerShell
param(
|
|
[string]$Repo = "ad3laid3/DevourUnlocker",
|
|
[string]$Tag = "latest",
|
|
[string]$GameDir = "",
|
|
[switch]$Uninstall,
|
|
[switch]$Update
|
|
)
|
|
$ErrorActionPreference = "Stop"
|
|
# Platform detector: Windows (native) — version.dll is primary (less flagged than winhttp.dll)
|
|
|
|
function Find-GameDir {
|
|
$cands = @(
|
|
"$env:ProgramFiles (x86)/Steam/steamapps/common/Devour",
|
|
"C:/Steam/steamapps/common/Devour",
|
|
"$env:USERPROFILE/.local/share/Steam/steamapps/common/Devour"
|
|
)
|
|
foreach ($c in $cands) { if (Test-Path "$c/DEVOUR.exe") { return $c } }
|
|
$vdf = "$env:ProgramFiles (x86)/Steam/steamapps/libraryfolders.vdf"
|
|
if (Test-Path $vdf) {
|
|
$txt = Get-Content $vdf -Raw
|
|
foreach ($m in [regex]::Matches($txt, '"path"\s+"([^"]+)"')) {
|
|
$p = $m.Groups[1].Value + "/steamapps/common/Devour"
|
|
if (Test-Path "$p/DEVOUR.exe") { return $p }
|
|
}
|
|
}
|
|
return $null
|
|
}
|
|
|
|
if (-not $GameDir) { $GameDir = Find-GameDir }
|
|
if (-not $GameDir -or -not (Test-Path "$GameDir/DEVOUR.exe")) {
|
|
Write-Error "Could not find Devour install. Use -GameDir C:/.../Devour"
|
|
exit 1
|
|
}
|
|
Write-Host "[*] OS: Windows Game dir: $GameDir Mode: $(if($Uninstall){"uninstall"}elseif($Update){"update"}else{"install"})"
|
|
|
|
if ($Uninstall) {
|
|
Write-Host "[*] Uninstalling..."
|
|
@("version.dll","winhttp.dll","DevourUnlocker.dll","DevourUnlocker.json","DevourUnlocker.log") | ForEach-Object { Remove-Item "$GameDir/$_" -ErrorAction SilentlyContinue }
|
|
@("version.dll.bak","winhttp.dll.bak") | ForEach-Object { if (Test-Path "$GameDir/$_") { Move-Item "$GameDir/$_" "$GameDir/$($_.Replace('.bak',''))" -Force; Write-Host "[*] Restored $_" } }
|
|
# Revert collectables.json for current user
|
|
$remote = "$env:USERPROFILE/../AppData/LocalLow/Straight Back Games/DEVOUR" # not needed, Steam Cloud is primary
|
|
Write-Host "[*] Uninstalled. To revert collectables, run: python standalone/devour_unlocker.py unlock --lock"
|
|
exit 0
|
|
}
|
|
|
|
if ($Update) {
|
|
$ga = Join-Path $GameDir "GameAssembly.dll"
|
|
if (Test-Path $ga) {
|
|
$sha = (Get-FileHash $ga -Algorithm SHA1).Hash
|
|
Write-Host "[*] GameAssembly sha1 $sha — will re-fetch release and re-verify offsets"
|
|
}
|
|
}
|
|
|
|
if ($Tag -eq "latest") {
|
|
# Try Forgejo first, then GitHub
|
|
try {
|
|
$api = "https://git.mithraic.cloud/api/v1/repos/$Repo/releases/latest"
|
|
$rel = Invoke-RestMethod -Uri $api -ErrorAction Stop
|
|
$Tag = $rel.tag_name
|
|
} catch {
|
|
$api = "https://api.github.com/repos/$Repo/releases/latest"
|
|
$rel = Invoke-RestMethod -Uri $api
|
|
$Tag = $rel.tag_name
|
|
}
|
|
}
|
|
Write-Host "[*] Installing $Repo $Tag"
|
|
$zipName = "DevourUnlocker_version_$Tag.zip"
|
|
$zipUrl = "https://git.mithraic.cloud/$Repo/releases/download/$Tag/$zipName"
|
|
$altUrl = "https://github.com/$Repo/releases/download/$Tag/$zipName"
|
|
$tmp = Join-Path $env:TEMP "devour_$Tag"
|
|
New-Item -ItemType Directory -Force -Path $tmp | Out-Null
|
|
$zip = Join-Path $tmp "pkg.zip"
|
|
try { Invoke-WebRequest -Uri $zipUrl -OutFile $zip -ErrorAction Stop }
|
|
catch { Invoke-WebRequest -Uri $altUrl -OutFile $zip }
|
|
Expand-Archive -Path $zip -DestinationPath $tmp -Force
|
|
|
|
# Backup if not ours
|
|
foreach($dll in @("version.dll","winhttp.dll")){
|
|
if (Test-Path "$GameDir/$dll") {
|
|
$isOurs = Select-String -Path "$GameDir/$dll" -Pattern "DevourUnlocker" -Quiet -ErrorAction SilentlyContinue
|
|
if (-not $isOurs) { Copy-Item "$GameDir/$dll" "$GameDir/$dll.bak" -Force; Write-Host "[*] Backed up $dll" }
|
|
}
|
|
}
|
|
if (Test-Path "$tmp/version.dll") { Copy-Item "$tmp/version.dll" "$GameDir/version.dll" -Force; Write-Host "[*] Installed version.dll (primary, less detectable)" }
|
|
if (Test-Path "$tmp/winhttp.dll") { Copy-Item "$tmp/winhttp.dll" "$GameDir/winhttp.dll" -Force; Write-Host "[*] Installed winhttp.dll (compat)" }
|
|
if (Test-Path "$tmp/DevourUnlocker.dll") { Copy-Item "$tmp/DevourUnlocker.dll" "$GameDir/DevourUnlocker.dll" -Force }
|
|
# Record GameAssembly hash
|
|
$ga = Join-Path $GameDir "GameAssembly.dll"
|
|
$sha = if(Test-Path $ga){(Get-FileHash $ga -Algorithm SHA1).Hash}else{""}
|
|
if (Test-Path "$tmp/DevourUnlocker.json") {
|
|
$j = Get-Content "$tmp/DevourUnlocker.json" | ConvertFrom-Json
|
|
$j | Add-Member -NotePropertyName gameAssemblySha -NotePropertyValue $sha -Force
|
|
$j | ConvertTo-Json | Out-File "$GameDir/DevourUnlocker.json"
|
|
} else {
|
|
@{unlockRobes=$true;unlockCharacters=$true;unlockPerks=$true;unlockPets=$true;unlockFlashlights=$true;unlockEmotes=$true;unlockOutfits=$true;gameAssemblySha=$sha} | ConvertTo-Json | Out-File "$GameDir/DevourUnlocker.json"
|
|
}
|
|
# Patch Steam Cloud collectables.json via python helper (proper game call: HasCollectedAllBarbedWires etc)
|
|
Write-Host "[*] Patching Steam Cloud collectables.json (proper call: HasCollectedAllBarbedWires)..."
|
|
try { python "$PSScriptRoot/../standalone/devour_unlocker.py" unlock --all } catch { Write-Host "[!] Could not patch collectables.json — will still unlock via runtime hook" }
|
|
|
|
Write-Host "[*] Installed to $GameDir — version.dll is auto-loaded on Windows (no launch option). Just launch Devour."
|
|
Remove-Item $tmp -Recurse -Force
|