Decompiled source of BetterBugphobia v1.1.1

plugins/com.github.StarAppeal.BetterBugphobia.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Sirenix.Utilities;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.StarAppeal.BetterBugphobia")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+a9f0bb9d406029309c3ef88851b75351b39b90dd")]
[assembly: AssemblyProduct("com.github.StarAppeal.BetterBugphobia")]
[assembly: AssemblyTitle("BetterBugphobia")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BetterBugphobia
{
	[HarmonyPatch(typeof(BeeSwarm), "Start")]
	public class BeeSwarmPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(BeeSwarm __instance)
		{
			Plugin.Log.LogInfo((object)"BeeSwarm Prefix started!");
			if ((Object)(object)Plugin.OriginalBeeSwarmMaterial == (Object)null)
			{
				Plugin.Log.LogInfo((object)"Saving original particles");
				Plugin.OriginalBeeSwarmMaterial = ((Renderer)((Component)__instance.beeParticles).GetComponent<ParticleSystemRenderer>()).material;
			}
			Plugin.ApplyBeeSwarmSettings(__instance);
			Plugin.Log.LogInfo((object)"BeeSwarm Prefix finished, preventing calling original method");
			return false;
		}
	}
	[HarmonyPatch(typeof(BugPhobia), "Start")]
	public class BugPhobiaPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(BugPhobia __instance)
		{
			BugPhobia __instance2 = __instance;
			Plugin.Log.LogInfo((object)"BugPhobia Prefix started!");
			Plugin.Log.LogDebug((object)(((Object)((Component)__instance2).gameObject).name ?? ""));
			Type type2 = Plugin.MonsterTypesHashSet.FirstOrDefault((Type type) => (Object)(object)((Component)__instance2).gameObject.GetComponentInChildren(type, true) != (Object)null);
			if (type2 == null)
			{
				Item componentInChildren = ((Component)__instance2).gameObject.GetComponentInChildren<Item>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					Plugin.Log.LogInfo((object)"No item found!");
					return true;
				}
				if (componentInChildren.UIData.itemName == "Tick")
				{
					type2 = typeof(Bugfix);
				}
			}
			Plugin.Log.LogInfo((object)$"Found type: {type2}");
			if (type2 == null)
			{
				return true;
			}
			Plugin.bugPhobiaMap.TryGetValue(type2, out ConfigEntry<bool> value);
			if (value == null)
			{
				return true;
			}
			GameObject[] defaultGameObjects = __instance2.defaultGameObjects;
			foreach (GameObject val in defaultGameObjects)
			{
				val.SetActive(!value.Value);
			}
			GameObject[] bugPhobiaGameObjects = __instance2.bugPhobiaGameObjects;
			foreach (GameObject val2 in bugPhobiaGameObjects)
			{
				val2.SetActive(value.Value);
			}
			if (Object.op_Implicit((Object)(object)__instance2.bbas))
			{
				__instance2.bbas.Init();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemUIData))]
	public class ItemPatcher
	{
		private static readonly Dictionary<string, Type> ItemNameToMobTypeMap = new Dictionary<string, Type>
		{
			{
				"Tick",
				typeof(Bugfix)
			},
			{
				"Scorpion",
				typeof(Scorpion)
			}
		};

		[HarmonyPatch("GetIcon")]
		[HarmonyPostfix]
		private static void Postfix(ItemUIData __instance, ref Texture2D __result)
		{
			if (ItemNameToMobTypeMap.TryGetValue(__instance.itemName, out Type value) && Plugin.bugPhobiaMap.TryGetValue(value, out ConfigEntry<bool> value2))
			{
				__result = (value2.Value ? __instance.altIcon : __instance.icon);
			}
		}
	}
	public static class MonsterCache
	{
		private static readonly Dictionary<Type, List<Component>> activeMobs = new Dictionary<Type, List<Component>>();

		public static void Add(Component mob)
		{
			Type type = ((object)mob).GetType();
			if (!activeMobs.ContainsKey(type))
			{
				activeMobs[type] = new List<Component>();
			}
			activeMobs[type].Add(mob);
		}

		public static void Remove(Component mob)
		{
			Type type = ((object)mob).GetType();
			if (activeMobs.TryGetValue(type, out List<Component> value))
			{
				value.Remove(mob);
			}
		}

		public static IEnumerable<Component> GetActiveMobs(Type mobType)
		{
			if (activeMobs.TryGetValue(mobType, out List<Component> value))
			{
				return value.ToList();
			}
			return (IEnumerable<Component>)Enumerable.Empty<MonoBehaviour>();
		}
	}
	[HarmonyPatch]
	public static class MonsterCreationPatcher
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private HashSet<Type>.Enumerator <>7__wrap1;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(HashSet<Type>.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = Plugin.MonsterTypesHashSet.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					}
					while (<>7__wrap1.MoveNext())
					{
						Type current = <>7__wrap1.Current;
						MethodInfo methodInfo = AccessTools.Method(current, "Awake", (Type[])null, (Type[])null) ?? AccessTools.Method(current, "Start", (Type[])null, (Type[])null);
						if (methodInfo != null)
						{
							<>2__current = methodInfo;
							<>1__state = 1;
							return true;
						}
						Plugin.Log.LogWarning((object)("[BetterBugphobia] Couldn't find start / awake method for " + current.Name + "."));
					}
					<>m__Finally1();
					<>7__wrap1 = default(HashSet<Type>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap1).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__0(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<TargetMethods>d__0))]
		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__0(-2);
		}

		[HarmonyPostfix]
		private static void Postfix(Component __instance)
		{
			MonsterCache.Add(__instance);
		}
	}
	[HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object) })]
	public static class MonsterDestructionPatcher
	{
		[HarmonyPrefix]
		private static void Prefix(Object __0)
		{
			GameObject val = (GameObject)(object)((__0 is GameObject) ? __0 : null);
			if (val == null)
			{
				return;
			}
			foreach (Type item in Plugin.MonsterTypesHashSet)
			{
				Component component = val.GetComponent(item);
				if ((Object)(object)component != (Object)null)
				{
					MonsterCache.Remove(component);
					Plugin.Log.LogInfo((object)("[BetterBugphobia] " + ((object)component).GetType().Name + " removed from cache."));
					break;
				}
			}
		}
	}
	[BepInPlugin("com.github.StarAppeal.BetterBugphobia", "BetterBugphobia", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public class Setting
		{
			public Type MobType { get; }

			public string SettingName { get; }

			public List<EventHandler> AdditionalOnSettingChanged { get; set; } = new List<EventHandler>();


			public Setting(Type mobType, string settingName)
			{
				MobType = mobType;
				SettingName = settingName;
			}
		}

		public static List<Setting> mobList = new List<Setting>(6)
		{
			new Setting(typeof(Antlion), "Antlion"),
			new Setting(typeof(BeeSwarm), "Bee")
			{
				AdditionalOnSettingChanged = new List<EventHandler>(1) { OnBeesSettingChanged }
			},
			new Setting(typeof(Beetle), "Beetle"),
			new Setting(typeof(Scorpion), "Scorpion")
			{
				AdditionalOnSettingChanged = new List<EventHandler>(2) { UpdateScorpionIcon, UpdateScorpionInWorldTextures }
			},
			new Setting(typeof(Spider), "Spider"),
			new Setting(typeof(Bugfix), "Tick")
			{
				AdditionalOnSettingChanged = new List<EventHandler>(2) { UpdateTickIcon, UpdateTickInWorldTextures }
			}
		};

		public static Dictionary<Type, ConfigEntry<bool>> bugPhobiaMap = new Dictionary<Type, ConfigEntry<bool>>();

		public static Material? OriginalBeeSwarmMaterial;

		public const string Id = "com.github.StarAppeal.BetterBugphobia";

		internal static ManualLogSource Log { get; private set; } = null;


		public static HashSet<Type> MonsterTypesHashSet { get; private set; }

		public static string Name => "BetterBugphobia";

		public static string Version => "1.1.1";

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			InitializeConfig();
			Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, (string)null);
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}

		private void InitializeConfig()
		{
			foreach (Setting mob in mobList)
			{
				ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("General", mob.SettingName, false, "Toggle the " + mob.SettingName + "s appearance. false = normal appearance, true = Bing Bong");
				foreach (EventHandler item in mob.AdditionalOnSettingChanged)
				{
					val.SettingChanged += item;
				}
				val.SettingChanged += delegate
				{
					OnBugPhobiaSettingChanged(mob.MobType);
				};
				bugPhobiaMap.Add(mob.MobType, val);
			}
		}

		private static void OnBugPhobiaSettingChanged(Type mobType)
		{
			if (!bugPhobiaMap.TryGetValue(mobType, out ConfigEntry<bool> value))
			{
				return;
			}
			bool value2 = value.Value;
			BugPhobia val2 = default(BugPhobia);
			foreach (Component activeMob in MonsterCache.GetActiveMobs(mobType))
			{
				if ((Object)(object)activeMob == (Object)null)
				{
					continue;
				}
				MonoBehaviour val = (MonoBehaviour)(object)((activeMob is MonoBehaviour) ? activeMob : null);
				if (val != null && ((Component)val).TryGetComponent<BugPhobia>(ref val2))
				{
					GameObject[] defaultGameObjects = val2.defaultGameObjects;
					foreach (GameObject val3 in defaultGameObjects)
					{
						val3.SetActive(!value2);
					}
					GameObject[] bugPhobiaGameObjects = val2.bugPhobiaGameObjects;
					foreach (GameObject val4 in bugPhobiaGameObjects)
					{
						val4.SetActive(value2);
					}
					if (Object.op_Implicit((Object)(object)val2.bbas))
					{
						val2.bbas.Init();
					}
				}
			}
		}

		private static void OnBeesSettingChanged(object? sender, EventArgs e)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			Log.LogInfo((object)"Bee setting changed, applying new settings");
			foreach (Component activeMob in MonsterCache.GetActiveMobs(typeof(BeeSwarm)))
			{
				ApplyBeeSwarmSettings((BeeSwarm)activeMob);
			}
		}

		private static void UpdateTickIcon(object s, EventArgs e)
		{
			UpdateItemIcons("Tick");
		}

		private static void UpdateTickInWorldTextures(object s, EventArgs e)
		{
			UpdateItemInWorldTextures("Tick", typeof(Bugfix));
		}

		private static void UpdateScorpionIcon(object s, EventArgs e)
		{
			UpdateItemIcons("Scorpion");
		}

		private static void UpdateScorpionInWorldTextures(object s, EventArgs e)
		{
			UpdateItemInWorldTextures("Scorpion", typeof(Scorpion));
		}

		private static void UpdateItemIcons(string itemName)
		{
			Log.LogInfo((object)(itemName + " setting changed, refreshing icons..."));
			Character localCharacter = Character.localCharacter;
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)localCharacter == (Object)null)
			{
				Log.LogWarning((object)"GUIManager or LocalCharacter not found. Cannot refresh icons.");
				return;
			}
			RefreshItemIconForUiSlot(localCharacter.player.tempFullSlot, instance.temporaryItem, itemName, "temporary slot");
			InventoryItemUI[] items = instance.items;
			ItemSlot[] itemSlots = localCharacter.player.itemSlots;
			for (int i = 0; i < itemSlots.Length; i++)
			{
				if (i < items.Length)
				{
					RefreshItemIconForUiSlot(itemSlots[i], items[i], itemName, $"slot {i}");
				}
			}
			Log.LogInfo((object)(itemName + " icon refresh complete."));
		}

		private static void RefreshItemIconForUiSlot(ItemSlot itemSlot, InventoryItemUI uiSlot, string itemName, string slotIdentifier)
		{
			if ((Object)(object)uiSlot != (Object)null && IsMatchingItemSlot(itemSlot, itemName))
			{
				Log.LogInfo((object)("Found " + itemName + " in " + slotIdentifier + ". Forcing icon texture update."));
				uiSlot.icon.texture = (Texture)(object)itemSlot.prefab.UIData.GetIcon();
			}
		}

		public static bool IsMatchingItemSlot(ItemSlot slot, string itemName)
		{
			if (!slot.IsEmpty())
			{
				return slot.prefab.UIData.itemName == itemName;
			}
			return false;
		}

		private static void UpdateItemInWorldTextures(string itemName, Type mobType)
		{
			string itemName2 = itemName;
			Log.LogInfo((object)(itemName2 + " setting changed, refreshing in-world textures..."));
			if (!bugPhobiaMap.TryGetValue(mobType, out ConfigEntry<bool> configEntry))
			{
				return;
			}
			LinqExtensions.ForEach<BugPhobia>(from item in Object.FindObjectsByType<Item>((FindObjectsSortMode)0)
				where item.UIData.itemName == itemName2
				select ((Component)item).GetComponent<BugPhobia>() into component
				where (Object)(object)component != (Object)null
				select component, (Action<BugPhobia>)delegate(BugPhobia bugPhobiaComponent)
			{
				LinqExtensions.ForEach<GameObject>((IEnumerable<GameObject>)bugPhobiaComponent.defaultGameObjects, (Action<GameObject>)delegate(GameObject go)
				{
					go.SetActive(!configEntry.Value);
				});
				LinqExtensions.ForEach<GameObject>((IEnumerable<GameObject>)bugPhobiaComponent.bugPhobiaGameObjects, (Action<GameObject>)delegate(GameObject go)
				{
					go.SetActive(configEntry.Value);
				});
				if (Object.op_Implicit((Object)(object)bugPhobiaComponent.bbas))
				{
					bugPhobiaComponent.bbas.Init();
				}
			});
		}

		public static void ApplyBeeSwarmSettings(BeeSwarm beeSwarm)
		{
			Log.LogInfo((object)"Applying BeeSwarm settings");
			if (bugPhobiaMap.TryGetValue(typeof(BeeSwarm), out ConfigEntry<bool> value))
			{
				ParticleSystemRenderer component = ((Component)beeSwarm.beeParticles).GetComponent<ParticleSystemRenderer>();
				if (value.Value)
				{
					((Renderer)component).material = beeSwarm.bingBongMaterial;
				}
				else if ((Object)(object)OriginalBeeSwarmMaterial != (Object)null)
				{
					((Renderer)component).material = OriginalBeeSwarmMaterial;
				}
				else
				{
					Log.LogWarning((object)"Original BeeSwarm Material not found, ignoring setting for now");
				}
			}
		}

		static Plugin()
		{
			HashSet<Type> hashSet = new HashSet<Type>();
			foreach (Type item in mobList.ConvertAll((Setting mob) => mob.MobType))
			{
				hashSet.Add(item);
			}
			MonsterTypesHashSet = hashSet;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}