Decompiled source of REPOBlacklist v0.2.2

REPOBlacklist.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("REPOBlacklist")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.2.0")]
[assembly: AssemblyInformationalVersion("0.2.2")]
[assembly: AssemblyProduct("REPOBlacklist")]
[assembly: AssemblyTitle("REPOBlacklist")]
[assembly: AssemblyVersion("0.2.2.0")]
namespace REPOBlacklist;

public static class BlacklistFilter
{
	private struct FieldHit
	{
		public FieldInfo Field;

		public BlacklistCategory Cat;

		public Type Elem;

		public ContainerKind Kind;
	}

	private enum ContainerKind
	{
		None,
		Array,
		List,
		Dictionary
	}

	private static readonly string[] ItemTypeCandidates = new string[1] { "Item" };

	private static readonly string[] ValuableTypeCandidates = new string[2] { "ValuableObject", "Valuable" };

	private static readonly string[] EnemyTypeCandidates = new string[3] { "EnemySetup", "EnemiesSetup", "EnemyParent" };

	private static Type _itemType;

	private static Type _valuableType;

	private static Type _enemyType;

	private static bool _resolved;

	private static List<FieldHit> _staticFieldCache;

	private static readonly Dictionary<Type, FieldHit[]> _instanceFieldCache = new Dictionary<Type, FieldHit[]>();

	private static readonly FieldHit[] _emptyHits = Array.Empty<FieldHit>();

	public static Type ItemType
	{
		get
		{
			Resolve();
			return _itemType;
		}
	}

	public static Type ValuableType
	{
		get
		{
			Resolve();
			return _valuableType;
		}
	}

	public static Type EnemyType
	{
		get
		{
			Resolve();
			return _enemyType;
		}
	}

	public static Type TypeFor(BlacklistCategory cat)
	{
		return cat switch
		{
			BlacklistCategory.Item => ItemType, 
			BlacklistCategory.Valuable => ValuableType, 
			BlacklistCategory.Enemy => EnemyType, 
			_ => null, 
		};
	}

	private static void Resolve()
	{
		if (!_resolved)
		{
			_resolved = true;
			_itemType = ResolveOne(ItemTypeCandidates);
			_valuableType = ResolveOne(ValuableTypeCandidates);
			_enemyType = ResolveOne(EnemyTypeCandidates);
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("Resolved types: Item=" + (_itemType?.FullName ?? "?") + ", Valuable=" + (_valuableType?.FullName ?? "?") + ", Enemy=" + (_enemyType?.FullName ?? "?")));
			}
		}
	}

	private static Type ResolveOne(string[] candidates)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			if (IsExternalAssembly(assembly))
			{
				continue;
			}
			Type[] source;
			try
			{
				source = assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				source = ex.Types.Where((Type t) => t != null).ToArray();
			}
			catch
			{
				continue;
			}
			foreach (string name in candidates)
			{
				Type type = source.FirstOrDefault((Type t) => t != null && t.Name == name && typeof(Object).IsAssignableFrom(t));
				if (type != null)
				{
					return type;
				}
			}
		}
		return null;
	}

	public static IEnumerable<Object> Discover(BlacklistCategory cat)
	{
		Type type = TypeFor(cat);
		if (type == null)
		{
			return Array.Empty<Object>();
		}
		return from o in Resources.FindObjectsOfTypeAll(type)
			where o != (Object)null
			select o;
	}

	public static void Apply()
	{
		ApplyInternal(dump: false);
	}

	public static void Dump()
	{
		ApplyInternal(dump: true);
	}

	private static void ApplyInternal(bool dump)
	{
		try
		{
			Resolve();
			if (Plugin.Store == null || (_itemType == null && _valuableType == null && _enemyType == null))
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			MonoBehaviour[] array = Object.FindObjectsOfType<MonoBehaviour>(true);
			foreach (MonoBehaviour val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				FieldHit[] matchedInstanceFields = GetMatchedInstanceFields(type);
				if (matchedInstanceFields.Length == 0)
				{
					continue;
				}
				FieldHit[] array2 = matchedInstanceFields;
				for (int j = 0; j < array2.Length; j++)
				{
					FieldHit fieldHit = array2[j];
					object value = fieldHit.Field.GetValue(val);
					num3++;
					if (value == null)
					{
						continue;
					}
					int num4 = ContainerCount(value, fieldHit.Kind);
					int num5 = StripBlacklisted(ref value, fieldHit.Cat, fieldHit.Elem, fieldHit.Kind);
					if (num5 > 0)
					{
						num++;
						num2 += num5;
						fieldHit.Field.SetValue(val, value);
					}
					if (dump)
					{
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogInfo((object)$"[dump] inst {type.FullName}.{fieldHit.Field.Name} : {fieldHit.Field.FieldType.Name} count={num4} removed={num5} cat={fieldHit.Cat}");
						}
					}
				}
			}
			if (_staticFieldCache == null)
			{
				BuildStaticFieldCache();
			}
			foreach (FieldHit item in _staticFieldCache)
			{
				object value2 = item.Field.GetValue(null);
				num3++;
				if (value2 == null)
				{
					continue;
				}
				int num6 = ContainerCount(value2, item.Kind);
				int num7 = StripBlacklisted(ref value2, item.Cat, item.Elem, item.Kind);
				if (num7 > 0)
				{
					num++;
					num2 += num7;
					item.Field.SetValue(null, value2);
				}
				if (dump)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"[dump] static {item.Field.DeclaringType?.FullName}.{item.Field.Name} : {item.Field.FieldType.Name} count={num6} removed={num7} cat={item.Cat}");
					}
				}
			}
			if (dump || num2 > 0)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)$"Filter pass: visited {num3} field(s), filtered {num2} entries across {num} field(s).");
				}
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log4 = Plugin.Log;
			if (log4 != null)
			{
				log4.LogError((object)$"Apply failed: {arg}");
			}
		}
	}

	private static void BuildStaticFieldCache()
	{
		_staticFieldCache = new List<FieldHit>();
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			if (IsExternalAssembly(assembly))
			{
				continue;
			}
			Type[] array;
			try
			{
				array = assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				array = ex.Types.Where((Type t) => t != null).ToArray();
			}
			catch
			{
				continue;
			}
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				if (type == null)
				{
					continue;
				}
				FieldInfo[] fields;
				try
				{
					fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
					continue;
				}
				FieldInfo[] array3 = fields;
				foreach (FieldInfo fieldInfo in array3)
				{
					var (blacklistCategory, elem, kind) = MatchField(fieldInfo.FieldType);
					if (blacklistCategory.HasValue)
					{
						_staticFieldCache.Add(new FieldHit
						{
							Field = fieldInfo,
							Cat = blacklistCategory.Value,
							Elem = elem,
							Kind = kind
						});
					}
				}
			}
		}
		ManualLogSource log = Plugin.Log;
		if (log != null)
		{
			log.LogInfo((object)$"Static field cache: {_staticFieldCache.Count} hit(s).");
		}
	}

	private static FieldHit[] GetMatchedInstanceFields(Type t)
	{
		if (_instanceFieldCache.TryGetValue(t, out var value))
		{
			return value;
		}
		if (IsExternalAssembly(t.Assembly))
		{
			_instanceFieldCache[t] = _emptyHits;
			return _emptyHits;
		}
		FieldInfo[] fields;
		try
		{
			fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}
		catch
		{
			_instanceFieldCache[t] = _emptyHits;
			return _emptyHits;
		}
		List<FieldHit> list = null;
		FieldInfo[] array = fields;
		foreach (FieldInfo fieldInfo in array)
		{
			var (blacklistCategory, elem, kind) = MatchField(fieldInfo.FieldType);
			if (blacklistCategory.HasValue)
			{
				(list ?? (list = new List<FieldHit>())).Add(new FieldHit
				{
					Field = fieldInfo,
					Cat = blacklistCategory.Value,
					Elem = elem,
					Kind = kind
				});
			}
		}
		FieldHit[] array2 = ((list == null) ? _emptyHits : list.ToArray());
		_instanceFieldCache[t] = array2;
		return array2;
	}

	private static (BlacklistCategory? cat, Type elem, ContainerKind kind) MatchField(Type fieldType)
	{
		if (fieldType.IsArray)
		{
			Type elementType = fieldType.GetElementType();
			BlacklistCategory? item = ClassifyElement(elementType);
			if (item.HasValue)
			{
				return (item, elementType, ContainerKind.Array);
			}
			return (null, null, ContainerKind.None);
		}
		if (fieldType.IsGenericType)
		{
			Type genericTypeDefinition = fieldType.GetGenericTypeDefinition();
			Type[] genericArguments = fieldType.GetGenericArguments();
			if (genericTypeDefinition == typeof(List<>))
			{
				Type type = genericArguments[0];
				BlacklistCategory? item2 = ClassifyElement(type);
				if (item2.HasValue)
				{
					return (item2, type, ContainerKind.List);
				}
				return (null, null, ContainerKind.None);
			}
			if (genericTypeDefinition == typeof(Dictionary<, >))
			{
				BlacklistCategory? item3 = ClassifyElement(genericArguments[0]);
				BlacklistCategory? item4 = ClassifyElement(genericArguments[1]);
				if (item3.HasValue)
				{
					return (item3, genericArguments[0], ContainerKind.Dictionary);
				}
				if (item4.HasValue)
				{
					return (item4, genericArguments[1], ContainerKind.Dictionary);
				}
			}
		}
		return (null, null, ContainerKind.None);
	}

	private static BlacklistCategory? ClassifyElement(Type elem)
	{
		if (elem == null)
		{
			return null;
		}
		if (_itemType != null && _itemType.IsAssignableFrom(elem))
		{
			return BlacklistCategory.Item;
		}
		if (_valuableType != null && _valuableType.IsAssignableFrom(elem))
		{
			return BlacklistCategory.Valuable;
		}
		if (_enemyType != null && _enemyType.IsAssignableFrom(elem))
		{
			return BlacklistCategory.Enemy;
		}
		return null;
	}

	private static int ContainerCount(object value, ContainerKind kind)
	{
		if (value == null)
		{
			return 0;
		}
		if (kind == ContainerKind.Dictionary && value is IDictionary dictionary)
		{
			return dictionary.Count;
		}
		if (value is ICollection collection)
		{
			return collection.Count;
		}
		return 0;
	}

	private static int StripBlacklisted(ref object value, BlacklistCategory cat, Type elem, ContainerKind kind)
	{
		if (value == null)
		{
			return 0;
		}
		switch (kind)
		{
		case ContainerKind.Array:
		{
			Array obj2 = (Array)value;
			List<object> list3 = new List<object>(obj2.Length);
			int num3 = 0;
			foreach (object item in obj2)
			{
				Object val4 = (Object)((item is Object) ? item : null);
				if (val4 != null && Plugin.Store.IsBlacklisted(cat, val4.name))
				{
					num3++;
				}
				else
				{
					list3.Add(item);
				}
			}
			if (num3 > 0)
			{
				Array array = Array.CreateInstance(elem, list3.Count);
				for (int i = 0; i < list3.Count; i++)
				{
					array.SetValue(list3[i], i);
				}
				value = array;
			}
			return num3;
		}
		case ContainerKind.List:
		{
			IList list2 = (IList)value;
			int num = 0;
			for (int num2 = list2.Count - 1; num2 >= 0; num2--)
			{
				object? obj = list2[num2];
				Object val3 = (Object)((obj is Object) ? obj : null);
				if (val3 != null && Plugin.Store.IsBlacklisted(cat, val3.name))
				{
					list2.RemoveAt(num2);
					num++;
				}
			}
			return num;
		}
		case ContainerKind.Dictionary:
		{
			IDictionary dictionary = (IDictionary)value;
			List<object> list = new List<object>();
			foreach (DictionaryEntry item2 in dictionary)
			{
				object key = item2.Key;
				Object val = (Object)((key is Object) ? key : null);
				if (val != null && Plugin.Store.IsBlacklisted(cat, val.name))
				{
					list.Add(item2.Key);
					continue;
				}
				object? value2 = item2.Value;
				Object val2 = (Object)((value2 is Object) ? value2 : null);
				if (val2 != null && Plugin.Store.IsBlacklisted(cat, val2.name))
				{
					list.Add(item2.Key);
				}
				else if (item2.Key is string name && Plugin.Store.IsBlacklisted(cat, name))
				{
					list.Add(item2.Key);
				}
			}
			foreach (object item3 in list)
			{
				dictionary.Remove(item3);
			}
			return list.Count;
		}
		default:
			return 0;
		}
	}

	private static bool IsExternalAssembly(Assembly asm)
	{
		string name = asm.GetName().Name;
		if (string.IsNullOrEmpty(name))
		{
			return true;
		}
		if (name == "REPOBlacklist")
		{
			return true;
		}
		if (name.StartsWith("UnityEngine") || name.StartsWith("Unity."))
		{
			return true;
		}
		if (name.StartsWith("System") || name == "mscorlib" || name == "netstandard")
		{
			return true;
		}
		if (name.StartsWith("BepInEx") || name == "0Harmony" || name.StartsWith("HarmonyX") || name == "Mono.Cecil")
		{
			return true;
		}
		if (name.StartsWith("Microsoft."))
		{
			return true;
		}
		return false;
	}
}
public enum BlacklistCategory
{
	Item,
	Valuable,
	Enemy
}
public class BlacklistStore
{
	[Serializable]
	private class Dto
	{
		public List<string> items = new List<string>();

		public List<string> valuables = new List<string>();

		public List<string> enemies = new List<string>();
	}

	private readonly string _path;

	private readonly HashSet<string> _items = new HashSet<string>(StringComparer.Ordinal);

	private readonly HashSet<string> _valuables = new HashSet<string>(StringComparer.Ordinal);

	private readonly HashSet<string> _enemies = new HashSet<string>(StringComparer.Ordinal);

	public event Action Changed;

	public BlacklistStore(string path)
	{
		_path = path;
		Load();
	}

	public bool IsBlacklisted(BlacklistCategory cat, string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return Set(cat).Contains(name);
	}

	public IReadOnlyCollection<string> Snapshot(BlacklistCategory cat)
	{
		return Set(cat);
	}

	public void Set(BlacklistCategory cat, string name, bool blacklisted)
	{
		if (!string.IsNullOrEmpty(name))
		{
			HashSet<string> hashSet = Set(cat);
			if (blacklisted ? hashSet.Add(name) : hashSet.Remove(name))
			{
				Save();
				this.Changed?.Invoke();
			}
		}
	}

	private HashSet<string> Set(BlacklistCategory cat)
	{
		return cat switch
		{
			BlacklistCategory.Item => _items, 
			BlacklistCategory.Valuable => _valuables, 
			BlacklistCategory.Enemy => _enemies, 
			_ => throw new ArgumentOutOfRangeException("cat"), 
		};
	}

	private void Load()
	{
		try
		{
			if (!File.Exists(_path))
			{
				return;
			}
			Dto dto = JsonUtility.FromJson<Dto>(File.ReadAllText(_path)) ?? new Dto();
			_items.Clear();
			foreach (string item in dto.items ?? new List<string>())
			{
				_items.Add(item);
			}
			_valuables.Clear();
			foreach (string item2 in dto.valuables ?? new List<string>())
			{
				_valuables.Add(item2);
			}
			_enemies.Clear();
			foreach (string item3 in dto.enemies ?? new List<string>())
			{
				_enemies.Add(item3);
			}
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[REPOBlacklist] Failed to load {_path}: {arg}");
		}
	}

	private void Save()
	{
		try
		{
			Directory.CreateDirectory(Path.GetDirectoryName(_path));
			Dto dto = new Dto
			{
				items = new List<string>(_items),
				valuables = new List<string>(_valuables),
				enemies = new List<string>(_enemies)
			};
			dto.items.Sort(StringComparer.Ordinal);
			dto.valuables.Sort(StringComparer.Ordinal);
			dto.enemies.Sort(StringComparer.Ordinal);
			File.WriteAllText(_path, JsonUtility.ToJson((object)dto, true));
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[REPOBlacklist] Failed to save {_path}: {arg}");
		}
	}
}
public class BlacklistUI : MonoBehaviour
{
	private bool _open;

	private Rect _window = new Rect(60f, 60f, 560f, 660f);

	private BlacklistCategory _tab;

	private string _filter = "";

	private Vector2 _scroll;

	private readonly Dictionary<BlacklistCategory, List<Object>> _cache = new Dictionary<BlacklistCategory, List<Object>>();

	private GUIStyle _windowStyle;

	private GUIStyle _toggleStyle;

	private bool _stylesReady;

	private bool _wasCursorVisible;

	private CursorLockMode _wasCursorLock;

	private BlacklistCategory? _resetArmed;

	private void Update()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Plugin.Instance != (Object)null && Input.GetKeyDown(Plugin.Instance.MenuToggleKey.Value))
		{
			Toggle();
		}
	}

	private void LateUpdate()
	{
		if (_open)
		{
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
		}
	}

	private void Toggle()
	{
		//IL_0063: 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)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		_open = !_open;
		InputBlocker.BlockInput = _open;
		_resetArmed = null;
		if (_open)
		{
			Refresh();
			_wasCursorVisible = Cursor.visible;
			_wasCursorLock = Cursor.lockState;
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
		}
		else
		{
			Cursor.visible = _wasCursorVisible;
			Cursor.lockState = _wasCursorLock;
			BlacklistFilter.Apply();
		}
	}

	private void Refresh()
	{
		foreach (BlacklistCategory value in Enum.GetValues(typeof(BlacklistCategory)))
		{
			_cache[value] = (from o in BlacklistFilter.Discover(value)
				where !string.IsNullOrEmpty(o.name)
				group o by o.name into g
				select g.First()).OrderBy<Object, string>((Object o) => o.name, StringComparer.OrdinalIgnoreCase).ToList();
		}
	}

	private void OnGUI()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		if (_open)
		{
			EnsureStyles();
			_window = GUI.Window(((Object)this).GetInstanceID() ^ 0x1B71A57, _window, new WindowFunction(DrawWindow), "REPO Blacklist", _windowStyle);
		}
	}

	private void EnsureStyles()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		if (!_stylesReady)
		{
			_windowStyle = new GUIStyle(GUI.skin.window);
			_toggleStyle = new GUIStyle(GUI.skin.toggle)
			{
				wordWrap = true
			};
			_stylesReady = true;
		}
	}

	private void DrawWindow(int id)
	{
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		DrawTabButton("Items", BlacklistCategory.Item);
		DrawTabButton("Valuables", BlacklistCategory.Valuable);
		DrawTabButton("Enemies", BlacklistCategory.Enemy);
		GUILayout.FlexibleSpace();
		if (GUILayout.Button("Refresh", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(72f) }))
		{
			Refresh();
		}
		if (GUILayout.Button("Dump", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
		{
			BlacklistFilter.Dump();
		}
		if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
		{
			Toggle();
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label("Filter:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
		_filter = GUILayout.TextField(_filter ?? "", Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("X", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }))
		{
			_filter = "";
		}
		GUILayout.EndHorizontal();
		if (!_cache.TryGetValue(_tab, out var value) || value == null || value.Count == 0)
		{
			GUILayout.FlexibleSpace();
			GUILayout.Label((BlacklistFilter.TypeFor(_tab) == null) ? $"Could not resolve the {_tab} type in any loaded assembly.\nThe game may not be loaded yet, or REPO renamed it." : $"No {_tab} assets currently loaded.\nEnter a level or open the shop, then hit Refresh.", Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
			return;
		}
		int num = value.Count((Object o) => Plugin.Store.IsBlacklisted(_tab, o.name));
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label($"{num} / {value.Count} blacklisted", Array.Empty<GUILayoutOption>());
		GUILayout.FlexibleSpace();
		if (GUILayout.Button((_resetArmed == _tab) ? "Confirm clear?" : $"Clear {_tab}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) }))
		{
			if (_resetArmed == _tab)
			{
				foreach (string item in Plugin.Store.Snapshot(_tab).ToList())
				{
					Plugin.Store.Set(_tab, item, blacklisted: false);
				}
				_resetArmed = null;
			}
			else
			{
				_resetArmed = _tab;
			}
		}
		GUILayout.EndHorizontal();
		_scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>());
		string text = (_filter ?? "").Trim();
		foreach (Object item2 in value)
		{
			if (text.Length <= 0 || item2.name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				bool flag = Plugin.Store.IsBlacklisted(_tab, item2.name);
				bool flag2 = GUILayout.Toggle(flag, item2.name, _toggleStyle, Array.Empty<GUILayoutOption>());
				if (flag2 != flag)
				{
					Plugin.Store.Set(_tab, item2.name, flag2);
				}
			}
		}
		GUILayout.EndScrollView();
		GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
	}

	private void DrawTabButton(string label, BlacklistCategory cat)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		Color backgroundColor = GUI.backgroundColor;
		if (_tab == cat)
		{
			GUI.backgroundColor = new Color(0.4f, 0.7f, 1f);
		}
		if (GUILayout.Button(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
		{
			_tab = cat;
			_resetArmed = null;
		}
		GUI.backgroundColor = backgroundColor;
	}
}
public static class InputBlocker
{
	[HarmonyPatch(typeof(Input), "GetAxis")]
	public static class GetAxisPatch
	{
		private static bool Prefix(ref float __result)
		{
			if (!BlockInput)
			{
				return true;
			}
			__result = 0f;
			return false;
		}
	}

	[HarmonyPatch(typeof(Input), "GetAxisRaw")]
	public static class GetAxisRawPatch
	{
		private static bool Prefix(ref float __result)
		{
			if (!BlockInput)
			{
				return true;
			}
			__result = 0f;
			return false;
		}
	}

	[HarmonyPatch(typeof(Input), "GetMouseButton")]
	public static class GetMouseButtonPatch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!BlockInput)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	[HarmonyPatch(typeof(Input), "GetMouseButtonDown")]
	public static class GetMouseButtonDownPatch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!BlockInput)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	[HarmonyPatch(typeof(Input), "GetMouseButtonUp")]
	public static class GetMouseButtonUpPatch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!BlockInput)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	public static bool BlockInput;

	public static void PatchInputSystem(Harmony harmony)
	{
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Expected O, but got Unknown
		try
		{
			Type type = (from a in AppDomain.CurrentDomain.GetAssemblies()
				where a.GetName().Name == "Unity.InputSystem"
				select a.GetType("UnityEngine.InputSystem.InputAction")).FirstOrDefault((Type t) => t != null);
			if (type == null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"New InputSystem not loaded; skipping its patches.");
				}
				return;
			}
			MethodInfo methodInfo = type.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "ReadValue" && m.IsGenericMethodDefinition && m.GetParameters().Length == 0);
			if (methodInfo == null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"Could not find InputAction.ReadValue<T>(); InputSystem patches not applied.");
				}
				return;
			}
			MethodInfo method = typeof(InputBlocker).GetMethod("GenericReadValuePrefix", BindingFlags.Static | BindingFlags.NonPublic);
			int num = 0;
			Type[] array = new Type[3]
			{
				typeof(Vector2),
				typeof(float),
				typeof(Vector3)
			};
			foreach (Type type2 in array)
			{
				try
				{
					MethodInfo methodInfo2 = methodInfo.MakeGenericMethod(type2);
					MethodInfo methodInfo3 = method.MakeGenericMethod(type2);
					harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				catch (Exception ex)
				{
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogWarning((object)("Could not patch InputAction.ReadValue<" + type2.Name + ">: " + ex.Message));
					}
				}
			}
			ManualLogSource log4 = Plugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)$"Patched InputAction.ReadValue<T>() for {num} closed generic(s).");
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log5 = Plugin.Log;
			if (log5 != null)
			{
				log5.LogError((object)$"PatchInputSystem failed: {arg}");
			}
		}
	}

	private static bool GenericReadValuePrefix<T>(ref T __result)
	{
		if (!BlockInput)
		{
			return true;
		}
		__result = default(T);
		return false;
	}
}
[BepInPlugin("isaia.repoblacklist", "REPOBlacklist", "0.2.2")]
public class Plugin : BaseUnityPlugin
{
	public const string GUID = "isaia.repoblacklist";

	public const string NAME = "REPOBlacklist";

	public const string VERSION = "0.2.2";

	public ConfigEntry<KeyCode> MenuToggleKey;

	private Harmony _harmony;

	private BlacklistUI _ui;

	public static Plugin Instance { get; private set; }

	public static ManualLogSource Log { get; private set; }

	public static BlacklistStore Store { get; private set; }

	private void Awake()
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		MenuToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("UI", "MenuToggleKey", (KeyCode)284, "Key that opens/closes the in-game blacklist menu.");
		string text = Path.Combine(Paths.ConfigPath, "REPOBlacklist.json");
		Store = new BlacklistStore(text);
		Store.Changed += OnBlacklistChanged;
		_harmony = new Harmony("isaia.repoblacklist");
		try
		{
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Harmony patch issues (non-fatal): " + ex.Message));
		}
		InputBlocker.PatchInputSystem(_harmony);
		_ui = ((Component)this).gameObject.AddComponent<BlacklistUI>();
		SceneManager.sceneLoaded += OnSceneLoaded;
		Log.LogInfo((object)("REPOBlacklist 0.2.2 loaded. Blacklist: " + text));
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		if (Store != null)
		{
			Store.Changed -= OnBlacklistChanged;
		}
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		((MonoBehaviour)this).StartCoroutine(ApplyNextFrame());
	}

	private IEnumerator ApplyNextFrame()
	{
		yield return null;
		BlacklistFilter.Apply();
	}

	private void OnBlacklistChanged()
	{
		BlacklistFilter.Apply();
	}
}
public static class MyPluginInfo
{
	public const string PLUGIN_GUID = "REPOBlacklist";

	public const string PLUGIN_NAME = "REPOBlacklist";

	public const string PLUGIN_VERSION = "0.2.2";
}