diff --git a/src/il2cpp_resolver.cpp b/src/il2cpp_resolver.cpp index 44ef4b5..ee8b285 100644 --- a/src/il2cpp_resolver.cpp +++ b/src/il2cpp_resolver.cpp @@ -17,6 +17,10 @@ namespace devour { +static std::set g_queriedDefs; +std::set& QueriedDefs(){ return g_queriedDefs; } +void RememberQueriedDef(uint64_t id){ g_queriedDefs.insert(id); } + #ifdef _WIN32 static HMODULE g_gameAsm = nullptr; @@ -560,7 +564,19 @@ int Il2CppResolver::fabricateOwnership(){ for(int i=0;i #include #include +#include // Minimal IL2CPP types — avoids needing il2cpp headers at compile time struct Il2CppString { void* klass; void* monitor; int32_t length; wchar_t chars[1]; }; @@ -9,6 +10,12 @@ struct MethodInfo; namespace devour { +// Def ids the game itself asked UserHasItem/PlayerHasItem about (DLC/promo defs +// absent from the store catalog live here). Fabricator injects these too. +std::set& QueriedDefs(); +void RememberQueriedDef(uint64_t id); + + // Resolves IL2CPP method pointers without hard offsets. // Strategy 1: via il2cpp exports (class/method lookup) // Strategy 2: xref string sigscan as fallback diff --git a/src/patches.cpp b/src/patches.cpp index bda572a..2ba3af8 100644 --- a/src/patches.cpp +++ b/src/patches.cpp @@ -91,6 +91,7 @@ static void __fastcall hUpdateLockedRobes(void* thiz, void* method) { if (oUpdRo // LOGS every query — if the pet UI never appears in the log, it reads the userItems list field directly. static bool __fastcall hUserHasItem(void* thiz, unsigned long long itemDef, void* method) { // pass-through + trace (v2.1.0 proved forcing true blocks purchases) + RememberQueriedDef((uint64_t)itemDef); char b[96]; snprintf(b,sizeof(b),"[trace] UserHasItem(def=%llu)", (unsigned long long)itemDef); logPatch(b); if (oUserHasItem) return oUserHasItem(thiz, itemDef, method); return false; @@ -99,6 +100,7 @@ static bool __fastcall hUserHasItem(void* thiz, unsigned long long itemDef, void static bool __fastcall hPlayerHasItem(void* thiz, int connectionId, unsigned long long itemDef, void* method) { // MUST stay pass-through: forcing true desyncs lobby validation vs injected // userItems and UNLOCKS REGRESS (pets locked again). See v2.1.1 regression. + RememberQueriedDef((uint64_t)itemDef); char b[128]; snprintf(b,sizeof(b),"[trace] PlayerHasItem(conn=%d def=%llu)", connectionId, (unsigned long long)itemDef); logPatch(b); if (oPlayerHasItem) return oPlayerHasItem(thiz, connectionId, itemDef, method); return false;