Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of QualityHUDdleUPCompat v1.0.2
QualitiesHUDdleUPCompat.dll
Decompiled 3 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("QualitiesHUDdleUPCompat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("QualitiesHUDdleUPCompat")] [assembly: AssemblyTitle("QualitiesHUDdleUPCompat")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace QualitiesHUDdleUPCompat { [BepInPlugin("com.dbossofdworld.qualitieshuddleupcompat", "Qualities HUDdleUP Compat", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private enum DisplayTiming { Always, AfterTeleporterBossDefeated, AfterTeleporterCharged, Never } private Harmony harmony; private static ConfigEntry<bool> enableQualityChestLabel; private static ConfigEntry<bool> enableQualityCloakedChestLabel; private static ConfigEntry<bool> enableQualityEquipmentBarrelLabel; private static ConfigEntry<bool> enableQualityPrinterLabel; private static ConfigEntry<DisplayTiming> qualityChestDisplayTiming; private static ConfigEntry<DisplayTiming> qualityCloakedChestDisplayTiming; private static ConfigEntry<DisplayTiming> qualityEquipmentBarrelDisplayTiming; private static ConfigEntry<DisplayTiming> qualityPrinterDisplayTiming; private static ConfigEntry<string> qualityChestLabel; private static ConfigEntry<string> qualityCloakedChestLabel; private static ConfigEntry<string> qualityEquipmentBarrelLabel; private static ConfigEntry<string> qualityPrinterLabel; private static ConfigEntry<string> qualityChestLabelColor; private static ConfigEntry<string> qualityCloakedChestLabelColor; private static ConfigEntry<string> qualityEquipmentBarrelLabelColor; private static ConfigEntry<string> qualityPrinterLabelColor; private static ConfigEntry<bool> combineQualityChestWithNormalChest; private static ConfigEntry<bool> combineQualityEquipmentBarrelWithNormalEquipmentBarrel; private static ConfigEntry<bool> enableDebugLogging; private static int qualityChests; private static int qualityChestsAvailable; private static int qualityCloakedChests; private static int qualityCloakedChestsAvailable; private static int qualityEquipmentBarrels; private static int qualityEquipmentBarrelsAvailable; private static int qualityPrinters; private static int qualityPrintersAvailable; private static MethodInfo hudFormatLabelMethod; private static MethodInfo hudFormatCounterMethod; public void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown BindConfig(); harmony = new Harmony("com.dbossofdworld.qualitieshuddleupcompat"); try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name.Equals("HUDdleUP", StringComparison.OrdinalIgnoreCase)); if (assembly == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"HUDdleUP assembly not found. Compat patch skipped."); return; } PatchInteractablesConstructor(assembly); PatchLootPanelText(assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Qualities HUDdleUP Compat 1.0.0 loaded."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private void BindConfig() { enableQualityChestLabel = ((BaseUnityPlugin)this).Config.Bind<bool>("Labels - Enable", "Enable Quality Chest", true, "If true, shows the Quality Chest line on HUDdleUP's loot panel."); enableQualityCloakedChestLabel = ((BaseUnityPlugin)this).Config.Bind<bool>("Labels - Enable", "Enable Quality Cloaked Chest", true, "If true, shows the Quality Cloaked Chest line on HUDdleUP's loot panel."); enableQualityEquipmentBarrelLabel = ((BaseUnityPlugin)this).Config.Bind<bool>("Labels - Enable", "Enable Quality Equipment Barrel", true, "If true, shows the Quality Equipment Barrel line on HUDdleUP's loot panel."); enableQualityPrinterLabel = ((BaseUnityPlugin)this).Config.Bind<bool>("Labels - Enable", "Enable Quality 3D Printer", true, "If true, shows the Quality 3D Printer line on HUDdleUP's loot panel."); qualityChestDisplayTiming = ((BaseUnityPlugin)this).Config.Bind<DisplayTiming>("Labels - Timing", "Quality Chest Timing", DisplayTiming.Always, "When the Quality Chest line should appear. Options: Always, AfterTeleporterBossDefeated, AfterTeleporterCharged, Never."); qualityCloakedChestDisplayTiming = ((BaseUnityPlugin)this).Config.Bind<DisplayTiming>("Labels - Timing", "Quality Cloaked Chest Timing", DisplayTiming.AfterTeleporterBossDefeated, "When the Quality Cloaked Chest line should appear. Options: Always, AfterTeleporterBossDefeated, AfterTeleporterCharged, Never."); qualityEquipmentBarrelDisplayTiming = ((BaseUnityPlugin)this).Config.Bind<DisplayTiming>("Labels - Timing", "Quality Equipment Barrel Timing", DisplayTiming.Always, "When the Quality Equipment Barrel line should appear. Options: Always, AfterTeleporterBossDefeated, AfterTeleporterCharged, Never."); qualityPrinterDisplayTiming = ((BaseUnityPlugin)this).Config.Bind<DisplayTiming>("Labels - Timing", "Quality 3D Printer Timing", DisplayTiming.AfterTeleporterBossDefeated, "When the Quality 3D Printer line should appear. Options: Always, AfterTeleporterBossDefeated, AfterTeleporterCharged, Never."); qualityChestLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Text", "Quality Chest Label", "Quality Chest", "Text used for the Quality Chest line."); qualityCloakedChestLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Text", "Quality Cloaked Chest Label", "Quality Cloaked Chest", "Text used for the Quality Cloaked Chest line."); qualityEquipmentBarrelLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Text", "Quality Equipment Barrel Label", "Quality Equipment Barrel", "Text used for the Quality Equipment Barrel line."); qualityPrinterLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Text", "Quality 3D Printer Label", "Quality 3D Printer", "Text used for the Quality 3D Printer line."); qualityChestLabelColor = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Color", "Quality Chest Label Color", "#FFFFFFFF", "Hex color for the Quality Chest label. Example: #FFFFFFFF for white."); qualityCloakedChestLabelColor = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Color", "Quality Cloaked Chest Label Color", "#FFFFFFFF", "Hex color for the Quality Cloaked Chest label. Example: #FFFFFFFF for white."); qualityEquipmentBarrelLabelColor = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Color", "Quality Equipment Barrel Label Color", "#FFFFFFFF", "Hex color for the Quality Equipment Barrel label. Example: #FFFFFFFF for white."); qualityPrinterLabelColor = ((BaseUnityPlugin)this).Config.Bind<string>("Labels - Color", "Quality 3D Printer Label Color", "#FFFFFFFF", "Hex color for the Quality 3D Printer label. Example: #FFFFFFFF for white."); combineQualityChestWithNormalChest = ((BaseUnityPlugin)this).Config.Bind<bool>("Formatting", "Combine Quality Chest With Normal Chest", false, "If true, Quality Chest counts are added to HUDdleUP's normal Chest line instead of showing a separate Quality Chest line."); combineQualityEquipmentBarrelWithNormalEquipmentBarrel = ((BaseUnityPlugin)this).Config.Bind<bool>("Formatting", "Combine Quality Equipment Barrel With Normal Equipment Barrel", false, "If true, Quality Equipment Barrel counts are added to HUDdleUP's normal Equipment Barrel line instead of showing a separate Quality Equipment Barrel line."); enableDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable Debug Logging", false, "If true, logs possible Quality interactables seen by the compatibility mod."); } private void PatchInteractablesConstructor(Assembly hudAsm) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown Type type = hudAsm.GetType("HUDdleUP.Loot.Interactables"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find HUDdleUP.Loot.Interactables. HUDdleUP may have changed its loot internals."); return; } ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(List<PurchaseInteraction>) }, null); if (constructor == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find Interactables(List<PurchaseInteraction>). HUDdleUP may have changed its loot internals."); return; } harmony.Patch((MethodBase)constructor, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin).GetMethod("InteractablesCtorPostfix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched HUDdleUP.Loot.Interactables constructor for separate Quality loot counts."); } private void PatchLootPanelText(Assembly hudAsm) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown Type type = hudAsm.GetType("HUDdleUP.Loot.LootPanel"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find HUDdleUP.Loot.LootPanel. Separate Quality loot lines will not be displayed."); return; } MethodInfo methodInfo = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "GenerateText" && m.ReturnType == typeof(string)); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find LootPanel.GenerateText returning string. Separate Quality loot lines will not be displayed."); return; } hudFormatLabelMethod = type.GetMethod("FormatLabel", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); hudFormatCounterMethod = type.GetMethod("FormatCounter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(int), typeof(int) }, null); if (hudFormatLabelMethod == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find HUDdleUP FormatLabel method. Falling back to local Quality line formatting."); } if (hudFormatCounterMethod == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find HUDdleUP FormatCounter method. Falling back to local Quality counter formatting."); } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin).GetMethod("GenerateTextPostfix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched HUDdleUP.Loot.LootPanel.GenerateText for separate Quality loot lines."); } private static void InteractablesCtorPostfix(object __instance, List<PurchaseInteraction> interactions) { if (__instance == null || interactions == null) { return; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; foreach (PurchaseInteraction interaction in interactions) { if ((Object)(object)interaction == (Object)null) { continue; } string text = interaction.displayNameToken ?? ""; string text2 = (Object.op_Implicit((Object)(object)((Component)interaction).gameObject) ? (((Object)((Component)interaction).gameObject).name ?? "") : ""); if (enableDebugLogging != null && enableDebugLogging.Value && LooksQualityRelated(text, text2)) { Debug.Log((object)$"[QualitiesHUDdleUPCompat] Saw possible Quality interactable: token={text}, object={text2}, available={interaction.available}"); } if (IsQualityPrinter(text, text2)) { num7++; if (interaction.available) { num8++; } } else if (IsQualityEquipmentBarrel(text, text2)) { num5++; if (interaction.available) { num6++; } } else { if (!IsQualityChest(text, text2)) { continue; } if (IsCloaked(text, text2)) { num3++; if (interaction.available) { num4++; } } else { num++; if (interaction.available) { num2++; } } } } qualityChests = num; qualityChestsAvailable = num2; qualityCloakedChests = num3; qualityCloakedChestsAvailable = num4; qualityEquipmentBarrels = num5; qualityEquipmentBarrelsAvailable = num6; qualityPrinters = num7; qualityPrintersAvailable = num8; } private static void GenerateTextPostfix(ref string __result) { if (string.IsNullOrEmpty(__result)) { return; } List<string> list = __result.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n') .ToList(); bool flag = false; bool flag2 = false; if (ShouldCombineQualityChestWithNormalChest()) { flag = TryMergeQualityCountIntoExistingLine(list, (string line) => ContainsIgnoreCase(line, "Chest") && !ContainsIgnoreCase(line, "Quality") && !ContainsIgnoreCase(line, "Cloaked") && !ContainsIgnoreCase(line, "Legendary") && !ContainsIgnoreCase(line, "Equipment"), "Chest", qualityChestsAvailable, qualityChests); } if (ShouldCombineQualityEquipmentBarrelWithNormalEquipmentBarrel()) { flag2 = TryMergeQualityCountIntoExistingLine(list, (string line) => ContainsIgnoreCase(line, "Equipment Barrel") && !ContainsIgnoreCase(line, "Quality"), "Equipment Barrel", qualityEquipmentBarrelsAvailable, qualityEquipmentBarrels); } List<string> list2 = BuildQualityOpenableLootLines(flag, flag2); List<string> list3 = BuildQualityPrinterLootLines(); if (list2.Count != 0 || list3.Count != 0 || flag || flag2) { if (list2.Count > 0) { InsertQualityOpenableLines(list, list2); } if (list3.Count > 0) { InsertQualityPrinterLines(list, list3); } __result = string.Join("\n", list); } } private static bool ShouldCombineQualityChestWithNormalChest() { if (combineQualityChestWithNormalChest != null && combineQualityChestWithNormalChest.Value && enableQualityChestLabel != null && enableQualityChestLabel.Value && qualityChests > 0) { return ShouldDisplay(qualityChestDisplayTiming.Value); } return false; } private static bool ShouldCombineQualityEquipmentBarrelWithNormalEquipmentBarrel() { if (combineQualityEquipmentBarrelWithNormalEquipmentBarrel != null && combineQualityEquipmentBarrelWithNormalEquipmentBarrel.Value && enableQualityEquipmentBarrelLabel != null && enableQualityEquipmentBarrelLabel.Value && qualityEquipmentBarrels > 0) { return ShouldDisplay(qualityEquipmentBarrelDisplayTiming.Value); } return false; } private static bool TryMergeQualityCountIntoExistingLine(List<string> lines, Func<string, bool> linePredicate, string normalLabel, int qualityAvailable, int qualityTotal) { if (lines == null || linePredicate == null || qualityTotal <= 0) { return false; } int num = FindLineIndex(lines, linePredicate); if (num < 0) { return false; } string text = lines[num]; Match match = Regex.Match(StripRichTextTags(text), "(?<available>\\d+)\\s*/\\s*(?<total>\\d+)"); if (!match.Success) { return false; } if (!int.TryParse(match.Groups["available"].Value, out var result)) { return false; } if (!int.TryParse(match.Groups["total"].Value, out var result2)) { return false; } string value = GetOriginalLinePrefixBeforeCounter(text); if (string.IsNullOrEmpty(value)) { value = FormatHudLabel(normalLabel); } value = CloseUnclosedRichTextTags(value); lines[num] = value + FormatHudCounter(result + qualityAvailable, result2 + qualityTotal); return true; } private static string GetOriginalLinePrefixBeforeCounter(string line) { if (string.IsNullOrEmpty(line)) { return string.Empty; } int num = line.LastIndexOf(':'); if (num < 0) { return string.Empty; } int i; for (i = num + 1; i < line.Length && char.IsWhiteSpace(line[i]); i++) { } return line.Substring(0, i); } private static string CloseUnclosedRichTextTags(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(value); int count = Regex.Matches(value, "<color(?:=|>)", RegexOptions.IgnoreCase).Count; for (int i = Regex.Matches(value, "</color>", RegexOptions.IgnoreCase).Count; i < count; i++) { stringBuilder.Append("</color>"); } int count2 = Regex.Matches(value, "<style(?:=|>)", RegexOptions.IgnoreCase).Count; for (int j = Regex.Matches(value, "</style>", RegexOptions.IgnoreCase).Count; j < count2; j++) { stringBuilder.Append("</style>"); } return stringBuilder.ToString(); } private static string StripRichTextTags(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } return Regex.Replace(value, "<.*?>", string.Empty); } private static void InsertQualityOpenableLines(List<string> lines, List<string> qualityLines) { int num = FindFirstUtilityLineIndex(lines); if (num >= 0) { int index = num; if (num > 0 && string.IsNullOrWhiteSpace(lines[num - 1])) { index = num - 1; } lines.InsertRange(index, qualityLines); return; } int num2 = FindLineIndex(lines, (string line) => ContainsIgnoreCase(line, "Enemies")); int num3 = FindLineIndex(lines, IsStageHeaderLine); int num4 = ((num2 >= 0) ? num2 : num3); if (num4 >= 0) { if (num4 > 0 && string.IsNullOrWhiteSpace(lines[num4 - 1])) { num4--; lines.RemoveAt(num4); } lines.InsertRange(num4, qualityLines); int num5 = num4 + qualityLines.Count; if (num5 >= lines.Count || !string.IsNullOrWhiteSpace(lines[num5])) { lines.Insert(num5, string.Empty); } } else { lines.AddRange(qualityLines); } } private static void InsertQualityPrinterLines(List<string> lines, List<string> qualityLines) { int num = FindLineIndex(lines, (string line) => ContainsIgnoreCase(line, "Enemies")); int num2 = FindLineIndex(lines, IsStageHeaderLine); int num3 = ((num >= 0) ? num : num2); int num4 = FindLastUtilityLineIndex(lines, num3); if (num4 >= 0) { lines.InsertRange(num4 + 1, qualityLines); } else if (num3 >= 0) { if (num3 > 0 && string.IsNullOrWhiteSpace(lines[num3 - 1])) { num3--; lines.RemoveAt(num3); } lines.InsertRange(num3, qualityLines); int num5 = num3 + qualityLines.Count; if (num5 >= lines.Count || !string.IsNullOrWhiteSpace(lines[num5])) { lines.Insert(num5, string.Empty); } } else { lines.AddRange(qualityLines); } } private static int FindFirstUtilityLineIndex(List<string> lines) { return FindLineIndex(lines, (string line) => !ContainsIgnoreCase(line, "Quality") && (ContainsIgnoreCase(line, "Scrapper") || ContainsIgnoreCase(line, "Printer"))); } private static int FindLastUtilityLineIndex(List<string> lines, int boundaryIndex) { int num = ((boundaryIndex >= 0) ? boundaryIndex : lines.Count); int result = -1; for (int i = 0; i < num; i++) { string value = lines[i]; if (!ContainsIgnoreCase(value, "Quality") && (ContainsIgnoreCase(value, "Scrapper") || ContainsIgnoreCase(value, "Printer"))) { result = i; } } return result; } private static int FindLineIndex(List<string> lines, Func<string, bool> predicate) { for (int i = 0; i < lines.Count; i++) { if (predicate(lines[i])) { return i; } } return -1; } private static bool IsStageHeaderLine(string line) { return line?.TrimStart().StartsWith("-- ", StringComparison.OrdinalIgnoreCase) ?? false; } private static bool ContainsIgnoreCase(string value, string search) { if (value != null) { return value.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static List<string> BuildQualityOpenableLootLines(bool qualityChestWasCombined, bool qualityEquipmentWasCombined) { List<string> list = new List<string>(); if (!qualityChestWasCombined && enableQualityChestLabel.Value && qualityChests > 0 && ShouldDisplay(qualityChestDisplayTiming.Value)) { bool flag = ShouldCombineQualityChestWithNormalChest(); list.Add(flag ? FormatNormalAvailableLine("Chest", qualityChestsAvailable, qualityChests) : FormatAvailableLine(qualityChestLabel.Value, qualityChestLabelColor.Value, qualityChestsAvailable, qualityChests)); } if (enableQualityCloakedChestLabel.Value && qualityCloakedChests > 0 && ShouldDisplay(qualityCloakedChestDisplayTiming.Value)) { list.Add(FormatAvailableLine(qualityCloakedChestLabel.Value, qualityCloakedChestLabelColor.Value, qualityCloakedChestsAvailable, qualityCloakedChests)); } if (!qualityEquipmentWasCombined && enableQualityEquipmentBarrelLabel.Value && qualityEquipmentBarrels > 0 && ShouldDisplay(qualityEquipmentBarrelDisplayTiming.Value)) { bool flag2 = ShouldCombineQualityEquipmentBarrelWithNormalEquipmentBarrel(); list.Add(flag2 ? FormatNormalAvailableLine("Equipment Barrel", qualityEquipmentBarrelsAvailable, qualityEquipmentBarrels) : FormatAvailableLine(qualityEquipmentBarrelLabel.Value, qualityEquipmentBarrelLabelColor.Value, qualityEquipmentBarrelsAvailable, qualityEquipmentBarrels)); } return list; } private static List<string> BuildQualityPrinterLootLines() { List<string> list = new List<string>(); if (enableQualityPrinterLabel.Value && qualityPrinters > 0 && ShouldDisplay(qualityPrinterDisplayTiming.Value)) { list.Add(FormatTotalOnlyLine(qualityPrinterLabel.Value, qualityPrinterLabelColor.Value, qualityPrinters)); } return list; } private static bool ShouldDisplay(DisplayTiming timing) { switch (timing) { case DisplayTiming.Always: return true; case DisplayTiming.AfterTeleporterBossDefeated: return IsTeleporterBossDefeated(); case DisplayTiming.AfterTeleporterCharged: if ((Object)(object)TeleporterInteraction.instance != (Object)null) { return TeleporterInteraction.instance.isCharged; } return false; default: return false; } } private static bool IsTeleporterBossDefeated() { TeleporterInteraction instance = TeleporterInteraction.instance; if ((Object)(object)instance == (Object)null) { return false; } if (instance.isCharged) { return true; } try { object memberValue = GetMemberValue(instance, "bossGroup"); if (memberValue == null) { memberValue = GetMemberValue(instance, "currentBossGroup"); } if (memberValue == null) { return false; } if (GetMemberValue(memberValue, "isDefeated") is bool result) { return result; } if (GetMemberValue(memberValue, "livingMembers") is int num) { return num <= 0; } if (GetMemberValue(memberValue, "membersList") is ICollection collection) { return collection.Count == 0; } } catch { } return false; } private static object GetMemberValue(object instance, string memberName) { if (instance == null || string.IsNullOrEmpty(memberName)) { return null; } Type type = instance.GetType(); FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(instance); } PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { return property.GetValue(instance, null); } return null; } private static string FormatNormalAvailableLine(string label, int available, int total) { return FormatHudLabel(label) + FormatHudCounter(available, total); } private static string FormatAvailableLine(string label, string color, int available, int total) { return FormatHudLabel(WrapColor(label, color)) + FormatHudCounter(available, total); } private static string FormatTotalOnlyLine(string label, string color, int total) { return FormatHudLabel(WrapColor(label, color)) + total; } private static string FormatHudLabel(string formattedLabel) { try { if (hudFormatLabelMethod != null) { return (string)hudFormatLabelMethod.Invoke(null, new object[1] { formattedLabel }); } } catch { } return "> " + formattedLabel + ": "; } private static string FormatHudCounter(int available, int total) { try { if (hudFormatCounterMethod != null) { return (string)hudFormatCounterMethod.Invoke(null, new object[2] { available, total }); } } catch { } return $"{available}/{total}"; } private static string WrapColor(string label, string color) { if (string.IsNullOrWhiteSpace(label)) { label = "Quality"; } string text = NormalizeColor(color); return "<color=" + text + ">" + label + "</color>"; } private static string NormalizeColor(string color) { if (string.IsNullOrWhiteSpace(color)) { return "#FFFFFFFF"; } color = color.Trim(); if (!color.StartsWith("#")) { color = "#" + color; } if (color.Length == 4 || color.Length == 7 || color.Length == 9) { return color; } return "#FFFFFFFF"; } private static bool LooksQualityRelated(string token, string objectName) { if (token.IndexOf("QUALITY", StringComparison.OrdinalIgnoreCase) < 0 && objectName.IndexOf("Quality", StringComparison.OrdinalIgnoreCase) < 0) { return objectName.IndexOf("ItemQualities", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool IsQualityChest(string token, string objectName) { if (LooksQualityRelated(token, objectName)) { if (token.IndexOf("CHEST", StringComparison.OrdinalIgnoreCase) < 0) { return objectName.IndexOf("Chest", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } return false; } private static bool IsQualityEquipmentBarrel(string token, string objectName) { if (LooksQualityRelated(token, objectName)) { if (token.IndexOf("EQUIPMENT", StringComparison.OrdinalIgnoreCase) < 0 && objectName.IndexOf("Equipment", StringComparison.OrdinalIgnoreCase) < 0) { return objectName.IndexOf("Barrel", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } return false; } private static bool IsQualityPrinter(string token, string objectName) { if (LooksQualityRelated(token, objectName)) { if (token.IndexOf("DUPLICATOR", StringComparison.OrdinalIgnoreCase) < 0 && token.IndexOf("PRINTER", StringComparison.OrdinalIgnoreCase) < 0 && objectName.IndexOf("Duplicator", StringComparison.OrdinalIgnoreCase) < 0) { return objectName.IndexOf("Printer", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } return false; } private static bool IsCloaked(string token, string objectName) { if (token.IndexOf("STEALTHED", StringComparison.OrdinalIgnoreCase) < 0 && objectName.IndexOf("Stealthed", StringComparison.OrdinalIgnoreCase) < 0) { return objectName.IndexOf("Cloaked", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } } }