- 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
39 lines
2.1 KiB
Python
39 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Check if GameAssembly.dll unlock offsets have shifted since last install.
|
|
Uses the same logic as src/il2cpp_resolver.cpp: tries to resolve IsRobeUnlocked etc via
|
|
il2cpp_class_from_name + hasCollectedAll, and also checks collectables.json full sets.
|
|
If GameAssembly sha1 differs from DevourUnlocker.json:gameAssemblySha, warns to --repair.
|
|
"""
|
|
import pathlib, hashlib, json, sys, re
|
|
def sha1(p): return hashlib.sha1(open(p,'rb').read()).hexdigest()
|
|
def check(game_dir):
|
|
ga = pathlib.Path(game_dir) / "GameAssembly.dll"
|
|
gm = pathlib.Path(game_dir) / "DEVOUR_Data/il2cpp_data/Metadata/global-metadata.dat"
|
|
dj = pathlib.Path(game_dir) / "DevourUnlocker.json"
|
|
print(f"GameAssembly: {ga} exists={ga.exists()} sha1={sha1(ga) if ga.exists() else 'missing'}")
|
|
if gm.exists():
|
|
data=open(gm,'rb').read()
|
|
for needle in [b'IsRobeUnlocked', b'IsCharacterUnlocked', b'UpdateLockedPets', b'HasPerk']:
|
|
print(f" {needle.decode()} in global-metadata: {'FOUND' if needle in data else 'NOT FOUND'} at {data.find(needle) if needle in data else -1}")
|
|
if dj.exists():
|
|
j=json.loads(dj.read_text())
|
|
print(f"DevourUnlocker.json gameAssemblySha={j.get('gameAssemblySha','')}")
|
|
if ga.exists():
|
|
cur=sha1(ga)
|
|
if j.get('gameAssemblySha') and j['gameAssemblySha']!=cur:
|
|
print(f"[!] GameAssembly changed since last install (was {j['gameAssemblySha'][:8]} now {cur[:8]}) — run: bash scripts/install.sh --repair or .\\scripts\\install.ps1 -Update")
|
|
return 1
|
|
else:
|
|
print("[*] GameAssembly unchanged since last install")
|
|
# Also check collectables.json for all users
|
|
for p in pathlib.Path.home().glob(".local/share/Steam/userdata/*/1274570/remote/collectables.json"):
|
|
try:
|
|
j=json.loads(p.read_text())
|
|
print(f"collectables {p.parent.parent.name}: BarbedWires {j.get('BarbedWires')} ({len(j.get('BarbedWires',[]))})")
|
|
except: pass
|
|
return 0
|
|
|
|
if __name__=="__main__":
|
|
gd = sys.argv[1] if len(sys.argv)>1 else "/home/mithral/.local/share/Steam/steamapps/common/Devour"
|
|
sys.exit(check(gd))
|