Decompiled source of HoharderSkin v1.0.1

com.github.zehsteam.HoharderSkin.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;
using com.github.zehsteam.HoharderSkin.Dependencies;
using com.github.zehsteam.HoharderSkin.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.zehsteam.HoharderSkin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Reskins the Hoarding Bug to PsychoHypnotic as a potato.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+07f57e5e9d085d4b1cd4d1e121351eeed825df38")]
[assembly: AssemblyProduct("HoharderSkin")]
[assembly: AssemblyTitle("com.github.zehsteam.HoharderSkin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace com.github.zehsteam.HoharderSkin
{
	internal static class AudioUtils
	{
		public static AudioClip LoadAudioClip(string path, AudioType type)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			string text = "file://" + path;
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(text, type);
			try
			{
				UnityWebRequestAsyncOperation val = audioClip.SendWebRequest();
				try
				{
					while (!((AsyncOperation)val).isDone)
					{
					}
					if ((int)audioClip.result != 1)
					{
						Plugin.logger.LogError((object)("Failed to load AudioClip from path \"" + path + "\". Error: " + audioClip.error));
						return null;
					}
					AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
					((Object)content).name = Path.GetFileNameWithoutExtension(path);
					Plugin.Instance.LogInfoExtended("Successfully loaded AudioClip \"" + ((Object)content).name + "\" from path \"" + path + "\".");
					return content;
				}
				catch (Exception arg)
				{
					Plugin.logger.LogError((object)$"Failed to load AudioClip from path \"{path}\". {arg}");
				}
				return null;
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
		}

		public static AudioType DetectAudioType(string filePath)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetExtension(filePath).ToLower();
			switch (text)
			{
			case ".wav":
				return (AudioType)20;
			case ".ogg":
				return (AudioType)14;
			case ".mp3":
				return (AudioType)13;
			default:
				Plugin.logger.LogWarning((object)("Unknown audio file extension: " + text + ". Defaulting to WAV."));
				return (AudioType)20;
			}
		}
	}
	internal static class ConfigHelper
	{
		public static void SetModIcon(Sprite sprite)
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.SetModIcon(sprite);
			}
		}

		public static void SetModDescription(string description)
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.SetModDescription(description);
			}
		}

		public static void SkipAutoGen()
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.SkipAutoGen();
			}
		}

		public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, bool requiresRestart, string description, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			if (configFile == null)
			{
				configFile = ((BaseUnityPlugin)Plugin.Instance).Config;
			}
			ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>())));
			if (settingChanged != null)
			{
				configEntry.SettingChanged += delegate
				{
					settingChanged?.Invoke(configEntry.Value);
				};
			}
			if (LethalConfigProxy.Enabled)
			{
				if (acceptableValues == null)
				{
					LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart);
				}
				else
				{
					LethalConfigProxy.AddConfigSlider<T>(configEntry, requiresRestart);
				}
			}
			return configEntry;
		}

		public static void AddButton(string section, string name, string description, string buttonText, Action callback)
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddButton(section, name, description, buttonText, callback);
			}
		}
	}
	internal class ConfigManager
	{
		public ConfigEntry<bool> ExtendedLogging { get; private set; }

		public ConfigManager()
		{
			BindConfigs();
		}

		private void BindConfigs()
		{
			ConfigHelper.SkipAutoGen();
			ExtendedLogging = ConfigHelper.Bind("General", "ExtendedLogging", defaultValue: false, requiresRestart: false, "Enable extended logging.");
		}
	}
	internal static class Content
	{
		public static GameObject HoharderControllerPrefab { get; private set; }

		public static List<AudioClip> ChitterSFX { get; private set; } = new List<AudioClip>();


		public static List<AudioClip> AngryScreechSFX { get; private set; } = new List<AudioClip>();


		public static List<AudioClip> BugWalkSFX { get; private set; } = new List<AudioClip>();


		public static void Load()
		{
			LoadAssetsFromAssetBundle();
			LoadAssetsFromHoharder();
		}

		private static void LoadAssetsFromAssetBundle()
		{
			AssetBundle val = LoadAssetBundle("hoharderskin_assets");
			if (!((Object)(object)val == (Object)null))
			{
				HoharderControllerPrefab = val.LoadAsset<GameObject>("HoharderController");
				Plugin.logger.LogInfo((object)"Successfully loaded assets from AssetBundle!");
			}
		}

		private static void LoadAssetsFromHoharder()
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
			string path = directoryName;
			string fullPath = Path.GetFullPath(Path.Combine(directoryName, ".."));
			string text = Directory.GetDirectories(path).Concat(Directory.GetDirectories(fullPath)).FirstOrDefault((string folder) => Path.GetFileName(folder).StartsWith("averageguy-Hoharder"));
			if (text == null)
			{
				Plugin.logger.LogError((object)"No folder found that starts with \"averageguy-Hoharder\" in the current or parent directory.");
				return;
			}
			string text2 = Directory.GetDirectories(text, "CustomSounds", SearchOption.AllDirectories).FirstOrDefault();
			if (text2 == null)
			{
				Plugin.logger.LogError((object)"No \"CustomSounds\" folder found inside \"averageguy-Hoharder\" or its subfolders.");
				return;
			}
			StringComparison ordinalIgnoreCase = StringComparison.OrdinalIgnoreCase;
			string[] array = (from f in Directory.GetFiles(text2, "*.*", SearchOption.AllDirectories)
				where f.EndsWith(".wav", ordinalIgnoreCase) || f.EndsWith(".ogg", ordinalIgnoreCase) || f.EndsWith(".mp3", ordinalIgnoreCase)
				select f).ToArray();
			if (array.Length == 0)
			{
				Plugin.logger.LogWarning((object)"No sound files were found in the \"CustomSounds\" folder.");
				return;
			}
			ChitterSFX = new List<AudioClip>();
			AngryScreechSFX = new List<AudioClip>();
			BugWalkSFX = new List<AudioClip>();
			string[] array2 = array;
			foreach (string text3 in array2)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text3);
				AudioType type = AudioUtils.DetectAudioType(text3);
				if (fileNameWithoutExtension.StartsWith("Chitter", ordinalIgnoreCase))
				{
					AudioClip val = AudioUtils.LoadAudioClip(text3, type);
					if ((Object)(object)val != (Object)null)
					{
						ChitterSFX.Add(val);
					}
				}
				else if (fileNameWithoutExtension.StartsWith("AngryScreech", ordinalIgnoreCase))
				{
					AudioClip val2 = AudioUtils.LoadAudioClip(text3, type);
					if ((Object)(object)val2 != (Object)null)
					{
						AngryScreechSFX.Add(val2);
					}
				}
				else if (fileNameWithoutExtension.StartsWith("BugWalk", ordinalIgnoreCase))
				{
					AudioClip val3 = AudioUtils.LoadAudioClip(text3, type);
					if ((Object)(object)val3 != (Object)null)
					{
						BugWalkSFX.Add(val3);
					}
				}
			}
			Plugin.logger.LogInfo((object)"Successfully loaded Hoharder assets.");
		}

		private static AssetBundle LoadAssetBundle(string fileName)
		{
			try
			{
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
				string text = Path.Combine(directoryName, fileName);
				return AssetBundle.LoadFromFile(text);
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Failed to load asset bundle \"{fileName}\".\n\n{arg}");
			}
			return null;
		}
	}
	[BepInPlugin("com.github.zehsteam.HoharderSkin", "HoharderSkin", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("com.github.zehsteam.HoharderSkin");

		internal static Plugin Instance;

		internal static ManualLogSource logger;

		internal static ConfigManager ConfigManager;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = Logger.CreateLogSource("com.github.zehsteam.HoharderSkin");
			logger.LogInfo((object)"HoharderSkin has awoken!");
			harmony.PatchAll(typeof(HoarderBugAIPatch));
			ConfigManager = new ConfigManager();
			Content.Load();
		}

		public void LogInfoExtended(object data)
		{
			if (ConfigManager.ExtendedLogging.Value)
			{
				logger.LogInfo(data);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.zehsteam.HoharderSkin";

		public const string PLUGIN_NAME = "HoharderSkin";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace com.github.zehsteam.HoharderSkin.Patches
{
	[HarmonyPatch(typeof(HoarderBugAI))]
	internal static class HoarderBugAIPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(ref HoarderBugAI __instance)
		{
			Object.Instantiate<GameObject>(Content.HoharderControllerPrefab, ((Component)__instance).transform);
		}
	}
}
namespace com.github.zehsteam.HoharderSkin.MonoBehaviours
{
	public class HoharderController : MonoBehaviour
	{
		public Mesh ReplacementMesh;

		public GameObject PotatoPrefab;

		private HoarderBugAI _hoarderBugAI;

		private GameObject _potatoObject;

		private void Start()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)this).transform.parent == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to initialize HoharderController. Transform parent is null.");
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			if (!((Component)((Component)this).transform.parent).TryGetComponent<HoarderBugAI>(ref _hoarderBugAI))
			{
				Plugin.logger.LogError((object)"Failed to initialize HoharderController. HoarderBugAI is null.");
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			((Component)this).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			ReplaceMesh();
			SpawnPotatoPrefab();
			HideInsideModel();
			SetScanNodeProperties();
			((MonoBehaviour)this).StartCoroutine(LateStartCoroutine());
		}

		private IEnumerator LateStartCoroutine()
		{
			yield return null;
			LateStart();
		}

		private void LateStart()
		{
			SetSFX();
		}

		private void ReplaceMesh()
		{
			if ((Object)(object)_hoarderBugAI == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to replace mesh. HoarderBugAI is null.");
				return;
			}
			if ((Object)(object)ReplacementMesh == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to replace mesh. ReplacementMesh is null.");
				return;
			}
			SkinnedMeshRenderer component;
			try
			{
				component = ((Component)((Component)_hoarderBugAI).transform.Find("HoarderBugModel").Find("Cube")).GetComponent<SkinnedMeshRenderer>();
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Failed to replace mesh. Could not find SkinnedMeshRenderer.\n\n{arg}");
				return;
			}
			if ((Object)(object)component == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to replace mesh. SkinnedMeshRenderer is null.");
				return;
			}
			component.sharedMesh = ReplacementMesh;
			Plugin.logger.LogInfo((object)"Replaced mesh.");
		}

		private void SpawnPotatoPrefab()
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_hoarderBugAI == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to spawn potato prefab. HoarderBugAI is null.");
				return;
			}
			if ((Object)(object)PotatoPrefab == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to spawn potato prefab. PotatoPrefab is null.");
				return;
			}
			Transform val;
			try
			{
				val = ((Component)((EnemyAI)_hoarderBugAI).creatureAnimator).transform.Find("Armature").Find("Abdomen").Find("Chest");
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Failed to spawn potato prefab. Could not find \"Chest\" Transform.\n\n{arg}");
				return;
			}
			if ((Object)(object)_potatoObject != (Object)null)
			{
				Object.Destroy((Object)(object)_potatoObject);
				return;
			}
			_potatoObject = Object.Instantiate<GameObject>(PotatoPrefab, val);
			_potatoObject.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			Plugin.logger.LogInfo((object)"Spawned potato prefab.");
		}

		private void HideInsideModel()
		{
			if ((Object)(object)_hoarderBugAI == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to hide inside model. HoarderBugAI is null.");
				return;
			}
			SkinnedMeshRenderer component;
			try
			{
				component = ((Component)((Component)_hoarderBugAI).transform.Find("HoarderBugModel").Find("Cube.001")).GetComponent<SkinnedMeshRenderer>();
			}
			catch (Exception arg)
			{
				Plugin.logger.LogError((object)$"Failed to hide inside model. Could not find SkinnedMeshRenderer.\n\n{arg}");
				return;
			}
			if ((Object)(object)component == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to hide inside model. SkinnedMeshRenderer is null.");
			}
			else
			{
				((Renderer)component).enabled = false;
			}
		}

		private void SetScanNodeProperties()
		{
			if ((Object)(object)_hoarderBugAI == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to set scan node properties. HoarderBugAI is null.");
				return;
			}
			ScanNodeProperties componentInChildren = ((Component)_hoarderBugAI).GetComponentInChildren<ScanNodeProperties>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to set scan node properties. ScanNodeProperties is null.");
			}
			else
			{
				componentInChildren.headerText = "Hoharding bug";
			}
		}

		private void SetSFX()
		{
			if ((Object)(object)_hoarderBugAI == (Object)null)
			{
				Plugin.logger.LogError((object)"Failed to set custom sounds. HoarderBugAI is null.");
				return;
			}
			if (Content.ChitterSFX.Count > 0)
			{
				_hoarderBugAI.chitterSFX = Content.ChitterSFX.ToArray();
			}
			if (Content.AngryScreechSFX.Count > 0)
			{
				_hoarderBugAI.angryScreechSFX = Content.AngryScreechSFX.ToArray();
			}
			PlayAudioAnimationEvent componentInChildren = ((Component)_hoarderBugAI).GetComponentInChildren<PlayAudioAnimationEvent>();
			if ((Object)(object)componentInChildren != (Object)null && Content.BugWalkSFX.Count > 0)
			{
				componentInChildren.randomClips = Content.BugWalkSFX.ToArray();
			}
			Plugin.logger.LogInfo((object)"Set custom sounds.");
		}
	}
}
namespace com.github.zehsteam.HoharderSkin.Dependencies
{
	internal static class LethalConfigProxy
	{
		public const string PLUGIN_GUID = "ainavt.lc.lethalconfig";

		public static bool Enabled => Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SetModIcon(Sprite sprite)
		{
			LethalConfigManager.SetModIcon(sprite);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SetModDescription(string description)
		{
			LethalConfigManager.SetModDescription(description);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SkipAutoGen()
		{
			LethalConfigManager.SkipAutoGen();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if (!(configEntry is ConfigEntry<string> val))
			{
				if (!(configEntry is ConfigEntry<bool> val2))
				{
					if (!(configEntry is ConfigEntry<float> val3))
					{
						if (!(configEntry is ConfigEntry<int> val4))
						{
							throw new NotSupportedException($"Unsupported type: {typeof(T)}");
						}
						LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(val4, requiresRestart));
					}
					else
					{
						LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(val3, requiresRestart));
					}
				}
				else
				{
					LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(val2, requiresRestart));
				}
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(val, requiresRestart));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfigSlider<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (!(configEntry is ConfigEntry<float> val))
			{
				if (!(configEntry is ConfigEntry<int> val2))
				{
					throw new NotSupportedException($"Slider not supported for type: {typeof(T)}");
				}
				LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(val2, requiresRestart));
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(val, requiresRestart));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddButton(string section, string name, string description, string buttonText, Action callback)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate
			{
				callback?.Invoke();
			}));
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}