Decompiled source of StatusEffectFilter v1.0.1

StatusEffectFilter.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using StatusEffectFilter.ConfigManagerEntry;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("StatusEffectFilter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("StatusEffectFilter")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 StatusEffectFilter
{
	[BepInPlugin("Azumatt.StatusEffectFilter", "StatusEffectFilter", "1.0.1")]
	public class StatusEffectFilterPlugin : BaseUnityPlugin
	{
		internal class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			public string? Category;

			[UsedImplicitly]
			public Action<ConfigEntryBase>? CustomDrawer;

			[UsedImplicitly]
			public bool? HideDefaultButton;
		}

		internal const string ModName = "StatusEffectFilter";

		internal const string ModVersion = "1.0.1";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.StatusEffectFilter";

		private static string ConfigFileName = "Azumatt.StatusEffectFilter.cfg";

		private static string ConfigFileFullPath;

		private readonly Harmony _harmony = new Harmony("Azumatt.StatusEffectFilter");

		public static readonly ManualLogSource StatusEffectFilterLogger;

		internal static ConfigEntry<string> ExcludedStatusEffects;

		public void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			ExcludedStatusEffects = config("HUD", "ExcludedStatusEffects", "LocalizedExample=On,$tokenized_example=Off", new ConfigDescription("List of status effects to exclude from HUD. You can use localized names or tokenized for the status effect. Make sure to use =On to enable and =Off to disable. Default values are examples of how to do this directly in the configuration file. The configuration manager will allow you to select these much faster!", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = ToggleStringListConfigEntry.Drawer
				}
			}));
			ExcludedStatusEffects.SettingChanged += delegate
			{
				ToggleStringListConfigEntry.ToggledStringValues();
			};
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
			ExcludedStatusEffects.SettingChanged -= delegate
			{
				ToggleStringListConfigEntry.ToggledStringValues();
			};
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				StatusEffectFilterLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch (Exception ex)
			{
				StatusEffectFilterLogger.LogError((object)("Error loading " + ConfigFileName + ": " + ex.Message));
			}
		}

		internal ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
		}

		internal ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		static StatusEffectFilterPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			StatusEffectFilterLogger = Logger.CreateLogSource("StatusEffectFilter");
			ExcludedStatusEffects = null;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "Start")]
	internal static class FejdStartupStartPatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			Setup();
		}

		private static void Setup()
		{
			ToggleStringListConfigEntry.AutoCompleteLabel = new AutoCompleteBox(GetStatusEffectNames);
			AutoCompleteBox.InitializeCacheIfNeeded();
		}

		private static IEnumerable<string> GetStatusEffectNames()
		{
			if ((Object)(object)ObjectDB.m_instance == (Object)null)
			{
				return new string[1] { "" };
			}
			StatusEffectSpriteManager.Instance.Initialize();
			return ObjectDB.m_instance.m_StatusEffects.Where(delegate(StatusEffect statusEffect)
			{
				if ((Object)(object)statusEffect.m_icon != (Object)null)
				{
					string name = statusEffect.m_name;
					if (name != null && name.Length > 0)
					{
						return !string.IsNullOrEmpty(statusEffect.m_name);
					}
				}
				return false;
			}).SelectMany((StatusEffect statusEffect) => new string[2]
			{
				statusEffect.m_name,
				Localization.instance.Localize(statusEffect.m_name)
			}).Distinct();
		}
	}
	[HarmonyPatch(typeof(Hud), "UpdateStatusEffects")]
	public static class HudUpdateStatusEffectsPatch
	{
		private static bool Prefix(ref List<StatusEffect> statusEffects)
		{
			statusEffects = FilterStatusEffects(statusEffects);
			return true;
		}

		private static List<StatusEffect> FilterStatusEffects(List<StatusEffect> originalEffects)
		{
			string[] excludedStatusEffects = (from s in StatusEffectFilterPlugin.ExcludedStatusEffects.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim() into s
				where s.EndsWith("=On")
				select s.Split(new char[1] { '=' })[0]).ToArray();
			return originalEffects.Where((StatusEffect effect) => !excludedStatusEffects.Contains(effect.m_name) && !excludedStatusEffects.Contains(Localization.instance.Localize(effect.m_name))).ToList();
		}
	}
	public class StatusEffectSpriteManager
	{
		private static StatusEffectSpriteManager _instance;

		private Dictionary<string, Sprite> _sprites;

		public static StatusEffectSpriteManager Instance => _instance ?? (_instance = new StatusEffectSpriteManager());

		private StatusEffectSpriteManager()
		{
			LoadSprites();
		}

		public void Initialize()
		{
			LoadSprites();
		}

		private void LoadSprites()
		{
			_sprites = new Dictionary<string, Sprite>();
			foreach (StatusEffect statusEffect in ObjectDB.m_instance.m_StatusEffects)
			{
				AddSprite(statusEffect.m_name, statusEffect.m_icon);
				AddSprite(Localization.instance.Localize(statusEffect.m_name), statusEffect.m_icon);
			}
		}

		private void AddSprite(string name, Sprite icon)
		{
			if (!string.IsNullOrEmpty(name) && (Object)(object)icon != (Object)null && !_sprites.ContainsKey(name))
			{
				_sprites[name] = icon;
			}
		}

		public Sprite GetSprite(string statusEffectName)
		{
			if (_sprites.TryGetValue(statusEffectName, out Sprite value))
			{
				return value;
			}
			string key = Localization.instance.Localize(statusEffectName);
			if (!_sprites.TryGetValue(key, out value))
			{
				return null;
			}
			return value;
		}
	}
}
namespace StatusEffectFilter.ConfigManagerEntry
{
	public class AutoCompleteBox
	{
		private static Func<IEnumerable<string>> _optionsFunc;

		private static List<string> _options;

		private readonly List<string> _currentOptions;

		private string _value;

		private Vector2 _scrollPosition;

		private static List<string> _sortedOptionsCache;

		private static bool _isCacheInitialized;

		public AutoCompleteBox(Func<IEnumerable<string>> optionsFunc)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			_optionsFunc = optionsFunc;
			List<string> list = new List<string>();
			foreach (string item in _optionsFunc())
			{
				list.Add(item);
			}
			_options = list;
			list = new List<string>();
			foreach (string option in _options)
			{
				list.Add(option);
			}
			_currentOptions = list;
			_value = string.Empty;
			_scrollPosition = Vector2.zero;
			list = new List<string>();
			foreach (string item2 in _options.OrderBy((string option) => !option.StartsWith(Localization.instance.Localize(option))))
			{
				list.Add(item2);
			}
			_sortedOptionsCache = list;
			_isCacheInitialized = true;
		}

		internal static void InitializeCacheIfNeeded()
		{
			if (_isCacheInitialized)
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (string item in _optionsFunc())
			{
				list.Add(item);
			}
			_options = list;
			_sortedOptionsCache = _options.OrderBy((string option) => !option.StartsWith(Localization.instance.Localize(option))).ToList();
			_isCacheInitialized = true;
		}

		public string DrawBox(string value)
		{
			if (_value != value)
			{
				_value = value;
				UpdateCurrentOptions();
				return DrawCurrentOptions();
			}
			return DrawCurrentOptions();
		}

		private void UpdateCurrentOptions()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			_currentOptions.Clear();
			IEnumerable<string> enumerable;
			if (!string.IsNullOrEmpty(_value))
			{
				enumerable = FilterOptions(_value);
			}
			else
			{
				IEnumerable<string> sortedOptionsCache = _sortedOptionsCache;
				enumerable = sortedOptionsCache;
			}
			IEnumerable<string> collection = enumerable;
			_currentOptions.AddRange(collection);
			_scrollPosition = Vector2.zero;
		}

		private IEnumerable<string> FilterOptions(string filter)
		{
			string filter2 = filter;
			return _options.Where((string option) => option.StartsWith(filter2, StringComparison.InvariantCultureIgnoreCase));
		}

		private string DrawCurrentOptions()
		{
			//IL_0002: 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)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			_scrollPosition = GUILayout.BeginScrollView(_scrollPosition, GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(250f)
			});
			string result = string.Empty;
			foreach (string currentOption in _currentOptions)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				Sprite sprite = StatusEffectSpriteManager.Instance.GetSprite(currentOption);
				if ((Object)(object)sprite != (Object)null)
				{
					Rect textureRect = sprite.textureRect;
					GUI.DrawTextureWithTexCoords(GUILayoutUtility.GetRect(((Rect)(ref textureRect)).width, ((Rect)(ref textureRect)).height), (Texture)(object)sprite.texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)sprite.texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)sprite.texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)sprite.texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)sprite.texture).height));
					GUILayout.FlexibleSpace();
				}
				if (GUILayout.Button(currentOption, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(40f) }))
				{
					result = currentOption;
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.EndScrollView();
			return result;
		}
	}
	public abstract class ToggleStringListConfigEntry
	{
		internal static AutoCompleteBox AutoCompleteLabel = null;

		private static readonly char[] ValueSeparator = new char[1] { ',' };

		private static readonly char[] ToggleSeperator = new char[1] { '=' };

		private static readonly List<string> ValuesCache = new List<string>();

		private static string _valueText = string.Empty;

		public static string[] ToggledStringValues()
		{
			return (from value in StatusEffectFilterPlugin.ExcludedStatusEffects.Value.Split(ValueSeparator, StringSplitOptions.RemoveEmptyEntries).Where(IsToggledOn)
				select value.Split(ToggleSeperator)[0]).ToArray();
		}

		private static bool IsToggledOn(string value)
		{
			string[] array = value.Split(ToggleSeperator, 2, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length >= 2)
			{
				return array[1].Equals("On", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		public static void Drawer(ConfigEntryBase configEntry)
		{
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			ValuesCache.Clear();
			ValuesCache.AddRange(configEntry.BoxedValue.ToString().Split(ValueSeparator, StringSplitOptions.RemoveEmptyEntries));
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			bool flag = GUILayout.Button("Toggle On", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			bool flag2 = GUILayout.Button("Toggle Off", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.EndHorizontal();
			bool flag3 = false;
			int num = -1;
			int i = 0;
			for (int count = ValuesCache.Count; i < count; i++)
			{
				string[] array = ValuesCache[i].Split(ToggleSeperator, 2, StringSplitOptions.RemoveEmptyEntries);
				bool flag4 = array.Length >= 2 && array[1].Equals("On", StringComparison.OrdinalIgnoreCase);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				bool flag5 = GUILayout.Toggle(flag4, array[0], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.MinWidth(40f),
					GUILayout.ExpandWidth(false)
				}))
				{
					num = i;
				}
				GUILayout.EndHorizontal();
				if (flag)
				{
					flag5 = true;
				}
				else if (flag2)
				{
					flag5 = false;
				}
				if (flag5 != flag4)
				{
					flag3 = true;
					ValuesCache[i] = array[0] + "=" + (flag5 ? "On" : "Off");
				}
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			_valueText = GUILayout.TextField(_valueText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUILayout.Space(3f);
			if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.MinWidth(40f),
				GUILayout.ExpandWidth(false)
			}) && !string.IsNullOrWhiteSpace(_valueText) && _valueText.IndexOf('=') < 0)
			{
				ValuesCache.Add(_valueText + "=On");
				_valueText = string.Empty;
				flag3 = true;
			}
			GUILayout.EndHorizontal();
			if (AutoCompleteLabel != null)
			{
				string text = AutoCompleteLabel.DrawBox(_valueText);
				if (!string.IsNullOrEmpty(text))
				{
					ValuesCache.Add(text + "=On");
					flag3 = true;
				}
			}
			GUILayout.EndVertical();
			if (num >= 0)
			{
				ValuesCache.RemoveAt(num);
				flag3 = true;
			}
			if (flag3)
			{
				configEntry.BoxedValue = string.Join(",", ValuesCache);
			}
		}
	}
}