- BepInEx: Patches now always-on (IsRobe/IsCharacter/HasPerk/HasOutfit true, UpdateLocked* skipped, WaitForPurchasedPetValidation skipped), GUI hidden by default, no selective checks - native winhttp: src/main.cpp minimal HookThread that waits for GameAssembly + IL2CPP domain then installPatches (no ImGui/D3D11 dummy, no AllocConsole, no libgcc dep) — fixes crash at 0xB5A02F8 strlen null - patches: hIsRobe/hIsChar etc now always true, hookUpdateLocked always bypass, retry for 60s until lobby - winhttp_proxy: runtime forwarding to C:\Windows\System32\winhttp.dll for all 26 WinHttp* (fixes Wine crash) - standalone: _patch_collectables_all now exact full sets (BarbedWires 6, Feathers 2, Tickets 7 etc) not superset 8, so HasCollectedAll* passes; diagnose checks WINEDLLOVERRIDES
84 lines
5 KiB
C#
84 lines
5 KiB
C#
using BepInEx;
|
|
using BepInEx.Logging;
|
|
using HarmonyLib;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace DevourUnlocker.BepInEx
|
|
{
|
|
[BepInPlugin("com.mithral.devourunlocker", "DevourUnlocker", "2.0.0")]
|
|
public class Plugin : BaseUnityPlugin
|
|
{
|
|
internal static ManualLogSource Log;
|
|
private Harmony _harmony;
|
|
|
|
void Awake()
|
|
{
|
|
Log = Logger;
|
|
Log.LogInfo("DevourUnlocker BepInEx v2 loaded — selective unlock");
|
|
_harmony = new Harmony("com.mithral.devourunlocker");
|
|
try {
|
|
_harmony.PatchAll();
|
|
Log.LogInfo("Harmony patches applied");
|
|
} catch (Exception e) { Log.LogError(e); }
|
|
}
|
|
|
|
void OnGUI()
|
|
{
|
|
if (!DevourGUI.visible) return;
|
|
DevourGUI.Draw();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.F6)) DevourGUI.visible = !DevourGUI.visible;
|
|
}
|
|
|
|
void OnDestroy() { _harmony?.UnpatchSelf(); }
|
|
}
|
|
|
|
// Generic unlock patches — try multiple owner classes
|
|
// Always-on: every IsRobe/IsCharacter/Has* check returns true, every UpdateLocked* is skipped
|
|
static class Patches
|
|
{
|
|
static System.Reflection.MethodBase Find(string typeName, string method) {
|
|
var t = AccessTools.TypeByName(typeName);
|
|
if (t==null) return null;
|
|
var m = AccessTools.Method(t, method);
|
|
if (m!=null) Plugin.Log?.LogInfo($"Found {typeName}.{method}");
|
|
return m;
|
|
}
|
|
static System.Reflection.MethodBase FindAny(string method, params string[] types){
|
|
foreach(var tn in types){ var m=Find(tn,method); if(m!=null) return m; }
|
|
Plugin.Log?.LogWarning($"{method} not found in {string.Join(",",types)}");
|
|
return null;
|
|
}
|
|
[HarmonyPatch] class IsRobeUnlockedPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("IsRobeUnlocked","NolanRankController","SurvivalLobbyController","LobbyController"); static bool Prefix(ref bool __result){ __result=true; return false; } }
|
|
[HarmonyPatch] class IsCharacterUnlockedPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("IsCharacterUnlocked","NolanRankController","SurvivalLobbyController"); static bool Prefix(ref bool __result){ __result=true; return false; } }
|
|
[HarmonyPatch] class HasPerkPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("HasPerk","NolanRankController"); static bool Prefix(ref bool __result){ __result=true; return false; } }
|
|
[HarmonyPatch] class HasOutfitPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("HasOutfit","NolanRankController"); static bool Prefix(ref bool __result){ __result=true; return false; } }
|
|
[HarmonyPatch] class HasCollectedAllPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("HasCollectedAllBarbedWires","NolanRankController"); static bool Prefix(ref bool __result){ __result=true; return false; } }
|
|
// UpdateLocked* — skip (return false to prevent original from marking locked)
|
|
[HarmonyPatch] class UpdateLockedPetsPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("UpdateLockedPets","SurvivalLobbyController","LobbyController"); static bool Prefix()=> false; }
|
|
[HarmonyPatch] class UpdateLockedPerksPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("UpdateLockedPerks","SurvivalLobbyController"); static bool Prefix()=> false; }
|
|
[HarmonyPatch] class UpdateLockedFlashlightsPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("UpdateLockedFlashlights","SurvivalLobbyController"); static bool Prefix()=> false; }
|
|
[HarmonyPatch] class UpdateLockedEmotesPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("UpdateLockedEmotes","SurvivalLobbyController"); static bool Prefix()=> false; }
|
|
[HarmonyPatch] class UpdateLockedOutfitsPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("UpdateLockedOutfits","SurvivalLobbyController"); static bool Prefix()=> false; }
|
|
[HarmonyPatch] class UpdateLockedRobesPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("UpdateLockedRobes","SurvivalLobbyController"); static bool Prefix()=> false; }
|
|
[HarmonyPatch] class WaitForPurchasedPetValidationPatch { static System.Reflection.MethodBase TargetMethod()=> FindAny("WaitForPurchasedPetValidation","SurvivalLobbyController"); static bool Prefix()=> false; }
|
|
}
|
|
|
|
static class DevourGUI
|
|
{
|
|
public static bool visible = false; // always-on, GUI hidden by default (F6 to show debug)
|
|
public static void Draw()
|
|
{
|
|
var rect = new UnityEngine.Rect(20, 20, 400, 100);
|
|
UnityEngine.GUI.Box(rect, "");
|
|
GUILayout.BeginArea(rect);
|
|
GUILayout.Label("DevourUnlocker — Always On (all robes/chars/perks/pets unlocked)");
|
|
GUILayout.Label("F6 to toggle this debug window");
|
|
GUILayout.EndArea();
|
|
}
|
|
}
|
|
}
|