Decompiled source of NoJunkPickup v1.2.0

NoJunkPickup.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("NoJunkPickup")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NoJunkPickup")]
[assembly: AssemblyTitle("NoJunkPickup")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 NoJunkPickup
{
	[BepInPlugin("dark.nojunkpickup", "No Junk Pickup", "1.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "dark.nojunkpickup";

		public const string ModName = "No Junk Pickup";

		public const string ModVersion = "1.2.0";

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<string> Blacklist;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<bool> ShowToggleMessage;

		internal static ConfigEntry<KeyboardShortcut> InventoryKey;

		internal static HashSet<string> BlacklistSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal static readonly HashSet<ItemDrop> DisabledByMod = new HashSet<ItemDrop>();

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private bool _toggleKeyBroken;

		private bool _inventoryKeyBroken;

		private static MethodInfo _getHoveredElement;

		private void Awake()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the auto pickup blacklist");
			Blacklist = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Blacklist", "Stone,Wood", "Comma-separated item IDs that are not picked up automatically (e.g. Stone,Wood,Resin,GreydwarfEye)");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkey", "ToggleKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Key to quickly turn the mod on and off. Any key or combination can be used (e.g. LeftControl + J)");
			ShowToggleMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("Hotkey", "ShowToggleMessage", true, "Show a message in the top left corner when the mod is toggled");
			InventoryKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkey", "InventoryKey", new KeyboardShortcut((KeyCode)325, Array.Empty<KeyCode>()), "Key to add or remove an item from the blacklist: hover over an item in your inventory or a chest and press it. Default: middle mouse button");
			RebuildBlacklist();
			Blacklist.SettingChanged += delegate
			{
				RebuildBlacklist();
				RefreshAllItems();
			};
			Enabled.SettingChanged += delegate
			{
				RefreshAllItems();
			};
			_getHoveredElement = AccessTools.Method(typeof(InventoryGrid), "GetHoveredElement", (Type[])null, (Type[])null);
			if (_getHoveredElement == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"InventoryGrid.GetHoveredElement not found: adding items from the inventory will not work");
			}
			_harmony = new Harmony("dark.nojunkpickup");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("No Junk Pickup 1.2.0 loaded. Blacklist: " + string.Join(", ", BlacklistSet) + ". " + $"Toggle key: {ToggleKey.Value}, inventory key: {InventoryKey.Value}"));
		}

		private void Update()
		{
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				HandleToggleKey();
				HandleInventoryKey();
			}
		}

		private void HandleToggleKey()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (_toggleKeyBroken)
			{
				return;
			}
			try
			{
				KeyboardShortcut value = ToggleKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown() && !IsTyping())
				{
					Enabled.Value = !Enabled.Value;
					if (ShowToggleMessage.Value)
					{
						string text = (Enabled.Value ? "ON" : "OFF");
						ShowMessage("Auto pickup blacklist: " + text);
					}
				}
			}
			catch (Exception arg)
			{
				_toggleKeyBroken = true;
				((BaseUnityPlugin)this).Logger.LogError((object)$"Toggle key disabled due to an error: {arg}");
			}
		}

		private void HandleInventoryKey()
		{
			//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)
			if (_inventoryKeyBroken || _getHoveredElement == null)
			{
				return;
			}
			try
			{
				if (!InventoryGui.IsVisible() || IsTyping())
				{
					return;
				}
				KeyboardShortcut value = InventoryKey.Value;
				if (!((KeyboardShortcut)(ref value)).IsDown())
				{
					return;
				}
				ItemData hoveredItem = GetHoveredItem();
				if (hoveredItem == null)
				{
					return;
				}
				string id = GetItemId(hoveredItem);
				if (string.IsNullOrEmpty(id))
				{
					return;
				}
				string text = Localize(hoveredItem.m_shared?.m_name) ?? id;
				if (BlacklistSet.Contains(id))
				{
					SetBlacklist(BlacklistSet.Where((string x) => !x.Equals(id, StringComparison.OrdinalIgnoreCase)));
					ShowMessage(text + " removed from blacklist");
				}
				else
				{
					SetBlacklist(BlacklistSet.Concat(new string[1] { id }));
					ShowMessage(text + " added to blacklist");
				}
			}
			catch (Exception arg)
			{
				_inventoryKeyBroken = true;
				((BaseUnityPlugin)this).Logger.LogError((object)$"Inventory key disabled due to an error: {arg}");
			}
		}

		private static ItemData GetHoveredItem()
		{
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			string[] array = new string[2] { "m_playerGrid", "m_containerGrid" };
			foreach (string text in array)
			{
				InventoryGrid value = Traverse.Create((object)instance).Field(text).GetValue<InventoryGrid>();
				if ((Object)(object)value == (Object)null || !((Component)value).gameObject.activeInHierarchy)
				{
					continue;
				}
				object obj = _getHoveredElement.Invoke(value, null);
				if (obj != null)
				{
					Traverse val = Traverse.Create(obj).Property("Position", (object[])null);
					int value2 = val.Field("x").GetValue<int>();
					int value3 = val.Field("y").GetValue<int>();
					Inventory gridInventory = GetGridInventory(value);
					ItemData val2 = ((gridInventory != null) ? gridInventory.GetItemAt(value2, value3) : null);
					if (val2 != null)
					{
						return val2;
					}
				}
			}
			return null;
		}

		private static Inventory GetGridInventory(InventoryGrid grid)
		{
			Traverse val = Traverse.Create((object)grid);
			Traverse val2 = val.Method("GetInventory", Array.Empty<object>());
			if (val2.MethodExists())
			{
				return val2.GetValue<Inventory>();
			}
			Traverse val3 = val.Field("m_inventory");
			return val3.FieldExists() ? val3.GetValue<Inventory>() : null;
		}

		private static void SetBlacklist(IEnumerable<string> ids)
		{
			Blacklist.Value = string.Join(",", ids.Distinct<string>(StringComparer.OrdinalIgnoreCase));
		}

		private static bool IsTyping()
		{
			return Console.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || TextInput.IsVisible() || Menu.IsVisible();
		}

		private static void ShowMessage(string text)
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)1, text, 0, (Sprite)null, false);
			}
		}

		private static string Localize(string token)
		{
			if (string.IsNullOrEmpty(token))
			{
				return null;
			}
			try
			{
				Type type = AccessTools.TypeByName("Localization");
				if (type == null)
				{
					return null;
				}
				object obj = Traverse.Create(type).Property("instance", (object[])null).GetValue() ?? Traverse.Create(type).Field("m_instance").GetValue();
				if (obj == null)
				{
					return null;
				}
				return Traverse.Create(obj).Method("Localize", new Type[1] { typeof(string) }, (object[])null).GetValue<string>(new object[1] { token });
			}
			catch
			{
				return null;
			}
		}

		private void OnDestroy()
		{
			RestoreAll();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		internal static void RebuildBlacklist()
		{
			BlacklistSet = new HashSet<string>(from s in Blacklist.Value.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim() into s
				where s.Length > 0
				select s, StringComparer.OrdinalIgnoreCase);
		}

		internal static bool IsBlacklisted(ItemDrop item)
		{
			if (!Enabled.Value || (Object)(object)item == (Object)null)
			{
				return false;
			}
			return BlacklistSet.Contains(GetItemId(item));
		}

		private static string GetItemId(ItemDrop item)
		{
			string itemId = GetItemId(item.m_itemData);
			if (!string.IsNullOrEmpty(itemId))
			{
				return itemId;
			}
			string name = ((Object)((Component)item).gameObject).name;
			int num = name.IndexOf("(Clone)", StringComparison.Ordinal);
			return ((num >= 0) ? name.Substring(0, num) : name).Trim();
		}

		private static string GetItemId(ItemData data)
		{
			return ((Object)(object)data?.m_dropPrefab != (Object)null) ? ((Object)data.m_dropPrefab).name : null;
		}

		internal static void Refresh(ItemDrop item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return;
			}
			if (IsBlacklisted(item))
			{
				if (item.m_autoPickup)
				{
					item.m_autoPickup = false;
					DisabledByMod.Add(item);
				}
			}
			else if (DisabledByMod.Remove(item))
			{
				item.m_autoPickup = true;
			}
		}

		internal static void RefreshAllItems()
		{
			DisabledByMod.RemoveWhere((ItemDrop i) => (Object)(object)i == (Object)null);
			ItemDrop[] array = Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0);
			foreach (ItemDrop item in array)
			{
				Refresh(item);
			}
		}

		internal static void RestoreAll()
		{
			foreach (ItemDrop item in DisabledByMod)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.m_autoPickup = true;
				}
			}
			DisabledByMod.Clear();
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "Awake")]
	internal static class ItemDropAwakePatch
	{
		private static void Postfix(ItemDrop __instance)
		{
			Plugin.Refresh(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "OnPlayerDrop")]
	internal static class ItemDropOnPlayerDropPatch
	{
		private static void Postfix(ItemDrop __instance)
		{
			Plugin.DisabledByMod.Remove(__instance);
		}
	}
}