The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of Too Many Hats v2.0.6
TooManyHats.dll
Decompiled a month agousing 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.0.5")] public class Plugin : BaseUnityPlugin { public struct 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 void Awake() { //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, "toomanyhats"); Logger.LogInfo((object)("[TooManyHats] Loading AssetBundle from: " + text)); 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> { LoadHat("mario"), LoadHat("luigi"), LoadHat("luffy"), LoadHat("kitty"), LoadHat("kitdy"), LoadHat("cat"), LoadHat("bucket"), LoadHat("construction"), LoadHat("crown"), LoadHat("cowboy"), LoadHat("pirate"), LoadHat("pilot"), LoadHat("rat"), LoadHat("sleepy"), LoadHat("elephant"), LoadHat("froggy"), LoadHat("kirby"), LoadHat("cinnamon"), LoadHat("bunny"), LoadHat("freeze"), LoadHat("spongebob"), LoadHat("longboy"), LoadHat("pikachu"), LoadHat("link") }; Logger.LogInfo((object)$"[TooManyHats] Loaded {hats.Count} hats."); _harmony = new Harmony("teddybrb.toomanyhats"); _harmony.PatchAll(typeof(PassportManagerPatch)); _harmony.PatchAll(typeof(CharacterCustomizationPatch)); _harmony.PatchAll(typeof(PlayerCustomizationDummyPatch)); _harmony.PatchAll(typeof(PeakHandlePatch)); Logger.LogInfo((object)"[TooManyHats] Patches applied."); } private static HatEntry LoadHat(string hatName) { Logger.LogInfo((object)("[TooManyHats] Loading hat '" + hatName + "'")); GameObject prefab = assetBundle.LoadAsset<GameObject>("Assets/" + hatName + ".prefab"); Texture2D icon = assetBundle.LoadAsset<Texture2D>("Assets/" + hatName + ".png"); return new HatEntry(hatName, prefab, icon); } } 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.Patches { [HarmonyPatch(typeof(CharacterCustomization), "Awake")] public static class CharacterCustomizationPatch { [HarmonyPostfix] public static void AwakePostfix(CharacterCustomization __instance) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) Transform child = ((Component)__instance).transform.GetChild(0).GetChild(0).GetChild(0) .GetChild(2) .GetChild(0) .GetChild(0) .GetChild(1) .GetChild(1); if ((Object)(object)child == (Object)null) { Plugin.Logger.LogError((object)"[TooManyHats] Could not find hats container!"); return; } foreach (Plugin.HatEntry hat in Plugin.hats) { GameObject val = Object.Instantiate<GameObject>(hat.Prefab, child.position, child.rotation, child); Renderer componentInChildren = val.GetComponentInChildren<Renderer>(); if ((Object)(object)componentInChildren == (Object)null) { Plugin.Logger.LogError((object)("[TooManyHats] No Renderer on hat '" + hat.Name + "'")); Object.Destroy((Object)(object)val); continue; } componentInChildren.material.shader = Shader.Find("W/Character"); ((Component)componentInChildren).gameObject.SetActive(false); __instance.refs.playerHats = CollectionExtensions.AddToArray<Renderer>(__instance.refs.playerHats, componentInChildren); Plugin.Logger.LogDebug((object)("[TooManyHats] Added hat '" + hat.Name + "' to playerHats")); } } } public class PassportManagerPatch { [CompilerGenerated] private sealed class <CameraInTranspiler>d__1 : 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__1(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { 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; break; case 2: <>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; } <>2__current = <instruction>5__2; <>1__state = 2; 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__1 <CameraInTranspiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <CameraInTranspiler>d__ = this; } else { <CameraInTranspiler>d__ = new <CameraInTranspiler>d__1(0); } <CameraInTranspiler>d__.instructions = <>3__instructions; return <CameraInTranspiler>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <CameraOutTranspiler>d__2 : 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__2(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { 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; break; case 2: <>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; } <>2__current = <instruction>5__2; <>1__state = 2; 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__2 <CameraOutTranspiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <CameraOutTranspiler>d__ = this; } else { <CameraOutTranspiler>d__ = new <CameraOutTranspiler>d__2(0); } <CameraOutTranspiler>d__.instructions = <>3__instructions; return <CameraOutTranspiler>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [HarmonyPatch(typeof(PassportManager), "Awake")] [HarmonyPostfix] public static void AwakePostfix(PassportManager __instance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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; } foreach (Plugin.HatEntry hat in Plugin.hats) { CustomizationOption val = ScriptableObject.CreateInstance<CustomizationOption>(); val.requiredAchievement = (ACHIEVEMENTTYPE)0; ((Object)val).name = hat.Name; val.texture = (Texture)(object)hat.Icon; val.type = (Type)50; component.hats = CollectionExtensions.AddToArray<CustomizationOption>(component.hats, val); Plugin.Logger.LogDebug((object)("[TooManyHats] Added hat option '" + hat.Name + "'")); } } [IteratorStateMachine(typeof(<CameraInTranspiler>d__1))] [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__1(-2) { <>3__instructions = instructions }; } [IteratorStateMachine(typeof(<CameraOutTranspiler>d__2))] [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__2(-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; } } }