using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using MoreHead;
using MoreHead.MoreHead.Patchers;
using MoreHeadUtilities.Plugin;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MoreHeadUtilities")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3911decbf9634d63ae1bca5173060ee0fee13c40")]
[assembly: AssemblyProduct("MoreHeadUtilities")]
[assembly: AssemblyTitle("MoreHeadUtilities")]
[assembly: AssemblyVersion("1.0.0.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.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 MoreHeadUtilities
{
public class PartShrinker : MonoBehaviour
{
[SerializeField]
private HiddenParts.Part partToHide = HiddenParts.Part.LeftPupil;
[SerializeField]
private bool hideChildren = true;
private Transform TotalParent;
private HiddenParts parentComponent;
private static double totalSearchingTime;
private bool isFrameOne = true;
private bool isFrameTwo;
public static ManualLogSource bepInExLog;
public static void Init(ManualLogSource source)
{
bepInExLog = source;
bepInExLog.LogInfo((object)"LoggerUtil initialized!");
}
public void Log(string message)
{
if (MoreHeadUtilitiesPlugin._enableDebugLogging.Value)
{
bepInExLog.LogInfo((object)message);
}
}
public void LogError(string message)
{
if (MoreHeadUtilitiesPlugin._enableDebugLogging.Value)
{
bepInExLog.LogError((object)message);
}
}
public void Update()
{
if (isFrameOne)
{
isFrameOne = false;
isFrameTwo = true;
}
else
{
if (!isFrameTwo)
{
return;
}
isFrameTwo = false;
Stopwatch.StartNew();
if (!Object.op_Implicit((Object)(object)parentComponent))
{
Log(((Object)((Component)this).gameObject).name + " is finding parent on awakening");
TotalParent = ((Component)this).transform;
while (((Object)TotalParent).name != "ANIM BOT" && ((Object)TotalParent).name != null && ((Object)TotalParent).name != "WorldDecorationFollower")
{
TotalParent = TotalParent.parent;
}
if (((Object)TotalParent).name == null)
{
LogError("No root found");
return;
}
if (((Object)TotalParent).name == "WorldDecorationFollower")
{
LogError(((Object)((Component)this).gameObject).name + " is set to world parent. MoreHeadUtilities does not support part removal from a world object.");
return;
}
parentComponent = ((Component)TotalParent).GetComponent<HiddenParts>();
if (!Object.op_Implicit((Object)(object)parentComponent))
{
parentComponent = ((Component)TotalParent).gameObject.AddComponent<HiddenParts>();
}
else
{
Log("Part already exists");
}
}
parentComponent.AddHiddenPart(partToHide, hideChildren);
}
}
private void OnDisable()
{
if (isFrameOne)
{
return;
}
isFrameOne = true;
if (!Object.op_Implicit((Object)(object)parentComponent))
{
Log(((Object)((Component)this).gameObject).name + " is finding parent for destruction");
TotalParent = ((Component)this).transform;
while (((Object)TotalParent).name != "ANIM BOT" && ((Object)TotalParent).name != null && ((Object)TotalParent).name != "WorldDecorationFollower")
{
TotalParent = TotalParent.parent;
}
if (((Object)TotalParent).name == null)
{
LogError("No root found");
return;
}
if (((Object)TotalParent).name == "WorldDecorationFollower")
{
LogError(((Object)((Component)this).gameObject).name + " is set to world parent. MoreHeadUtilities does not support part removal from a world object.");
return;
}
parentComponent = ((Component)TotalParent).GetComponent<HiddenParts>();
if (!Object.op_Implicit((Object)(object)parentComponent))
{
parentComponent = ((Component)TotalParent).gameObject.AddComponent<HiddenParts>();
}
else
{
Log("Component already exists");
}
}
parentComponent.RemoveHiddenPart(partToHide, hideChildren);
}
}
public class HiddenParts : MonoBehaviour
{
public enum Part
{
Health,
LeftArm,
RightArm,
LeftLeg,
RightLeg,
EyeLeft,
EyeRight,
Head,
Neck,
Body,
Hips,
LeftPupil,
RightPupil
}
public static ManualLogSource bepInExLog;
private string[][] partNames = new string[13][]
{
new string[3] { "mesh_health", "mesh_health frame", "mesh_health shadow" },
new string[1] { "mesh_arm_l" },
new string[1] { "mesh_arm_r" },
new string[1] { "mesh_leg_l" },
new string[1] { "mesh_leg_r" },
new string[1] { "mesh_eye_l" },
new string[1] { "mesh_eye_r" },
new string[1] { "mesh_head_top" },
new string[2] { "mesh_head_bot_sphere", "mesh_head_bot_flat" },
new string[2] { "mesh_body_top_sphere", "mesh_body_top_flat" },
new string[1] { "mesh_body_bot" },
new string[1] { "mesh_pupil_l" },
new string[1] { "mesh_pupil_r" }
};
private MeshRenderer[][] partRenderers = new MeshRenderer[13][]
{
(MeshRenderer[])(object)new MeshRenderer[3],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[2],
(MeshRenderer[])(object)new MeshRenderer[2],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1],
(MeshRenderer[])(object)new MeshRenderer[1]
};
private Part[][] childParts = new Part[13][]
{
new Part[0],
new Part[0],
new Part[0],
new Part[0],
new Part[0],
new Part[1] { Part.LeftPupil },
new Part[1] { Part.RightPupil },
new Part[2]
{
Part.EyeLeft,
Part.EyeRight
},
new Part[2]
{
Part.Head,
Part.Health
},
new Part[3]
{
Part.Neck,
Part.LeftArm,
Part.RightArm
},
new Part[3]
{
Part.Body,
Part.LeftLeg,
Part.RightLeg
},
new Part[0],
new Part[0]
};
private List<Part> hiddenParts = new List<Part>();
private bool updatedThisFrame;
public static void Init(ManualLogSource source)
{
bepInExLog = source;
bepInExLog.LogInfo((object)"LoggerUtil initialized!");
}
public void Log(string message)
{
ManualLogSource obj = bepInExLog;
if (obj != null)
{
obj.LogInfo((object)message);
}
}
public void LogError(string message)
{
ManualLogSource obj = bepInExLog;
if (obj != null)
{
obj.LogError((object)message);
}
}
public void Start()
{
foreach (Part value in Enum.GetValues(typeof(Part)))
{
for (int i = 0; i < partNames[(int)value].Length; i++)
{
Transform val = FindInHierarchy(((Component)this).transform, partNames[(int)value][i]);
if ((Object)(object)val == (Object)null)
{
Log("Part '" + partNames[(int)value][i] + "' not found");
continue;
}
MeshRenderer component = ((Component)val).gameObject.GetComponent<MeshRenderer>();
if (Object.op_Implicit((Object)(object)component))
{
Log("Found part '" + partNames[(int)value][i] + "'");
partRenderers[(int)value][i] = component;
}
}
}
}
public void AddHiddenPart(Part part, bool hideChildren, bool update = true)
{
Log($"Adding part {part}");
hiddenParts.Add(part);
if (hideChildren)
{
Part[] array = childParts[(int)part];
foreach (Part part2 in array)
{
AddHiddenPart(part2, hideChildren, update: false);
}
}
updatedThisFrame = true;
}
public void RemoveHiddenPart(Part part, bool hideChildren, bool update = true)
{
if (hiddenParts.Contains(part))
{
hiddenParts.Remove(part);
}
if (hideChildren)
{
Part[] array = childParts[(int)part];
foreach (Part part2 in array)
{
RemoveHiddenPart(part2, hideChildren, update: false);
}
}
updatedThisFrame = true;
}
private Transform FindInHierarchy(Transform parent, string name)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
if (((Object)parent).name == name)
{
return parent;
}
foreach (Transform item in parent)
{
Transform parent2 = item;
Transform val = FindInHierarchy(parent2, name);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
public void LateUpdate()
{
if (updatedThisFrame)
{
UpdateHiddenParts();
updatedThisFrame = false;
}
}
public void UpdateHiddenParts()
{
Log($"Updating parts, to be hidden: {hiddenParts.ToArray()}");
foreach (Part value in Enum.GetValues(typeof(Part)))
{
ShowPart(value);
}
foreach (Part hiddenPart in hiddenParts)
{
HidePart(hiddenPart);
}
}
private void ShowPart(Part partToShow)
{
for (int i = 0; i < partNames[(int)partToShow].Length; i++)
{
MeshRenderer component = ((Component)partRenderers[(int)partToShow][i]).gameObject.GetComponent<MeshRenderer>();
if (Object.op_Implicit((Object)(object)component))
{
((Renderer)component).enabled = true;
}
}
}
private void HidePart(Part partToHide)
{
for (int i = 0; i < partNames[(int)partToHide].Length; i++)
{
MeshRenderer component = ((Component)partRenderers[(int)partToHide][i]).gameObject.GetComponent<MeshRenderer>();
if (Object.op_Implicit((Object)(object)component))
{
((Renderer)component).enabled = false;
}
}
}
}
}
namespace MoreHeadUtilities.Plugin
{
[BepInPlugin("com.maygik.moreheadutilities", "MoreHeadUtilities", "1.0.0")]
public class MoreHeadUtilitiesPlugin : BaseUnityPlugin
{
public static ConfigEntry<bool> _enableDebugLogging;
private void Awake()
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
_enableDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableDebugLogging", false, "Enable debug logging for MoreHeadUtilities.");
if (_enableDebugLogging.Value)
{
PartShrinker.Init(((BaseUnityPlugin)this).Logger);
ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
if (logger != null)
{
logger.LogInfo((object)"MoreHeadUtilities initialized and logger passed to PartShrinker.");
}
HiddenParts.Init(((BaseUnityPlugin)this).Logger);
ManualLogSource logger2 = ((BaseUnityPlugin)this).Logger;
if (logger2 != null)
{
logger2.LogInfo((object)"MoreHeadUtilities initialized and logger passed to HiddenParts.");
}
Logger.Init(((BaseUnityPlugin)this).Logger);
ManualLogSource logger3 = ((BaseUnityPlugin)this).Logger;
if (logger3 != null)
{
logger3.LogInfo((object)"MoreHeadUtilities initialized and logger passed to DecorationGroups.");
}
}
new Harmony("com.maygik.moreheadutilities").PatchAll();
ManualLogSource logger4 = ((BaseUnityPlugin)this).Logger;
if (logger4 != null)
{
logger4.LogInfo((object)"Harmony patches applied.");
}
}
}
}
namespace MoreHead
{
internal static class Logger
{
public static ManualLogSource? log;
public static void Init(ManualLogSource logger)
{
log = logger;
}
public static void Log(string message)
{
ManualLogSource? obj = log;
if (obj != null)
{
obj.LogInfo((object)message);
}
}
public static void LogError(string message)
{
ManualLogSource? obj = log;
if (obj != null)
{
obj.LogError((object)message);
}
}
}
internal static class MoreHeadGroupStorage
{
public static Dictionary<string?, List<string?>> tagGroupElements = new Dictionary<string, List<string>>();
public static Dictionary<string, bool> activeGroups = new Dictionary<string, bool>();
}
internal static class MoreHeadUIStorage
{
[CanBeNull]
public static REPOPopupPage page = null;
[CanBeNull]
public static string group = null;
public static bool resetPosition = true;
public static Dictionary<string?, REPOButton> groupButtons = new Dictionary<string, REPOButton>();
public static Dictionary<string?, List<string>> groupButtonTags = new Dictionary<string, List<string>>();
}
internal class HeadDecorationManagerStorage
{
public static List<string?> Decorations = new List<string>();
}
[HarmonyPatch(typeof(MoreHeadUI))]
[HarmonyPatch("CreateAllDecorationButtons", new Type[] { typeof(REPOPopupPage) })]
internal static class Patch_CreateAllDecorationButtons
{
private static readonly MethodInfo ClearScrolls = AccessTools.Method(typeof(Dictionary<string, List<REPOScrollViewElement>>), "Clear", (Type[])null, (Type[])null);
private static readonly MethodInfo ToListDecorations = AccessTools.Method(typeof(Enumerable), "ToList", (Type[])null, (Type[])null).MakeGenericMethod(typeof(DecorationInfo));
private static readonly MethodInfo Helper1 = AccessTools.Method(typeof(MoreHeadUIHelpers), "Patch1_CreateAllDecorationButtons", (Type[])null, (Type[])null);
private static readonly MethodInfo Helper2 = AccessTools.Method(typeof(MoreHeadUIHelpers), "Patch2_CreateAllDecorationButtons", new Type[1] { typeof(REPOPopupPage) }, (Type[])null);
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instrs, ILGenerator il)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Expected O, but got Unknown
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Expected O, but got Unknown
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Expected O, but got Unknown
List<CodeInstruction> list = instrs.ToList();
bool flag = false;
bool flag2 = false;
for (int i = 0; i < list.Count; i++)
{
CodeInstruction val = list[i];
if (!flag && val.opcode == OpCodes.Callvirt && val.operand == ClearScrolls)
{
Logger.Log("Patching Patch1_CreateAllDecorationButtons");
list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)Helper1));
flag = true;
}
else if (!flag2 && val.opcode == OpCodes.Call && val.operand == ToListDecorations)
{
Logger.Log("Patching Patch2_CreateAllDecorationButtons");
int num = list.FindLastIndex((CodeInstruction ci) => ci.opcode == OpCodes.Ret);
if (num < 0)
{
throw new InvalidOperationException("Couldn't find the final ret in CreateAllDecorationButtons");
}
CodeInstruction obj = list[num];
Label label = il.DefineLabel();
obj.labels.Add(label);
list.Insert(++i, new CodeInstruction(OpCodes.Ldarg_0, (object)null));
list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)Helper2));
list.Insert(++i, new CodeInstruction(OpCodes.Leave_S, (object)label));
Logger.Log("Patched Patch2_CreateAllDecorationButtons");
break;
}
}
return list;
}
}
[HarmonyPatch(typeof(MoreHeadUI))]
[HarmonyPatch("CreateAllDecorationButtons", new Type[] { typeof(REPOPopupPage) })]
internal static class Prefix_CreateAllDecorationButtons
{
[HarmonyPrefix]
private static bool Prefix(REPOPopupPage page)
{
MoreHeadUIStorage.page = page;
MoreHeadUIStorage.groupButtons.Clear();
MoreHeadUIStorage.groupButtonTags.Clear();
return true;
}
}
[HarmonyPatch(typeof(MoreHeadUI))]
[HarmonyPatch("CreateDecorationButton", new Type[]
{
typeof(REPOPopupPage),
typeof(DecorationInfo)
})]
internal static class Patch_CreateDecorationButton
{
private static readonly MethodInfo ShowTagDecorationsMI = AccessTools.Method(typeof(MoreHeadUI), "ShowTagDecorations", new Type[1] { typeof(string) }, (Type[])null);
[HarmonyPrefix]
private static bool Prefix(REPOPopupPage page, DecorationInfo decoration)
{
try
{
string text = HeadDecorationManagerStorage.Decorations[HeadDecorationManager.Decorations.IndexOf(decoration)];
if (text != null && text != "" && MoreHeadGroupStorage.tagGroupElements.TryGetValue("ALL", out List<string> value))
{
if (!MoreHeadGroupStorage.activeGroups.ContainsKey(text))
{
Logger.Log("Initialising group: " + text);
MoreHeadGroupStorage.activeGroups[text] = false;
}
if (!value.Contains(text))
{
CreateGroupButton(page, text);
}
}
string[] source = (string[])typeof(MoreHeadUI).GetField("LIMB_TAGS", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null);
MoreHeadGroupStorage.tagGroupElements["ALL"].Add(text);
if (text != null)
{
if (!MoreHeadUIStorage.groupButtonTags.ContainsKey(text))
{
Logger.Log("Initialising group button tag list for " + text);
MoreHeadUIStorage.groupButtonTags[text] = new List<string>();
}
MoreHeadUIStorage.groupButtonTags[text].Add("ALL");
}
List<string> value2;
if (source.Contains(decoration.ParentTag.ToUpper()))
{
MoreHeadGroupStorage.tagGroupElements["LIMBS"].Add(text);
if (text != null)
{
MoreHeadUIStorage.groupButtonTags[text].Add("LIMBS");
}
}
else if (MoreHeadGroupStorage.tagGroupElements.TryGetValue(decoration.ParentTag.ToUpper(), out value2))
{
value2.Add(text);
if (text != null)
{
MoreHeadUIStorage.groupButtonTags[text].Add(decoration.ParentTag.ToUpper());
}
}
return true;
}
catch (Exception arg)
{
Logger.LogError($"Error creating decoration button {decoration.Name}: {arg}");
throw;
}
}
private static string GetGroupButtonText(string group)
{
if (!MoreHeadGroupStorage.activeGroups[group])
{
return "<size=20><color=#CCCCCC>[+]" + group + "</color></size>";
}
return "<size=20><color=#777777>[-]" + group + "</color></size>";
}
private static void CreateGroupButton(REPOPopupPage page, string groupName)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
Logger.Log("Creating group button: " + groupName);
try
{
string buttonText = GetGroupButtonText(groupName);
REPOButton repoButton = null;
page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
repoButton = MenuAPI.CreateREPOButton(buttonText, (Action)delegate
{
OnDecorationGroupButtonClick(groupName);
}, scrollView, default(Vector2));
return ((REPOElement)repoButton).rectTransform;
}, 0f, 0f);
if ((Object)(object)repoButton != (Object)null)
{
MoreHeadUIStorage.groupButtons[groupName] = repoButton;
MoreHeadUIStorage.groupButtonTags[groupName] = new List<string>();
MoreHeadUIStorage.group = groupName;
Logger.Log("Created group button: " + groupName);
return;
}
throw new Exception("Failed to create group button.");
}
catch (Exception ex)
{
Logger.Log("Error creating group button: " + ex.Message);
}
}
private static void OnDecorationGroupButtonClick(string? groupName)
{
Logger.Log("OnDecorationGroupButtonClick called for group: " + groupName);
MoreHeadGroupStorage.activeGroups[groupName] = !MoreHeadGroupStorage.activeGroups[groupName];
Logger.Log("Invoking show tag decorations");
string text = (string)typeof(MoreHeadUI).GetField("currentTagFilter", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
MoreHeadUIStorage.resetPosition = false;
ShowTagDecorationsMI.Invoke(null, new object[1] { text });
if (MoreHeadUIStorage.groupButtons.TryGetValue(groupName, out var value))
{
string groupButtonText = GetGroupButtonText(groupName);
((TMP_Text)value.labelTMP).text = groupButtonText;
}
MoreHeadUIStorage.resetPosition = true;
}
}
[HarmonyPatch(typeof(HeadDecorationManager))]
[HarmonyPatch("LoadDecorationBundle", new Type[] { typeof(string) })]
internal static class Patch_LoadDecorationBundle
{
private static readonly MethodInfo EnsureUniqueDisplayName = AccessTools.Method(typeof(HeadDecorationManager), "EnsureUniqueDisplayName", new Type[1] { typeof(string) }, (Type[])null);
private static readonly MethodInfo EnsureUniqueName = AccessTools.Method(typeof(HeadDecorationManager), "EnsureUniqueName", new Type[1] { typeof(string) }, (Type[])null);
private static readonly MethodInfo AddDecorationHelper1 = AccessTools.Method(typeof(HeadDecorationManagerHelpers), "Patch1_LoadDecorationBundle", new Type[1] { typeof(string) }, (Type[])null);
private static readonly MethodInfo AddDecorationHelper2 = AccessTools.Method(typeof(HeadDecorationManagerHelpers), "Patch2_LoadDecorationBundle", (Type[])null, (Type[])null);
private static readonly MethodInfo AddDecorationHelper3 = AccessTools.Method(typeof(HeadDecorationManagerHelpers), "Patch3_LoadDecorationBundle", (Type[])null, (Type[])null);
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instrs)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Expected O, but got Unknown
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Expected O, but got Unknown
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Expected O, but got Unknown
List<CodeInstruction> list = instrs.ToList();
bool flag = false;
bool flag2 = false;
bool flag3 = false;
for (int i = 0; i < list.Count(); i++)
{
CodeInstruction val = list[i];
if (val.opcode == OpCodes.Call && val.operand == EnsureUniqueDisplayName)
{
Logger.Log("Patching AddDecorationHelper2");
list.Insert(i, new CodeInstruction(OpCodes.Call, (object)AddDecorationHelper2));
Logger.Log("Patched AddDecorationHelper2");
flag2 = true;
i += 2;
}
if (val.opcode == OpCodes.Call && val.operand == EnsureUniqueName)
{
Logger.Log("Patching AddDecorationHelper1");
list.Insert(i, new CodeInstruction(OpCodes.Dup, (object)null));
list.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)AddDecorationHelper1));
Logger.Log("Patched AddDecorationHelper1");
flag = true;
i += 2;
}
if (!flag3 && list[i].opcode == OpCodes.Call && list[i].operand == AccessTools.Method(typeof(DecorationBlacklistManager), "IsBlacklisted", new Type[1] { typeof(string) }, (Type[])null))
{
int num = i + 4;
Logger.Log("Patching AddDecorationHelper3");
list.Insert(num++, new CodeInstruction(OpCodes.Call, (object)AddDecorationHelper3));
Logger.Log("Patched AddDecorationHelper3");
flag3 = true;
i += 5;
}
if (flag2 && flag && flag3)
{
break;
}
}
return list;
}
}
[HarmonyPatch(typeof(MoreHeadUI))]
[HarmonyPatch("CreateDecorationButton", new Type[]
{
typeof(REPOPopupPage),
typeof(DecorationInfo)
})]
internal static class Transpiler_CreateDecorationButton
{
private static readonly MethodInfo PatchMethod = AccessTools.Method(typeof(MoreHeadUIHelpers), "Patch1_CreateDecorationButton", new Type[2]
{
typeof(DecorationInfo),
typeof(string)
}, (Type[])null);
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instrs)
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Expected O, but got Unknown
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Expected O, but got Unknown
List<CodeInstruction> list = instrs.ToList();
for (int i = 0; i < list.Count; i++)
{
CodeInstruction val = list[i];
if (val.opcode == OpCodes.Callvirt && val.operand is MethodInfo methodInfo && methodInfo.Name == "Add" && methodInfo.DeclaringType == typeof(List<REPOScrollViewElement>))
{
Logger.Log("Patch adding group");
list.Insert(i + 1, new CodeInstruction(OpCodes.Ldarg_1, (object)null));
list.Insert(i + 2, new CodeInstruction(OpCodes.Ldstr, (object)(MoreHeadUIStorage.group ?? "")));
list.Insert(i + 3, new CodeInstruction(OpCodes.Call, (object)PatchMethod));
i += 3;
}
}
return list;
}
}
[HarmonyPatch(typeof(MoreHeadUI))]
[HarmonyPatch("ShowTagDecorations", new Type[] { typeof(string) })]
internal static class Patch_ShowTagDecorations
{
[HarmonyPrefix]
private static bool Prefix(string tag)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
try
{
Type typeFromHandle = typeof(MoreHeadUI);
Logger.Log("Accessing decorationsPage");
REPOPopupPage val = (REPOPopupPage)typeFromHandle.GetField("decorationsPage", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null);
Logger.Log("Accessing tagScrollViewElements");
Dictionary<string, List<REPOScrollViewElement>> dictionary = (Dictionary<string, List<REPOScrollViewElement>>)typeFromHandle.GetField("tagScrollViewElements", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null);
Logger.Log("Accessing currentTagFilter");
FieldInfo field = typeFromHandle.GetField("currentTagFilter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
string text = (string)field.GetValue(null);
Logger.Log("Running the proper ShowTagDecorations function");
dictionary.TryGetValue(text, out var value);
MoreHeadGroupStorage.tagGroupElements.TryGetValue(text, out List<string> value2);
Logger.Log($"There are {value.Count()} scroll elements and {value2.Count()} grouped elements");
if (!string.IsNullOrEmpty(text))
{
for (int i = 0; i < value.Count(); i++)
{
if ((Object)(object)value[i] != (Object)null)
{
value[i].visibility = false;
}
}
for (int j = 0; j < value2.Count(); j++)
{
if (value2[j] != null)
{
((REPOElement)MoreHeadUIStorage.groupButtons[value2[j]]).repoScrollViewElement.visibility = false;
}
}
}
Logger.Log("Element visibility hidden");
dictionary.TryGetValue(tag, out value);
MoreHeadGroupStorage.tagGroupElements.TryGetValue(tag, out value2);
Logger.Log($"There are {value.Count()} tagged scroll elements and {value2.Count()} tagged grouped elements");
if (!string.IsNullOrEmpty(tag))
{
for (int k = 0; k < value.Count(); k++)
{
if (value2[k] == null)
{
if ((Object)(object)value[k] != (Object)null)
{
value[k].visibility = true;
}
}
else if ((Object)(object)value[k] != (Object)null && MoreHeadGroupStorage.activeGroups[value2[k]])
{
value[k].visibility = true;
}
}
for (int l = 0; l < value2.Count(); l++)
{
if (value2[l] != null && MoreHeadUIStorage.groupButtonTags[value2[l]].Contains(tag))
{
((REPOElement)MoreHeadUIStorage.groupButtons[value2[l]]).repoScrollViewElement.visibility = true;
}
}
}
field.SetValue(null, tag);
if (MoreHeadUIStorage.resetPosition)
{
val.scrollView.SetScrollPosition(0f);
}
val.scrollView.UpdateElements();
}
catch (Exception ex)
{
Logger.LogError("Error showing decorations for tag: " + tag + " | Error: " + ex.Message);
}
return false;
}
}
}
namespace MoreHead.MoreHead.Patchers
{
public static class HeadDecorationManagerHelpers
{
public static string bundleName;
public static void Patch1_LoadDecorationBundle(string bundleBaseName)
{
Logger.Log("Saving bundle name");
bundleName = bundleBaseName;
}
public static void Patch2_LoadDecorationBundle()
{
Logger.Log("Patch_LoadDecorationBundle called");
string text = null;
if (bundleName.Contains("~"))
{
string[] array = bundleName.Split(new char[1] { '~' });
if (array.Length >= 2)
{
text = array[^1].ToLower();
Logger.Log("Setting group: " + text);
}
}
Logger.Log("Adding decoration");
HeadDecorationManagerStorage.Decorations.Add(text);
}
public static void Patch3_LoadDecorationBundle()
{
HeadDecorationManagerStorage.Decorations.RemoveAt(HeadDecorationManagerStorage.Decorations.Count - 1);
Logger.Log("Removing last from decoration group list");
}
}
public static class MoreHeadUIHelpers
{
private static bool _inHelper;
public static void Patch1_CreateAllDecorationButtons()
{
Logger.Log("Starting patch of CreateAllDecorationButtons");
Logger.Log("Accessing type MoreHeadUI");
Type typeFromHandle = typeof(MoreHeadUI);
Logger.Log("Setting binding flags to Static and NonPublic");
Logger.Log("Retrieving ALL_TAGS field from MoreHeadUI");
string[] array = (string[])typeFromHandle.GetField("ALL_TAGS", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
foreach (string key in array)
{
MoreHeadGroupStorage.tagGroupElements[key] = new List<string>();
}
}
public static void Patch2_CreateAllDecorationButtons(REPOPopupPage page)
{
try
{
Logger.Log("Starting Patch2_CreateAllDecorationButtons");
_ = (string[])typeof(MoreHeadUI).GetField("ALL_TAGS", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
List<DecorationInfo> allDecorations = HeadDecorationManager.Decorations.ToList();
Logger.Log("Gotten IsBuiltInDecoration");
MethodInfo isBuiltInMI = AccessTools.Method(typeof(MoreHeadUI), "IsBuiltInDecoration", new Type[1] { typeof(DecorationInfo) }, (Type[])null);
if (isBuiltInMI.GetParameters().Length == 1 && isBuiltInMI.ReturnType == typeof(bool))
{
_ = (Func<DecorationInfo, bool>)Delegate.CreateDelegate(typeof(Func<DecorationInfo, bool>), isBuiltInMI);
Logger.Log("Delegate successfully created for IsBuiltInDecoration.");
Logger.Log("Bound Delegate");
List<DecorationInfo> list = (from decoration in allDecorations
where (bool)isBuiltInMI.Invoke(null, new object[1] { decoration })
orderby HeadDecorationManagerStorage.Decorations[allDecorations.IndexOf(decoration)], decoration.DisplayName
select decoration).ToList();
Logger.Log("builtInDecorations sorted");
List<DecorationInfo> list2 = (from decoration in allDecorations
where !(bool)isBuiltInMI.Invoke(null, new object[1] { decoration })
orderby HeadDecorationManagerStorage.Decorations[allDecorations.IndexOf(decoration)] ?? '\uffff'.ToString(), decoration.DisplayName
select decoration).ToList();
Logger.Log("externalDecorations sorted");
MethodInfo methodInfo = AccessTools.Method(typeof(MoreHeadUI), "CreateDecorationButton", new Type[2]
{
typeof(REPOPopupPage),
typeof(DecorationInfo)
}, (Type[])null);
foreach (DecorationInfo item in list)
{
methodInfo.Invoke(null, new object[2] { page, item });
}
foreach (DecorationInfo item2 in list2)
{
methodInfo.Invoke(null, new object[2] { page, item2 });
}
Logger.Log("externalDecorations all created");
MoreHeadUIStorage.group = null;
return;
}
throw new InvalidOperationException("IsBuiltInDecoration method signature does not match Func<DecorationInfo, bool>.");
}
catch (Exception arg)
{
Logger.LogError($"Error creating all decoration buttons: {arg}");
throw;
}
}
public static void Patch1_CreateDecorationButton(DecorationInfo decoration, string group)
{
if (_inHelper)
{
return;
}
_inHelper = true;
try
{
}
finally
{
_inHelper = false;
}
}
}
}