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.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;
}
}
}