Decompiled source of Eclipse by FAiNEL v1.2.9
BepInEx/plugins/Eclipse.dll
Decompiled 3 hours ago
The result has been truncated due to the large size, download it to view full contents!
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("Eclipse")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Eclipse")] [assembly: AssemblyTitle("Eclipse")] [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 Eclipse { [BepInPlugin("fix.eclipseplus.ui", "Eclipse by FAiNEL", "1.2.9")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class EclipsePlugin : BasePlugin { public const string GUID = "fix.eclipseplus.ui"; public const string NAME = "Eclipse by FAiNEL"; public const string VERSION = "1.2.9"; 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; internal static ConfigEntry<bool> CfgTabGlow; internal static ConfigEntry<bool> CfgQuickPrestige; public override void Load() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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)."); CfgTabGlow = ((BasePlugin)this).Config.Bind<bool>("Features", "TabGlow", true, "Bright contour on the selected mode tab (Weapon Expertise / Blood Legacies / Professions / Class)."); CfgQuickPrestige = ((BasePlugin)this).Config.Bind<bool>("Features", "QuickPrestige", true, "Prestige quick-buttons: .prestige me in the Stat Bonuses header + Experience/ExoForm on the Prestige Leaderboard card."); try { string text = EclipseTypes.Validate(); if (text != null) { ((BasePlugin)this).Log.LogWarning((object)("Eclipse: 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)("Eclipse: patch " + patchType.Name + " disabled by config.")); continue; } try { HarmonyInst.CreateClassProcessor(patchType).Patch(); } catch (Exception ex) { ((BasePlugin)this).Log.LogError((object)("Eclipse: patch " + patchType.Name + " failed: " + ex)); } } ((BasePlugin)this).Log.LogInfo((object)"Eclipse loaded: weapon panel synthesis + 4/4 slots + 4th HUD stat + icon healing + locale caps repair."); } catch (Exception ex2) { ((BasePlugin)this).Log.LogError((object)("Eclipse patch failure: " + ex2)); } } private static bool ShouldPatch(Type t) { switch (t.Name) { case "QuipsDiagPatch": case "UpdateRowClickDiagPostfix": return CfgDiag.Value; case "WireParseDiagPatch": return false; 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(EclipsePlugin).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 Type HudData = AccessTools.TypeByName("Eclipse.Services.HUD.Shared.HudData"); internal static Type LayoutService = AccessTools.TypeByName("Eclipse.Services.LayoutService"); 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 = EclipsePlugin.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 float _nextDiag; 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); MethodInfo methodInfo = AccessTools.GetDeclaredMethods(HuT).FirstOrDefault((MethodInfo m) => m.Name == "ClassSynergy" && m.IsGenericMethodDefinition && m.GetParameters().Length == 3); if (methodInfo != null && EclipseTypes.WeaponStatType != null) { try { MClassSynergy = methodInfo.MakeGenericMethod(EclipseTypes.WeaponStatType); } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("WeaponPanelSynth: ClassSynergy<WeaponStatType> resolve failed: " + ex.Message)); } } } if (MClassSynergy == null) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)"WeaponPanelSynth: ClassSynergy method not resolved — x1.5 synergy will NOT be applied."); } } } 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; try { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup >= _nextDiag) { _nextDiag = realtimeSinceStartup + 10f; int num11 = list.Count((object e) => Convert.ToInt32(EntryT.GetProperty("IsSelected")?.GetValue(e) ?? ((object)false)) != 0); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[DiagTab] selNames=[" + ((enumerable == null) ? "<null>" : string.Join("|", enumerable)) + "] selected=" + num5 + " green=" + num11 + " capKeys=" + (dictionary?.Count ?? (-1)))); } } } catch { } object obj2 = MWeaponIcons.Invoke(null, new object[1] { text }); MUpdateHeaderIcon.Invoke(tab, new object[1] { obj2 }); 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 num12 = Math.Min(list.Count, list2.Count); Delegate obj3 = BuildFormatter(); Delegate obj4 = Delegate.CreateDelegate(typeof(Action<int>), typeof(WeaponPanelSynth).GetMethod("SendWeaponCust", BindingFlags.Static | BindingFlags.Public)); for (int num13 = 0; num13 < num12; num13++) { MUpdateRow.Invoke(null, new object[4] { list2[num13], list[num13], obj3, obj4 }); } } } 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 = EclipsePlugin.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 = EclipsePlugin.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); } try { StatLineDiag.MaybeDump(__args); } catch { } } } internal static class StatLineDiag { private static readonly FieldInfo FCaps = AccessTools.Field(EclipseTypes.DataService, "_weaponStatValues"); private static readonly FieldInfo FBonusW = AccessTools.Field(EclipseTypes.DataHUD, "_expertiseBonusStats"); private static readonly FieldInfo FBonusB = AccessTools.Field(EclipseTypes.DataHUD, "_legacyBonusStats"); private static float _next; internal static void MaybeDump(object[] args) { WireParseDiagPatch.TryApplyOnce(); TabGlow.TryApplyOnce(); float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup < _next) { return; } _next = realtimeSinceStartup + 10f; try { IEnumerable enumerable = args[0] as IEnumerable; string text = ((enumerable == null) ? "<null-list>" : string.Join("|", from object x in enumerable select (x != null) ? ("'" + x?.ToString() + "'") : "<null>")); object[] array = (args[1] as IEnumerable)?.Cast<object>().ToArray(); Func<int, string, string> func = args[3] as Func<int, string, string>; string text2 = "<n/a>"; object obj = enumerable?.Cast<object>().FirstOrDefault(); if (func != null && obj is string text3 && !string.IsNullOrWhiteSpace(text3)) { try { text2 = "'" + func(0, text3) + "'"; } catch (Exception ex) { text2 = "THROW:" + ex.GetType().Name + ":" + ex.Message; } } string text4 = "<null-texts>"; if (array != null) { List<string> list = new List<string>(); for (int num = 0; num < array.Length && num < 3; num++) { object obj2 = array[num]; if (obj2 == null) { list.Add(num + "=<null>"); continue; } string text5 = "?"; try { object obj3 = obj2.GetType().GetProperty("String")?.GetValue(obj2) ?? obj2.GetType().GetProperty("Text")?.GetValue(obj2); text5 = ((obj3 == null) ? "?" : ((obj3.ToString()?.Length ?? 0) + "ch")); } catch { } bool flag = false; bool flag2 = false; try { Component val = (Component)((obj2 is Component) ? obj2 : null); flag = (Object)(object)val != (Object)null && val.gameObject.activeInHierarchy; flag2 = Convert.ToBoolean(obj2.GetType().GetProperty("enabled")?.GetValue(obj2)); } catch { } list.Add(num + "=act:" + flag + ",en:" + flag2 + "," + text5); } text4 = string.Join(" ", list); } int num2 = 0; try { num2 = (FCaps?.GetValue(null) as IDictionary)?.Count ?? (-1); } catch { num2 = -2; } string text6 = ((FBonusW?.GetValue(null) is IEnumerable<string> values) ? string.Join("|", values) : "<err>"); string text7 = ((FBonusB?.GetValue(null) is IEnumerable<string> values2) ? string.Join("|", values2) : "<err>"); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[Diag4] bonus=[" + text + "] caps=" + num2 + " sample=" + text2 + " texts=[" + text4 + "] expB=[" + text6 + "] legB=[" + text7 + "]")); } } catch (Exception ex2) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("[Diag4] dump failed: " + ex2.Message)); } } } } [HarmonyPatch] internal class WireParseDiagPatch { private static readonly FieldInfo FEnabled = AccessTools.Field(EclipseTypes.DataService, "_familiarSystemEnabled"); private static readonly FieldInfo FBattles = AccessTools.Field(EclipseTypes.DataService, "_familiarBattlesEnabled"); private static readonly FieldInfo FReady = AccessTools.Field(EclipseTypes.DataService, "_familiarBattleDataReady"); private static float _nextPlayer; private static float _nextConfig; private static float _next6; private static float _next7; private static float _nextMac; private static bool _applied; internal static void TryApplyOnce() { if (_applied) { return; } _applied = true; try { EclipsePlugin.HarmonyInst.CreateClassProcessor(typeof(WireParseDiagPatch)).Patch(); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)"[DiagWire] parse-diag patched (lazy, in-world)."); } } catch (Exception ex) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("[DiagWire] lazy patch failed: " + ex.Message)); } } } private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[5] { "ParsePlayerData", "ParseConfigData", "ParseFamiliarBattleData", "ParseWeaponStatBonusData", "TryParseFamiliarBoxChatMessage" }; foreach (string text in array) { MethodInfo methodInfo = AccessTools.Method(EclipseTypes.DataService, text, (Type[])null, (Type[])null); if (methodInfo != null) { yield return methodInfo; } } } private static void Prefix(MethodBase __originalMethod, object[] __args) { try { string name = __originalMethod.Name; string text; if (__args == null || __args.Length == 0) { text = "noargs"; } else if (__args[0] is string text2) { text = text2; } else if (__args[0] is IEnumerable enumerable) { List<string> list = new List<string>(); int num = 0; bool flag = false; foreach (object item in enumerable) { string text3 = item?.ToString() ?? "<null>"; num += text3.Length; list.Add(text3); if (list.Count >= 60 || num > 1400) { flag = true; break; } } string text4 = string.Join(" ‖ ", list); if (text4.Length > 1200) { text4 = text4.Substring(0, 1200) + "…"; flag = true; } text = "<" + __args[0].GetType().Name + " n=" + (flag ? "≥" : "") + list.Count + "> " + text4; } else { text = "<" + (__args[0]?.GetType().Name ?? "null") + ">"; } float realtimeSinceStartup = Time.realtimeSinceStartup; switch (name) { case "ParsePlayerData": if (!(realtimeSinceStartup < _nextPlayer)) { _nextPlayer = realtimeSinceStartup + 10f; ManualLogSource logger4 = EclipsePlugin.Logger; if (logger4 != null) { logger4.LogInfo((object)("[DiagWire] evt=1 playerData " + Cut(text, 1300))); } } break; case "ParseConfigData": if (!(realtimeSinceStartup < _nextConfig)) { _nextConfig = realtimeSinceStartup + 10f; ManualLogSource logger3 = EclipsePlugin.Logger; if (logger3 != null) { logger3.LogInfo((object)("[DiagWire] evt=2 config " + Cut(text, 1300))); } } break; case "ParseFamiliarBattleData": if (!(realtimeSinceStartup < _next6)) { _next6 = realtimeSinceStartup + 5f; ManualLogSource logger5 = EclipsePlugin.Logger; if (logger5 != null) { logger5.LogInfo((object)("[DiagWire] evt=6 familiarBattle " + Cut(text, 300))); } } break; case "ParseWeaponStatBonusData": if (!(realtimeSinceStartup < _next7)) { _next7 = realtimeSinceStartup + 5f; ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)("[DiagWire] evt=7 statBonus " + Cut(text, 300))); } } break; case "TryParseFamiliarBoxChatMessage": if (text.Length != 0 && text[0] == '[' && !(realtimeSinceStartup < _nextMac)) { _nextMac = realtimeSinceStartup + 5f; ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[DiagWire] nonVerified " + Cut(text, 300))); } } break; } } catch (Exception ex) { ManualLogSource logger6 = EclipsePlugin.Logger; if (logger6 != null) { logger6.LogWarning((object)("[DiagWire] prefix failed: " + ex.Message)); } } } private static void Postfix(MethodBase __originalMethod, object[] __args) { try { string name = __originalMethod.Name; if (!(name == "ParseFamiliarBattleData")) { if (!(name == "ParseConfigData")) { return; } List<string> list = ((__args != null && __args.Length != 0) ? (__args[0] as List<string>) : null); if (list == null || list.Count <= 5 || !(FEnabled != null) || !int.TryParse(list[5], out var result) || result <= 0) { return; } object value = FEnabled.GetValue(null); if (value is bool && !(bool)value) { FEnabled.SetValue(null, true); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[DiagWire] familiar gate fallback: MaxFamiliarLevel=" + result + " -> _familiarSystemEnabled=true (server sends no [6]).")); } } } else { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)("[DiagWire] evt=6 parsed -> system=" + (FEnabled?.GetValue(null))?.ToString() + " battles=" + (FBattles?.GetValue(null))?.ToString() + " ready=" + FReady?.GetValue(null))); } } } catch (Exception ex) { ManualLogSource logger3 = EclipsePlugin.Logger; if (logger3 != null) { logger3.LogWarning((object)("[DiagWire] postfix failed: " + ex.Message)); } } } private static string Cut(string s, int n) { if (s == null) { return "len=?"; } if (s.Length > n) { return "len=" + s.Length + " head='" + s.Substring(0, n) + "…'"; } return "len=" + s.Length + " head='" + s + "'"; } } 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>(); MethodInfo methodInfo = AccessTools.GetDeclaredMethods(HuT).FirstOrDefault((MethodInfo m) => m.Name == "ClassSynergy" && m.IsGenericMethodDefinition && m.GetParameters().Length == 3); if (methodInfo != null) { try { if (EclipseTypes.WeaponStatType != null) { MClassSynWeapon = methodInfo.MakeGenericMethod(EclipseTypes.WeaponStatType); } if (EclipseTypes.BloodStatType != null) { MClassSynBlood = methodInfo.MakeGenericMethod(EclipseTypes.BloodStatType); } } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("FourthStat: ClassSynergy<T> specialize failed: " + ex.Message)); } } } if (MClassSynWeapon == null || MClassSynBlood == null) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("FourthStat: ClassSynergy not resolved (weapon=" + ((MClassSynWeapon != null) ? "ok" : "null") + ", blood=" + ((MClassSynBlood != null) ? "ok" : "null") + ") — x1.5 synergy will NOT be applied.")); } } } 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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.Logger; if (logger != null) { logger.LogError((object)("FourthStat error: " + e)); } } } } [HarmonyPatch] internal class QuestIconBridgePatch { private static MethodBase TargetMethod() { return AccessTools.Method(EclipseTypes.HudUtilities, "FindSprites", (Type[])null, (Type[])null); } private static void Postfix() { QuestIconBridge.Run(); } } internal static class QuestIconBridge { private static readonly FieldInfo FSrcStd = AccessTools.Field(EclipseTypes.HudData, "QuestKillStandardUnit"); private static readonly FieldInfo FSrcVB = AccessTools.Field(EclipseTypes.HudData, "QuestKillVBloodUnit"); private static readonly FieldInfo FDstStd = AccessTools.Field(EclipseTypes.DataHUD, "_questKillStandardUnit"); private static readonly FieldInfo FDstVB = AccessTools.Field(EclipseTypes.DataHUD, "_questKillVBloodUnit"); private static bool _logged; internal static void Run() { try { if (!(FSrcStd == null) && !(FDstStd == null) && !(FSrcVB == null) && !(FDstVB == null) && (Copy(FSrcStd, FDstStd) | Copy(FSrcVB, FDstVB)) && !_logged) { _logged = true; ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)"QuestIconBridge: wired DataHUD._questKill* from HudData (1.4.0 dead-field fix)."); } } } catch (Exception ex) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("QuestIconBridge: " + ex.Message)); } } } private static bool Copy(FieldInfo src, FieldInfo dst) { object obj = src.GetValue(null); if (obj != null) { Sprite val = (Sprite)((obj is Sprite) ? obj : null); if (val == null || !((Object)(object)val == (Object)null)) { goto IL_004d; } } Sprite val2 = SpriteRepair.Get(((object)src == FSrcVB) ? "BloodIcon_Cursed" : "BloodIcon_Warrior"); if ((Object)(object)val2 == (Object)null) { return false; } src.SetValue(null, val2); obj = val2; goto IL_004d; IL_004d: if (dst.GetValue(null) == obj) { return false; } dst.SetValue(null, obj); return true; } } [HarmonyPatch] internal class ProfessionIconCapturePatch { private static MethodBase TargetMethod() { return AccessTools.Method(EclipseTypes.LayoutService, "RegisterElement", (Type[])null, (Type[])null); } private static void Prefix(string __0, RectTransform __1) { WireParseDiagPatch.TryApplyOnce(); TabGlow.TryApplyOnce(); if (__0 == null || !__0.StartsWith("Profession.")) { return; } try { ProfessionIconHealer.Capture(__0, __1); } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("ProfessionIconCapture: " + ex.Message)); } } } } [HarmonyPatch] internal class ProfessionIconRescanPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo methodInfo = AccessTools.Method(EclipseTypes.HudUpdateManager, "UpdateProfessions", (Type[])null, (Type[])null); MethodInfo m2 = AccessTools.Method(EclipseTypes.HudUpdateManager, "UpdateQuests", (Type[])null, (Type[])null); if (methodInfo != null) { yield return methodInfo; } if (m2 != null) { yield return m2; } } private static void Postfix() { try { ProfessionIconHealer.Tick(); } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("ProfessionIconRescan: " + ex.Message)); } } } } internal static class SpriteRepair { private static readonly FieldInfo FHudSprites = AccessTools.Field(EclipseTypes.HudData, "Sprites"); private static readonly Dictionary<string, Sprite> _cache = new Dictionary<string, Sprite>(); internal static Sprite Get(string name) { if (string.IsNullOrEmpty(name)) { return null; } IDictionary dictionary = null; try { dictionary = FHudSprites?.GetValue(null) as IDictionary; } catch { } try { if (dictionary != null && dictionary.Contains(name)) { object? obj2 = dictionary[name]; Sprite val = (Sprite)((obj2 is Sprite) ? obj2 : null); if (val != null && (Object)(object)val != (Object)null) { _cache[name] = val; return val; } } } catch { } try { if (_cache.TryGetValue(name, out var value) && (Object)(object)value != (Object)null) { try { if (dictionary != null) { dictionary[name] = value; } } catch { } return value; } } catch { } try { foreach (Sprite item in Resources.FindObjectsOfTypeAll<Sprite>()) { if (!((Object)(object)item != (Object)null) || !(((Object)item).name == name)) { continue; } _cache[name] = item; try { if (dictionary != null) { dictionary[name] = item; } } catch { } return item; } } catch { } return null; } } internal static class ProfessionIconHealer { private static readonly Dictionary<object, Image> Icons = new Dictionary<object, Image>(); private static readonly HashSet<object> Pending = new HashSet<object>(); private static readonly FieldInfo FProfIcons = AccessTools.Field(EclipseTypes.DataHUD, "ProfessionIcons"); private static readonly FieldInfo FHudSprites = AccessTools.Field(EclipseTypes.HudData, "Sprites"); private static readonly MethodInfo MFindSprites = AccessTools.Method(EclipseTypes.HudUtilities, "FindSprites", (Type[])null, (Type[])null); private static float _nextScan = float.NegativeInfinity; private static float _nextStatus; private static bool _loggedHeal; private static bool _loggedTick; private const float ScanCooldown = 5f; internal static void Capture(string layoutKey, RectTransform rect) { if (FProfIcons == null || (Object)(object)rect == (Object)null || !(FProfIcons.GetValue(null) is IDictionary dictionary)) { return; } string b = layoutKey.Substring("Profession.".Length); object obj = null; foreach (object key in dictionary.Keys) { if (string.Equals(key.ToString(), b, StringComparison.OrdinalIgnoreCase)) { obj = key; break; } } if (obj == null) { return; } Image val = FindChildImage(((Component)rect).gameObject.transform, "LevelBackground"); if (!((Object)(object)val == (Object)null)) { Icons[obj] = val; if (!Resolve(obj)) { Pending.Add(obj); } ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[DiagHeal] capture: prof=" + obj?.ToString() + " pending=" + Pending.Count)); } } } internal static void Tick() { if (Pending.Count == 0) { _loggedTick = false; } else { if (MFindSprites == null) { return; } if (!_loggedTick) { _loggedTick = true; ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[DiagHeal] tick: pending=" + Pending.Count + " [" + string.Join(",", Pending.Select((object p) => p.ToString())) + "]")); } } float realtimeSinceStartup = Time.realtimeSinceStartup; if (!float.IsNegativeInfinity(_nextScan) && realtimeSinceStartup - _nextScan < 5f) { return; } _nextScan = realtimeSinceStartup + 5f; MFindSprites.Invoke(null, null); object[] array = Pending.ToArray(); foreach (object obj in array) { if (Resolve(obj)) { Pending.Remove(obj); } } if (Pending.Count == 0 && !_loggedHeal) { _loggedHeal = true; ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)"ProfessionIconHealer: all profession icons resolved via rescan."); } } if (Pending.Count <= 0 || !(realtimeSinceStartup >= _nextStatus)) { return; } _nextStatus = realtimeSinceStartup + 15f; try { IDictionary dictionary = FProfIcons?.GetValue(null) as IDictionary; object key = Pending.First(); string text = ((dictionary != null && dictionary.Contains(key)) ? (dictionary[key] as string) : null); int num2 = -1; try { num2 = ((!(FHudSprites?.GetValue(null) is IDictionary dictionary2)) ? (-1) : dictionary2.Count); } catch { } ManualLogSource logger3 = EclipsePlugin.Logger; if (logger3 != null) { logger3.LogInfo((object)("[DiagHeal] status pend=" + Pending.Count + " key='" + text + "' live=" + (text != null && (Object)(object)SpriteRepair.Get(text) != (Object)null) + " dict=" + num2)); } } catch (Exception ex) { ManualLogSource logger4 = EclipsePlugin.Logger; if (logger4 != null) { logger4.LogWarning((object)("[DiagHeal] status: " + ex.Message)); } } } } private static bool Resolve(object prof) { try { if (!Icons.TryGetValue(prof, out var value) || (Object)(object)value == (Object)null) { return false; } if (!(FProfIcons?.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(prof)) { return false; } if (!(dictionary[prof] is string name)) { return false; } Sprite val = SpriteRepair.Get(name); if ((Object)(object)val == (Object)null) { return false; } if ((Object)(object)value.sprite != (Object)(object)val) { value.sprite = val; } return true; } catch { return false; } } private static Image FindChildImage(Transform root, string name) { for (int i = 0; i < root.childCount; i++) { Transform child = root.GetChild(i); if (((Object)((Component)child).gameObject).name == name) { return ((Component)child).gameObject.GetComponent<Image>(); } if (child.childCount > 0) { Image val = FindChildImage(child, name); if ((Object)(object)val != (Object)null) { return val; } } } return null; } } [HarmonyPatch] internal class LocaleCapsRepairPatch { private static MethodBase TargetMethod() { return AccessTools.Method(EclipseTypes.DataService, "ParseConfigData", (Type[])null, (Type[])null); } private static void Prefix(ref List<string> configData) { try { configData = LocaleCapsRepair.Repair(configData); } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("LocaleCapsRepair: " + ex.Message)); } } } } internal static class LocaleCapsRepair { private const int Scalars = 9; private const int Caps = 24; private static bool _logged; internal static List<string> Repair(List<string> list) { if (list == null || list.Count <= 9 || list[9] == null || list[9].Contains(".")) { return list; } List<string> list2 = new List<string>(list.Count); for (int i = 0; i < 9; i++) { list2.Add(list[i]); } int num = 0; int num2 = 9; while (num2 < list.Count && num < 24) { string text = list[num2]; if (text.Contains(".")) { list2.Add(text); num2++; num++; continue; } string text2 = ((num2 + 1 < list.Count) ? list[num2 + 1] : null); if (!IsDigits(text) || text2 == null || !IsDigits(text2) || text2.Length != 2) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("LocaleCapsRepair: ambiguous token '" + text + "' at index " + num2 + " — leaving message as-is.")); } return list; } list2.Add(text + "." + text2); num2 += 2; num++; } while (num2 < list.Count) { list2.Add(list[num2++]); } if (!_logged) { _logged = true; ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)("LocaleCapsRepair: merged " + num + " locale-decimal caps (server uses a comma-decimal locale — vanilla Bloodcraft bug).")); } } return list2; } private static bool IsDigits(string s) { if (string.IsNullOrEmpty(s)) { return false; } for (int i = 0; i < s.Length; i++) { if (!char.IsDigit(s[i])) { return false; } } return true; } } [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 = EclipsePlugin.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 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogError((object)("[PhantomFilter] " + fieldName + ": " + ex)); } } } } internal static class TabGlow { internal static readonly Color GlowColor = new Color(1f, 0.22f, 0.24f, 1f); internal static readonly Vector2 GlowDistance = new Vector2(3f, -3f); internal static readonly Vector2 RestDistance = new Vector2(1f, -1f); internal const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static bool _applied; private static bool _probed; private static PropertyInfo _fhProp; private static FieldInfo _fhField; internal static void TryApplyOnce() { if (!_applied) { _applied = true; ApplyOne(typeof(ModeTabGlowPatch)); ApplyOne(typeof(SubTabGlowPatch)); } } private static void ApplyOne(Type patchType) { try { EclipsePlugin.HarmonyInst.CreateClassProcessor(patchType).Patch(); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[DiagTab] " + patchType.Name + " patched (lazy, in-world).")); } } catch (Exception ex) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("[DiagTab] " + patchType.Name + " failed: " + ex.Message)); } } } internal static object GetMember(object obj, string name) { Type type = obj.GetType(); PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(obj); } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field != null)) { return null; } return field.GetValue(obj); } internal static void TryForceHighlight(object btn, bool on) { try { if (btn == null) { return; } if (!_probed) { _probed = true; Type type = btn.GetType(); _fhProp = type.GetProperty("ForceHighlight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _fhField = type.GetField("ForceHighlight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[DiagTab] ForceHighlight on " + type.Name + ": " + ((_fhProp != null) ? "property" : ((_fhField != null) ? "field" : "MISSING (outline-only)")))); } } if (_fhProp != null) { _fhProp.SetValue(btn, on); } else if (_fhField != null) { _fhField.SetValue(btn, on); } } catch { } } } [HarmonyPatch] internal class ModeTabGlowPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("Eclipse.Services.CharacterMenu.Tabs.StatBonusesTab"); if (!(type != null)) { return null; } return AccessTools.Method(type, "ConfigureModeTabVisual", (Type[])null, (Type[])null); } private static void Postfix(object __0, bool __1) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) try { if (__0 == null || EclipsePlugin.CfgTabGlow == null || !EclipsePlugin.CfgTabGlow.Value) { return; } object member = TabGlow.GetMember(__0, "Border"); Outline val = (Outline)((member is Outline) ? member : null); if ((Object)(object)val != (Object)null) { ((Shadow)val).effectDistance = (__1 ? TabGlow.GlowDistance : TabGlow.RestDistance); if (__1) { ((Shadow)val).effectColor = TabGlow.GlowColor; } } TabGlow.TryForceHighlight(TabGlow.GetMember(__0, "Button"), __1); } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("[DiagTab] mode-tab glow: " + ex.Message)); } } } } [HarmonyPatch] internal class SubTabGlowPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("Eclipse.Services.CharacterMenu.Tabs.ProgressionTab"); if (!(type != null)) { return null; } return AccessTools.Method(type, "UpdateSubTabSelection", (Type[])null, (Type[])null); } private static void Postfix(object __instance) { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) try { if (__instance == null || EclipsePlugin.CfgTabGlow == null || !EclipsePlugin.CfgTabGlow.Value) { return; } Type type = __instance.GetType(); FieldInfo field = type.GetField("_subTabButtons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("_activeSubTab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field2 == null) { return; } object value = field.GetValue(__instance); if (value == null) { return; } int num = Convert.ToInt32(field2.GetValue(__instance)); Type type2 = value.GetType(); PropertyInfo property = type2.GetProperty("Count", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo property2 = type2.GetProperty("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || property2 == null) { return; } int num2 = (int)property.GetValue(value); for (int i = 0; i < num2; i++) { object value2 = property2.GetValue(value, new object[1] { i }); Component val = (Component)((value2 is Component) ? value2 : null); if ((Object)(object)val == (Object)null) { continue; } bool flag = i == num; Outline val2 = val.GetComponent<Outline>(); if (flag) { if ((Object)(object)val2 == (Object)null) { val2 = val.gameObject.AddComponent<Outline>(); } ((Shadow)val2).effectColor = TabGlow.GlowColor; ((Shadow)val2).effectDistance = TabGlow.GlowDistance; ((Behaviour)val2).enabled = true; } else if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = false; } TabGlow.TryForceHighlight(value2, flag); } } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("[DiagTab] sub-tab glow: " + ex.Message)); } } } } internal static class PrestigeButton { internal static readonly Color BtnBg = new Color(0.08f, 0.08f, 0.1f, 0.95f); internal static readonly Color BtnBorder = new Color(1f, 1f, 1f, 0.15f); internal static readonly Color BtnText = new Color(0.95f, 0.84f, 0.7f, 1f); private static FieldInfo _fHeaderName; private static FieldInfo _fSlots; private static FieldInfo _fMode; private static bool _warned; private static GameObject _btn; private static object _tab; internal static void Ensure(object tab) { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) try { if (tab == null) { return; } _tab = tab; if (_fHeaderName == null) { _fHeaderName = AccessTools.Field(EclipseTypes.Tab, "_headerNameText"); } if (_fSlots == null) { _fSlots = AccessTools.Field(EclipseTypes.Tab, "_headerSlotsText"); } if (_fHeaderName == null && _fSlots == null) { if (!_warned) { _warned = true; ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)"[PrestigeBtn] header text fields unresolved - button disabled."); } } return; } object obj = ((_fHeaderName != null) ? _fHeaderName.GetValue(tab) : null); if (obj == null && _fSlots != null) { obj = _fSlots.GetValue(tab); } Component val = (Component)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { return; } Transform val2 = (((Object)(object)val.transform.parent != (Object)null) ? val.transform.parent.parent : null); if ((Object)(object)val2 == (Object)null) { return; } if ((Object)(object)_btn != (Object)null) { if ((Object)(object)_btn.transform.parent == (Object)(object)val2) { return; } Object.Destroy((Object)(object)_btn); _btn = null; } GameObject val3 = new GameObject("EF_PrestigeButton"); val3.transform.SetParent(val2, false); val3.transform.SetAsLastSibling(); ((Graphic)val3.AddComponent<Image>()).color = BtnBg; Outline obj2 = val3.AddComponent<Outline>(); ((Shadow)obj2).effectColor = BtnBorder; ((Shadow)obj2).effectDistance = new Vector2(1f, -1f); LayoutElement obj3 = val3.AddComponent<LayoutElement>(); obj3.preferredWidth = 92f; obj3.minWidth = 92f; obj3.preferredHeight = 28f; obj3.minHeight = 28f; if (StatSynergyMarker.CreateStyledLabel(val3.transform, obj, "Prestige", 12f, BtnText) == null) { Object.Destroy((Object)(object)val3); return; } Button obj4 = val3.AddComponent<Button>(); ((Selectable)obj4).transition = (Transition)0; ((UnityEvent)obj4.onClick).AddListener(UnityAction.op_Implicit((Action)SendForCurrent)); _btn = val3; ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)"[PrestigeBtn] button created in the Stat Bonuses header."); } } catch (Exception ex) { ManualLogSource logger3 = EclipsePlugin.Logger; if (logger3 != null) { logger3.LogWarning((object)("[PrestigeBtn] Ensure failed: " + ex)); } } } internal static void SendForCurrent() { try { if (EclipsePlugin.CfgQuickPrestige == null || !EclipsePlugin.CfgQuickPrestige.Value || _tab == null) { return; } if (_fMode == null) { _fMode = AccessTools.Field(EclipseTypes.Tab, "_mode"); } string text = ((!(_fMode != null)) ? null : _fMode.GetValue(_tab)?.ToString()); string text2 = null; string text3 = ""; if (text == "BloodLegacies") { object obj = AccessTools.Field(EclipseTypes.DataHUD, "_legacyType")?.GetValue(null); text3 = "legacy=" + ((obj as string) ?? "<null>"); if (!string.IsNullOrWhiteSpace(obj as string)) { text2 = ".prestige me " + obj?.ToString() + "Legacy"; } } else if (text == "WeaponExpertise") { string text4 = AccessTools.Field(EclipseTypes.DataHUD, "_expertiseType")?.GetValue(null) as string; text3 = "hud=" + (text4 ?? "<null>"); if (string.IsNullOrWhiteSpace(text4)) { object obj2 = AccessTools.Field(EclipseTypes.DataService, "_weaponStatBonusData")?.GetValue(null); if (obj2 != null) { PropertyInfo propertyInfo = AccessTools.Property(obj2.GetType(), "WeaponType"); text4 = ((propertyInfo != null) ? propertyInfo.GetValue(obj2) : null) as string; } text3 = text3 + " data=" + (text4 ?? ((obj2 != null) ? "<empty>" : "<null>")); } if (string.IsNullOrWhiteSpace(text4)) { text4 = WeaponPanelSynth.CurrentWeaponType; } text3 = text3 + " cache=" + (text4 ?? "<null>"); if (!string.IsNullOrWhiteSpace(text4)) { text2 = ".prestige me " + text4 + "Expertise"; } } else { text3 = "<unrecognized mode>"; } if (text2 == null) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[PrestigeBtn] click ignored: mode=" + (text ?? "<null>") + " " + text3)); } return; } AccessTools.Method(EclipseTypes.Quips, "SendCommand", (Type[])null, (Type[])null)?.Invoke(null, new object[1] { text2 }); ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)("[PrestigeBtn] sent: " + text2)); } } catch (Exception ex) { ManualLogSource logger3 = EclipsePlugin.Logger; if (logger3 != null) { logger3.LogWarning((object)("[PrestigeBtn] send failed: " + ex)); } } } } [HarmonyPatch] internal class PrestigeButtonPatch { private static MethodBase TargetMethod() { return AccessTools.Method(EclipseTypes.Tab, "UpdateHeader", (Type[])null, (Type[])null); } private static void Postfix(object __instance) { try { if (EclipsePlugin.CfgQuickPrestige != null && EclipsePlugin.CfgQuickPrestige.Value) { PrestigeButton.Ensure(__instance); } } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("[PrestigeBtn] patch: " + ex)); } } } } internal static class PrestigeBoardButtons { internal static void Ensure(Transform header, object sourceText) { try { if (!((Object)(object)header == (Object)null) && sourceText != null && !((Object)(object)header.Find("EF_BoardExperience") != (Object)null)) { Build(header, sourceText, "EF_BoardExperience", "Experience", 96f, -94f, ".prestige me experience"); Build(header, sourceText, "EF_BoardExoForm", "ExoForm", 80f, -8f, ".prestige me exo"); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)"[PrestigeBtn] Experience/ExoForm buttons created on the leaderboard card."); } } } catch (Exception ex) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("[PrestigeBtn] board Ensure failed: " + ex)); } } } private static void Build(Transform header, object sourceText, string name, string label, float width, float xFromRight, string cmd) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0026: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); RectTransform obj = val.AddComponent<RectTransform>(); ((Transform)obj).SetParent(header, false); obj.anchorMin = new Vector2(1f, 0.5f); obj.anchorMax = new Vector2(1f, 0.5f); obj.pivot = new Vector2(1f, 0.5f); obj.anchoredPosition = new Vector2(xFromRight, 0f); obj.sizeDelta = new Vector2(width, 20f); val.AddComponent<LayoutElement>().ignoreLayout = true; ((Graphic)val.AddComponent<Image>()).color = PrestigeButton.BtnBg; Outline obj2 = val.AddComponent<Outline>(); ((Shadow)obj2).effectColor = PrestigeButton.BtnBorder; ((Shadow)obj2).effectDistance = new Vector2(1f, -1f); if (StatSynergyMarker.CreateStyledLabel((Transform)(object)obj, sourceText, label, 11f, PrestigeButton.BtnText) == null) { Object.Destroy((Object)(object)val); return; } Button obj3 = val.AddComponent<Button>(); ((Selectable)obj3).transition = (Transition)0; string captured = cmd; ((UnityEvent)obj3.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { Send(captured); })); } private static void Send(string cmd) { try { if (EclipsePlugin.CfgQuickPrestige != null && EclipsePlugin.CfgQuickPrestige.Value) { AccessTools.Method(EclipseTypes.Quips, "SendCommand", (Type[])null, (Type[])null)?.Invoke(null, new object[1] { cmd }); ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogInfo((object)("[PrestigeBtn] sent: " + cmd)); } } } catch (Exception ex) { ManualLogSource logger2 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("[PrestigeBtn] board send failed: " + ex)); } } } } [HarmonyPatch] internal class PrestigeBoardButtonsPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("Eclipse.Services.CharacterMenu.Tabs.PrestigeTab"); if (!(type != null)) { return null; } return AccessTools.Method(type, "CreateCardHeader", (Type[])null, (Type[])null); } private static void Postfix(RectTransform __result, object __1, string __2) { try { if (EclipsePlugin.CfgQuickPrestige != null && EclipsePlugin.CfgQuickPrestige.Value && !(__2 != "Prestige Leaderboard")) { PrestigeBoardButtons.Ensure((Transform)(object)__result, __1); } } catch (Exception ex) { ManualLogSource logger = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("[PrestigeBtn] board patch: " + 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 = EclipsePlugin.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 = EclipsePlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)"[ClickDiag] prefix method not found."); } return; } EclipsePlugin.HarmonyInst.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ManualLogSource logger3 = EclipsePlugin.Logger; if (logger3 != null) { logger3.LogInfo((object)"[ClickDiag] Quips.SendCommand prefix applied lazily (world ready)."); } } catch (Exception ex) { ManualLogSource logger4 = EclipsePlugin.Logger; if (logger4 != null) { logger4.LogError((object)("[ClickDiag] lazy Quips patch failed: " + ex)); } } } private static void Prefix(string command) { ManualLogSource logger = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.Logger; if (logger != null) { logger.LogWarning((object)("StatBonusesIconSynth: field " + fieldName + " not found.")); } return; } if (!(fieldInfo.GetValue(null) is IDictionary dictionary)) { ManualLogSource logger2 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = EclipsePlugin.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 = "Eclipse_" + 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 = EclipsePlugin.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).AppendLitera