Decompiled source of QualityStars v1.0.0

QualityStars.dll

Decompiled 3 days ago
using 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);
			}
		}
	}
}