Decompiled source of EclipseFixes v1.2.4

BepInEx/plugins/EclipseFixes.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("EclipseFixes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EclipseFixes")]
[assembly: AssemblyTitle("EclipseFixes")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 EclipseFixes
{
	[BepInPlugin("fix.eclipseplus.ui", "EclipseFixes", "1.2.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EclipseFixesPlugin : BasePlugin
	{
		public const string GUID = "fix.eclipseplus.ui";

		public const string NAME = "EclipseFixes";

		public const string VERSION = "1.2.3";

		public const string EP_GUID = "com.dinasor.eclipseplus";

		internal static ManualLogSource Logger;

		internal static Harmony HarmonyInst;

		internal static ConfigEntry<bool> CfgCoreUi;

		internal static ConfigEntry<bool> CfgIcons;

		internal static ConfigEntry<bool> CfgMarker;

		internal static ConfigEntry<bool> CfgFamiliars;

		internal static ConfigEntry<bool> CfgDiag;

		public override void Load()
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			CfgCoreUi = ((BasePlugin)this).Config.Bind<bool>("Features", "CoreUiFixes", true, "Vanilla menu fixes: 4/4 expertise slots, 4 legacy choices, 4th HUD stat, phantom-row filter.");
			CfgIcons = ((BasePlugin)this).Config.Bind<bool>("Features", "WeaponIcons", true, "Real game icons for new weapons/bloods in Stat Bonuses (sprite scan on first panel open).");
			CfgMarker = ((BasePlugin)this).Config.Bind<bool>("Features", "SynergyMarker", true, "Yellow x1.5 marker centered on class-synergy rows in Expertise/Legacies lists.");
			CfgFamiliars = ((BasePlugin)this).Config.Bind<bool>("Features", "FamiliarsTabFix", true, "Hide unused Familiars mode tabs and clip the character menu scroll.");
			CfgDiag = ((BasePlugin)this).Config.Bind<bool>("Features", "Diagnostics", false, "Verbose click/update diagnostics in the log (troubleshooting only).");
			try
			{
				string text = EclipseTypes.Validate();
				if (text != null)
				{
					((BasePlugin)this).Log.LogWarning((object)("EclipseFixes: EclipsePlus types not resolved yet (" + text + "), skipping patches."));
					return;
				}
				if (CfgIcons.Value)
				{
					StatBonusesIconSynth.Apply();
				}
				HarmonyInst = new Harmony("fix.eclipseplus.ui");
				foreach (Type patchType in GetPatchTypes())
				{
					if (!ShouldPatch(patchType))
					{
						((BasePlugin)this).Log.LogInfo((object)("EclipseFixes: patch " + patchType.Name + " disabled by config."));
						continue;
					}
					try
					{
						HarmonyInst.CreateClassProcessor(patchType).Patch();
					}
					catch (Exception ex)
					{
						((BasePlugin)this).Log.LogError((object)("EclipseFixes: patch " + patchType.Name + " failed: " + ex));
					}
				}
				((BasePlugin)this).Log.LogInfo((object)"EclipseFixes loaded: weapon panel synthesis + 4/4 slots + 4th HUD stat.");
			}
			catch (Exception ex2)
			{
				((BasePlugin)this).Log.LogError((object)("EclipseFixes patch failure: " + ex2));
			}
		}

		private static bool ShouldPatch(Type t)
		{
			switch (t.Name)
			{
			case "QuipsDiagPatch":
			case "UpdateRowClickDiagPostfix":
				return CfgDiag.Value;
			case "StatPanelKindWeaponPatch":
			case "StatPanelKindBloodPatch":
			case "StatSynergyMarker":
				return CfgMarker.Value;
			case "FamiliarsTabCleanupPatch":
				return CfgFamiliars.Value;
			case "WeaponIconGameSprites":
				return CfgIcons.Value;
			default:
				return CfgCoreUi.Value;
			}
		}

		private static IEnumerable<Type> GetPatchTypes()
		{
			Type[] types = typeof(EclipseFixesPlugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0)
				{
					yield return type;
				}
			}
		}

		public override bool Unload()
		{
			return true;
		}
	}
	internal static class EclipseTypes
	{
		internal static Type Tab = AccessTools.TypeByName("Eclipse.Services.CharacterMenu.Tabs.StatBonusesTab");

		internal static Type DataService = AccessTools.TypeByName("Eclipse.Services.DataService");

		internal static Type DataHUD = AccessTools.TypeByName("Eclipse.Services.CanvasService+DataHUD");

		internal static Type HudUpdateManager = AccessTools.TypeByName("Eclipse.Services.HUD.HudUpdateManager");

		internal static Type HudUtilities = AccessTools.TypeByName("Eclipse.Services.HUD.Shared.HudUtilities");

		internal static Type Quips = AccessTools.TypeByName("Eclipse.Utilities.Quips");

		internal static Type WeaponStatType = AccessTools.TypeByName("Eclipse.Services.DataService+WeaponStatType");

		internal static Type BloodStatType = AccessTools.TypeByName("Eclipse.Services.DataService+BloodStatType");

		internal static Type CharacterMenuService = AccessTools.TypeByName("Eclipse.Services.CharacterMenuService");

		internal static string Validate()
		{
			if (Tab == null)
			{
				return "StatBonusesTab";
			}
			if (DataService == null)
			{
				return "DataService";
			}
			if (DataHUD == null)
			{
				return "DataHUD";
			}
			if (HudUpdateManager == null)
			{
				return "HudUpdateManager";
			}
			if (HudUtilities == null)
			{
				return "HudUtilities";
			}
			if (Quips == null)
			{
				return "Quips";
			}
			if (WeaponStatType == null)
			{
				return "WeaponStatType";
			}
			if (BloodStatType == null)
			{
				return "BloodStatType";
			}
			if (CharacterMenuService == null)
			{
				return "CharacterMenuService";
			}
			return null;
		}
	}
	[HarmonyPatch]
	internal class WeaponExpertisePanelPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(EclipseTypes.Tab, "UpdateWeaponExpertisePanel", (Type[])null, (Type[])null);
		}

		private static bool Prefix(object __instance)
		{
			try
			{
				bool num = Convert.ToBoolean(AccessTools.Field(EclipseTypes.DataService, "_statBonusDataReady").GetValue(null));
				object value = AccessTools.Field(EclipseTypes.DataService, "_weaponStatBonusData").GetValue(null);
				if (num && value != null)
				{
					return true;
				}
			}
			catch
			{
				return true;
			}
			try
			{
				WeaponPanelSynth.Synthesize(__instance);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Weapon panel synthesis failed: " + ex));
				}
			}
			return false;
		}
	}
	internal static class WeaponPanelSynth
	{
		private static readonly Type TabT;

		private static readonly Type DsT;

		private static readonly Type HudT;

		private static readonly Type HuT;

		private static readonly Type EntryT;

		private static readonly FieldInfo FRows;

		private static readonly MethodInfo MUpdateHeader;

		private static readonly MethodInfo MUpdateHeaderIcon;

		private static readonly MethodInfo MEnsureRows;

		private static readonly MethodInfo MUpdateRow;

		private static readonly MethodInfo MWeaponIcons;

		private static readonly MethodInfo MFormatWeaponValue;

		private static readonly FieldInfo FWeaponValues;

		private static readonly FieldInfo FSynergies;

		private static readonly FieldInfo FPrestigeMult;

		private static readonly FieldInfo FExpType;

		private static readonly FieldInfo FExpLevel;

		private static readonly FieldInfo FExpMax;

		private static readonly FieldInfo FExpProg;

		private static readonly FieldInfo FExpPrestige;

		private static readonly FieldInfo FClassType;

		private static readonly FieldInfo FExpBonus;

		private static readonly MethodInfo MSplitPascal;

		private static readonly MethodInfo MClassSynergy;

		internal static volatile string CurrentWeaponType;

		static WeaponPanelSynth()
		{
			TabT = EclipseTypes.Tab;
			DsT = EclipseTypes.DataService;
			HudT = EclipseTypes.DataHUD;
			HuT = EclipseTypes.HudUtilities;
			EntryT = TabT.GetNestedType("StatBonusEntry", BindingFlags.NonPublic);
			FRows = AccessTools.Field(TabT, "_rows");
			MUpdateHeader = AccessTools.Method(TabT, "UpdateHeader", (Type[])null, (Type[])null);
			MUpdateHeaderIcon = AccessTools.Method(TabT, "UpdateHeaderIcon", (Type[])null, (Type[])null);
			MEnsureRows = AccessTools.Method(TabT, "EnsureRows", (Type[])null, (Type[])null);
			MUpdateRow = AccessTools.Method(TabT, "UpdateRow", (Type[])null, (Type[])null);
			MWeaponIcons = AccessTools.Method(TabT, "GetWeaponTypeIconSprites", (Type[])null, (Type[])null);
			MFormatWeaponValue = AccessTools.Method(TabT, "FormatWeaponStatValue", (Type[])null, (Type[])null);
			FWeaponValues = AccessTools.Field(DsT, "_weaponStatValues");
			FSynergies = AccessTools.Field(DsT, "_classStatSynergies");
			FPrestigeMult = AccessTools.Field(DsT, "_prestigeStatMultiplier");
			FExpType = AccessTools.Field(HudT, "_expertiseType");
			FExpLevel = AccessTools.Field(HudT, "_expertiseLevel");
			FExpMax = AccessTools.Field(HudT, "_expertiseMaxLevel");
			FExpProg = AccessTools.Field(HudT, "_expertiseProgress");
			FExpPrestige = AccessTools.Field(HudT, "_expertisePrestige");
			FClassType = AccessTools.Field(HudT, "_classType");
			FExpBonus = AccessTools.Field(HudT, "_expertiseBonusStats");
			MSplitPascal = AccessTools.Method(HuT, "SplitPascalCase", (Type[])null, (Type[])null);
			MClassSynergy = AccessTools.GetDeclaredMethods(HuT).FirstOrDefault((MethodInfo m) => m.Name == "ClassSynergy" && m.GetParameters().Length == 3 && m.GetParameters()[0].ParameterType == EclipseTypes.WeaponStatType);
		}

		internal static void Synthesize(object tab)
		{
			WeaponIconGameSprites.Ensure();
			string text = (string)FExpType.GetValue(null);
			int num = Convert.ToInt32(FExpLevel.GetValue(null));
			int num2 = Convert.ToInt32(FExpMax.GetValue(null));
			float num3 = Convert.ToSingle(FExpProg.GetValue(null));
			int num4 = Convert.ToInt32(FExpPrestige.GetValue(null));
			object value = FClassType.GetValue(null);
			IEnumerable<string> enumerable = FExpBonus.GetValue(null) as IEnumerable<string>;
			int num5 = 0;
			if (enumerable != null)
			{
				foreach (string item2 in enumerable)
				{
					if (!string.IsNullOrWhiteSpace(item2) && Enum.TryParse(EclipseTypes.WeaponStatType, item2, ignoreCase: true, out object result) && Convert.ToInt32(result) != 0)
					{
						num5++;
					}
				}
			}
			float num6 = Convert.ToSingle(FPrestigeMult.GetValue(null));
			object value2 = FSynergies.GetValue(null);
			IDictionary dictionary = FWeaponValues.GetValue(null) as IDictionary;
			float num7 = ((num2 > 0) ? ((float)num / (float)num2) : 0f);
			List<object> list = new List<object>();
			foreach (object value3 in Enum.GetValues(EclipseTypes.WeaponStatType))
			{
				if (Convert.ToInt32(value3) != 0)
				{
					string text2 = value3.ToString();
					string text3 = (string)MSplitPascal.Invoke(null, new object[1] { text2 });
					bool flag = enumerable?.Contains(text2) ?? false;
					float num8 = ((dictionary != null && dictionary.Contains(value3)) ? Convert.ToSingle(dictionary[value3]) : 0f);
					float num9 = ((MClassSynergy != null && value != null && value2 != null) ? Convert.ToSingle(MClassSynergy.Invoke(null, new object[3] { value3, value, value2 })) : 1f);
					float num10 = num8 * (1f + num6 * (float)num4) * num9 * num7;
					object item = Activator.CreateInstance(EntryT, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new object[4]
					{
						Convert.ToInt32(value3),
						text3,
						num10,
						flag
					}, null);
					list.Add(item);
				}
			}
			CurrentWeaponType = text;
			object obj = MWeaponIcons.Invoke(null, new object[1] { text });
			MUpdateHeaderIcon.Invoke(tab, new object[1] { obj });
			MUpdateHeader.Invoke(tab, new object[5]
			{
				text ?? string.Empty,
				num5,
				4,
				num,
				num3
			});
			MEnsureRows.Invoke(tab, new object[1] { list.Count });
			if (FRows.GetValue(tab) is IList list2)
			{
				int num11 = Math.Min(list.Count, list2.Count);
				Delegate obj2 = BuildFormatter();
				Delegate obj3 = Delegate.CreateDelegate(typeof(Action<int>), typeof(WeaponPanelSynth).GetMethod("SendWeaponCust", BindingFlags.Static | BindingFlags.Public));
				for (int i = 0; i < num11; i++)
				{
					MUpdateRow.Invoke(null, new object[4]
					{
						list2[i],
						list[i],
						obj2,
						obj3
					});
				}
			}
		}

		public static void SendWeaponCust(int statIndex)
		{
			try
			{
				MethodInfo methodInfo = AccessTools.Method(EclipseTypes.Quips, "SendCommand", (Type[])null, (Type[])null);
				string currentWeaponType = CurrentWeaponType;
				string text = (string.IsNullOrWhiteSpace(currentWeaponType) ? $".wep cst {statIndex}" : $".wep cst {currentWeaponType} {statIndex}");
				methodInfo?.Invoke(null, new object[1] { text });
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("SendWeaponCust: " + ex));
				}
			}
		}

		private static Delegate BuildFormatter()
		{
			DynamicMethod dynamicMethod = new DynamicMethod("EfFmtWeapon", typeof(string), new Type[1] { EntryT }, typeof(WeaponPanelSynth).Module, skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			MethodInfo method = EntryT.GetMethod("get_StatIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo method2 = EntryT.GetMethod("get_Value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			iLGenerator.Emit(OpCodes.Ldarga_S, (byte)0);
			iLGenerator.Emit(OpCodes.Call, method);
			iLGenerator.Emit(OpCodes.Ldarga_S, (byte)0);
			iLGenerator.Emit(OpCodes.Call, method2);
			iLGenerator.Emit(OpCodes.Call, MFormatWeaponValue);
			iLGenerator.Emit(OpCodes.Ret);
			return dynamicMethod.CreateDelegate(typeof(Func<, >).MakeGenericType(EntryT, typeof(string)));
		}
	}
	[HarmonyPatch]
	internal class LegacyPanelMaxChoicesPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(EclipseTypes.Tab, "UpdateBloodLegaciesPanel", (Type[])null, (Type[])null);
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 3; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Call && list[i].operand is MethodInfo { Name: "UpdateHeader" } methodInfo && methodInfo.DeclaringType == EclipseTypes.Tab && list[i - 3].opcode == OpCodes.Ldc_I4_3)
				{
					list[i - 3].opcode = OpCodes.Ldc_I4_4;
					ManualLogSource logger = EclipseFixesPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)"Legacy panel max choices: 3 -> 4.");
					}
				}
			}
			return list;
		}
	}
	[HarmonyPatch]
	internal class HudFourthStatPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo methodInfo = AccessTools.Method(EclipseTypes.HudUpdateManager, "UpdateWeaponStats", (Type[])null, (Type[])null);
			MethodInfo m2 = AccessTools.Method(EclipseTypes.HudUpdateManager, "UpdateBloodStats", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				yield return methodInfo;
			}
			if (m2 != null)
			{
				yield return m2;
			}
		}

		private static void Postfix(object[] __args)
		{
			try
			{
				FourthStat.Apply(__args);
			}
			catch (Exception e)
			{
				FourthStat.NoteError(e);
			}
		}
	}
	internal static class FourthStat
	{
		private class CacheEntry
		{
			public GameObject Go;

			public object Lt;

			public MethodInfo ForceSet;

			public string Last;
		}

		private static readonly Dictionary<object, CacheEntry> Cache;

		private static bool _loggedError;

		private static readonly Type DsT;

		private static readonly Type HudT;

		private static readonly Type HuT;

		private static readonly FieldInfo FWeaponValues;

		private static readonly FieldInfo FBloodValues;

		private static readonly FieldInfo FSynergies;

		private static readonly FieldInfo FPrestigeMult;

		private static readonly FieldInfo FAbbrev;

		private static readonly FieldInfo FExpLevel;

		private static readonly FieldInfo FExpMax;

		private static readonly FieldInfo FExpPrestige;

		private static readonly FieldInfo FLegLevel;

		private static readonly FieldInfo FLegMax;

		private static readonly FieldInfo FLegPrestige;

		private static readonly FieldInfo FClassType;

		private static readonly MethodInfo MFormatWeaponBar;

		private static readonly MethodInfo MClassSynWeapon;

		private static readonly MethodInfo MClassSynBlood;

		private static readonly HashSet<object> _loggedParents;

		static FourthStat()
		{
			Cache = new Dictionary<object, CacheEntry>();
			DsT = EclipseTypes.DataService;
			HudT = EclipseTypes.DataHUD;
			HuT = EclipseTypes.HudUtilities;
			FWeaponValues = AccessTools.Field(DsT, "_weaponStatValues");
			FBloodValues = AccessTools.Field(DsT, "_bloodStatValues");
			FSynergies = AccessTools.Field(DsT, "_classStatSynergies");
			FPrestigeMult = AccessTools.Field(DsT, "_prestigeStatMultiplier");
			FAbbrev = AccessTools.Field(HuT, "BloodStatTypeAbbreviations");
			FExpLevel = AccessTools.Field(HudT, "_expertiseLevel");
			FExpMax = AccessTools.Field(HudT, "_expertiseMaxLevel");
			FExpPrestige = AccessTools.Field(HudT, "_expertisePrestige");
			FLegLevel = AccessTools.Field(HudT, "_legacyLevel");
			FLegMax = AccessTools.Field(HudT, "_legacyMaxLevel");
			FLegPrestige = AccessTools.Field(HudT, "_legacyPrestige");
			FClassType = AccessTools.Field(HudT, "_classType");
			MFormatWeaponBar = AccessTools.Method(HuT, "FormatWeaponStatBar", (Type[])null, (Type[])null);
			_loggedParents = new HashSet<object>();
			List<MethodInfo> declaredMethods = AccessTools.GetDeclaredMethods(HuT);
			MClassSynWeapon = declaredMethods.FirstOrDefault((MethodInfo m) => m.Name == "ClassSynergy" && m.GetParameters().Length == 3 && m.GetParameters()[0].ParameterType == EclipseTypes.WeaponStatType);
			MClassSynBlood = declaredMethods.FirstOrDefault((MethodInfo m) => m.Name == "ClassSynergy" && m.GetParameters().Length == 3 && m.GetParameters()[0].ParameterType == EclipseTypes.BloodStatType);
		}

		internal static void Apply(object[] args)
		{
			IEnumerable<string> enumerable = args[0] as IEnumerable<string>;
			IEnumerable enumerable2 = args[1] as IEnumerable;
			if (enumerable == null || enumerable2 == null)
			{
				return;
			}
			List<string> list = (enumerable as List<string>) ?? enumerable.ToList();
			object[] array = enumerable2.Cast<object>().ToArray();
			if (array.Length < 3 || array[0] == null || array[2] == null)
			{
				return;
			}
			if (!Cache.TryGetValue(array[0], out var value))
			{
				value = CreateClone(array[0], array[2]);
				if (value == null)
				{
					return;
				}
				Cache[array[0]] = value;
			}
			string text = ((list.Count > 3) ? list[3] : null);
			if (string.IsNullOrWhiteSpace(text) || text.Equals("None", StringComparison.OrdinalIgnoreCase))
			{
				SetText(value, null);
				return;
			}
			string text2 = ((args[3] is Func<int, string, string> func && func.Method.Name.IndexOf("Blood", StringComparison.OrdinalIgnoreCase) >= 0) ? BuildBlood(text) : BuildWeapon(text));
			SetText(value, string.IsNullOrEmpty(text2) ? null : text2);
		}

		private static CacheEntry CreateClone(object firstLt, object thirdLt)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			Component val = (Component)((thirdLt is Component) ? thirdLt : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject gameObject = val.gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				return null;
			}
			Transform parent = gameObject.transform.parent;
			GameObject val2 = Object.Instantiate<GameObject>(gameObject, parent);
			((Object)val2).name = ((Object)gameObject).name + "_Stat4";
			val2.transform.SetSiblingIndex(gameObject.transform.GetSiblingIndex() + 1);
			try
			{
				if ((Object)(object)(((Object)(object)parent != (Object)null) ? ((Component)parent).GetComponent<HorizontalOrVerticalLayoutGroup>() : null) == (Object)null)
				{
					RectTransform component = val2.GetComponent<RectTransform>();
					object obj = ((firstLt is Component) ? firstLt : null);
					object obj2;
					if (obj == null)
					{
						obj2 = null;
					}
					else
					{
						GameObject gameObject2 = ((Component)obj).gameObject;
						obj2 = ((gameObject2 != null) ? gameObject2.GetComponent<RectTransform>() : null);
					}
					if (obj2 == null)
					{
						obj2 = gameObject.GetComponent<RectTransform>();
					}
					RectTransform val3 = (RectTransform)obj2;
					if ((Object)(object)component != (Object)null && (Object)(object)val3 != (Object)null)
					{
						component.anchorMin = val3.anchorMin;
						component.anchorMax = val3.anchorMax;
						component.pivot = val3.pivot;
						component.sizeDelta = val3.sizeDelta;
						Vector2 anchoredPosition = val3.anchoredPosition;
						Rect rect = val3.rect;
						component.anchoredPosition = anchoredPosition + new Vector2(0f, 0f - (((Rect)(ref rect)).height + 4f));
					}
				}
				LogPanelLayoutOnce(parent, gameObject, firstLt);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("FourthStat layout tweak failed: " + ex.Message));
				}
			}
			Type type = thirdLt.GetType();
			object obj3 = null;
			try
			{
				MethodInfo methodInfo = typeof(GameObject).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo x) => x.Name == "GetComponent" && x.IsGenericMethodDefinition && x.GetParameters().Length == 0);
				if (methodInfo != null)
				{
					obj3 = methodInfo.MakeGenericMethod(type).Invoke(val2, null);
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource logger2 = EclipseFixesPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)("[FourthStat] generic GetComponent failed: " + ex2.Message));
				}
			}
			if (obj3 == null)
			{
				int num = Array.IndexOf(Il2CppArrayBase<Component>.op_Implicit(gameObject.GetComponents<Component>()), val);
				Il2CppArrayBase<Component> components = val2.GetComponents<Component>();
				if (num >= 0 && num < components.Length)
				{
					obj3 = components[num];
				}
			}
			Behaviour val4 = (Behaviour)((obj3 is Behaviour) ? obj3 : null);
			if (val4 != null)
			{
				val4.enabled = true;
			}
			ManualLogSource logger3 = EclipseFixesPlugin.Logger;
			if (logger3 != null)
			{
				logger3.LogInfo((object)("[FourthStat] lt resolved: " + ((obj3 != null) ? obj3.GetType().FullName : "NULL")));
			}
			MethodInfo forceSet = AccessTools.Method(type, "ForceSet", (Type[])null, (Type[])null);
			val2.SetActive(false);
			return new CacheEntry
			{
				Go = val2,
				Lt = obj3,
				ForceSet = forceSet,
				Last = null
			};
		}

		private static void LogPanelLayoutOnce(object parentObj, GameObject thirdGo, object firstLt)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			Component val = (Component)((parentObj is Component) ? parentObj : null);
			if ((Object)(object)val == (Object)null || !_loggedParents.Add(val))
			{
				return;
			}
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("[FourthStat] panel '").Append(((Object)val.gameObject).name).Append("' components: ");
				foreach (Component component3 in val.GetComponents<Component>())
				{
					stringBuilder.Append(((object)component3).GetType().Name).Append(", ");
				}
				object obj = ((firstLt is Component) ? firstLt : null);
				GameObject val2 = ((obj != null) ? ((Component)obj).gameObject : null);
				if ((Object)(object)val2 != (Object)null)
				{
					RectTransform component = val2.GetComponent<RectTransform>();
					RectTransform component2 = thirdGo.GetComponent<RectTransform>();
					StringBuilder stringBuilder2 = stringBuilder.Append("| first='").Append(((Object)val2).name).Append("' pos=");
					Vector2 val3 = component.anchoredPosition;
					StringBuilder stringBuilder3 = stringBuilder2.Append(((Vector2)(ref val3)).ToString("F0")).Append(" size=");
					Rect rect = component.rect;
					val3 = ((Rect)(ref rect)).size;
					StringBuilder stringBuilder4 = stringBuilder3.Append(((Vector2)(ref val3)).ToString("F0")).Append(" anchorMin=");
					val3 = component.anchorMin;
					StringBuilder stringBuilder5 = stringBuilder4.Append(((Vector2)(ref val3)).ToString("F2")).Append(" anchorMax=");
					val3 = component.anchorMax;
					StringBuilder stringBuilder6 = stringBuilder5.Append(((Vector2)(ref val3)).ToString("F2")).Append("| third='").Append(((Object)thirdGo).name)
						.Append("' pos=");
					val3 = component2.anchoredPosition;
					StringBuilder stringBuilder7 = stringBuilder6.Append(((Vector2)(ref val3)).ToString("F0")).Append(" size=");
					rect = component2.rect;
					val3 = ((Rect)(ref rect)).size;
					stringBuilder7.Append(((Vector2)(ref val3)).ToString("F0"));
				}
				if ((Object)(object)val != (Object)null)
				{
					stringBuilder.Append("| children: ");
					for (int i = 0; i < val.transform.childCount; i++)
					{
						stringBuilder.Append(((Object)val.transform.GetChild(i)).name).Append(", ");
					}
				}
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)stringBuilder.ToString());
				}
			}
			catch
			{
			}
		}

		private static void SetText(CacheEntry ce, string text)
		{
			if (text == null)
			{
				if ((Object)(object)ce.Go != (Object)null && ce.Go.activeSelf)
				{
					ce.Go.SetActive(false);
				}
				ce.Last = null;
				return;
			}
			if ((Object)(object)ce.Go != (Object)null && !ce.Go.activeSelf)
			{
				ce.Go.SetActive(true);
			}
			if (ce.Last != text)
			{
				ce.ForceSet?.Invoke(ce.Lt, new object[1] { text });
				ce.Last = text;
			}
		}

		private static float ComputeValue(FieldInfo valuesField, Type enumT, MethodInfo classSyn, object stat, FieldInfo fPrestige, FieldInfo fLevel, FieldInfo fMax)
		{
			if (!(valuesField.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(stat))
			{
				return -1f;
			}
			float num = Convert.ToSingle(dictionary[stat]);
			float num2 = Convert.ToSingle(FPrestigeMult.GetValue(null));
			int num3 = Convert.ToInt32(fPrestige.GetValue(null));
			int num4 = Convert.ToInt32(fLevel.GetValue(null));
			int num5 = Convert.ToInt32(fMax.GetValue(null));
			object value = FClassType.GetValue(null);
			object value2 = FSynergies.GetValue(null);
			float num6 = ((classSyn != null && value != null && value2 != null) ? Convert.ToSingle(classSyn.Invoke(null, new object[3] { stat, value, value2 })) : 1f);
			float num7 = ((num5 > 0) ? ((float)num4 / (float)num5) : 0f);
			return num * (1f + num2 * (float)num3) * num6 * num7;
		}

		private static string BuildWeapon(string statName)
		{
			if (!Enum.TryParse(EclipseTypes.WeaponStatType, statName, ignoreCase: true, out object result))
			{
				return null;
			}
			float num = ComputeValue(FWeaponValues, EclipseTypes.WeaponStatType, MClassSynWeapon, result, FExpPrestige, FExpLevel, FExpMax);
			if (num < 0f)
			{
				return null;
			}
			return (string)MFormatWeaponBar.Invoke(null, new object[2] { result, num });
		}

		private static string BuildBlood(string statName)
		{
			if (!Enum.TryParse(EclipseTypes.BloodStatType, statName, ignoreCase: true, out object result))
			{
				return null;
			}
			float num = ComputeValue(FBloodValues, EclipseTypes.BloodStatType, MClassSynBlood, result, FLegPrestige, FLegLevel, FLegMax);
			if (num < 0f)
			{
				return null;
			}
			string value = ((FAbbrev.GetValue(null) is IDictionary dictionary && dictionary.Contains(result)) ? dictionary[result].ToString() : statName);
			return $"<color=#00FFFF>{value}</color>: <color=#90EE90>{(num * 100f).ToString("F0", CultureInfo.InvariantCulture)}%</color>";
		}

		internal static void NoteError(Exception e)
		{
			if (!_loggedError)
			{
				_loggedError = true;
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("FourthStat error: " + e));
				}
			}
		}
	}
	[HarmonyPatch]
	internal class BonusStatsPhantomFilterPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(EclipseTypes.DataService, "ParsePlayerData", (Type[])null, (Type[])null);
		}

		private static void Postfix()
		{
			Filter("_legacyBonusStats");
			Filter("_expertiseBonusStats");
		}

		private static void Filter(string fieldName)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			try
			{
				if (!(AccessTools.Field(EclipseTypes.DataHUD, fieldName)?.GetValue(null) is List<string> list))
				{
					return;
				}
				bool flag = false;
				for (int num = list.Count - 1; num >= 0; num--)
				{
					string text = list[num];
					if (!string.IsNullOrEmpty(text) && (text == "0" || text.Equals("None", StringComparison.OrdinalIgnoreCase)))
					{
						list.RemoveAt(num);
						flag = true;
					}
				}
				while (list.Count < 3)
				{
					list.Add(string.Empty);
				}
				if (!flag)
				{
					return;
				}
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					bool flag2 = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(52, 2, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PhantomFilter] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fieldName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": dropped D8 zero-pad entries, ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" left");
					}
					logger.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = EclipseFixesPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("[PhantomFilter] " + fieldName + ": " + ex));
				}
			}
		}
	}
	internal static class QuipsDiagPatch
	{
		private static bool _attempted;

		internal static void EnsureApplied()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			if (_attempted)
			{
				return;
			}
			_attempted = true;
			try
			{
				MethodInfo methodInfo = AccessTools.Method(EclipseTypes.Quips, "SendCommand", new Type[1] { typeof(string) }, (Type[])null);
				if (methodInfo == null)
				{
					ManualLogSource logger = EclipseFixesPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"[ClickDiag] Quips.SendCommand not found.");
					}
					return;
				}
				MethodInfo method = typeof(QuipsDiagPatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic);
				if (method == null)
				{
					ManualLogSource logger2 = EclipseFixesPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)"[ClickDiag] prefix method not found.");
					}
					return;
				}
				EclipseFixesPlugin.HarmonyInst.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				ManualLogSource logger3 = EclipseFixesPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogInfo((object)"[ClickDiag] Quips.SendCommand prefix applied lazily (world ready).");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = EclipseFixesPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("[ClickDiag] lazy Quips patch failed: " + ex));
				}
			}
		}

		private static void Prefix(string command)
		{
			ManualLogSource logger = EclipseFixesPlugin.Logger;
			if (logger != null)
			{
				logger.LogInfo((object)("[ClickDiag] Quips.SendCommand: " + command));
			}
		}
	}
	[HarmonyPatch]
	internal class UpdateRowClickDiagPostfix
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(EclipseTypes.Tab, "UpdateRow", (Type[])null, (Type[])null);
		}

		private static void Postfix(object[] __args)
		{
			try
			{
				RowClickDiag.Apply(__args);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("[ClickDiag] UpdateRow postfix failed: " + ex));
				}
			}
		}
	}
	internal static class RowClickDiag
	{
		private static readonly Type RowT = ((EclipseTypes.Tab != null) ? EclipseTypes.Tab.GetNestedType("StatBonusRow", BindingFlags.NonPublic) : null);

		private static readonly PropertyInfo PButton = RowT?.GetProperty("Button", BindingFlags.Instance | BindingFlags.Public);

		private static readonly PropertyInfo PRoot = RowT?.GetProperty("Root", BindingFlags.Instance | BindingFlags.Public);

		private static readonly PropertyInfo PStatIndex = RowT?.GetProperty("StatIndex", BindingFlags.Instance | BindingFlags.Public);

		private static readonly HashSet<object> _fallbackAttached = new HashSet<object>();

		private static readonly Dictionary<string, float> _lastAcceptedClick = new Dictionary<string, float>();

		private const float ClickDebounceSeconds = 0.3f;

		internal static void Apply(object[] args)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			QuipsDiagPatch.EnsureApplied();
			object obj = ((args.Length != 0) ? args[0] : null);
			Action<int> action = ((args.Length > 3) ? (args[3] as Action<int>) : null);
			if (obj == null || RowT == null || PButton == null)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"[ClickDiag] UpdateRow: row=NULL or StatBonusRow type unresolved.");
				}
				return;
			}
			object value = PButton.GetValue(obj);
			object obj2 = ((PRoot != null) ? PRoot.GetValue(obj) : null);
			object obj3 = ((obj2 is Component) ? obj2 : null);
			GameObject val = (GameObject)(((obj3 != null) ? ((Component)obj3).gameObject : null) ?? ((obj2 is GameObject) ? obj2 : null));
			string text = (((Object)(object)val != (Object)null) ? ((Object)val).name : "?");
			int num = Convert.ToInt32((PStatIndex != null) ? PStatIndex.GetValue(obj) : ((object)(-1)));
			bool flag = default(bool);
			ManualLogSource logger2;
			if (value != null)
			{
				Object val2 = (Object)((value is Object) ? value : null);
				if (val2 == null || !(val2 == (Object)null))
				{
					object obj4 = value.GetType().GetProperty("onClick", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value);
					UnityEvent val3 = (UnityEvent)((obj4 is UnityEvent) ? obj4 : null);
					if (val3 == null)
					{
						logger2 = EclipseFixesPlugin.Logger;
						if (logger2 != null)
						{
							BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(50, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[ClickDiag] UpdateRow: onClick unavailable (");
								((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(obj4?.GetType().FullName ?? "null");
								((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", go=");
								((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(text);
								((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")");
							}
							logger2.LogInfo(val4);
						}
						return;
					}
					((UnityEventBase)val3).RemoveAllListeners();
					AttachClickHandler(val3, obj, text, action);
					logger2 = EclipseFixesPlugin.Logger;
					if (logger2 != null)
					{
						BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(79, 4, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[ClickDiag] UpdateRow stat=");
							((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(num);
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" go=");
							((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(text);
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" button=OK onClick=");
							((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(obj4.GetType().Name);
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" ");
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("listener attached (handler=");
							((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>((action != null) ? action.Method.Name : "NULL");
							((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")");
						}
						logger2.LogInfo(val4);
					}
					return;
				}
			}
			logger2 = EclipseFixesPlugin.Logger;
			if (logger2 != null)
			{
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(83, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[ClickDiag] UpdateRow: row.Button == NULL (stat=");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", go=");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(") — original never subscribes.");
				}
				logger2.LogInfo(val4);
			}
			AttachFallback(obj, val, action);
		}

		private static void AttachClickHandler(UnityEvent ue, object row, string goName, Action<int> onClicked)
		{
			ue.AddListener(UnityAction.op_Implicit((Action)delegate
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Expected O, but got Unknown
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Expected O, but got Unknown
				int num = -1;
				try
				{
					num = Convert.ToInt32(PStatIndex.GetValue(row));
				}
				catch
				{
				}
				string text = ((onClicked != null) ? onClicked.Method.Name : "NULL");
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				bool flag = default(bool);
				if (logger != null)
				{
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(43, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[ClickDiag] row click: stat=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", go=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(goName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", handler=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					}
					logger.LogInfo(val);
				}
				string key = text + ":" + num;
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (_lastAcceptedClick.TryGetValue(key, out var value) && realtimeSinceStartup - value < 0.3f)
				{
					logger = EclipseFixesPlugin.Logger;
					if (logger != null)
					{
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(84, 3, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[ClickDiag] debounced duplicate click: stat=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", handler=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(0.3f, "0.0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s window) - command NOT sent");
						}
						logger.LogInfo(val);
					}
				}
				else
				{
					_lastAcceptedClick[key] = realtimeSinceStartup;
					if (onClicked != null)
					{
						try
						{
							onClicked(num);
						}
						catch (Exception ex)
						{
							ManualLogSource logger2 = EclipseFixesPlugin.Logger;
							if (logger2 != null)
							{
								logger2.LogError((object)("[ClickDiag] click handler threw: " + ex));
							}
						}
					}
				}
			}));
		}

		private static void AttachFallback(object row, GameObject go, Action<int> onClicked)
		{
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			if ((Object)(object)go == (Object)null)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"[ClickDiag] fallback: row has no GameObject, cannot attach.");
				}
			}
			else
			{
				if (!_fallbackAttached.Add(go))
				{
					return;
				}
				try
				{
					Type type = FindType("SimpleStunButton");
					if (type == null)
					{
						ManualLogSource logger2 = EclipseFixesPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogInfo((object)"[ClickDiag] fallback: SimpleStunButton type not found.");
						}
						return;
					}
					MethodInfo methodInfo = typeof(GameObject).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "AddComponent" && m.IsGenericMethodDefinition && m.GetParameters().Length == 0);
					if (methodInfo == null)
					{
						ManualLogSource logger3 = EclipseFixesPlugin.Logger;
						if (logger3 != null)
						{
							logger3.LogInfo((object)"[ClickDiag] fallback: AddComponent<T> not found.");
						}
						return;
					}
					object obj = methodInfo.MakeGenericMethod(type).Invoke(go, null);
					object obj2 = obj?.GetType().GetProperty("onClick", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj);
					UnityEvent val = (UnityEvent)((obj2 is UnityEvent) ? obj2 : null);
					bool flag = default(bool);
					ManualLogSource logger4;
					if (val == null)
					{
						logger4 = EclipseFixesPlugin.Logger;
						if (logger4 != null)
						{
							BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(57, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[ClickDiag] fallback: created ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(type.Name);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" but onClick unavailable (");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(obj2?.GetType().FullName ?? "null");
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
							}
							logger4.LogInfo(val2);
						}
						return;
					}
					AttachClickHandler(val, row, ((Object)go).name, onClicked);
					logger4 = EclipseFixesPlugin.Logger;
					if (logger4 != null)
					{
						BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(48, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[ClickDiag] fallback: added ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(type.Name);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" to ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)go).name);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" and subscribed.");
						}
						logger4.LogInfo(val2);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource logger5 = EclipseFixesPlugin.Logger;
					if (logger5 != null)
					{
						logger5.LogError((object)("[ClickDiag] fallback failed: " + ex));
					}
				}
			}
		}

		private static Type FindType(string shortName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch
				{
					continue;
				}
				Type[] array = types;
				foreach (Type type in array)
				{
					if (type.Name == shortName)
					{
						return type;
					}
				}
			}
			return null;
		}
	}
	internal static class StatBonusesIconSynth
	{
		private static bool _applied;

		internal static void Apply()
		{
			if (_applied)
			{
				return;
			}
			try
			{
				Extend("WeaponTypeIconSpriteNames", new Dictionary<string, string[]>
				{
					["Unarmed"] = new string[2] { "strength_level_icon", "Poneti_Icon_Sword_v2_48" },
					["FishingPole"] = new string[2] { "Poneti_Icon_Engineering_59_mega_fishingrod", "Stunlock_Icon_Bag_Background_Fish" },
					["TwinBlades"] = new string[2] { "Poneti_Icon_Sword_v2_48", "Poneti_Icon_Dagger_v2_01" },
					["Daggers"] = new string[2] { "Poneti_Icon_Dagger_v2_01", "Poneti_Icon_Sword_v2_48" },
					["Claws"] = new string[2] { "Poneti_Icon_Dagger_v2_01", "Poneti_Icon_Sword_v2_48" }
				});
				Extend("BloodTypeIconSpriteNames", new Dictionary<string, string[]>
				{
					["Immortal"] = new string[3] { "BloodType_Draculin_Big", "BloodType_Draculin_Small", "Stunlock_Icons_spellbook_blood" },
					["VBlood"] = new string[3] { "MobLevel_Skull", "BloodType_Draculin_Small", "Stunlock_Icons_spellbook_blood" },
					["GateBoss"] = new string[3] { "MobLevel_Skull", "BloodType_Draculin_Small", "Stunlock_Icons_spellbook_blood" }
				});
				_applied = true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("StatBonusesIconSynth: " + ex));
				}
			}
		}

		private static void Extend(string fieldName, Dictionary<string, string[]> additions)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			FieldInfo fieldInfo = AccessTools.Field(EclipseTypes.Tab, fieldName);
			if (fieldInfo == null)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("StatBonusesIconSynth: field " + fieldName + " not found."));
				}
				return;
			}
			if (!(fieldInfo.GetValue(null) is IDictionary dictionary))
			{
				ManualLogSource logger2 = EclipseFixesPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)("StatBonusesIconSynth: " + fieldName + " is not an IDictionary."));
				}
				return;
			}
			int num = 0;
			foreach (KeyValuePair<string, string[]> addition in additions)
			{
				if (!dictionary.Contains(addition.Key))
				{
					dictionary.Add(addition.Key, addition.Value);
					num++;
				}
			}
			ManualLogSource logger3 = EclipseFixesPlugin.Logger;
			if (logger3 != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(53, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("StatBonusesIconSynth: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fieldName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": +");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" entries (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(additions.Count - num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" already present).");
				}
				logger3.LogInfo(val);
			}
		}
	}
	internal static class WeaponIconGameSprites
	{
		private static readonly Type HudDataT = AccessTools.TypeByName("Eclipse.Services.HUD.Shared.HudData");

		private static readonly string[] Plan0 = new string[16]
		{
			"Sword", "Axe", "Mace", "Spear", "Crossbow", "GreatSword", "Slashers", "Pistols", "Reaper", "Longbow",
			"Whip", "TwinBlades", "Daggers", "Claws", "FishingPole", "Unarmed"
		};

		private static readonly HashSet<string> _pending = new HashSet<string>(Plan0);

		private static readonly HashSet<string> _satisfied = new HashSet<string>();

		private static float _lastScanTime = float.NegativeInfinity;

		private const float RescanCooldown = 30f;

		private static readonly (string WeaponType, string[][] Tiers)[] Plan = new(string, string[][])[16]
		{
			("Sword", new string[2][]
			{
				new string[3] { "stunlock_icon_ironsword", "stunlock_icon_weapon_sword", "stunlock_icon_sword" },
				new string[2] { "icon_sword", "iconsword" }
			}),
			("Axe", new string[2][]
			{
				new string[3] { "stunlock_icon_ironaxe", "stunlock_icon_weapon_axe", "stunlock_icon_axe" },
				new string[3] { "icon_axe", "iconaxe", "axes" }
			}),
			("Mace", new string[2][]
			{
				new string[3] { "stunlock_icon_ironmace", "stunlock_icon_weapon_mace", "stunlock_icon_hammer" },
				new string[4] { "icon_hammer", "iconhammer", "icon_mace", "mace" }
			}),
			("Spear", new string[2][]
			{
				new string[3] { "stunlock_icon_ironspear", "stunlock_icon_weapon_spear", "stunlock_icon_spear" },
				new string[2] { "icon_spear", "spear" }
			}),
			("Crossbow", new string[2][]
			{
				new string[3] { "stunlock_icon_ironcrossbow", "stunlock_icon_weapon_crossbow", "stunlock_icon_crossbow" },
				new string[2] { "icon_crossbow", "crossbow" }
			}),
			("GreatSword", new string[2][]
			{
				new string[3] { "stunlock_icon_irongreatsword", "stunlock_icon_weapon_greatsword", "stunlock_icon_greatsword" },
				new string[2] { "icon_greatsword", "greatsword" }
			}),
			("Slashers", new string[2][]
			{
				new string[3] { "stunlock_icon_ironslashers", "stunlock_icon_weapon_slashers", "stunlock_icon_slasher" },
				new string[2] { "icon_slasher", "slasher" }
			}),
			("Pistols", new string[2][]
			{
				new string[3] { "stunlock_icon_ironpistols", "stunlock_icon_weapon_pistols", "stunlock_icon_pistol" },
				new string[2] { "icon_pistol", "pistol" }
			}),
			("Reaper", new string[2][]
			{
				new string[3] { "stunlock_icon_ironreaper", "stunlock_icon_weapon_reaper", "stunlock_icon_reaper" },
				new string[4] { "icon_scythe", "icon_reaper", "scythe", "reaper" }
			}),
			("Longbow", new string[2][]
			{
				new string[3] { "stunlock_icon_ironlongbow", "stunlock_icon_weapon_longbow", "stunlock_icon_longbow" },
				new string[2] { "icon_bow", "longbow" }
			}),
			("Whip", new string[2][]
			{
				new string[3] { "stunlock_icon_ironwhip", "stunlock_icon_weapon_whip", "stunlock_icon_whip" },
				new string[2] { "icon_whip", "whip" }
			}),
			("TwinBlades", new string[2][]
			{
				new string[3] { "stunlock_icon_irontwinblades", "stunlock_icon_weapon_twinblades", "stunlock_icon_twinblade" },
				new string[3] { "twinblade", "dualblade", "twinsword" }
			}),
			("Daggers", new string[2][]
			{
				new string[3] { "stunlock_icon_irondagger", "stunlock_icon_weapon_daggers", "stunlock_icon_dagger" },
				new string[1] { "dagger" }
			}),
			("Claws", new string[2][]
			{
				new string[3] { "stunlock_icon_ironclaw", "stunlock_icon_weapon_claws", "stunlock_icon_claw" },
				new string[1] { "claw" }
			}),
			("FishingPole", new string[3][]
			{
				new string[3] { "stunlock_icon_fishingrod", "stunlock_icon_fishingpole", "stunlock_icon_fishing" },
				new string[4] { "fishingrod", "fishrod", "fishingpole", "fishpole" },
				new string[1] { "fishing" }
			}),
			("Unarmed", new string[2][]
			{
				new string[2] { "stunlock_icon_ability_unarmed", "stunlock_icon_unarmed" },
				new string[4] { "unarmed", "barehand", "fist", "punch" }
			})
		};

		internal static void Ensure()
		{
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Expected O, but got Unknown
			try
			{
				if (_pending.Count == 0)
				{
					return;
				}
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (!float.IsNegativeInfinity(_lastScanTime) && realtimeSinceStartup - _lastScanTime < 30f)
				{
					return;
				}
				_lastScanTime = realtimeSinceStartup;
				if (HudDataT == null)
				{
					ManualLogSource logger = EclipseFixesPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"WeaponIconGameSprites: HudData not found.");
					}
					return;
				}
				if (!(AccessTools.Field(HudDataT, "Sprites")?.GetValue(null) is Dictionary<string, Sprite> dictionary))
				{
					ManualLogSource logger2 = EclipseFixesPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)"WeaponIconGameSprites: HudData.Sprites not found.");
					}
					return;
				}
				if (!(AccessTools.Field(EclipseTypes.Tab, "WeaponTypeIconSpriteNames")?.GetValue(null) is IDictionary dictionary2))
				{
					ManualLogSource logger3 = EclipseFixesPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)"WeaponIconGameSprites: weapon icon dictionary not found.");
					}
					return;
				}
				Sprite[] array = Il2CppArrayBase<Sprite>.op_Implicit(Resources.FindObjectsOfTypeAll<Sprite>());
				(string, string[][])[] plan = Plan;
				bool flag2 = default(bool);
				for (int i = 0; i < plan.Length; i++)
				{
					(string, string[][]) tuple = plan[i];
					if (!_pending.Contains(tuple.Item1))
					{
						continue;
					}
					List<Sprite> list = null;
					string[][] item = tuple.Item2;
					string[] array4;
					foreach (string[] array2 in item)
					{
						list = new List<Sprite>();
						Sprite[] array3 = array;
						foreach (Sprite val in array3)
						{
							string text = (((Object)(object)val != (Object)null) ? ((Object)val).name : null);
							if (string.IsNullOrEmpty(text))
							{
								continue;
							}
							array4 = array2;
							foreach (string value in array4)
							{
								if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
								{
									list.Add(val);
									break;
								}
							}
						}
						if (list.Count > 0)
						{
							break;
						}
					}
					if (list == null || list.Count == 0)
					{
						if (!_satisfied.Contains(tuple.Item1))
						{
							_satisfied.Add(tuple.Item1);
							ManualLogSource logger4 = EclipseFixesPlugin.Logger;
							if (logger4 != null)
							{
								logger4.LogInfo((object)("WeaponIconGameSprites: no game sprite candidates for " + tuple.Item1));
							}
						}
						continue;
					}
					Sprite val2 = (from s in list
						orderby ArtRank(((Object)s).name), (((Object)s).name.IndexOf("icon", StringComparison.OrdinalIgnoreCase) < 0) ? 1 : 0, ((Object)s).name.Length
						select s).ThenBy<Sprite, string>((Sprite s) => ((Object)s).name, StringComparer.OrdinalIgnoreCase).First();
					string text2 = "EclipseFixes_" + tuple.Item1;
					Sprite value2;
					bool flag = !dictionary.TryGetValue(text2, out value2) || (Object)(object)value2 != (Object)(object)val2;
					dictionary[text2] = val2;
					string[] obj = ((dictionary2.Contains(tuple.Item1) ? dictionary2[tuple.Item1] : null) as string[]) ?? new string[1] { "Poneti_Icon_Sword_v2_48" };
					List<string> list2 = new List<string>(obj.Length + 1) { text2 };
					array4 = obj;
					foreach (string text3 in array4)
					{
						if (!string.IsNullOrEmpty(text3) && text3 != text2 && !list2.Contains(text3))
						{
							list2.Add(text3);
						}
					}
					dictionary2[tuple.Item1] = list2.ToArray();
					if (((Object)val2).name.StartsWith("Stunlock_Icon", StringComparison.OrdinalIgnoreCase))
					{
						_pending.Remove(tuple.Item1);
					}
					if (!flag)
					{
						continue;
					}
					string text4 = string.Join(", ", list.Select((Sprite c) => ((Object)c).name).Take(10));
					ManualLogSource logger5 = EclipseFixesPlugin.Logger;
					if (logger5 != null)
					{
						BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(45, 4, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("WeaponIconGameSprites: ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(tuple.Item1);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" -> '");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(((Object)val2).name);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' (");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(list.Count);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" candidates: ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text4);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")");
						}
						logger5.LogInfo(val3);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger6 = EclipseFixesPlugin.Logger;
				if (logger6 != null)
				{
					logger6.LogError((object)("WeaponIconGameSprites: " + ex));
				}
			}
		}

		private static int ArtRank(string name)
		{
			if (name.StartsWith("Stunlock_Icon", StringComparison.OrdinalIgnoreCase))
			{
				return 0;
			}
			if (name.StartsWith("Poneti", StringComparison.OrdinalIgnoreCase) || name.StartsWith("FantasyIcon", StringComparison.OrdinalIgnoreCase))
			{
				return 2;
			}
			return 1;
		}
	}
	[HarmonyPatch]
	internal class StatPanelKindWeaponPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(EclipseTypes.Tab, "UpdateWeaponExpertisePanel", (Type[])null, (Type[])null);
		}

		private static void Prefix()
		{
			StatSynergyMarker.PanelKind = 0;
		}
	}
	[HarmonyPatch]
	internal class StatPanelKindBloodPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(EclipseTypes.Tab, "UpdateBloodLegaciesPanel", (Type[])null, (Type[])null);
		}

		private static void Prefix()
		{
			StatSynergyMarker.PanelKind = 1;
		}
	}
	[HarmonyPatch]
	internal class StatSynergyMarker
	{
		internal const int WeaponPanel = 0;

		internal const int BloodPanel = 1;

		internal static volatile int PanelKind;

		private static readonly Type TabT;

		private static readonly FieldInfo FClassType;

		private static readonly FieldInfo FSynergies;

		private static readonly PropertyInfo PStatIndex;

		private static readonly PropertyInfo PNameText;

		private static readonly PropertyInfo PRoot;

		private static readonly MethodInfo MClassSynergy;

		private static MethodInfo _weaponCall;

		private static MethodInfo _bloodCall;

		private static Type _tmpTextSType;

		private static Type _tmpIl2CppType;

		private static PropertyInfo _pText;

		private static PropertyInfo _pColor;

		private static PropertyInfo _pFontSize;

		private static PropertyInfo _pAlignment;

		private static PropertyInfo _pWrap;

		private static PropertyInfo _pRaycast;

		private static PropertyInfo _pFont;

		private static bool _tmpPropsResolved;

		private static bool _warnedNoTmp;

		private static bool _firstLogged;

		private const string MarkerName = "SynergyMarker";

		private static PropertyInfo _pPointer;

		static StatSynergyMarker()
		{
			TabT = EclipseTypes.Tab;
			FClassType = AccessTools.Field(EclipseTypes.DataHUD, "_classType");
			FSynergies = AccessTools.Field(EclipseTypes.DataService, "_classStatSynergies");
			try
			{
				Type nestedType = TabT.GetNestedType("StatBonusRow", BindingFlags.NonPublic);
				if (nestedType != null)
				{
					PStatIndex = nestedType.GetProperty("StatIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					PNameText = nestedType.GetProperty("NameText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					PRoot = nestedType.GetProperty("Root", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				MClassSynergy = AccessTools.GetDeclaredMethods(EclipseTypes.HudUtilities).FirstOrDefault((MethodInfo m) => m.Name == "ClassSynergy" && m.IsGenericMethodDefinition && m.GetParameters().Length == 3);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("StatSynergyMarker init: " + ex));
				}
			}
		}

		private static void ResolveTmpProps()
		{
			if (!_tmpPropsResolved && !(_tmpTextSType == null))
			{
				_tmpPropsResolved = true;
				_pText = _tmpTextSType.GetProperty("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pColor = _tmpTextSType.GetProperty("color", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pFontSize = _tmpTextSType.GetProperty("fontSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pAlignment = _tmpTextSType.GetProperty("alignment", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pWrap = _tmpTextSType.GetProperty("enableWordWrapping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pRaycast = _tmpTextSType.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_pFont = _tmpTextSType.GetProperty("font", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
		}

		private static bool EnsureTmpType(object nameText)
		{
			if (_tmpIl2CppType != (Type)null)
			{
				return true;
			}
			if (nameText == null)
			{
				return false;
			}
			try
			{
				_tmpTextSType = nameText.GetType();
				_tmpIl2CppType = Il2CppType.From(_tmpTextSType);
				ResolveTmpProps();
				return _tmpIl2CppType != (Type)null;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("StatSynergyMarker: TMP type resolve failed: " + ex.Message));
				}
				return false;
			}
		}

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(TabT, "UpdateRow", (Type[])null, (Type[])null);
		}

		private static void Postfix(object row)
		{
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Expected O, but got Unknown
			try
			{
				if (row == null || PStatIndex == null || PNameText == null || PRoot == null || MClassSynergy == null)
				{
					return;
				}
				object obj = ((FClassType != null) ? FClassType.GetValue(null) : null);
				object obj2 = ((FSynergies != null) ? FSynergies.GetValue(null) : null);
				if (obj == null || obj2 == null)
				{
					return;
				}
				int num;
				try
				{
					num = Convert.ToInt32(PStatIndex.GetValue(row));
				}
				catch
				{
					return;
				}
				bool flag = PanelKind == 1;
				Type type = (flag ? EclipseTypes.BloodStatType : EclipseTypes.WeaponStatType);
				if (type == null)
				{
					return;
				}
				if (flag)
				{
					if (_bloodCall == null)
					{
						_bloodCall = MClassSynergy.MakeGenericMethod(type);
					}
				}
				else if (_weaponCall == null)
				{
					_weaponCall = MClassSynergy.MakeGenericMethod(type);
				}
				float num2 = Convert.ToSingle((flag ? _bloodCall : _weaponCall).Invoke(null, new object[3]
				{
					Enum.ToObject(type, num),
					obj,
					obj2
				}));
				object? value = PRoot.GetValue(row);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				object value2 = PNameText.GetValue(row);
				Transform val2 = val.transform.Find("SynergyMarker");
				if (num2 <= 1f)
				{
					if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeSelf)
					{
						((Component)val2).gameObject.SetActive(false);
					}
					return;
				}
				if (!EnsureTmpType(value2))
				{
					if (!_warnedNoTmp)
					{
						_warnedNoTmp = true;
						ManualLogSource logger = EclipseFixesPlugin.Logger;
						if (logger != null)
						{
							logger.LogWarning((object)("StatSynergyMarker: TMP type unresolved (nameText=" + ((value2 == null) ? "null" : value2.GetType().FullName) + ") - markers disabled"));
						}
					}
					return;
				}
				if (!_firstLogged)
				{
					_firstLogged = true;
					ManualLogSource logger2 = EclipseFixesPlugin.Logger;
					if (logger2 != null)
					{
						bool flag2 = default(bool);
						BepInExDebugLogInterpolatedStringHandler val3 = new BepInExDebugLogInterpolatedStringHandler(49, 3, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("StatSynergyMarker: synergy row stat=");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" mult=");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(num2, "0.##");
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" panel=");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(flag ? "blood" : "weapon");
						}
						logger2.LogDebug(val3);
					}
				}
				GameObject val4 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null);
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = CreateMarker(val, value2);
					if ((Object)(object)val4 == (Object)null)
					{
						return;
					}
				}
				else if (!val4.activeSelf)
				{
					val4.SetActive(true);
				}
				string text = "×" + num2.ToString("0.##");
				object obj4 = TypedTmp(val4.GetComponent(_tmpIl2CppType));
				if (obj4 != null && _pText != null && _pText.GetValue(obj4) as string != text)
				{
					_pText.SetValue(obj4, text);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger3 = EclipseFixesPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogWarning((object)("StatSynergyMarker: " + ex));
				}
			}
		}

		private static object TypedTmp(object baseWrapper)
		{
			try
			{
				if (baseWrapper == null || _tmpTextSType == null)
				{
					return null;
				}
				if (_pPointer == null)
				{
					_pPointer = baseWrapper.GetType().GetProperty("Pointer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (_pPointer == null)
				{
					return null;
				}
				IntPtr intPtr = (IntPtr)_pPointer.GetValue(baseWrapper);
				if (intPtr == IntPtr.Zero)
				{
					return null;
				}
				return Activator.CreateInstance(_tmpTextSType, intPtr);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("StatSynergyMarker TypedTmp: " + ex.Message));
				}
				return null;
			}
		}

		private static GameObject CreateMarker(GameObject rowGo, object nameText)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (_tmpIl2CppType == (Type)null || _tmpTextSType == null)
				{
					return null;
				}
				ResolveTmpProps();
				GameObject val = new GameObject("SynergyMarker");
				RectTransform obj = val.AddComponent<RectTransform>();
				((Transform)obj).SetParent(rowGo.transform, false);
				obj.anchorMin = new Vector2(0.5f, 0f);
				obj.anchorMax = new Vector2(0.5f, 1f);
				obj.pivot = new Vector2(0.5f, 0.5f);
				obj.sizeDelta = new Vector2(48f, 0f);
				((Transform)obj).SetAsLastSibling();
				val.AddComponent<LayoutElement>().ignoreLayout = true;
				Component val2 = val.AddComponent(_tmpIl2CppType);
				if ((Object)(object)val2 == (Object)null)
				{
					ManualLogSource logger = EclipseFixesPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"StatSynergyMarker CreateMarker: AddComponent returned null");
					}
					return null;
				}
				object obj2 = TypedTmp(val2);
				if (obj2 == null)
				{
					ManualLogSource logger2 = EclipseFixesPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)"StatSynergyMarker CreateMarker: typed TMP wrapper failed");
					}
					return null;
				}
				if (_pFont != null && nameText != null)
				{
					PropertyInfo property = nameText.GetType().GetProperty("font", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (property != null)
					{
						object value = property.GetValue(nameText);
						_pFont.SetValue(obj2, value);
					}
				}
				if (_pColor != null)
				{
					_pColor.SetValue(obj2, (object)new Color(1f, 0.843f, 0f, 1f));
				}
				if (_pFontSize != null)
				{
					float num = 12f;
					if (nameText != null)
					{
						PropertyInfo property2 = nameText.GetType().GetProperty("fontSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (property2 != null && property2.GetValue(nameText) is float num2 && num2 > 0f)
						{
							num = num2;
						}
					}
					_pFontSize.SetValue(obj2, num);
				}
				if (_pAlignment != null)
				{
					_pAlignment.SetValue(obj2, Enum.Parse(_pAlignment.PropertyType, "Center"));
				}
				if (_pWrap != null)
				{
					_pWrap.SetValue(obj2, false);
				}
				if (_pRaycast != null)
				{
					_pRaycast.SetValue(obj2, false);
				}
				ManualLogSource logger3 = EclipseFixesPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogDebug((object)("StatSynergyMarker: centered marker created in '" + ((Object)rowGo).name + "'"));
				}
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = EclipseFixesPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogWarning((object)("StatSynergyMarker CreateMarker: " + ex));
				}
				return null;
			}
		}
	}
	[HarmonyPatch]
	internal class PrestigeRowAlignPatch
	{
		private const string RowName = "PrestigeRow";

		private const float Pad = 10f;

		private const float RankW = 22f;

		private const float Gap = 10f;

		private const float ValueW = 56f;

		private const float TextH = 20f;

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("Eclipse.Services.CharacterMenu.Tabs.PrestigeTab"), "CreateLeaderboardRow", (Type[])null, (Type[])null);
		}

		private static void Postfix(object __0)
		{
			try
			{
				Transform val = (Transform)((__0 is Transform) ? __0 : null);
				if (!((Object)(object)val == (Object)null) && val.childCount != 0)
				{
					Transform child = val.GetChild(val.childCount - 1);
					if (!((Object)(object)child == (Object)null) && !(((Object)child).name != "PrestigeRow") && child.childCount >= 3)
					{
						PinLeft(child.GetChild(0), 10f, 22f);
						PinName(child.GetChild(1), 42f, 76f);
						PinRight(child.GetChild(2), 10f, 56f);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("PrestigeRowAlign: " + ex));
				}
			}
		}

		private static void Freeze(Transform t)
		{
			LayoutElement val = ((Component)t).GetComponent<LayoutElement>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)t).gameObject.AddComponent<LayoutElement>();
			}
			val.ignoreLayout = true;
		}

		private static RectTransform FreezeRt(Transform t)
		{
			Freeze(t);
			return (RectTransform)(object)((t is RectTransform) ? t : null);
		}

		private static void PinLeft(Transform t, float x, float w)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = FreezeRt(t);
			if (!((Object)(object)val == (Object)null))
			{
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(0f, 0.5f);
				val.anchorMax = val2;
				val.anchorMin = val2;
				val.pivot = new Vector2(0f, 0.5f);
				val.anchoredPosition = new Vector2(x, 0f);
				val.sizeDelta = new Vector2(w, 20f);
			}
		}

		private static void PinRight(Transform t, float rightInset, float w)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = FreezeRt(t);
			if (!((Object)(object)val == (Object)null))
			{
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(1f, 0.5f);
				val.anchorMax = val2;
				val.anchorMin = val2;
				val.pivot = new Vector2(1f, 0.5f);
				val.anchoredPosition = new Vector2(0f - rightInset, 0f);
				val.sizeDelta = new Vector2(w, 20f);
			}
		}

		private static void PinName(Transform t, float left, float rightInset)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = FreezeRt(t);
			if (!((Object)(object)val == (Object)null))
			{
				val.anchorMin = new Vector2(0f, 0.5f);
				val.anchorMax = new Vector2(1f, 0.5f);
				val.pivot = new Vector2(0f, 0.5f);
				val.offsetMin = new Vector2(left, -10f);
				val.offsetMax = new Vector2(0f - rightInset, 10f);
			}
		}
	}
	[HarmonyPatch]
	internal class PrestigeDropdownTypesPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(EclipseTypes.DataService, "ParsePrestigeLeaderboardData", (Type[])null, (Type[])null);
		}

		private static void Postfix(string __0)
		{
			try
			{
				PrestigeBoardMerge.HandlePayload(__0);
				PrestigeTypeOrder.Complete();
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("PrestigeDropdown: " + ex));
				}
			}
		}
	}
	internal static class PrestigeBoardMerge
	{
		private static readonly FieldInfo FBoards = AccessTools.Field(EclipseTypes.DataService, "_prestigeLeaderboards");

		private static readonly FieldInfo FOrder = AccessTools.Field(EclipseTypes.DataService, "_prestigeLeaderboardOrder");

		private static readonly FieldInfo FReady = AccessTools.Field(EclipseTypes.DataService, "_prestigeDataReady");

		private static readonly Type EntryT = AccessTools.TypeByName("Eclipse.Services.DataService+PrestigeLeaderboardEntry");

		private static readonly Type EntryListT = ((EntryT != null) ? typeof(List<>).MakeGenericType(EntryT) : null);

		private static readonly Dictionary<string, object> Shadow = new Dictionary<string, object>();

		private static readonly List<string> ShadowOrder = new List<string>();

		internal static void HandlePayload(string payload)
		{
			if (EntryT == null || EntryListT == null || FBoards == null || FOrder == null || string.IsNullOrEmpty(payload))
			{
				return;
			}
			string[] array = payload.Split('|');
			if (array.Length == 0)
			{
				return;
			}
			string[] array2 = array[0].Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			bool result = default(bool);
			bool num = array2.Length != 0 && bool.TryParse(array2[0], out result) && result;
			bool result2 = default(bool);
			bool flag = array2.Length > 1 && bool.TryParse(array2[1], out result2) && result2;
			if (!num || !flag)
			{
				Shadow.Clear();
				ShadowOrder.Clear();
				return;
			}
			int part = 0;
			int total = 0;
			List<string> list = new List<string>();
			for (int i = 1; i < array.Length; i++)
			{
				string text = array[i];
				if (!string.IsNullOrWhiteSpace(text) && (text[0] != '!' || !TryParsePart(text, out part, out total)))
				{
					list.Add(text);
				}
			}
			if (total <= 0)
			{
				return;
			}
			if (part <= 1)
			{
				Shadow.Clear();
				ShadowOrder.Clear();
			}
			foreach (string item in list)
			{
				string[] array3 = item.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				if (array3.Length < 3)
				{
					continue;
				}
				string text2 = array3[0];
				if (!Shadow.TryGetValue(text2, out var value))
				{
					value = Activator.CreateInstance(EntryListT);
					Shadow[text2] = value;
					ShadowOrder.Add(text2);
				}
				IList list2 = (IList)value;
				for (int j = 1; j + 1 < array3.Length; j += 2)
				{
					string text3 = array3[j].Trim();
					if (text3.Length != 0 && int.TryParse(array3[j + 1].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3) && result3 > 0)
					{
						list2.Add(Activator.CreateInstance(EntryT, text3, result3));
					}
				}
			}
			RebuildLive();
		}

		private static bool TryParsePart(string seg, out int part, out int total)
		{
			part = 0;
			total = 0;
			string[] array = seg.Substring(1).Split('/');
			if (array.Length == 2 && int.TryParse(array[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out part) && int.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out total) && part > 0)
			{
				return total >= part;
			}
			return false;
		}

		private static void RebuildLive()
		{
			if (FBoards.GetValue(null) is IDictionary dictionary)
			{
				dictionary.Clear();
				foreach (string item in ShadowOrder)
				{
					dictionary.Add(item, Shadow[item]);
				}
			}
			if (FOrder.GetValue(null) is List<string> list)
			{
				list.Clear();
				list.AddRange(ShadowOrder);
			}
			if (FReady != null)
			{
				FReady.SetValue(null, true);
			}
		}
	}
	internal static class PrestigeTypeOrder
	{
		internal static readonly string[] All = new string[28]
		{
			"Experience", "Exo", "SwordExpertise", "AxeExpertise", "MaceExpertise", "SpearExpertise", "CrossbowExpertise", "GreatSwordExpertise", "SlashersExpertise", "PistolsExpertise",
			"ReaperExpertise", "LongbowExpertise", "WhipExpertise", "UnarmedExpertise", "FishingPoleExpertise", "TwinBladesExpertise", "DaggersExpertise", "ClawsExpertise", "WorkerLegacy", "WarriorLegacy",
			"ScholarLegacy", "RogueLegacy", "MutantLegacy", "DraculinLegacy", "ImmortalLegacy", "CreatureLegacy", "BruteLegacy", "CorruptionLegacy"
		};

		private static readonly FieldInfo FOrder = AccessTools.Field(EclipseTypes.DataService, "_prestigeLeaderboardOrder");

		private static readonly FieldInfo FSystem = AccessTools.Field(EclipseTypes.DataService, "_prestigeSystemEnabled");

		private static readonly FieldInfo FBoard = AccessTools.Field(EclipseTypes.DataService, "_prestigeLeaderboardEnabled");

		internal static void Complete()
		{
			if (FOrder == null || FSystem == null || FBoard == null)
			{
				return;
			}
			object value = FSystem.GetValue(null);
			if (!(value is bool) || !(bool)value)
			{
				return;
			}
			value = FBoard.GetValue(null);
			if (!(value is bool) || !(bool)value || !(FOrder.GetValue(null) is List<string> list))
			{
				return;
			}
			int num = 0;
			string[] all = All;
			foreach (string text in all)
			{
				int num2 = -1;
				for (int j = num; j < list.Count; j++)
				{
					if (string.Equals(list[j], text, StringComparison.Ordinal))
					{
						num2 = j;
						break;
					}
				}
				if (num2 < 0)
				{
					list.Insert(num, text);
					num++;
				}
				else
				{
					num = num2 + 1;
				}
			}
		}
	}
	[HarmonyPatch]
	internal class FamiliarsTabCleanupPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(AccessTools.TypeByName("Eclipse.Services.CharacterMenu.Tabs.FamiliarsTab"), "CreateModeTabs", (Type[])null, (Type[])null);
		}

		private static void Postfix()
		{
			try
			{
				FamiliarsTabCleanup.Apply();
			}
			catch (Exception ex)
			{
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("FamiliarsTabCleanup: " + ex));
				}
			}
		}
	}
	internal static class FamiliarsTabCleanup
	{
		private static readonly string[] HiddenModes = new string[2] { "FamiliarsModeTab_BattleGroups", "FamiliarsModeTab_Talents" };

		private static bool _diagLogged;

		internal static void Apply()
		{
			GameObject val = FindSceneObject("FamiliarsModeTabs");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string[] hiddenModes = HiddenModes;
			foreach (string text in hiddenModes)
			{
				Transform val2 = val.transform.Find(text);
				if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeSelf)
				{
					((Component)val2).gameObject.SetActive(false);
				}
			}
			EnsureScrollClipping(val.transform);
		}

		private static string PathOf(Transform t)
		{
			if ((Object)(object)t == (Object)null)
			{
				return "<null>";
			}
			string text = ((Object)t).name;
			while ((Object)(object)t.parent != (Object)null)
			{
				t = t.parent;
				text = ((Object)t).name + "/" + text;
			}
			return text;
		}

		private static void EnsureScrollClipping(Transform from)
		{
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Expected O, but got Unknown
			Transform val = from;
			while ((Object)(object)val != (Object)null && ((Object)val).name != "Scroll View")
			{
				val = val.parent;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ScrollRect component = ((Component)val).GetComponent<ScrollRect>();
			RectTransform val2 = null;
			if ((Object)(object)component != (Object)null && (Object)(object)component.viewport != (Object)null)
			{
				val2 = component.viewport;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Transform val3 = val.Find("Viewport");
				if ((Object)(object)val3 != (Object)null)
				{
					val2 = (RectTransform)(object)((val3 is RectTransform) ? val3 : null);
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Transform val4 = ((Transform)val2).Find("AttributesTabContent");
			Transform val5 = from;
			while ((Object)(object)val5 != (Object)null && ((Object)val5).name != "BloodcraftContentRoot")
			{
				val5 = val5.parent;
			}
			bool flag = false;
			if ((Object)(object)val5 != (Object)null && (Object)(object)val4 != (Object)null && (Object)(object)val5.parent != (Object)(object)val4)
			{
				string text = PathOf(val5.parent);
				val5.SetParent(val4, false);
				flag = true;
				ManualLogSource logger = EclipseFixesPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)("FamiliarsTabCleanup: content re-parented under the scroll viewport (was: " + text + ")"));
				}
			}
			if ((Object)(object)component != (Object)null && (Object)(object)val4 != (Object)null)
			{
				RectTransform val6 = (RectTransform)(object)((val4 is RectTransform) ? val4 : null);
				if ((Object)(object)val6 != (Object)null && (Object)(object)component.content != (Object)(object)val6)
				{
					try
					{
						component.content = val6;
					}
					catch
					{
					}
				}
			}
			if ((Object)(object)((Component)val2).GetComponent<RectMask2D>() == (Object)null)
			{
				((Component)val2).gameObject.AddComponent<RectMask2D>();
				ManualLogSource logger2 = EclipseFixesPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)"FamiliarsTabCleanup: RectMask2D added to Scroll View viewport.");
				}
			}
			int num = 0;
			if ((Object)(object)val4 != (Object)null)
			{
				foreach (MaskableGraphic componentsInChild in ((Component)val4).GetComponentsInChildren<MaskableGraphic>(true))
				{
					if ((Object)(object)componentsInChild != (Object)null && !componentsInChild.maskable)
					{
						componentsInChild.maskable = true;
						num++;
					}
				}
			}
			if (_diagLogged)
			{
				return;
			}
			_diagLogged = true;
			ManualLogSource logger3 = EclipseFixesPlugin.Logger;
			if (logger3 != null)
			{
				bool flag2 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(89, 5, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("FamiliarsTabCleanup: viewportMask=");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<bool>((Object)(object)((Component)val2).GetComponent<Mask>() != (Object)null);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("reParented=");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<bool>(flag);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" maskableFixed=");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("contentRoot=");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(((Object)(object)val5 != (Object)null) ? PathOf(val5) : "?");
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("scrollContent=");
					((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(((Object)(object)component != (Object)null && (Object)(object)component.content != (Object)null) ? PathOf((Transform)(object)component.content) : "?");
				}
				logger3.LogInfo(val7);
			}
		}

		private static GameObject FindSceneObject(string name)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject item in Resources.FindObjectsOfTypeAll<GameObject>())
			{
				if ((Object)(object)item != (Object)null && ((Object)item).name == name)
				{
					Scene scene = item.scene;
					if (((Scene)(ref scene)).IsValid())
					{
						return item;
					}
				}
			}
			return null;
		}
	}
}