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