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 CosmeticTokenCountHUD v4.0.0
CosmeticTokenCountHUD.dll
Decompiled 2 days agousing 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<bool> Enable; internal static ConfigEntry<bool> ShowDebugLog; internal static ConfigEntry<float> RefreshIntervalSeconds; internal static ConfigEntry<bool> ShowOnlyInShop; internal static ConfigEntry<bool> HideWhenNoToken; internal static ConfigEntry<bool> ShowZeroCountRarity; internal static ConfigEntry<HudAnchor> Anchor; internal static ConfigEntry<float> OffsetX; internal static ConfigEntry<float> OffsetY; internal static ConfigEntry<int> FontSize; internal static ConfigEntry<float> BackgroundOpacity; internal static ConfigEntry<float> TextOpacity; internal static ConfigEntry<int> SortingOrder; internal static ConfigEntry<float> LineSpacing; internal static ConfigEntry<float> PaddingX; internal static ConfigEntry<float> PaddingY; internal static ConfigEntry<float> Width; internal static ConfigEntry<bool> AutoResizeWidth; internal static ConfigEntry<HudTextAlign> TextAlign; internal static ConfigEntry<DisplayOrderMode> DisplayOrder; internal static ConfigEntry<string> CustomDisplayOrder; internal static ConfigEntry<string> TitleText; internal static ConfigEntry<string> CommonLabel; internal static ConfigEntry<string> UncommonLabel; internal static ConfigEntry<string> RareLabel; internal static ConfigEntry<string> UltraRareLabel; internal static ConfigEntry<bool> UseRarityTextColor; internal static ConfigEntry<string> CommonColor; internal static ConfigEntry<string> UncommonColor; internal static ConfigEntry<string> RareColor; internal static ConfigEntry<string> UltraRareColor; internal static ConfigEntry<string> BackgroundColor; internal static ConfigEntry<bool> RefreshOnCosmeticTokenUISetup; internal static ConfigEntry<bool> 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<CosmeticTokenCountHUDController>() == (Object)null) { ((Component)this).gameObject.AddComponent<CosmeticTokenCountHUDController>(); } 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<bool>("General", "Enable", true, "Enable the HUD display.HUD表示を有効化します"); ShowDebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDebugLog", false, "Show debug logs.デバッグログを表示します"); RefreshIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RefreshIntervalSeconds", 0.35f, new ConfigDescription("Refresh interval in seconds.更新間隔の秒数です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>())); ShowOnlyInShop = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowOnlyInShop", true, "Show only while you are in the shop.ショップ中のみ表示します"); HideWhenNoToken = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "HideWhenNoToken", true, "Hide the HUD when you have no cosmetic tokens.コスメトークンを持っていない時にHUDを非表示にします"); ShowZeroCountRarity = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowZeroCountRarity", true, "Show rarity rows even when the count is zero.0枚のレアリティも表示します"); Anchor = ((BaseUnityPlugin)this).Config.Bind<HudAnchor>("Display", "Anchor", HudAnchor.BottomRight, "HUD anchor position.HUDの基準位置です"); OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "OffsetX", -40f, "Horizontal offset from the anchor.基準位置からの横方向オフセットです"); OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "OffsetY", 160f, "Vertical offset from the anchor.基準位置からの縦方向オフセットです"); FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "FontSize", 18, new ConfigDescription("Text font size.文字サイズです", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 48), Array.Empty<object>())); BackgroundOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "BackgroundOpacity", 0.35f, new ConfigDescription("Background opacity.背景の不透明度です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); TextOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "TextOpacity", 1f, new ConfigDescription("Text opacity.文字の不透明度です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); SortingOrder = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "SortingOrder", 300, new ConfigDescription("Canvas sorting order.Canvasの描画順です", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())); LineSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "LineSpacing", 4f, new ConfigDescription("Spacing between lines.行間です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 24f), Array.Empty<object>())); PaddingX = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "PaddingX", 12f, new ConfigDescription("Horizontal padding.横方向の余白です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); PaddingY = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "PaddingY", 10f, new ConfigDescription("Vertical padding.縦方向の余白です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); Width = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "Width", 260f, new ConfigDescription("HUD width.HUDの横幅です", (AcceptableValueBase)(object)new AcceptableValueRange<float>(120f, 800f), Array.Empty<object>())); AutoResizeWidth = ((BaseUnityPlugin)this).Config.Bind<bool>("Layout", "AutoResizeWidth", true, "Automatically widen the HUD when text is long.文字が長い場合にHUDの横幅を自動調整します"); TextAlign = ((BaseUnityPlugin)this).Config.Bind<HudTextAlign>("Layout", "TextAlign", HudTextAlign.Left, "Text alignment.文字揃えです"); DisplayOrder = ((BaseUnityPlugin)this).Config.Bind<DisplayOrderMode>("Layout", "DisplayOrder", DisplayOrderMode.LowToHigh, "Rarity display order.レアリティの表示順です"); CustomDisplayOrder = ((BaseUnityPlugin)this).Config.Bind<string>("Layout", "CustomDisplayOrder", "Common,Uncommon,Rare,UltraRare", "Custom display order when DisplayOrder is Custom.DisplayOrderがCustomの時の表示順です"); TitleText = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "TitleText", "Cosmetic Tokens", "HUD title text.HUDタイトル文字列です"); CommonLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "CommonLabel", "Common", "Common rarity label.Commonレアリティの表示名です"); UncommonLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "UncommonLabel", "Uncommon", "Uncommon rarity label.Uncommonレアリティの表示名です"); RareLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "RareLabel", "Rare", "Rare rarity label.Rareレアリティの表示名です"); UltraRareLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "UltraRareLabel", "UltraRare", "UltraRare rarity label.UltraRareレアリティの表示名です"); UseRarityTextColor = ((BaseUnityPlugin)this).Config.Bind<bool>("Color", "UseRarityTextColor", true, "Use different text colors for each rarity.レアリティごとに文字色を変えます"); CommonColor = ((BaseUnityPlugin)this).Config.Bind<string>("Color", "CommonColor", "#00C807", "Common text color in hex.Common文字色の16進数指定です"); UncommonColor = ((BaseUnityPlugin)this).Config.Bind<string>("Color", "UncommonColor", "#0398CB", "Uncommon text color in hex.Uncommon文字色の16進数指定です"); RareColor = ((BaseUnityPlugin)this).Config.Bind<string>("Color", "RareColor", "#BD06BB", "Rare text color in hex.Rare文字色の16進数指定です"); UltraRareColor = ((BaseUnityPlugin)this).Config.Bind<string>("Color", "UltraRareColor", "#B89005", "UltraRare text color in hex.UltraRare文字色の16進数指定です"); BackgroundColor = ((BaseUnityPlugin)this).Config.Bind<string>("Color", "BackgroundColor", "#000000", "Background color in hex.背景色の16進数指定です"); ApplyTokenColorDefaults(); RefreshOnCosmeticTokenUISetup = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "RefreshOnCosmeticTokenUISetup", false, "Refresh when vanilla CosmeticTokenUI is refreshed.バニラのCosmeticTokenUI更新時にHUDも更新します"); RefreshOnCosmeticShopMachineInteract = ((BaseUnityPlugin)this).Config.Bind<bool>("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<string> 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<int> GetCosmeticTokens() { try { object metaManagerInstance = GetMetaManagerInstance(); if (metaManagerInstance == null || CosmeticTokensField == null) { return null; } return CosmeticTokensField.GetValue(metaManagerInstance) as List<int>; } 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<Text> rarityTexts = new List<Text>(); 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<int> 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<int> 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<Canvas>(); hudCanvas.renderMode = (RenderMode)0; hudCanvas.sortingOrder = CosmeticTokenCountHUDPlugin.SortingOrder.Value; CanvasScaler val = hudRoot.AddComponent<CanvasScaler>(); 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<RectTransform>(); backgroundImage = val2.AddComponent<Image>(); ((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<RectTransform>(); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); Text val3 = val.AddComponent<Text>(); 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<Font>("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<RarityLine> 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<RectTransform>(); component.sizeDelta = new Vector2(width - paddingX * 2f, lineHeight + 2f); component.anchoredPosition = new Vector2(paddingX, 0f - paddingY - (float)index * (lineHeight + CosmeticTokenCountHUDPlugin.LineSpacing.Value)); } } private List<RarityLine> 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<int> displayOrder = GetDisplayOrder(); List<RarityLine> list = new List<RarityLine>(); 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<int> GetDisplayOrder() { List<int> list = new List<int>(); 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<int> ParseCustomDisplayOrder() { List<int> list = new List<int>(); 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<RarityLine> 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 } }