Decompiled source of Too Many Hats v2.1.0

TooManyHats.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TooManyHats.Helpers;
using TooManyHats.Patches;
using UnityEngine;

[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("TooManyHats")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: AssemblyInformationalVersion("1.1.3")]
[assembly: AssemblyProduct("TooManyHats")]
[assembly: AssemblyTitle("TooManyHats")]
[assembly: AssemblyVersion("1.1.3.0")]
[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 TooManyHats
{
	[BepInPlugin("TeddyBRB.toomanyhats", "Too Many Hats", "2.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public class HatEntry
		{
			public string Name;

			public GameObject Prefab;

			public Texture2D Icon;

			public HatEntry(string name, GameObject prefab, Texture2D icon)
			{
				Name = name;
				Prefab = prefab;
				Icon = icon;
			}
		}

		public static AssetBundle assetBundle;

		public static List<HatEntry> hats;

		internal static ManualLogSource Logger;

		internal static Harmony _harmony;

		public static int BaseHatCount { get; set; }

		public static int OverrideHatCount { get; set; }

		public void Awake()
		{
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			BaseHatCount = 0;
			OverrideHatCount = 0;
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = Path.Combine(directoryName, "toomanyhats");
			Logger.LogInfo((object)("[TooManyHats] Loading AssetBundle from: " + text));
			if (!File.Exists(text))
			{
				Logger.LogError((object)("[TooManyHats] AssetBundle file not found: " + text));
				return;
			}
			byte[] array = File.ReadAllBytes(text);
			assetBundle = AssetBundle.LoadFromMemory(array);
			if ((Object)(object)assetBundle == (Object)null)
			{
				Logger.LogError((object)"[TooManyHats] Failed to load AssetBundle!");
				return;
			}
			hats = new List<HatEntry>();
			AddHatIfValid("mario");
			AddHatIfValid("luigi");
			AddHatIfValid("luffy");
			AddHatIfValid("kitty");
			AddHatIfValid("kitdy");
			AddHatIfValid("cat");
			AddHatIfValid("bucket");
			AddHatIfValid("construction");
			AddHatIfValid("crown");
			AddHatIfValid("cowboy");
			AddHatIfValid("pirate");
			AddHatIfValid("pilot");
			AddHatIfValid("rat");
			AddHatIfValid("sleepy");
			AddHatIfValid("elephant");
			AddHatIfValid("froggy");
			AddHatIfValid("kirby");
			AddHatIfValid("cinnamon");
			AddHatIfValid("bunny");
			AddHatIfValid("freeze");
			AddHatIfValid("spongebob");
			AddHatIfValid("longboy");
			AddHatIfValid("pikachu");
			AddHatIfValid("link");
			Logger.LogInfo((object)$"[TooManyHats] Loaded {hats.Count} valid hats.");
			_harmony = new Harmony("TeddyBRB.toomanyhats");
			_harmony.PatchAll(typeof(PassportManagerPatch));
			_harmony.PatchAll(typeof(CharacterCustomizationPatch));
			_harmony.PatchAll(typeof(PlayerCustomizationDummyPatch));
			_harmony.PatchAll(typeof(PeakHandlePatch));
			_harmony.PatchAll(typeof(PassportButtonPatch));
			Logger.LogInfo((object)"[TooManyHats] Patches applied.");
		}

		private static void AddHatIfValid(string hatName)
		{
			HatEntry hatEntry = LoadHat(hatName);
			if (!((Object)(object)hatEntry.Prefab == (Object)null))
			{
				hats.Add(hatEntry);
			}
		}

		private static HatEntry LoadHat(string hatName)
		{
			Logger.LogInfo((object)("[TooManyHats] Loading hat '" + hatName + "'"));
			GameObject val = assetBundle.LoadAsset<GameObject>("Assets/" + hatName + ".prefab");
			Texture2D val2 = assetBundle.LoadAsset<Texture2D>("Assets/" + hatName + ".png");
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError((object)("[TooManyHats] Missing prefab for hat '" + hatName + "' (Assets/" + hatName + ".prefab)"));
				return null;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Logger.LogWarning((object)("[TooManyHats] Missing icon for hat '" + hatName + "' (Assets/" + hatName + ".png). It will still load."));
			}
			return new HatEntry(hatName, val, val2);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TooManyHats";

		public const string PLUGIN_NAME = "TooManyHats";

		public const string PLUGIN_VERSION = "1.1.3";
	}
}
namespace TooManyHats.Data
{
	public abstract class CustomizationData : ScriptableObject
	{
		public abstract Texture IconTexture { get; }

		public abstract Type Type { get; }

		public abstract bool IsValid();
	}
	public abstract class CustomAccessoryData : CustomizationData
	{
		public sealed override Type Type => (Type)10;
	}
	public abstract class CustomEyesData : CustomizationData
	{
		public sealed override Type Type => (Type)20;
	}
	public abstract class CustomMouthData : CustomizationData
	{
		public sealed override Type Type => (Type)30;
	}
	public abstract class CustomHatData : CustomizationData
	{
		public sealed override Type Type => (Type)50;
	}
	[CreateAssetMenu(menuName = "PEAK More Customizations/Accessory", fileName = "New Custom Accessory", order = int.MinValue)]
	public class CustomAccessory_V1 : CustomAccessoryData
	{
		[field: SerializeField]
		public Texture Texture { get; internal set; }

		public override Texture IconTexture => Texture;

		public override bool IsValid()
		{
			return Object.op_Implicit((Object)(object)Texture);
		}
	}
	[CreateAssetMenu(menuName = "PEAK More Customizations/Eye", fileName = "New Custom Eye", order = int.MinValue)]
	public class CustomEyes_V1 : CustomEyesData
	{
		[field: SerializeField]
		public Texture Texture { get; internal set; }

		public override Texture IconTexture => Texture;

		public override bool IsValid()
		{
			return Object.op_Implicit((Object)(object)Texture);
		}
	}
	[CreateAssetMenu(menuName = "PEAK More Customizations/Hat", fileName = "New Custom Hat", order = int.MinValue)]
	public class CustomHat_V1 : CustomHatData
	{
		[field: SerializeField]
		public Texture Icon { get; internal set; }

		[field: SerializeField]
		public GameObject Prefab { get; internal set; }

		[field: SerializeField]
		public Texture MainTexture { get; internal set; }

		[field: SerializeField]
		public Texture SubTexture { get; internal set; }

		[field: SerializeField]
		public Vector3 PositionOffset { get; internal set; }

		[field: SerializeField]
		public Vector3 EulerAngleOffset { get; internal set; }

		public Vector3 SwizzledPositionOffset => new Vector3(PositionOffset.x, 0f - PositionOffset.z, PositionOffset.y);

		public Vector3 SwizzledRotationOffset => new Vector3(EulerAngleOffset.x, 0f - EulerAngleOffset.z, 0f - EulerAngleOffset.y);

		public override Texture IconTexture => Icon;

		public override bool IsValid()
		{
			return Object.op_Implicit((Object)(object)Icon) && Object.op_Implicit((Object)(object)Prefab);
		}
	}
	[CreateAssetMenu(menuName = "PEAK More Customizations/Mouth", fileName = "New Custom Mouth", order = int.MinValue)]
	public class CustomMouth_V1 : CustomMouthData
	{
		[field: SerializeField]
		public Texture Texture { get; internal set; }

		public override Texture IconTexture => Texture;

		public override bool IsValid()
		{
			return Object.op_Implicit((Object)(object)Texture);
		}
	}
}
namespace TooManyHats.Patches
{
	[HarmonyPatch]
	public static class CharacterCustomizationPatch
	{
		[CompilerGenerated]
		private sealed class <SetCharacterHatTranspiler>d__3 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private List<CodeInstruction> <codes>5__1;

			private bool <patched>5__2;

			private int <i>5__3;

			private bool <canMatch>5__4;

			private MethodInfo <getOverrideHatCount>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<codes>5__1 = null;
				<getOverrideHatCount>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0309: Expected O, but got Unknown
				//IL_0320: Unknown result type (might be due to invalid IL or missing references)
				//IL_032a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<codes>5__1 = instructions.ToList();
					<patched>5__2 = false;
					<i>5__3 = 0;
					break;
				case 1:
					<>1__state = -1;
					<>2__current = <codes>5__1[<i>5__3 + 1];
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = <codes>5__1[<i>5__3 + 2];
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					<>2__current = <codes>5__1[<i>5__3 + 3];
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					<>2__current = <codes>5__1[<i>5__3 + 4];
					<>1__state = 5;
					return true;
				case 5:
					<>1__state = -1;
					<getOverrideHatCount>5__5 = AccessTools.Method(typeof(CharacterCustomizationPatch), "GetOverrideHatCount", (Type[])null, (Type[])null);
					<>2__current = new CodeInstruction(OpCodes.Call, (object)<getOverrideHatCount>5__5);
					<>1__state = 6;
					return true;
				case 6:
					<>1__state = -1;
					<>2__current = new CodeInstruction(OpCodes.Add, (object)null);
					<>1__state = 7;
					return true;
				case 7:
					<>1__state = -1;
					<i>5__3 += 4;
					goto IL_0372;
				case 8:
					{
						<>1__state = -1;
						goto IL_0372;
					}
					IL_0372:
					<i>5__3++;
					break;
				}
				if (<i>5__3 < <codes>5__1.Count)
				{
					<canMatch>5__4 = <i>5__3 <= <codes>5__1.Count - 5;
					if (<canMatch>5__4 && <codes>5__1[<i>5__3].opcode == OpCodes.Ldarg_0 && <codes>5__1[<i>5__3 + 1].opcode == OpCodes.Call && <codes>5__1[<i>5__3 + 1].operand != null && <codes>5__1[<i>5__3 + 1].operand.ToString().Contains("get_Instance") && <codes>5__1[<i>5__3 + 2].opcode == OpCodes.Ldfld && <codes>5__1[<i>5__3 + 2].operand != null && <codes>5__1[<i>5__3 + 2].operand.ToString().Contains("hats") && <codes>5__1[<i>5__3 + 3].opcode == OpCodes.Ldlen && <codes>5__1[<i>5__3 + 4].opcode == OpCodes.Conv_I4)
					{
						<patched>5__2 = true;
						<>2__current = <codes>5__1[<i>5__3];
						<>1__state = 1;
						return true;
					}
					<>2__current = <codes>5__1[<i>5__3];
					<>1__state = 8;
					return true;
				}
				if (!<patched>5__2)
				{
					Plugin.Logger.LogWarning((object)"[TooManyHats] SetCharacterHat transpiler did not find hats length pattern.");
				}
				return false;
			}

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

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

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<SetCharacterHatTranspiler>d__3 <SetCharacterHatTranspiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<SetCharacterHatTranspiler>d__ = this;
				}
				else
				{
					<SetCharacterHatTranspiler>d__ = new <SetCharacterHatTranspiler>d__3(0);
				}
				<SetCharacterHatTranspiler>d__.instructions = <>3__instructions;
				return <SetCharacterHatTranspiler>d__;
			}

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

		private static Shader _characterShader;

		private static int GetOverrideHatCount()
		{
			return Plugin.OverrideHatCount;
		}

		[HarmonyPatch(typeof(CharacterCustomization), "Awake")]
		[HarmonyPostfix]
		public static void AwakePostfix(CharacterCustomization __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)_characterShader == (Object)null)
			{
				_characterShader = Shader.Find("W/Character");
			}
			Transform val = null;
			try
			{
				val = ((Component)__instance).transform.GetChild(0).GetChild(0).GetChild(0)
					.GetChild(2)
					.GetChild(0)
					.GetChild(0)
					.GetChild(1)
					.GetChild(1);
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Logger.LogError((object)"[TooManyHats] Could not find hats container!");
				return;
			}
			if ((Object)(object)__instance.refs == (Object)null)
			{
				Plugin.Logger.LogError((object)"[TooManyHats] CharacterCustomization.refs is null!");
				return;
			}
			List<Renderer> list = new List<Renderer>((IEnumerable<Renderer>)(((object)__instance.refs.playerHats) ?? ((object)new Renderer[0])));
			if (Plugin.hats == null || Plugin.hats.Count == 0)
			{
				Plugin.Logger.LogWarning((object)"[TooManyHats] No hats to instantiate in CharacterCustomizationPatch.");
				__instance.refs.playerHats = list.ToArray();
				return;
			}
			foreach (Plugin.HatEntry hat in Plugin.hats)
			{
				if (hat == null || (Object)(object)hat.Prefab == (Object)null)
				{
					Plugin.Logger.LogWarning((object)"[TooManyHats] Skipping null hat/prefab.");
					continue;
				}
				GameObject val2 = Object.Instantiate<GameObject>(hat.Prefab, val, false);
				Renderer componentInChildren = val2.GetComponentInChildren<Renderer>(true);
				if ((Object)(object)componentInChildren == (Object)null)
				{
					Plugin.Logger.LogError((object)("[TooManyHats] No Renderer on hat '" + hat.Name + "'"));
					Object.Destroy((Object)(object)val2);
					continue;
				}
				if ((Object)(object)_characterShader != (Object)null)
				{
					Material[] materials = componentInChildren.materials;
					for (int i = 0; i < materials.Length; i++)
					{
						if ((Object)(object)materials[i] != (Object)null)
						{
							materials[i].shader = _characterShader;
						}
					}
					componentInChildren.materials = materials;
				}
				else
				{
					Plugin.Logger.LogWarning((object)"[TooManyHats] Shader 'W/Character' not found.");
				}
				((Component)componentInChildren).gameObject.SetActive(false);
				((Object)componentInChildren).name = hat.Name;
				list.Add(componentInChildren);
				Plugin.Logger.LogDebug((object)("[TooManyHats] Added hat '" + hat.Name + "' to playerHats"));
			}
			__instance.refs.playerHats = list.ToArray();
			Plugin.Logger.LogInfo((object)$"[TooManyHats] CharacterCustomization hats ready. playerHats={__instance.refs.playerHats.Length}");
		}

		[IteratorStateMachine(typeof(<SetCharacterHatTranspiler>d__3))]
		[HarmonyPatch(typeof(CharacterCustomization), "SetCharacterHat")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> SetCharacterHatTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetCharacterHatTranspiler>d__3(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	public class PassportButtonPatch
	{
		[HarmonyPatch(typeof(PassportButton), "SetButton")]
		[HarmonyPostfix]
		private static void SetButton(ref int ___currentIndex, CustomizationOption option)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			if (!((Object)(object)option == (Object)null) && (int)option.type == 50 && ___currentIndex >= Plugin.BaseHatCount)
			{
				___currentIndex += Plugin.OverrideHatCount;
			}
		}
	}
	public class PassportManagerPatch
	{
		[CompilerGenerated]
		private sealed class <CameraInTranspiler>d__5 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private IEnumerator<CodeInstruction> <>s__1;

			private CodeInstruction <instruction>5__2;

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

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

			[DebuggerHidden]
			public <CameraInTranspiler>d__5(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();
					}
				}
				<>s__1 = null;
				<instruction>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<instruction>5__2 = null;
						break;
					}
					if (<>s__1.MoveNext())
					{
						<instruction>5__2 = <>s__1.Current;
						if (<instruction>5__2.opcode == OpCodes.Ldc_R4 && <instruction>5__2.operand != null && <instruction>5__2.operand.Equals(1f))
						{
							<instruction>5__2.operand = 3f;
						}
						<>2__current = <instruction>5__2;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__1 = null;
					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;
				if (<>s__1 != null)
				{
					<>s__1.Dispose();
				}
			}

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

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<CameraInTranspiler>d__5 <CameraInTranspiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<CameraInTranspiler>d__ = this;
				}
				else
				{
					<CameraInTranspiler>d__ = new <CameraInTranspiler>d__5(0);
				}
				<CameraInTranspiler>d__.instructions = <>3__instructions;
				return <CameraInTranspiler>d__;
			}

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

		[CompilerGenerated]
		private sealed class <CameraOutTranspiler>d__6 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private IEnumerator<CodeInstruction> <>s__1;

			private CodeInstruction <instruction>5__2;

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

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

			[DebuggerHidden]
			public <CameraOutTranspiler>d__6(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();
					}
				}
				<>s__1 = null;
				<instruction>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<instruction>5__2 = null;
						break;
					}
					if (<>s__1.MoveNext())
					{
						<instruction>5__2 = <>s__1.Current;
						if (<instruction>5__2.opcode == OpCodes.Ldc_R4 && <instruction>5__2.operand != null && <instruction>5__2.operand.Equals(1f))
						{
							<instruction>5__2.operand = 3f;
						}
						<>2__current = <instruction>5__2;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__1 = null;
					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;
				if (<>s__1 != null)
				{
					<>s__1.Dispose();
				}
			}

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

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<CameraOutTranspiler>d__6 <CameraOutTranspiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<CameraOutTranspiler>d__ = this;
				}
				else
				{
					<CameraOutTranspiler>d__ = new <CameraOutTranspiler>d__6(0);
				}
				<CameraOutTranspiler>d__.instructions = <>3__instructions;
				return <CameraOutTranspiler>d__;
			}

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

		[CompilerGenerated]
		private sealed class <SetActiveButtonTranspiler>d__4 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private List<CodeInstruction> <codes>5__1;

			private bool <patched>5__2;

			private int <i>5__3;

			private bool <canMatch>5__4;

			private MethodInfo <getBaseHatCount>5__5;

			private Label <skipLabel>5__6;

			private MethodInfo <getOverrideHatCount>5__7;

			private CodeInstruction <nop>5__8;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<codes>5__1 = null;
				<getBaseHatCount>5__5 = null;
				<getOverrideHatCount>5__7 = null;
				<nop>5__8 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0276: Unknown result type (might be due to invalid IL or missing references)
				//IL_0280: Expected O, but got Unknown
				//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c2: Expected O, but got Unknown
				//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f9: Expected O, but got Unknown
				//IL_0331: Unknown result type (might be due to invalid IL or missing references)
				//IL_033b: Expected O, but got Unknown
				//IL_0352: Unknown result type (might be due to invalid IL or missing references)
				//IL_035c: Expected O, but got Unknown
				//IL_0373: Unknown result type (might be due to invalid IL or missing references)
				//IL_037d: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<codes>5__1 = instructions.ToList();
					<patched>5__2 = false;
					<i>5__3 = 0;
					break;
				case 1:
					<>1__state = -1;
					<>2__current = <codes>5__1[<i>5__3 + 1];
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = <codes>5__1[<i>5__3 + 2];
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					<>2__current = new CodeInstruction(OpCodes.Dup, (object)null);
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					<getBaseHatCount>5__5 = AccessTools.Method(typeof(PassportManagerPatch), "GetBaseHatCount", (Type[])null, (Type[])null);
					<>2__current = new CodeInstruction(OpCodes.Call, (object)<getBaseHatCount>5__5);
					<>1__state = 5;
					return true;
				case 5:
					<>1__state = -1;
					<skipLabel>5__6 = default(Label);
					<>2__current = new CodeInstruction(OpCodes.Ble_S, (object)<skipLabel>5__6);
					<>1__state = 6;
					return true;
				case 6:
					<>1__state = -1;
					<getOverrideHatCount>5__7 = AccessTools.Method(typeof(PassportManagerPatch), "GetOverrideHatCount", (Type[])null, (Type[])null);
					<>2__current = new CodeInstruction(OpCodes.Call, (object)<getOverrideHatCount>5__7);
					<>1__state = 7;
					return true;
				case 7:
					<>1__state = -1;
					<>2__current = new CodeInstruction(OpCodes.Sub, (object)null);
					<>1__state = 8;
					return true;
				case 8:
					<>1__state = -1;
					<nop>5__8 = new CodeInstruction(OpCodes.Nop, (object)null);
					<nop>5__8.labels.Add(<skipLabel>5__6);
					<>2__current = <nop>5__8;
					<>1__state = 9;
					return true;
				case 9:
					<>1__state = -1;
					<>2__current = <codes>5__1[<i>5__3 + 3];
					<>1__state = 10;
					return true;
				case 10:
					<>1__state = -1;
					<i>5__3 += 3;
					goto IL_0414;
				case 11:
					{
						<>1__state = -1;
						goto IL_0414;
					}
					IL_0414:
					<i>5__3++;
					break;
				}
				if (<i>5__3 < <codes>5__1.Count)
				{
					<canMatch>5__4 = <i>5__3 <= <codes>5__1.Count - 4;
					if (<canMatch>5__4 && <codes>5__1[<i>5__3].opcode == OpCodes.Ldloc_0 && <codes>5__1[<i>5__3 + 1].opcode == OpCodes.Ldfld && <codes>5__1[<i>5__3 + 1].operand != null && <codes>5__1[<i>5__3 + 1].operand.ToString().Contains("customizationData") && <codes>5__1[<i>5__3 + 2].opcode == OpCodes.Ldfld && <codes>5__1[<i>5__3 + 2].operand != null && <codes>5__1[<i>5__3 + 2].operand.ToString().Contains("currentHat") && IsStloc(<codes>5__1[<i>5__3 + 3]))
					{
						<patched>5__2 = true;
						<>2__current = <codes>5__1[<i>5__3];
						<>1__state = 1;
						return true;
					}
					<>2__current = <codes>5__1[<i>5__3];
					<>1__state = 11;
					return true;
				}
				if (!<patched>5__2)
				{
					Plugin.Logger.LogWarning((object)"[TooManyHats] SetActiveButton transpiler did not find currentHat pattern.");
				}
				return false;
			}

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

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

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<SetActiveButtonTranspiler>d__4 <SetActiveButtonTranspiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<SetActiveButtonTranspiler>d__ = this;
				}
				else
				{
					<SetActiveButtonTranspiler>d__ = new <SetActiveButtonTranspiler>d__4(0);
				}
				<SetActiveButtonTranspiler>d__.instructions = <>3__instructions;
				return <SetActiveButtonTranspiler>d__;
			}

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

		private static int GetBaseHatCount()
		{
			return Plugin.BaseHatCount;
		}

		private static int GetOverrideHatCount()
		{
			return Plugin.OverrideHatCount;
		}

		private static bool IsStloc(CodeInstruction code)
		{
			return code.opcode == OpCodes.Stloc || code.opcode == OpCodes.Stloc_S || code.opcode == OpCodes.Stloc_0 || code.opcode == OpCodes.Stloc_1 || code.opcode == OpCodes.Stloc_2 || code.opcode == OpCodes.Stloc_3;
		}

		[HarmonyPatch(typeof(PassportManager), "Awake")]
		[HarmonyPostfix]
		public static void AwakePostfix(PassportManager __instance)
		{
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			Customization component = ((Component)__instance).GetComponent<Customization>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Logger.LogError((object)"[TooManyHats] Missing Customization component!");
				return;
			}
			List<CustomizationOption> list = new List<CustomizationOption>((IEnumerable<CustomizationOption>)(((object)component.hats) ?? ((object)new CustomizationOption[0])));
			Plugin.BaseHatCount = list.Count;
			Plugin.OverrideHatCount = 0;
			if (component.fits != null)
			{
				CustomizationOption[] fits = component.fits;
				foreach (CustomizationOption val in fits)
				{
					if ((Object)(object)val != (Object)null && val.overrideHat)
					{
						Plugin.OverrideHatCount++;
					}
				}
			}
			if (Plugin.hats == null || Plugin.hats.Count == 0)
			{
				Plugin.Logger.LogWarning((object)"[TooManyHats] No hats found to inject.");
				component.hats = list.ToArray();
				return;
			}
			foreach (Plugin.HatEntry hat in Plugin.hats)
			{
				if (hat != null)
				{
					CustomizationOption val2 = ScriptableObject.CreateInstance<CustomizationOption>();
					val2.requiredAchievement = (ACHIEVEMENTTYPE)0;
					((Object)val2).name = hat.Name;
					val2.texture = (Texture)(object)hat.Icon;
					val2.type = (Type)50;
					list.Add(val2);
					Plugin.Logger.LogDebug((object)("[TooManyHats] Added hat option '" + hat.Name + "'"));
				}
			}
			component.hats = list.ToArray();
			Plugin.Logger.LogInfo((object)($"[TooManyHats] Awake complete. BaseHatCount={Plugin.BaseHatCount}, " + $"OverrideHatCount={Plugin.OverrideHatCount}, TotalHats={component.hats.Length}"));
		}

		[IteratorStateMachine(typeof(<SetActiveButtonTranspiler>d__4))]
		[HarmonyPatch(typeof(PassportManager), "SetActiveButton")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> SetActiveButtonTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetActiveButtonTranspiler>d__4(-2)
			{
				<>3__instructions = instructions
			};
		}

		[IteratorStateMachine(typeof(<CameraInTranspiler>d__5))]
		[HarmonyPatch(typeof(PassportManager), "CameraIn")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> CameraInTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CameraInTranspiler>d__5(-2)
			{
				<>3__instructions = instructions
			};
		}

		[IteratorStateMachine(typeof(<CameraOutTranspiler>d__6))]
		[HarmonyPatch(typeof(PassportManager), "CameraOut")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> CameraOutTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CameraOutTranspiler>d__6(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	public class PeakHandlePatch
	{
		[HarmonyPatch(typeof(PeakHandler), "SetCosmetics")]
		[HarmonyPrefix]
		private static void SetCosmetics(PeakHandler __instance, List<Character> characters)
		{
			if (!CustomizationRefsHelper.SyncCustomHats(__instance.firstCutsceneScout))
			{
				Plugin.Logger.LogError((object)"Something went wrong in PeakHandlePatch [firstCutsceneScout]...");
			}
			for (int i = 0; i < __instance.cutsceneScoutRefs.Count(); i++)
			{
				if (!CustomizationRefsHelper.SyncCustomHats(__instance.cutsceneScoutRefs[i]))
				{
					Plugin.Logger.LogError((object)string.Format("Something went wrong in {0} [cutsceneScoutRefs-{1}]...", "PeakHandlePatch", i));
				}
			}
		}
	}
	public class PlayerCustomizationDummyPatch
	{
		[HarmonyPatch(typeof(PlayerCustomizationDummy), "SetPlayerHat")]
		[HarmonyPrefix]
		private static void SetPlayerHat(PlayerCustomizationDummy __instance, int index)
		{
			if (!CustomizationRefsHelper.SyncCustomHats(__instance.refs))
			{
				Plugin.Logger.LogError((object)"Something went wrong in SetPlayerHat patch...");
			}
		}
	}
}
namespace TooManyHats.Helpers
{
	public class CustomizationRefsHelper
	{
		public const string REF_TO_HATS_PATH = "Armature/Hip/Mid/AimJoint/Torso/Head/Hat";

		public static bool SyncCustomHats(CustomizationRefs dstRefs, CustomizationRefs srcRefs = null)
		{
			if ((Object)(object)srcRefs == (Object)null)
			{
				Character localCharacter = Character.localCharacter;
				CharacterCustomization val = default(CharacterCustomization);
				if (!Object.op_Implicit((Object)(object)localCharacter) || !((Component)localCharacter).TryGetComponent<CharacterCustomization>(ref val))
				{
					Plugin.Logger.LogError((object)"Cannot get [LocalCharacter] or its' [CustomizationRefs] ...");
					return false;
				}
				srcRefs = val.refs;
			}
			Renderer[] playerHats = srcRefs.playerHats;
			Renderer[] playerHats2 = dstRefs.playerHats;
			if (playerHats.Length == playerHats2.Length)
			{
				return true;
			}
			Renderer val2 = playerHats2.FirstOrDefault();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				Plugin.Logger.LogError((object)"Cannot find renders in dstPlayerHats...");
				return false;
			}
			int layer = ((Component)val2).gameObject.layer;
			Transform val3 = ((Component)srcRefs).transform.Find("Armature/Hip/Mid/AimJoint/Torso/Head/Hat");
			Transform val4 = ((Component)dstRefs).transform.Find("Armature/Hip/Mid/AimJoint/Torso/Head/Hat");
			List<Renderer> list = new List<Renderer>(playerHats2);
			for (int i = playerHats2.Length; i < playerHats.Length; i++)
			{
				Transform val5 = ((Component)playerHats[i]).transform;
				while ((Object)(object)val5.parent != (Object)(object)val3)
				{
					val5 = val5.parent;
				}
				GameObject val6 = Object.Instantiate<GameObject>(((Component)val5).gameObject, val4, false);
				((Object)val6).name = ((Object)val5).name;
				Renderer componentInChildren = val6.GetComponentInChildren<Renderer>(true);
				((Component)componentInChildren).gameObject.layer = layer;
				list.Add(componentInChildren);
			}
			dstRefs.playerHats = list.ToArray();
			return true;
		}
	}
}