Decompiled source of LootFilter v1.0.0

plugins/LootFilter.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LootFilter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Marks items or item groups as junk: no auto-pickup and no sparkles on the ground.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b842e5737e7a8006377d712939acbf222a2c8827")]
[assembly: AssemblyProduct("LootFilter")]
[assembly: AssemblyTitle("LootFilter")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 LootFilter
{
	internal sealed class DropEffects : MonoBehaviour
	{
		private sealed class State
		{
			public readonly List<Behaviour> DisabledBehaviours = new List<Behaviour>();

			public readonly List<ParticleSystem> StoppedParticles = new List<ParticleSystem>();

			public readonly Dictionary<ParticleSystem, MinMaxGradient> RecoloredParticles = new Dictionary<ParticleSystem, MinMaxGradient>();

			public readonly Dictionary<Light, (Color color, float intensity)> RecoloredLights = new Dictionary<Light, (Color, float)>();
		}

		private const float ScanInterval = 0.25f;

		private readonly Dictionary<ItemDrop, State> _changed = new Dictionary<ItemDrop, State>();

		private float _nextScan;

		private int _seenVersion = -1;

		private bool _wasRevealing;

		private bool _effectSettingsChanged;

		private void Awake()
		{
			Settings.FilteredSparkles.SettingChanged += OnEffectSettingChanged;
			Settings.SparkleColor.SettingChanged += OnEffectSettingChanged;
		}

		private void OnEffectSettingChanged(object sender, EventArgs e)
		{
			_effectSettingsChanged = true;
		}

		private void Update()
		{
			bool flag = Input.Held(Settings.Reveal);
			if (flag != _wasRevealing || _seenVersion != Rules.Version || _effectSettingsChanged || !(Time.time < _nextScan))
			{
				if (_effectSettingsChanged)
				{
					RestoreAll();
					_effectSettingsChanged = false;
				}
				_wasRevealing = flag;
				_seenVersion = Rules.Version;
				_nextScan = Time.time + 0.25f;
				Scan(flag);
			}
		}

		private void OnDestroy()
		{
			RestoreAll();
		}

		private void RestoreAll()
		{
			foreach (State value in _changed.Values)
			{
				Restore(value);
			}
			_changed.Clear();
		}

		private void Scan(bool revealing)
		{
			bool flag = Settings.FilteredSparkles.Value != SparkleMode.Unchanged;
			foreach (ItemDrop s_instance in ItemDrop.s_instances)
			{
				if (!Object.op_Implicit((Object)(object)s_instance))
				{
					continue;
				}
				bool num = flag && !revealing && !Rules.Paused && Rules.IsFiltered(s_instance.m_itemData);
				State value;
				bool flag2 = _changed.TryGetValue(s_instance, out value);
				if (num)
				{
					if (!flag2)
					{
						value = (_changed[s_instance] = new State());
					}
					Apply(s_instance, value);
				}
				else if (flag2)
				{
					Restore(value);
					_changed.Remove(s_instance);
				}
			}
			foreach (ItemDrop item in _changed.Keys.Where((ItemDrop d) => !Object.op_Implicit((Object)(object)d)).ToList())
			{
				_changed.Remove(item);
			}
		}

		private static void Apply(ItemDrop drop, State state)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Settings.FilteredSparkles.Value == SparkleMode.Hidden;
			Color value = Settings.SparkleColor.Value;
			if (value.a <= 0f)
			{
				flag = true;
			}
			ParticleSystem[] componentsInChildren = ((Component)drop).GetComponentsInChildren<ParticleSystem>();
			foreach (ParticleSystem val in componentsInChildren)
			{
				if (flag)
				{
					if (val.isPlaying)
					{
						val.Stop(true, (ParticleSystemStopBehavior)0);
						state.StoppedParticles.Add(val);
					}
				}
				else if (!state.RecoloredParticles.ContainsKey(val))
				{
					MainModule main = val.main;
					state.RecoloredParticles[val] = ((MainModule)(ref main)).startColor;
					((MainModule)(ref main)).startColor = new MinMaxGradient(value);
					val.Clear(false);
				}
			}
			Light[] componentsInChildren2 = ((Component)drop).GetComponentsInChildren<Light>();
			foreach (Light val2 in componentsInChildren2)
			{
				if (flag)
				{
					if (((Behaviour)val2).enabled)
					{
						((Behaviour)val2).enabled = false;
						state.DisabledBehaviours.Add((Behaviour)(object)val2);
					}
				}
				else if (!state.RecoloredLights.ContainsKey(val2))
				{
					state.RecoloredLights[val2] = (val2.color, val2.intensity);
					val2.color = new Color(value.r, value.g, value.b);
					val2.intensity *= value.a;
				}
			}
		}

		private static void Restore(State state)
		{
			//IL_00a9: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			foreach (Behaviour disabledBehaviour in state.DisabledBehaviours)
			{
				if (Object.op_Implicit((Object)(object)disabledBehaviour))
				{
					disabledBehaviour.enabled = true;
				}
			}
			foreach (ParticleSystem stoppedParticle in state.StoppedParticles)
			{
				if (Object.op_Implicit((Object)(object)stoppedParticle))
				{
					stoppedParticle.Play(true);
				}
			}
			foreach (KeyValuePair<ParticleSystem, MinMaxGradient> recoloredParticle in state.RecoloredParticles)
			{
				if (Object.op_Implicit((Object)(object)recoloredParticle.Key))
				{
					MainModule main = recoloredParticle.Key.main;
					((MainModule)(ref main)).startColor = recoloredParticle.Value;
					recoloredParticle.Key.Clear(false);
				}
			}
			foreach (KeyValuePair<Light, (Color, float)> recoloredLight in state.RecoloredLights)
			{
				if (Object.op_Implicit((Object)(object)recoloredLight.Key))
				{
					recoloredLight.Key.color = recoloredLight.Value.Item1;
					recoloredLight.Key.intensity = recoloredLight.Value.Item2;
				}
			}
		}
	}
	internal static class Input
	{
		private static readonly KeyCode[] ModifierKeys;

		public static bool Pressed(ConfigEntry<KeyboardShortcut> entry)
		{
			//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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = entry.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false))
			{
				return false;
			}
			List<KeyCode> modifiers = ((KeyboardShortcut)(ref value)).Modifiers.ToList();
			if (modifiers.Any((KeyCode key) => !ZInput.GetKey(key, false)))
			{
				return false;
			}
			return !ModifierKeys.Any((KeyCode key) => !modifiers.Contains(key) && ZInput.GetKey(key, false));
		}

		public static bool Held(ConfigEntry<KeyboardShortcut> entry)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = entry.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey != 0 && ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, false))
			{
				return ((KeyboardShortcut)(ref value)).Modifiers.All((KeyCode key) => ZInput.GetKey(key, false));
			}
			return false;
		}

		public static bool IsTyping()
		{
			if (!Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !Minimap.InTextInput())
			{
				if (Object.op_Implicit((Object)(object)Chat.instance))
				{
					return Chat.instance.HasFocus();
				}
				return false;
			}
			return true;
		}

		static Input()
		{
			KeyCode[] array = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			ModifierKeys = (KeyCode[])(object)array;
		}
	}
	[Flags]
	public enum ItemGroups
	{
		None = 0,
		Materials = 1,
		FoodAndPotions = 2,
		Weapons = 4,
		Shields = 8,
		Armor = 0x10,
		Ammo = 0x20,
		Trophies = 0x40,
		Fish = 0x80,
		ToolsAndTorches = 0x100,
		UtilityAndTrinkets = 0x200,
		Misc = 0x400
	}
	internal static class Groups
	{
		public static ItemGroups Of(ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected I4, but got Unknown
			ItemType itemType = item.m_shared.m_itemType;
			switch (itemType - 1)
			{
			case 0:
				return ItemGroups.Materials;
			case 1:
				return ItemGroups.FoodAndPotions;
			case 2:
			case 3:
			case 13:
			case 19:
			case 21:
				return ItemGroups.Weapons;
			case 4:
				return ItemGroups.Shields;
			case 5:
			case 6:
			case 10:
			case 11:
			case 16:
				return ItemGroups.Armor;
			case 8:
			case 22:
				return ItemGroups.Ammo;
			case 12:
				return ItemGroups.Trophies;
			case 20:
				return ItemGroups.Fish;
			case 14:
			case 18:
				return ItemGroups.ToolsAndTorches;
			case 17:
			case 23:
				return ItemGroups.UtilityAndTrinkets;
			default:
				return ItemGroups.Misc;
			}
		}

		public static string Describe(ItemGroups group)
		{
			return group switch
			{
				ItemGroups.FoodAndPotions => "Food & potions", 
				ItemGroups.ToolsAndTorches => "Tools & torches", 
				ItemGroups.UtilityAndTrinkets => "Utility & trinkets", 
				_ => group.ToString(), 
			};
		}
	}
	internal sealed class Marker : MonoBehaviour
	{
		private void Update()
		{
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || Input.IsTyping())
			{
				return;
			}
			if (Input.Pressed(Settings.TogglePause))
			{
				Rules.Paused = !Rules.Paused;
				Message(Rules.Paused ? "Loot filter paused: filtered items will be picked up" : "Loot filter active");
			}
			bool flag = Input.Pressed(Settings.ToggleItem);
			bool flag2 = Input.Pressed(Settings.ToggleGroup);
			if (!flag && !flag2)
			{
				return;
			}
			ItemData val = HoveredItem();
			if (val != null)
			{
				if (flag)
				{
					MarkItem(val);
				}
				if (flag2)
				{
					MarkGroup(val);
				}
			}
		}

		private static void MarkItem(ItemData target)
		{
			bool flag = Rules.ToggleItem(target);
			Message(Localization.instance.Localize(target.m_shared.m_name) + ": " + (flag ? "filtered" : "not filtered"));
		}

		private static void MarkGroup(ItemData target)
		{
			ItemGroups itemGroups = Groups.Of(target);
			bool flag = Rules.ToggleGroup(itemGroups);
			Message("All " + Groups.Describe(itemGroups).ToLowerInvariant() + ": " + (flag ? "filtered" : "not filtered"));
		}

		private static ItemData HoveredItem()
		{
			if (InventoryGui.IsVisible())
			{
				InventoryGui instance = InventoryGui.instance;
				return HoveredIn(instance.m_playerGrid) ?? HoveredIn(instance.m_containerGrid);
			}
			GameObject hoverObject = ((Humanoid)Player.m_localPlayer).GetHoverObject();
			ItemDrop val = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<ItemDrop>() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.m_itemData;
		}

		private static ItemData HoveredIn(InventoryGrid grid)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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 (!Object.op_Implicit((Object)(object)grid) || !((Behaviour)grid).isActiveAndEnabled)
			{
				return null;
			}
			InventoryElement hoveredElement = grid.GetHoveredElement();
			if ((Object)(object)hoveredElement == (Object)null)
			{
				return null;
			}
			Vector2i elementPos = grid.GetElementPos(hoveredElement);
			Inventory inventory = grid.GetInventory();
			if (inventory == null)
			{
				return null;
			}
			return inventory.GetItemAt(elementPos.x, elementPos.y);
		}

		private static void Message(string text)
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)1, text, 0, (Sprite)null, false);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "AutoPickup")]
	internal static class AutoPickupPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			FieldInfo autoPickup = AccessTools.Field(typeof(ItemDrop), "m_autoPickup");
			MethodInfo replacement = AccessTools.Method(typeof(AutoPickupPatch), "CanAutoPickup", (Type[])null, (Type[])null);
			int replaced = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.LoadsField(instruction, autoPickup, false))
				{
					replaced++;
					yield return new CodeInstruction(OpCodes.Call, (object)replacement)
					{
						labels = instruction.labels,
						blocks = instruction.blocks
					};
				}
				else
				{
					yield return instruction;
				}
			}
			if (replaced != 1)
			{
				Debug.LogWarning((object)$"[LootFilter] Expected one m_autoPickup check in Player.AutoPickup, found {replaced}; auto-pickup filtering may not work");
			}
		}

		private static bool CanAutoPickup(ItemDrop drop)
		{
			if (drop.m_autoPickup)
			{
				return !Rules.BlocksAutoPickup(drop.m_itemData);
			}
			return false;
		}
	}
	internal static class BuildCameraPickupPatch
	{
		public const string Guid = "EndosBuildCamera";

		public static void Apply(Harmony harmony, ManualLogSource log)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("MyValheimBuildCamera.BuildCameraBase"), "ExecuteCameraAutoPickup", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				log.LogWarning((object)"My Build Camera's camera pickup method wasn't found (different version?); its pickups aren't filtered");
			}
			else
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BuildCameraPickupPatch), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo canAddItem = AccessTools.Method(typeof(Inventory), "CanAddItem", new Type[2]
			{
				typeof(ItemData),
				typeof(int)
			}, (Type[])null);
			MethodInfo replacement = AccessTools.Method(typeof(BuildCameraPickupPatch), "CanAddItem", (Type[])null, (Type[])null);
			int replaced = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, canAddItem))
				{
					replaced++;
					yield return new CodeInstruction(OpCodes.Call, (object)replacement)
					{
						labels = instruction.labels,
						blocks = instruction.blocks
					};
				}
				else
				{
					yield return instruction;
				}
			}
			if (replaced != 1)
			{
				Debug.LogWarning((object)$"[LootFilter] Expected one CanAddItem check in My Build Camera's pickup, found {replaced}; its pickups may not be filtered");
			}
		}

		private static bool CanAddItem(Inventory inventory, ItemData item, int stack)
		{
			if (inventory.CanAddItem(item, stack))
			{
				return !Rules.BlocksAutoPickup(item);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int),
		typeof(bool)
	})]
	internal static class TooltipPatch
	{
		private static void Postfix(ItemData item, bool crafting, ref string __result)
		{
			if (!crafting && Settings.ShowInTooltip.Value)
			{
				string text = (Rules.Paused ? ", paused" : "");
				switch (Rules.Explain(item))
				{
				case FilterReason.Item:
					__result = __result + "\n<color=#ff9a5c>Loot filter: filtered" + (Rules.Paused ? " (paused)" : "") + "</color>";
					break;
				case FilterReason.Group:
					__result = __result + "\n<color=#ff9a5c>Loot filter: filtered (group: " + Groups.Describe(Groups.Of(item)) + text + ")</color>";
					break;
				}
			}
		}
	}
	[BepInPlugin("s992.LootFilter", "LootFilter", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Settings.Bind(((BaseUnityPlugin)this).Config);
			Rules.Init();
			Harmony val = new Harmony("s992.LootFilter");
			val.PatchAll();
			if (Chainloader.PluginInfos.ContainsKey("EndosBuildCamera"))
			{
				BuildCameraPickupPatch.Apply(val, ((BaseUnityPlugin)this).Logger);
			}
			((Component)this).gameObject.AddComponent<Marker>();
			((Component)this).gameObject.AddComponent<DropEffects>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LootFilter 1.0.0 loaded");
		}
	}
	internal enum FilterReason
	{
		NotFiltered,
		Item,
		Group
	}
	internal static class Rules
	{
		private static HashSet<string> s_items = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static bool s_paused;

		public static int Version { get; private set; }

		public static bool Paused
		{
			get
			{
				return s_paused;
			}
			set
			{
				if (s_paused != value)
				{
					s_paused = value;
					Version++;
				}
			}
		}

		public static bool BlocksAutoPickup(ItemData item)
		{
			if (Settings.BlockAutoPickup.Value && !Paused)
			{
				return IsFiltered(item);
			}
			return false;
		}

		public static void Init()
		{
			ParseItems();
			Settings.FilteredItems.SettingChanged += delegate
			{
				ParseItems();
				Version++;
			};
			Settings.FilteredGroups.SettingChanged += delegate
			{
				Version++;
			};
		}

		private static void ParseItems()
		{
			s_items = new HashSet<string>(from s in Settings.FilteredItems.Value.Split(',')
				select s.Trim() into s
				where s.Length > 0
				select s, StringComparer.OrdinalIgnoreCase);
		}

		public static string ItemName(ItemData item)
		{
			if (!Object.op_Implicit((Object)(object)item.m_dropPrefab))
			{
				return item.m_shared.m_name;
			}
			return ((Object)item.m_dropPrefab).name;
		}

		public static bool IsFiltered(ItemData item)
		{
			return Explain(item) != FilterReason.NotFiltered;
		}

		public static FilterReason Explain(ItemData item)
		{
			if (item == null)
			{
				return FilterReason.NotFiltered;
			}
			if (s_items.Contains(ItemName(item)))
			{
				return FilterReason.Item;
			}
			if ((Settings.FilteredGroups.Value & Groups.Of(item)) != ItemGroups.None)
			{
				return FilterReason.Group;
			}
			return FilterReason.NotFiltered;
		}

		public static bool ToggleItem(ItemData item)
		{
			string item2 = ItemName(item);
			HashSet<string> hashSet = new HashSet<string>(s_items, StringComparer.OrdinalIgnoreCase);
			bool num = !hashSet.Remove(item2);
			if (num)
			{
				hashSet.Add(item2);
			}
			Settings.FilteredItems.Value = string.Join(", ", hashSet.OrderBy<string, string>((string s) => s, StringComparer.OrdinalIgnoreCase));
			return num;
		}

		public static bool ToggleGroup(ItemGroups group)
		{
			ConfigEntry<ItemGroups> filteredGroups = Settings.FilteredGroups;
			filteredGroups.Value ^= group;
			return (Settings.FilteredGroups.Value & group) != 0;
		}
	}
	public enum SparkleMode
	{
		Hidden,
		Recolored,
		Unchanged
	}
	internal static class Settings
	{
		public static ConfigEntry<string> FilteredItems;

		public static ConfigEntry<ItemGroups> FilteredGroups;

		public static ConfigEntry<bool> BlockAutoPickup;

		public static ConfigEntry<bool> ShowInTooltip;

		public static ConfigEntry<SparkleMode> FilteredSparkles;

		public static ConfigEntry<Color> SparkleColor;

		public static ConfigEntry<KeyboardShortcut> ToggleItem;

		public static ConfigEntry<KeyboardShortcut> ToggleGroup;

		public static ConfigEntry<KeyboardShortcut> Reveal;

		public static ConfigEntry<KeyboardShortcut> TogglePause;

		public static void Bind(ConfigFile config)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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)
			FilteredItems = config.Bind<string>("Rules", "FilteredItems", "", "Comma-separated item names to filter (internal prefab names, e.g. Resin, Stone, RoundLog). Easiest to edit with the ToggleItem key while hovering an item.");
			FilteredGroups = config.Bind<ItemGroups>("Rules", "FilteredGroups", ItemGroups.None, "Item groups to filter.");
			BlockAutoPickup = config.Bind<bool>("Behaviour", "BlockAutoPickup", true, "Don't auto-pickup filtered items. They can still be picked up manually.");
			ShowInTooltip = config.Bind<bool>("Behaviour", "ShowInTooltip", true, "Add a line to item tooltips saying whether (and why) the item is filtered.");
			FilteredSparkles = config.Bind<SparkleMode>("Effects", "FilteredSparkles", SparkleMode.Hidden, "What to do with the sparkles and glow of filtered drops: hide them, recolor them with SparkleColor, or leave them alone.");
			SparkleColor = config.Bind<Color>("Effects", "SparkleColor", new Color(0.55f, 0.55f, 0.55f, 0.35f), "Color of filtered drops' sparkles when FilteredSparkles is Recolored. The alpha (A) value sets how visible they are.");
			ToggleItem = config.Bind<KeyboardShortcut>("Keys", "ToggleItem", new KeyboardShortcut((KeyCode)127, Array.Empty<KeyCode>()), "Filter/unfilter the hovered item (inventory, chest or on the ground).");
			ToggleGroup = config.Bind<KeyboardShortcut>("Keys", "ToggleGroup", new KeyboardShortcut((KeyCode)127, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Filter/unfilter the hovered item's group (Weapons, Trophies, ...).");
			Reveal = config.Bind<KeyboardShortcut>("Keys", "Reveal", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold to show the original effects of filtered items.");
			TogglePause = config.Bind<KeyboardShortcut>("Keys", "TogglePause", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Pause/resume the filter: while paused, filtered items are auto-picked up and keep their effects. The filter is always active again after restarting the game.");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "s992.LootFilter";

		public const string PLUGIN_NAME = "LootFilter";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}