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 QualityStars v1.0.0
QualityStars.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace QualityStars; [BepInPlugin("morbi.qualitystars", "Quality Stars", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "morbi.qualitystars"; internal const string StarName = "QS_Stars"; internal static Plugin Inst; internal static ManualLogSource Log; internal static ConfigEntry<bool> CfgEnabled; internal static ConfigEntry<float> CfgSize; internal static ConfigEntry<float> CfgSpacing; internal static ConfigEntry<string> CfgColor; internal static ConfigEntry<float> CfgOffsetX; internal static ConfigEntry<float> CfgOffsetY; internal static ConfigEntry<bool> CfgShadow; internal static int Version = 1; internal static Color StarColor = new Color(1f, 0.72f, 0.36f, 1f); internal static Sprite StarSprite; private void Awake() { //IL_017c: Unknown result type (might be due to invalid IL or missing references) Inst = this; Log = ((BaseUnityPlugin)this).Logger; CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Show quality as stars instead of the number."); CfgSize = ((BaseUnityPlugin)this).Config.Bind<float>("Look", "StarSize", 11f, "Size of one star in pixels."); CfgSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Look", "Spacing", 0f, "Gap between stars in pixels (negative = overlap)."); CfgColor = ((BaseUnityPlugin)this).Config.Bind<string>("Look", "Color", "#FFB75C", "Star color as HTML color (#RRGGBB). Default is the vanilla orange."); CfgOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Look", "OffsetX", -2f, "Horizontal offset of the star row from the slot's top-right corner."); CfgOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Look", "OffsetY", -2f, "Vertical offset of the star row from the slot's top-right corner."); CfgShadow = ((BaseUnityPlugin)this).Config.Bind<bool>("Look", "Shadow", true, "Draw a thin dark shadow behind the stars so they stay readable."); ReadColor(); EventHandler eventHandler = delegate { ReadColor(); Version++; }; CfgEnabled.SettingChanged += eventHandler; CfgSize.SettingChanged += eventHandler; CfgSpacing.SettingChanged += eventHandler; CfgColor.SettingChanged += eventHandler; CfgOffsetX.SettingChanged += eventHandler; CfgOffsetY.SettingChanged += eventHandler; CfgShadow.SettingChanged += eventHandler; new Harmony("morbi.qualitystars").PatchAll(typeof(GridPatch)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Quality Stars loaded."); } private static void ReadColor() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Color starColor = default(Color); if (ColorUtility.TryParseHtmlString(CfgColor.Value, ref starColor)) { StarColor = starColor; } else { StarColor = new Color(1f, 0.72f, 0.36f, 1f); } } internal static Sprite GetStarSprite() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_0156: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StarSprite != (Object)null) { return StarSprite; } Vector2[] array = (Vector2[])(object)new Vector2[10]; float num = 32f; float num2 = 34f; float num3 = 30.72f; float num4 = num3 * 0.4f; for (int i = 0; i < 10; i++) { float num5 = (float)Math.PI / 2f + (float)i * (float)Math.PI / 5f; float num6 = ((i % 2 == 0) ? num3 : num4); array[i] = new Vector2(num + Mathf.Cos(num5) * num6, num2 + Mathf.Sin(num5) * num6); } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int j = 0; j < 64; j++) { for (int k = 0; k < 64; k++) { int num7 = 0; for (int l = 0; l < 4; l++) { for (int m = 0; m < 4; m++) { float x = (float)k + ((float)m + 0.5f) / 4f; float y = (float)j + ((float)l + 0.5f) / 4f; if (Inside(array, x, y)) { num7++; } } } byte b = (byte)(255 * num7 / 16); array2[j * 64 + k] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array2); val.Apply(); StarSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f); ((Object)StarSprite).name = "QS_Star"; return StarSprite; } private static bool Inside(Vector2[] p, float x, float y) { bool flag = false; int num = 0; int num2 = p.Length - 1; while (num < p.Length) { if (p[num].y > y != p[num2].y > y && x < (p[num2].x - p[num].x) * (y - p[num].y) / (p[num2].y - p[num].y) + p[num].x) { flag = !flag; } num2 = num++; } return flag; } } internal static class GridPatch { private static FieldInfo _elementsField; private static FieldInfo _invField; private static readonly Dictionary<Type, FieldInfo> QualityFields = new Dictionary<Type, FieldInfo>(); private static readonly Dictionary<int, long> State = new Dictionary<int, long>(); private static bool _failedLogged; private static readonly Dictionary<Type, FieldInfo[]> UsedFields = new Dictionary<Type, FieldInfo[]>(); [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] [HarmonyPostfix] private static void Postfix(InventoryGrid __instance) { try { if (_elementsField == null) { _elementsField = AccessTools.Field(typeof(InventoryGrid), "m_elements"); } if (_elementsField == null || !(_elementsField.GetValue(__instance) is IList list)) { return; } if (_invField == null) { _invField = AccessTools.Field(typeof(InventoryGrid), "m_inventory"); } Inventory val = (Inventory)((_invField != null) ? /*isinst with value type is only supported in some contexts*/: null); int num = ((val != null) ? val.GetWidth() : 0); for (int i = 0; i < list.Count; i++) { object obj = list[i]; if (obj != null) { ItemData item = null; if (val != null && num > 0) { item = val.GetItemAt(i % num, i / num); } Handle(obj, item); } } } catch (Exception ex) { if (!_failedLogged) { _failedLogged = true; Plugin.Log.LogWarning((object)("Quality Stars: " + ex)); } } } private static void Handle(object el, ItemData item) { //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) Type type = el.GetType(); if (!QualityFields.TryGetValue(type, out var value)) { value = AccessTools.Field(type, "m_quality"); QualityFields[type] = value; } if (value == null) { return; } object? value2 = value.GetValue(el); TMP_Text val = (TMP_Text)((value2 is TMP_Text) ? value2 : null); Text val2 = (Text)((value2 is Text) ? value2 : null); Component val3 = (Component)(((Object)(object)val != (Object)null) ? ((object)val) : ((object)val2)); if ((Object)(object)val3 == (Object)null) { return; } bool value3 = Plugin.CfgEnabled.Value; Transform val4 = val3.transform.Find("QS_Stars"); if (!value3) { if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = true; } if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = true; } if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(false); } return; } if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = false; } if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = false; } bool flag = val3.gameObject.activeSelf && IsEquipment(item); if (!int.TryParse(((Object)(object)val != (Object)null) ? val.text : val2.text, out var result)) { result = 0; } if (result > 12) { result = 12; } if (result < 2) { flag = false; } if (!flag) { if ((Object)(object)val4 != (Object)null && ((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(false); } return; } GameObject val5; if ((Object)(object)val4 == (Object)null) { val5 = new GameObject("QS_Stars", new Type[1] { typeof(RectTransform) }); val5.layer = val3.gameObject.layer; RectTransform component = val5.GetComponent<RectTransform>(); ((Transform)component).SetParent(val3.transform, false); component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 1f); component.sizeDelta = Vector2.zero; component.anchoredPosition = Vector2.zero; } else { val5 = ((Component)val4).gameObject; if (!val5.activeSelf) { val5.SetActive(true); } } int instanceID = ((Object)val5).GetInstanceID(); long num = (long)result * 100000L + Plugin.Version; if (!State.TryGetValue(instanceID, out var value4) || value4 != num) { State[instanceID] = num; Rebuild(val5, result); } } private static bool IsEquipment(ItemData item) { if (item == null || item.m_shared == null) { return false; } switch (((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString()) { case "OneHandedWeapon": case "TwoHandedWeapon": case "Helmet": case "Shield": case "Chest": case "Torch": case "Legs": case "Tool": case "Trinket": case "Utility": case "TwoHandedWeaponLeft": case "Bow": case "Shoulder": case "Attach_Atgeir": return true; default: return false; } } private static bool SlotUsed(object el) { Type type = el.GetType(); if (!UsedFields.TryGetValue(type, out var value)) { value = new FieldInfo[2] { AccessTools.Field(type, "m_used"), AccessTools.Field(type, "m_icon") }; UsedFields[type] = value; } if (value[0] != null && value[0].FieldType == typeof(bool)) { return (bool)value[0].GetValue(el); } if (value[1] != null) { object? value2 = value[1].GetValue(el); Image val = (Image)((value2 is Image) ? value2 : null); if ((Object)(object)val != (Object)null) { if (((Behaviour)val).enabled) { return (Object)(object)val.sprite != (Object)null; } return false; } } return true; } private static void Rebuild(GameObject box, int quality) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) Transform transform = box.transform; for (int num = transform.childCount - 1; num >= 0; num--) { GameObject gameObject = ((Component)transform.GetChild(num)).gameObject; gameObject.SetActive(false); Object.Destroy((Object)(object)gameObject); } if (quality < 1) { return; } float num2 = Mathf.Max(2f, Plugin.CfgSize.Value); float num3 = num2 + Plugin.CfgSpacing.Value; Sprite starSprite = Plugin.GetStarSprite(); for (int i = 0; i < quality; i++) { GameObject val = new GameObject("S" + i, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.layer = box.layer; RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(transform, false); component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 1f); component.sizeDelta = new Vector2(num2, num2); component.anchoredPosition = new Vector2(Plugin.CfgOffsetX.Value - (float)i * num3, Plugin.CfgOffsetY.Value); Image component2 = val.GetComponent<Image>(); component2.sprite = starSprite; ((Graphic)component2).color = Plugin.StarColor; ((Graphic)component2).raycastTarget = false; if (Plugin.CfgShadow.Value) { Shadow obj = val.AddComponent<Shadow>(); obj.effectColor = new Color(0f, 0f, 0f, 0.75f); obj.effectDistance = new Vector2(1f, -1f); } } } }