DevourUnlocker/scripts/install.ps1
MiTHRAL 6329350e90
Some checks are pending
Build DevourUnlocker / windows-cross (push) Waiting to run
Build DevourUnlocker / linux (push) Waiting to run
Build DevourUnlocker / standalone (push) Waiting to run
add version.dll (less flagged) + per-platform installers with redownload/shift check
- 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
2026-08-24 00:03:19 -04:00

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