using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Assets.Scripts.Inventory__Items__Pickups.Chests;
using Assets.Scripts.Inventory__Items__Pickups.Interactables;
using Assets.Scripts.Managers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AutoInteract")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Automatically interacts with pots, pumpkins, tumbleweeds, and more")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+22c31cd9a85c53b53ffda9eb36170da3df183286")]
[assembly: AssemblyProduct("AutoInteract")]
[assembly: AssemblyTitle("AutoInteract")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace AutoInteract
{
[BepInPlugin("ZeusesNeckMeat_AutoInteract", "AutoInteract", "1.0.0")]
public class AutoInteract : BasePlugin
{
private static ManualLogSource _logger;
public static ManualLogSource Logger => _logger;
public AutoInteract()
{
_logger = ((BasePlugin)this).Log;
}
public override void Load()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
ManualLogSource logger = _logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(14, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loading ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("AutoInteract");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" by ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ZeusesNeckMeat");
}
logger.LogInfo(val);
Harmony val2 = new Harmony("ZeusesNeckMeat_AutoInteract");
val2.PatchAll();
ModConfig.Init(((BasePlugin)this).Config);
if (!ModConfig.IsEnabled)
{
_logger.LogInfo((object)"AutoInteract is disabled in config. Skipping cache initialization.");
}
}
}
internal static class AvailableInteractables
{
private static readonly Dictionary<string, InteractableType> _interactableTypes = new Dictionary<string, InteractableType>
{
{
((MemberInfo)Il2CppType.Of<InteractablePot>()).Name,
InteractableType.Pot
},
{
((MemberInfo)Il2CppType.Of<InteractableTumbleWeed>()).Name,
InteractableType.Tumbleweed
},
{
((MemberInfo)Il2CppType.Of<InteractableChest>()).Name,
InteractableType.Chest
},
{
((MemberInfo)Il2CppType.Of<InteractableShadyGuy>()).Name,
InteractableType.ShadyGuy
},
{
((MemberInfo)Il2CppType.Of<InteractableShrineBalance>()).Name,
InteractableType.BaldHead
},
{
((MemberInfo)Il2CppType.Of<InteractableGravestone>()).Name,
InteractableType.Gravestone
},
{
((MemberInfo)Il2CppType.Of<InteractableShrineChallenge>()).Name,
InteractableType.ChallengeShrine
},
{
((MemberInfo)Il2CppType.Of<InteractableShrineCursed>()).Name,
InteractableType.BossCurseShrine
},
{
((MemberInfo)Il2CppType.Of<InteractableShrineGreed>()).Name,
InteractableType.GreedShrine
},
{
((MemberInfo)Il2CppType.Of<InteractableShrineMagnet>()).Name,
InteractableType.MagnetShrine
},
{
((MemberInfo)Il2CppType.Of<InteractableShrineMoai>()).Name,
InteractableType.MoaiShrine
}
};
private static readonly Dictionary<InteractableType, bool> _defaultAutoInteractValues = new Dictionary<InteractableType, bool>
{
{
InteractableType.Pot,
true
},
{
InteractableType.Tumbleweed,
true
},
{
InteractableType.Chest,
true
},
{
InteractableType.ShadyGuy,
false
},
{
InteractableType.BaldHead,
false
},
{
InteractableType.Gravestone,
false
},
{
InteractableType.ChallengeShrine,
false
},
{
InteractableType.BossCurseShrine,
false
},
{
InteractableType.GreedShrine,
false
},
{
InteractableType.MagnetShrine,
false
},
{
InteractableType.MoaiShrine,
false
}
};
public static HashSet<string> GetAllTypeNames()
{
return _interactableTypes.Keys.ToHashSet();
}
public static HashSet<InteractableType> GetAllTypes()
{
return _interactableTypes.Values.ToHashSet();
}
public static bool TryGetType(string il2CppTypeName, out InteractableType type)
{
return _interactableTypes.TryGetValue(il2CppTypeName, out type);
}
public static bool TryGetType(Type il2CppType, out InteractableType type)
{
return TryGetType((il2CppType != null) ? ((MemberInfo)il2CppType).Name : null, out type);
}
public static bool TryGetType(BaseInteractable interactable, out InteractableType type)
{
return TryGetType((interactable != null) ? ((Object)interactable).GetIl2CppType() : null, out type);
}
public static bool IsSupportedType(string il2CppTypeName)
{
return _interactableTypes.ContainsKey(il2CppTypeName);
}
public static bool IsSupportedType(Type il2CppType)
{
return IsSupportedType((il2CppType != null) ? ((MemberInfo)il2CppType).Name : null);
}
public static bool IsSupportedType(BaseInteractable interactable)
{
return IsSupportedType((interactable != null) ? ((Object)interactable).GetIl2CppType() : null);
}
public static bool GetDefaultAutoInteractValue(InteractableType type)
{
bool value;
return _defaultAutoInteractValues.TryGetValue(type, out value) && value;
}
}
public enum InteractableType
{
Pot,
Tumbleweed,
Chest,
ShadyGuy,
BaldHead,
Gravestone,
ChallengeShrine,
BossCurseShrine,
GreedShrine,
MagnetShrine,
MoaiShrine
}
internal static class Constants
{
public const string MODNAME = "AutoInteract";
public const string AUTHOR = "ZeusesNeckMeat";
public const string GUID = "ZeusesNeckMeat_AutoInteract";
public const string VERSION = "1.0.0";
}
internal static class InteractableCache
{
private static readonly HashSet<int> _interactables = new HashSet<int>();
private static readonly Dictionary<InteractableType, HashSet<int>> _typeSpecificCaches = new Dictionary<InteractableType, HashSet<int>>();
public static void AddInteractable(int id, InteractableType interactableType)
{
_interactables.Add(id);
if (!_typeSpecificCaches.ContainsKey(interactableType))
{
_typeSpecificCaches[interactableType] = new HashSet<int>();
}
_typeSpecificCaches[interactableType].Add(id);
}
public static bool RemoveInteractable(int id, InteractableType interactableType)
{
_interactables.Remove(id);
if (_typeSpecificCaches.TryGetValue(interactableType, out var value))
{
value.Remove(id);
}
return true;
}
public static bool HasInteractable(int id)
{
return _interactables.Contains(id);
}
public static void Clear()
{
_interactables.Clear();
_typeSpecificCaches.Clear();
}
}
internal static class InteractableService
{
public static void TryRegisterInteractable(BaseInteractable interactable)
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
try
{
if (ModConfig.IsEnabled && IsInteractableValid(interactable) && AvailableInteractables.TryGetType(interactable, out var type) && ModConfig.CanAutoInteract(type))
{
InteractableCache.AddInteractable(((Object)interactable).GetInstanceID(), type);
}
}
catch (Exception ex)
{
ManualLogSource logger = AutoInteract.Logger;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to register interactable: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
logger.LogError(val);
}
}
public static void TryUseInteractable(DetectInteractables detector)
{
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Expected O, but got Unknown
try
{
if (ModConfig.IsEnabled && !((Object)(object)detector == (Object)null) && !((Il2CppObjectBase)detector).WasCollected && !((MonoBehaviour)detector).IsInvoking("TryInteract"))
{
BaseInteractable currentInteractable = detector.currentInteractable;
if (IsInteractableValid(currentInteractable) && AvailableInteractables.TryGetType(currentInteractable, out var type) && ModConfig.CanAutoInteract(type) && ((Object)detector.currentInteractable).GetInstanceID() == ((Object)currentInteractable).GetInstanceID() && InteractableCache.HasInteractable(((Object)currentInteractable).GetInstanceID()) && ((Behaviour)currentInteractable).isActiveAndEnabled)
{
detector.TryInteract();
InteractableCache.RemoveInteractable(((Object)currentInteractable).GetInstanceID(), type);
}
}
}
catch (Exception ex)
{
ManualLogSource logger = AutoInteract.Logger;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to use interactable: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
logger.LogError(val);
}
}
private static bool IsInteractableValid(BaseInteractable interactable)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
int result;
if ((Object)(object)interactable != (Object)null && !((Il2CppObjectBase)interactable).WasCollected && (Object)(object)((Component)interactable).gameObject != (Object)null && !((Il2CppObjectBase)((Component)interactable).gameObject).WasCollected)
{
Scene scene = ((Component)interactable).gameObject.scene;
result = ((((Scene)(ref scene)).name == "GeneratedMap") ? 1 : 0);
}
else
{
result = 0;
}
return (byte)result != 0;
}
}
internal class ModConfig
{
private static ConfigEntry<bool> _isEnabled;
private static readonly Dictionary<InteractableType, ConfigEntry<bool>> _interactableSettings = new Dictionary<InteractableType, ConfigEntry<bool>>();
private static ConfigEntry<float> _interactableRange;
public static bool IsEnabled => _isEnabled.Value;
public static float InteractableRange => _interactableRange.Value;
public static void Init(ConfigFile config)
{
_isEnabled = config.Bind<bool>("General", "Is Enabled", true, "Enable or disable the AutoInteract mod.");
_interactableRange = config.Bind<float>("General", "Interaction Range", 3f, "Maximum distance for interacting with interactables. This is a GLOBAL change, meaning it will affect the interaction range of ALL interactables, including ones not available for auto interaction with this mod.");
foreach (InteractableType allType in AvailableInteractables.GetAllTypes())
{
string text = $"Auto Interact with {allType}s";
string text2 = "Allow auto-interacting with " + allType.ToString().ToLower() + "s.";
bool defaultAutoInteractValue = AvailableInteractables.GetDefaultAutoInteractValue(allType);
if (allType == InteractableType.Pot)
{
text = "Auto Interact with Pots AND Pumpkins";
text2 = "Allow auto-interacting with pots and pumpkins. (Pots and pumpkins share the same interactable type, so this setting will affect both.)";
}
_interactableSettings[allType] = config.Bind<bool>("Interactables", text, defaultAutoInteractValue, text2);
}
}
public static bool CanAutoInteract(InteractableType type)
{
ConfigEntry<bool> value;
return _interactableSettings.TryGetValue(type, out value) && value.Value;
}
}
}
namespace AutoInteract.Patches
{
[HarmonyPatch(typeof(BaseInteractable), "Start")]
internal class BaseInteractable_Start_Patch
{
[HarmonyPostfix]
public static void BaseInteractable_Start_Postfix(BaseInteractable __instance)
{
InteractableService.TryRegisterInteractable(__instance);
}
}
[HarmonyPatch(typeof(DetectInteractables), "Update")]
internal class DetectInteractables_Update_Patch
{
[HarmonyPostfix]
public static void DetectInteractables_Update_Postfix(DetectInteractables __instance)
{
InteractableService.TryUseInteractable(__instance);
}
}
[HarmonyPatch(typeof(DetectInteractables), "Awake")]
internal class DetectInteractables_Awake_Patch
{
[HarmonyPostfix]
public static void DetectInteractables_Awake_Postfix(DetectInteractables __instance)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
if (ModConfig.IsEnabled && !((Object)(object)__instance == (Object)null))
{
ManualLogSource logger = AutoInteract.Logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Setting interactable range to ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(ModConfig.InteractableRange);
}
logger.LogInfo(val);
__instance.interactableRange = ModConfig.InteractableRange;
}
}
}
[HarmonyPatch(typeof(MapController), "StartNewMap")]
internal static class MapController_StartNewMap_Patch
{
[HarmonyPostfix]
public static void Postfix()
{
if (ModConfig.IsEnabled)
{
if (!MapController.IsFirstStage())
{
AutoInteract.Logger.LogDebug((object)"MapController.StartNewMap called. Not first stage, skipping cache clear.");
return;
}
AutoInteract.Logger.LogDebug((object)"MapController.StartNewMap called. First stage detected, clearing interactable cache.");
InteractableCache.Clear();
}
}
}
}