Decompiled source of AutoInteract v1.0.0

AutoInteract.dll

Decompiled 2 days ago
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();
			}
		}
	}
}