using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 REPOJP.CosmeticTokenCountHUD { [BepInPlugin("REPOJP.CosmeticTokenCountHUD", "CosmeticTokenCountHUD", "4.0.0")] public class CosmeticTokenCountHUDPlugin : BaseUnityPlugin { public const string PluginGuid = "REPOJP.CosmeticTokenCountHUD"; public const string PluginName = "CosmeticTokenCountHUD"; public const string PluginVersion = "4.0.0"; internal static ManualLogSource Log; internal static bool PendingRefresh; internal static ConfigEntry Enable; internal static ConfigEntry ShowDebugLog; internal static ConfigEntry RefreshIntervalSeconds; internal static ConfigEntry ShowOnlyInShop; internal static ConfigEntry HideWhenNoToken; internal static ConfigEntry ShowZeroCountRarity; internal static ConfigEntry Anchor; internal static ConfigEntry OffsetX; internal static ConfigEntry OffsetY; internal static ConfigEntry FontSize; internal static ConfigEntry BackgroundOpacity; internal static ConfigEntry TextOpacity; internal static ConfigEntry SortingOrder; internal static ConfigEntry LineSpacing; internal static ConfigEntry PaddingX; internal static ConfigEntry PaddingY; internal static ConfigEntry Width; internal static ConfigEntry AutoResizeWidth; internal static ConfigEntry TextAlign; internal static ConfigEntry DisplayOrder; internal static ConfigEntry CustomDisplayOrder; internal static ConfigEntry TitleText; internal static ConfigEntry CommonLabel; internal static ConfigEntry UncommonLabel; internal static ConfigEntry RareLabel; internal static ConfigEntry UltraRareLabel; internal static ConfigEntry UseRarityTextColor; internal static ConfigEntry CommonColor; internal static ConfigEntry UncommonColor; internal static ConfigEntry RareColor; internal static ConfigEntry UltraRareColor; internal static ConfigEntry BackgroundColor; internal static ConfigEntry RefreshOnCosmeticTokenUISetup; internal static ConfigEntry RefreshOnCosmeticShopMachineInteract; internal static Type MetaManagerType; internal static Type SemiFuncType; internal static Type RunManagerType; internal static Type GameDirectorType; internal static Type ShopManagerType; internal static Type CosmeticShopMachineType; internal static Type CosmeticTokenUIType; internal static FieldInfo MetaManagerInstanceField; internal static FieldInfo CosmeticTokensField; internal static FieldInfo RunManagerInstanceField; internal static FieldInfo GameDirectorInstanceField; internal static FieldInfo GameDirectorCurrentStateField; internal static MethodInfo RunIsShopMethod; private Harmony harmony; private void Awake() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown try { if ((Object)(object)((Component)this).transform.parent != (Object)null) { ((Component)this).transform.parent = null; } ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Log = ((BaseUnityPlugin)this).Logger; BindConfig(); CacheGameTypes(); if ((Object)(object)((Component)this).GetComponent() == (Object)null) { ((Component)this).gameObject.AddComponent(); } harmony = new Harmony("REPOJP.CosmeticTokenCountHUD"); ApplyPatches(); WriteDebugLog("Plugin loaded. Version=4.0.0"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex)); } } private void OnDestroy() { try { if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: OnDestroy\n" + ex)); } } private void BindConfig() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Expected O, but got Unknown //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Expected O, but got Unknown Enable = ((BaseUnityPlugin)this).Config.Bind("General", "Enable", true, "Enable the HUD display.HUD表示を有効化します"); ShowDebugLog = ((BaseUnityPlugin)this).Config.Bind("General", "ShowDebugLog", false, "Show debug logs.デバッグログを表示します"); RefreshIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind("General", "RefreshIntervalSeconds", 0.35f, new ConfigDescription("Refresh interval in seconds.更新間隔の秒数です", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 2f), Array.Empty())); ShowOnlyInShop = ((BaseUnityPlugin)this).Config.Bind("Display", "ShowOnlyInShop", true, "Show only while you are in the shop.ショップ中のみ表示します"); HideWhenNoToken = ((BaseUnityPlugin)this).Config.Bind("Display", "HideWhenNoToken", true, "Hide the HUD when you have no cosmetic tokens.コスメトークンを持っていない時にHUDを非表示にします"); ShowZeroCountRarity = ((BaseUnityPlugin)this).Config.Bind("Display", "ShowZeroCountRarity", true, "Show rarity rows even when the count is zero.0枚のレアリティも表示します"); Anchor = ((BaseUnityPlugin)this).Config.Bind("Display", "Anchor", HudAnchor.BottomRight, "HUD anchor position.HUDの基準位置です"); OffsetX = ((BaseUnityPlugin)this).Config.Bind("Display", "OffsetX", -40f, "Horizontal offset from the anchor.基準位置からの横方向オフセットです"); OffsetY = ((BaseUnityPlugin)this).Config.Bind("Display", "OffsetY", 160f, "Vertical offset from the anchor.基準位置からの縦方向オフセットです"); FontSize = ((BaseUnityPlugin)this).Config.Bind("Display", "FontSize", 18, new ConfigDescription("Text font size.文字サイズです", (AcceptableValueBase)(object)new AcceptableValueRange(8, 48), Array.Empty())); BackgroundOpacity = ((BaseUnityPlugin)this).Config.Bind("Display", "BackgroundOpacity", 0.35f, new ConfigDescription("Background opacity.背景の不透明度です", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); TextOpacity = ((BaseUnityPlugin)this).Config.Bind("Display", "TextOpacity", 1f, new ConfigDescription("Text opacity.文字の不透明度です", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 1f), Array.Empty())); SortingOrder = ((BaseUnityPlugin)this).Config.Bind("Display", "SortingOrder", 300, new ConfigDescription("Canvas sorting order.Canvasの描画順です", (AcceptableValueBase)(object)new AcceptableValueRange(0, 1000), Array.Empty())); LineSpacing = ((BaseUnityPlugin)this).Config.Bind("Layout", "LineSpacing", 4f, new ConfigDescription("Spacing between lines.行間です", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 24f), Array.Empty())); PaddingX = ((BaseUnityPlugin)this).Config.Bind("Layout", "PaddingX", 12f, new ConfigDescription("Horizontal padding.横方向の余白です", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f), Array.Empty())); PaddingY = ((BaseUnityPlugin)this).Config.Bind("Layout", "PaddingY", 10f, new ConfigDescription("Vertical padding.縦方向の余白です", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f), Array.Empty())); Width = ((BaseUnityPlugin)this).Config.Bind("Layout", "Width", 260f, new ConfigDescription("HUD width.HUDの横幅です", (AcceptableValueBase)(object)new AcceptableValueRange(120f, 800f), Array.Empty())); AutoResizeWidth = ((BaseUnityPlugin)this).Config.Bind("Layout", "AutoResizeWidth", true, "Automatically widen the HUD when text is long.文字が長い場合にHUDの横幅を自動調整します"); TextAlign = ((BaseUnityPlugin)this).Config.Bind("Layout", "TextAlign", HudTextAlign.Left, "Text alignment.文字揃えです"); DisplayOrder = ((BaseUnityPlugin)this).Config.Bind("Layout", "DisplayOrder", DisplayOrderMode.LowToHigh, "Rarity display order.レアリティの表示順です"); CustomDisplayOrder = ((BaseUnityPlugin)this).Config.Bind("Layout", "CustomDisplayOrder", "Common,Uncommon,Rare,UltraRare", "Custom display order when DisplayOrder is Custom.DisplayOrderがCustomの時の表示順です"); TitleText = ((BaseUnityPlugin)this).Config.Bind("Text", "TitleText", "Cosmetic Tokens", "HUD title text.HUDタイトル文字列です"); CommonLabel = ((BaseUnityPlugin)this).Config.Bind("Text", "CommonLabel", "Common", "Common rarity label.Commonレアリティの表示名です"); UncommonLabel = ((BaseUnityPlugin)this).Config.Bind("Text", "UncommonLabel", "Uncommon", "Uncommon rarity label.Uncommonレアリティの表示名です"); RareLabel = ((BaseUnityPlugin)this).Config.Bind("Text", "RareLabel", "Rare", "Rare rarity label.Rareレアリティの表示名です"); UltraRareLabel = ((BaseUnityPlugin)this).Config.Bind("Text", "UltraRareLabel", "UltraRare", "UltraRare rarity label.UltraRareレアリティの表示名です"); UseRarityTextColor = ((BaseUnityPlugin)this).Config.Bind("Color", "UseRarityTextColor", true, "Use different text colors for each rarity.レアリティごとに文字色を変えます"); CommonColor = ((BaseUnityPlugin)this).Config.Bind("Color", "CommonColor", "#00C807", "Common text color in hex.Common文字色の16進数指定です"); UncommonColor = ((BaseUnityPlugin)this).Config.Bind("Color", "UncommonColor", "#0398CB", "Uncommon text color in hex.Uncommon文字色の16進数指定です"); RareColor = ((BaseUnityPlugin)this).Config.Bind("Color", "RareColor", "#BD06BB", "Rare text color in hex.Rare文字色の16進数指定です"); UltraRareColor = ((BaseUnityPlugin)this).Config.Bind("Color", "UltraRareColor", "#B89005", "UltraRare text color in hex.UltraRare文字色の16進数指定です"); BackgroundColor = ((BaseUnityPlugin)this).Config.Bind("Color", "BackgroundColor", "#000000", "Background color in hex.背景色の16進数指定です"); ApplyTokenColorDefaults(); RefreshOnCosmeticTokenUISetup = ((BaseUnityPlugin)this).Config.Bind("Compatibility", "RefreshOnCosmeticTokenUISetup", false, "Refresh when vanilla CosmeticTokenUI is refreshed.バニラのCosmeticTokenUI更新時にHUDも更新します"); RefreshOnCosmeticShopMachineInteract = ((BaseUnityPlugin)this).Config.Bind("Compatibility", "RefreshOnCosmeticShopMachineInteract", true, "Refresh immediately when the cosmetic shop machine is used.コスメショップマシン使用時に即時更新します"); } private void ApplyTokenColorDefaults() { try { SetColorIfOldDefault(CommonColor, "#FFFFFF", "#00C807"); SetColorIfOldDefault(UncommonColor, "#6EFF6E", "#0398CB"); SetColorIfOldDefault(RareColor, "#6EA8FF", "#BD06BB"); SetColorIfOldDefault(UltraRareColor, "#D66EFF", "#B89005"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failure: ApplyTokenColorDefaults\n" + ex)); } } private void SetColorIfOldDefault(ConfigEntry entry, string oldValue, string newValue) { if (entry != null && string.Equals(NormalizeHexColor(entry.Value), NormalizeHexColor(oldValue), StringComparison.OrdinalIgnoreCase)) { entry.Value = newValue; } } private string NormalizeHexColor(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } string text = value.Trim(); if (!text.StartsWith("#")) { text = "#" + text; } return text; } private void CacheGameTypes() { MetaManagerType = AccessTools.TypeByName("MetaManager"); SemiFuncType = AccessTools.TypeByName("SemiFunc"); RunManagerType = AccessTools.TypeByName("RunManager"); GameDirectorType = AccessTools.TypeByName("GameDirector"); ShopManagerType = AccessTools.TypeByName("ShopManager"); CosmeticShopMachineType = AccessTools.TypeByName("CosmeticShopMachine"); CosmeticTokenUIType = AccessTools.TypeByName("CosmeticTokenUI"); if (MetaManagerType != null) { MetaManagerInstanceField = AccessTools.Field(MetaManagerType, "instance"); CosmeticTokensField = AccessTools.Field(MetaManagerType, "cosmeticTokens"); } if (SemiFuncType != null) { RunIsShopMethod = AccessTools.Method(SemiFuncType, "RunIsShop", (Type[])null, (Type[])null); } if (RunManagerType != null) { RunManagerInstanceField = AccessTools.Field(RunManagerType, "instance"); } if (GameDirectorType != null) { GameDirectorInstanceField = AccessTools.Field(GameDirectorType, "instance"); GameDirectorCurrentStateField = AccessTools.Field(GameDirectorType, "currentState"); } if (MetaManagerType == null) { Log.LogWarning((object)"Failure: MetaManager type was not found. HUD will stay hidden."); } if (CosmeticTokensField == null) { Log.LogWarning((object)"Failure: cosmeticTokens field was not found. HUD will stay hidden."); } } private void ApplyPatches() { TryPatchPostfix(MetaManagerType, "CosmeticTokenAdd", "MetaManager_CosmeticTokenAdd_Postfix"); TryPatchPostfix(MetaManagerType, "CosmeticTokenRemove", "MetaManager_CosmeticTokenRemove_Postfix"); TryPatchPostfix(ShopManagerType, "ShopInitialize", "ShopManager_ShopInitialize_Postfix"); TryPatchPostfix(CosmeticShopMachineType, "Interact", "CosmeticShopMachine_Interact_Postfix"); TryPatchPostfix(CosmeticShopMachineType, "RewardSet", "CosmeticShopMachine_RewardSet_Postfix"); TryPatchPostfix(CosmeticTokenUIType, "Setup", "CosmeticTokenUI_Setup_Postfix"); } private void TryPatchPostfix(Type targetType, string targetMethodName, string postfixMethodName) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown try { if (targetType == null) { WriteDebugLog("Patch skipped because target type is missing: " + targetMethodName); return; } MethodInfo methodInfo = AccessTools.Method(targetType, targetMethodName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(CosmeticTokenCountHUDPlugin), postfixMethodName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { WriteDebugLog("Patch skipped: " + targetType.Name + "." + targetMethodName); return; } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); WriteDebugLog("Patch applied: " + targetType.Name + "." + targetMethodName); } catch (Exception ex) { Log.LogWarning((object)("Failure: TryPatchPostfix " + targetMethodName + "\n" + ex)); } } private static void MetaManager_CosmeticTokenAdd_Postfix() { RequestRefresh("CosmeticTokenAdd"); } private static void MetaManager_CosmeticTokenRemove_Postfix() { RequestRefresh("CosmeticTokenRemove"); } private static void ShopManager_ShopInitialize_Postfix() { RequestRefresh("ShopInitialize"); } private static void CosmeticShopMachine_Interact_Postfix() { if (RefreshOnCosmeticShopMachineInteract != null && RefreshOnCosmeticShopMachineInteract.Value) { RequestRefresh("CosmeticShopMachine.Interact"); } } private static void CosmeticShopMachine_RewardSet_Postfix() { RequestRefresh("CosmeticShopMachine.RewardSet"); } private static void CosmeticTokenUI_Setup_Postfix() { if (RefreshOnCosmeticTokenUISetup != null && RefreshOnCosmeticTokenUISetup.Value) { RequestRefresh("CosmeticTokenUI.Setup"); } } internal static List GetCosmeticTokens() { try { object metaManagerInstance = GetMetaManagerInstance(); if (metaManagerInstance == null || CosmeticTokensField == null) { return null; } return CosmeticTokensField.GetValue(metaManagerInstance) as List; } catch (Exception ex) { WriteDebugLog("Failure: GetCosmeticTokens\n" + ex); return null; } } internal static object GetMetaManagerInstance() { try { if (MetaManagerInstanceField == null) { return null; } return MetaManagerInstanceField.GetValue(null); } catch (Exception ex) { WriteDebugLog("Failure: GetMetaManagerInstance\n" + ex); return null; } } internal static bool IsSafeShopState() { try { if (RunManagerInstanceField == null || GameDirectorInstanceField == null || GameDirectorCurrentStateField == null || RunIsShopMethod == null) { return false; } object value = RunManagerInstanceField.GetValue(null); object value2 = GameDirectorInstanceField.GetValue(null); if (value == null || value2 == null) { return false; } object value3 = GameDirectorCurrentStateField.GetValue(value2); if (value3 == null || !string.Equals(value3.ToString(), "Main", StringComparison.OrdinalIgnoreCase)) { return false; } object obj = RunIsShopMethod.Invoke(null, null); return obj is bool && (bool)obj; } catch (Exception ex) { WriteDebugLog("Failure: IsSafeShopState\n" + ex); return false; } } internal static void RequestRefresh(string reason) { PendingRefresh = true; CosmeticTokenCountHUDController instance = CosmeticTokenCountHUDController.Instance; if ((Object)(object)instance != (Object)null) { instance.RequestImmediateRefresh(reason); } } internal static void WriteDebugLog(string message) { if (ShowDebugLog != null && ShowDebugLog.Value && Log != null) { Log.LogInfo((object)message); } } } internal class CosmeticTokenCountHUDController : MonoBehaviour { internal static CosmeticTokenCountHUDController Instance; private GameObject hudRoot; private Canvas hudCanvas; private RectTransform panelTransform; private Image backgroundImage; private Text titleText; private readonly List rarityTexts = new List(); private Font cachedFont; private float refreshTimer; private bool forceRefresh; private string lastSignature = string.Empty; private void Awake() { Instance = this; } private void OnDestroy() { DestroyHud("controller destroyed"); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { try { if (CosmeticTokenCountHUDPlugin.Enable == null || !CosmeticTokenCountHUDPlugin.Enable.Value) { DestroyHud("disabled"); return; } if (CosmeticTokenCountHUDPlugin.PendingRefresh) { CosmeticTokenCountHUDPlugin.PendingRefresh = false; forceRefresh = true; } if (forceRefresh) { forceRefresh = false; refreshTimer = GetRefreshInterval(); RefreshHud(); return; } refreshTimer -= Time.deltaTime; if (refreshTimer <= 0f) { refreshTimer = GetRefreshInterval(); RefreshHud(); } } catch (Exception ex) { CosmeticTokenCountHUDPlugin.WriteDebugLog("Failure: Update\n" + ex); DestroyHud("update failure"); } } internal void RequestImmediateRefresh(string reason) { forceRefresh = true; CosmeticTokenCountHUDPlugin.WriteDebugLog("Refresh requested: " + reason); } private void RefreshHud() { if (!ShouldDisplayHud()) { DestroyHud("display condition not met"); return; } List cosmeticTokens = CosmeticTokenCountHUDPlugin.GetCosmeticTokens(); if (cosmeticTokens == null) { DestroyHud("token list missing"); return; } TokenCounts counts = CountTokens(cosmeticTokens); if (CosmeticTokenCountHUDPlugin.HideWhenNoToken.Value && counts.TotalValid <= 0) { DestroyHud("no token"); return; } EnsureHudExists(); if (!((Object)(object)hudRoot == (Object)null)) { ApplyHud(counts); } } private bool ShouldDisplayHud() { if (CosmeticTokenCountHUDPlugin.GetMetaManagerInstance() == null) { return false; } if (CosmeticTokenCountHUDPlugin.ShowOnlyInShop.Value && !CosmeticTokenCountHUDPlugin.IsSafeShopState()) { return false; } return true; } private TokenCounts CountTokens(List tokens) { TokenCounts result = default(TokenCounts); for (int i = 0; i < tokens.Count; i++) { switch (tokens[i]) { case 0: result.Common++; result.TotalValid++; break; case 1: result.Uncommon++; result.TotalValid++; break; case 2: result.Rare++; result.TotalValid++; break; case 3: result.UltraRare++; result.TotalValid++; break; default: result.Invalid++; break; } } if (result.Invalid > 0) { CosmeticTokenCountHUDPlugin.WriteDebugLog("Invalid cosmetic token rarity count: " + result.Invalid); } return result; } private void EnsureHudExists() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown if ((Object)(object)hudRoot != (Object)null) { return; } try { hudRoot = new GameObject("CosmeticTokenCountHUD_Canvas"); hudCanvas = hudRoot.AddComponent(); hudCanvas.renderMode = (RenderMode)0; hudCanvas.sortingOrder = CosmeticTokenCountHUDPlugin.SortingOrder.Value; CanvasScaler val = hudRoot.AddComponent(); val.uiScaleMode = (ScaleMode)1; val.referenceResolution = new Vector2(1920f, 1080f); val.screenMatchMode = (ScreenMatchMode)0; val.matchWidthOrHeight = 0.5f; GameObject val2 = new GameObject("Panel"); val2.transform.SetParent(hudRoot.transform, false); panelTransform = val2.AddComponent(); backgroundImage = val2.AddComponent(); ((Graphic)backgroundImage).raycastTarget = false; titleText = CreateText("Title", (Transform)(object)panelTransform, isTitle: true); rarityTexts.Clear(); rarityTexts.Add(CreateText("Common", (Transform)(object)panelTransform, isTitle: false)); rarityTexts.Add(CreateText("Uncommon", (Transform)(object)panelTransform, isTitle: false)); rarityTexts.Add(CreateText("Rare", (Transform)(object)panelTransform, isTitle: false)); rarityTexts.Add(CreateText("UltraRare", (Transform)(object)panelTransform, isTitle: false)); CosmeticTokenCountHUDPlugin.WriteDebugLog("HUD created"); } catch (Exception ex) { CosmeticTokenCountHUDPlugin.WriteDebugLog("Failure: EnsureHudExists\n" + ex); DestroyHud("create failure"); } } private Text CreateText(string objectName, Transform parent, bool isTitle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); Text val3 = val.AddComponent(); val3.font = GetFont(); val3.fontSize = CosmeticTokenCountHUDPlugin.FontSize.Value; val3.fontStyle = (FontStyle)(isTitle ? 1 : 0); val3.alignment = GetTextAnchor(); val3.horizontalOverflow = (HorizontalWrapMode)1; val3.verticalOverflow = (VerticalWrapMode)1; ((Graphic)val3).raycastTarget = false; ((Graphic)val3).color = GetTextColor("#FFFFFF"); return val3; } private Font GetFont() { if ((Object)(object)cachedFont == (Object)null) { cachedFont = Resources.GetBuiltinResource("Arial.ttf"); } return cachedFont; } private void ApplyHud(TokenCounts counts) { //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) string text = BuildSignature(counts); if (text == lastSignature) { return; } lastSignature = text; if ((Object)(object)hudCanvas != (Object)null) { hudCanvas.sortingOrder = CosmeticTokenCountHUDPlugin.SortingOrder.Value; } List list = BuildRarityLines(counts); int num = Mathf.Clamp(CosmeticTokenCountHUDPlugin.FontSize.Value, 8, 48); float num2 = Mathf.Clamp(CosmeticTokenCountHUDPlugin.PaddingX.Value, 0f, 60f); float num3 = Mathf.Clamp(CosmeticTokenCountHUDPlugin.PaddingY.Value, 0f, 60f); float num4 = Mathf.Clamp(CosmeticTokenCountHUDPlugin.LineSpacing.Value, 0f, 24f); float num5 = (float)num + 6f; int num6 = 1 + list.Count; float num7 = Mathf.Clamp(CosmeticTokenCountHUDPlugin.Width.Value, 120f, 800f); if (CosmeticTokenCountHUDPlugin.AutoResizeWidth.Value) { int maxTextLength = GetMaxTextLength(list); float num8 = (float)maxTextLength * (float)num * 0.62f + num2 * 2f; num7 = Mathf.Clamp(Mathf.Max(num7, num8), 120f, 1000f); } float height = num3 * 2f + (float)num6 * num5 + (float)Mathf.Max(0, num6 - 1) * num4; ApplyPanelTransform(num7, height); if ((Object)(object)backgroundImage != (Object)null) { ((Graphic)backgroundImage).color = GetBackgroundColor(); } ApplyTextTransform(titleText, CosmeticTokenCountHUDPlugin.TitleText.Value, GetTextColor("#FFFFFF"), num2, num3, num7, num5, num, 0); for (int i = 0; i < rarityTexts.Count; i++) { if (i < list.Count) { ((Component)rarityTexts[i]).gameObject.SetActive(true); ApplyTextTransform(rarityTexts[i], list[i].Text, list[i].Color, num2, num3, num7, num5, num, i + 1); } else { ((Component)rarityTexts[i]).gameObject.SetActive(false); } } CosmeticTokenCountHUDPlugin.WriteDebugLog("HUD refreshed: Common=" + counts.Common + ", Uncommon=" + counts.Uncommon + ", Rare=" + counts.Rare + ", UltraRare=" + counts.UltraRare); } private void ApplyPanelTransform(float width, float height) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)panelTransform == (Object)null)) { switch (CosmeticTokenCountHUDPlugin.Anchor.Value) { case HudAnchor.TopLeft: panelTransform.anchorMin = new Vector2(0f, 1f); panelTransform.anchorMax = new Vector2(0f, 1f); panelTransform.pivot = new Vector2(0f, 1f); break; case HudAnchor.TopRight: panelTransform.anchorMin = new Vector2(1f, 1f); panelTransform.anchorMax = new Vector2(1f, 1f); panelTransform.pivot = new Vector2(1f, 1f); break; case HudAnchor.BottomLeft: panelTransform.anchorMin = new Vector2(0f, 0f); panelTransform.anchorMax = new Vector2(0f, 0f); panelTransform.pivot = new Vector2(0f, 0f); break; default: panelTransform.anchorMin = new Vector2(1f, 0f); panelTransform.anchorMax = new Vector2(1f, 0f); panelTransform.pivot = new Vector2(1f, 0f); break; } panelTransform.sizeDelta = new Vector2(width, height); panelTransform.anchoredPosition = new Vector2(CosmeticTokenCountHUDPlugin.OffsetX.Value, CosmeticTokenCountHUDPlugin.OffsetY.Value); } } private void ApplyTextTransform(Text text, string value, Color color, float paddingX, float paddingY, float width, float lineHeight, int fontSize, int index) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)text == (Object)null)) { text.text = value; ((Graphic)text).color = color; text.fontSize = fontSize; text.alignment = GetTextAnchor(); RectTransform component = ((Component)text).GetComponent(); component.sizeDelta = new Vector2(width - paddingX * 2f, lineHeight + 2f); component.anchoredPosition = new Vector2(paddingX, 0f - paddingY - (float)index * (lineHeight + CosmeticTokenCountHUDPlugin.LineSpacing.Value)); } } private List BuildRarityLines(TokenCounts counts) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) List displayOrder = GetDisplayOrder(); List list = new List(); for (int i = 0; i < displayOrder.Count; i++) { int rarity = displayOrder[i]; int countByRarity = GetCountByRarity(counts, rarity); if (CosmeticTokenCountHUDPlugin.ShowZeroCountRarity.Value || countByRarity > 0) { string labelByRarity = GetLabelByRarity(rarity); string text = labelByRarity + ": " + countByRarity; Color colorByRarity = GetColorByRarity(rarity); list.Add(new RarityLine(text, colorByRarity)); } } return list; } private List GetDisplayOrder() { List list = new List(); switch (CosmeticTokenCountHUDPlugin.DisplayOrder.Value) { case DisplayOrderMode.HighToLow: list.Add(3); list.Add(2); list.Add(1); list.Add(0); break; case DisplayOrderMode.Custom: list = ParseCustomDisplayOrder(); break; default: list.Add(0); list.Add(1); list.Add(2); list.Add(3); break; } if (list.Count == 0) { list.Add(0); list.Add(1); list.Add(2); list.Add(3); } return list; } private List ParseCustomDisplayOrder() { List list = new List(); string value = CosmeticTokenCountHUDPlugin.CustomDisplayOrder.Value; if (string.IsNullOrEmpty(value)) { return list; } string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { int num = ParseRarityName(array[i].Trim()); if (num >= 0 && !list.Contains(num)) { list.Add(num); } } return list; } private int ParseRarityName(string value) { if (string.Equals(value, "Common", StringComparison.OrdinalIgnoreCase)) { return 0; } if (string.Equals(value, "Uncommon", StringComparison.OrdinalIgnoreCase)) { return 1; } if (string.Equals(value, "Rare", StringComparison.OrdinalIgnoreCase)) { return 2; } if (string.Equals(value, "UltraRare", StringComparison.OrdinalIgnoreCase) || string.Equals(value, "Ultra Rare", StringComparison.OrdinalIgnoreCase)) { return 3; } return -1; } private int GetCountByRarity(TokenCounts counts, int rarity) { return rarity switch { 0 => counts.Common, 1 => counts.Uncommon, 2 => counts.Rare, 3 => counts.UltraRare, _ => 0, }; } private string GetLabelByRarity(int rarity) { return rarity switch { 0 => CosmeticTokenCountHUDPlugin.CommonLabel.Value, 1 => CosmeticTokenCountHUDPlugin.UncommonLabel.Value, 2 => CosmeticTokenCountHUDPlugin.RareLabel.Value, 3 => CosmeticTokenCountHUDPlugin.UltraRareLabel.Value, _ => "Unknown", }; } private Color GetColorByRarity(int rarity) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (!CosmeticTokenCountHUDPlugin.UseRarityTextColor.Value) { return GetTextColor("#FFFFFF"); } return (Color)(rarity switch { 0 => GetTextColor(CosmeticTokenCountHUDPlugin.CommonColor.Value), 1 => GetTextColor(CosmeticTokenCountHUDPlugin.UncommonColor.Value), 2 => GetTextColor(CosmeticTokenCountHUDPlugin.RareColor.Value), 3 => GetTextColor(CosmeticTokenCountHUDPlugin.UltraRareColor.Value), _ => GetTextColor("#FFFFFF"), }); } private Color GetTextColor(string hex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Color result = ParseColor(hex, Color.white); result.a = Mathf.Clamp(CosmeticTokenCountHUDPlugin.TextOpacity.Value, 0.1f, 1f); return result; } private Color GetBackgroundColor() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Color result = ParseColor(CosmeticTokenCountHUDPlugin.BackgroundColor.Value, Color.black); result.a = Mathf.Clamp01(CosmeticTokenCountHUDPlugin.BackgroundOpacity.Value); return result; } private Color ParseColor(string hex, Color fallback) { //IL_0008: 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_0034: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(hex)) { return fallback; } string text = hex.Trim(); if (!text.StartsWith("#")) { text = "#" + text; } Color result = default(Color); if (ColorUtility.TryParseHtmlString(text, ref result)) { return result; } return fallback; } private TextAnchor GetTextAnchor() { return (TextAnchor)(CosmeticTokenCountHUDPlugin.TextAlign.Value switch { HudTextAlign.Center => 1, HudTextAlign.Right => 2, _ => 0, }); } private int GetMaxTextLength(List lines) { int num = 0; if (!string.IsNullOrEmpty(CosmeticTokenCountHUDPlugin.TitleText.Value)) { num = CosmeticTokenCountHUDPlugin.TitleText.Value.Length; } for (int i = 0; i < lines.Count; i++) { if (!string.IsNullOrEmpty(lines[i].Text) && lines[i].Text.Length > num) { num = lines[i].Text.Length; } } return num; } private string BuildSignature(TokenCounts counts) { return counts.Common + "|" + counts.Uncommon + "|" + counts.Rare + "|" + counts.UltraRare + "|" + CosmeticTokenCountHUDPlugin.ShowZeroCountRarity.Value + "|" + CosmeticTokenCountHUDPlugin.Anchor.Value.ToString() + "|" + CosmeticTokenCountHUDPlugin.OffsetX.Value + "|" + CosmeticTokenCountHUDPlugin.OffsetY.Value + "|" + CosmeticTokenCountHUDPlugin.FontSize.Value + "|" + CosmeticTokenCountHUDPlugin.BackgroundOpacity.Value + "|" + CosmeticTokenCountHUDPlugin.TextOpacity.Value + "|" + CosmeticTokenCountHUDPlugin.SortingOrder.Value + "|" + CosmeticTokenCountHUDPlugin.LineSpacing.Value + "|" + CosmeticTokenCountHUDPlugin.PaddingX.Value + "|" + CosmeticTokenCountHUDPlugin.PaddingY.Value + "|" + CosmeticTokenCountHUDPlugin.Width.Value + "|" + CosmeticTokenCountHUDPlugin.AutoResizeWidth.Value + "|" + CosmeticTokenCountHUDPlugin.TextAlign.Value.ToString() + "|" + CosmeticTokenCountHUDPlugin.DisplayOrder.Value.ToString() + "|" + CosmeticTokenCountHUDPlugin.CustomDisplayOrder.Value + "|" + CosmeticTokenCountHUDPlugin.TitleText.Value + "|" + CosmeticTokenCountHUDPlugin.CommonLabel.Value + "|" + CosmeticTokenCountHUDPlugin.UncommonLabel.Value + "|" + CosmeticTokenCountHUDPlugin.RareLabel.Value + "|" + CosmeticTokenCountHUDPlugin.UltraRareLabel.Value + "|" + CosmeticTokenCountHUDPlugin.UseRarityTextColor.Value + "|" + CosmeticTokenCountHUDPlugin.CommonColor.Value + "|" + CosmeticTokenCountHUDPlugin.UncommonColor.Value + "|" + CosmeticTokenCountHUDPlugin.RareColor.Value + "|" + CosmeticTokenCountHUDPlugin.UltraRareColor.Value + "|" + CosmeticTokenCountHUDPlugin.BackgroundColor.Value; } private float GetRefreshInterval() { if (CosmeticTokenCountHUDPlugin.RefreshIntervalSeconds == null) { return 0.35f; } return Mathf.Clamp(CosmeticTokenCountHUDPlugin.RefreshIntervalSeconds.Value, 0.1f, 2f); } private void DestroyHud(string reason) { if ((Object)(object)hudRoot != (Object)null) { Object.Destroy((Object)(object)hudRoot); hudRoot = null; hudCanvas = null; panelTransform = null; backgroundImage = null; titleText = null; rarityTexts.Clear(); lastSignature = string.Empty; CosmeticTokenCountHUDPlugin.WriteDebugLog("HUD destroyed: " + reason); } } } internal struct TokenCounts { internal int Common; internal int Uncommon; internal int Rare; internal int UltraRare; internal int TotalValid; internal int Invalid; } internal struct RarityLine { internal readonly string Text; internal readonly Color Color; internal RarityLine(string text, Color color) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Text = text; Color = color; } } public enum HudAnchor { TopLeft, TopRight, BottomLeft, BottomRight } public enum HudTextAlign { Left, Center, Right } public enum DisplayOrderMode { LowToHigh, HighToLow, Vanilla, Custom } }