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