Decompiled source of WorldItemDropDisplay v1.1.0

WorldItemDropDisplay.dll

Decompiled 2 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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("WorldItemDropDisplay")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("WorldItemDropDisplay")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.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 WorldItemDropDisplay
{
	[RequireComponent(typeof(ItemDrop))]
	public class DataDisplayBehaviour : MonoBehaviour
	{
		private ItemDrop _drop;

		private GameObject _ui;

		private RectTransform _rt;

		private Image _bkg;

		private Image _icon;

		private Image _equipped;

		private Image _noteleport;

		private Image _food;

		private TMP_Text _amountText;

		private TMP_Text _qualityText;

		private TMP_Text _bindingText;

		private GuiBar _durabilityBar;

		private int _lastStack = -1;

		private int _lastQuality = -1;

		private string _lastName = "";

		private float _lastDurPct = -1f;

		private Sprite _lastIcon;

		private Color _lastFoodColor;

		private void Awake()
		{
			_drop = ((Component)this).GetComponent<ItemDrop>();
			ItemDropDisplayManager instance = ItemDropDisplayManager.Instance;
			_ui = instance.Pool.Get();
			((Object)_ui).name = "DataDisplay_" + ((Object)_drop).GetInstanceID();
			Transform transform = _ui.transform;
			_rt = _ui.GetComponent<RectTransform>();
			_bkg = _ui.GetComponent<Image>();
			_icon = ((Component)transform.Find("icon")).GetComponent<Image>();
			_amountText = ((Component)transform.Find("amount")).GetComponent<TMP_Text>();
			_qualityText = ((Component)transform.Find("quality")).GetComponent<TMP_Text>();
			_bindingText = ((Component)transform.Find("binding")).GetComponent<TMP_Text>();
			_equipped = ((Component)transform.Find("equiped")).GetComponent<Image>();
			_noteleport = ((Component)transform.Find("noteleport")).GetComponent<Image>();
			_food = ((Component)transform.Find("foodicon")).GetComponent<Image>();
			_durabilityBar = ((Component)transform.Find("durability")).GetComponent<GuiBar>();
			((Behaviour)_bkg).enabled = WorldItemDropDisplayPlugin.ShowUIBackground.Value.IsOn();
			instance.RegisterBehaviour(this);
			RefreshData();
			StackPatch.OnStackChanged += OnStackChanged;
			ItemDropDisplayManager.Instance.SettingsChanged += OnConfigChanged;
		}

		private void OnDestroy()
		{
			StackPatch.OnStackChanged -= OnStackChanged;
			ItemDropDisplayManager.Instance.SettingsChanged -= OnConfigChanged;
			if (!((Object)(object)_ui == (Object)null) && !((Object)(object)ItemDropDisplayManager.Instance == (Object)null))
			{
				ItemDropDisplayManager.Instance.UnregisterBehaviour(this);
				ItemDropDisplayManager.Instance.Pool.Release(_ui);
			}
		}

		private void OnStackChanged(ItemDrop d)
		{
			if ((Object)(object)d == (Object)(object)_drop)
			{
				RefreshData();
			}
		}

		private void OnConfigChanged()
		{
			((Behaviour)_bkg).enabled = WorldItemDropDisplayPlugin.ShowUIBackground.Value.IsOn();
			RefreshData();
		}

		private void RefreshData()
		{
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Invalid comparison between Unknown and I4
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: 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_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			ItemData itemData = _drop.m_itemData;
			SharedData shared = itemData.m_shared;
			Sprite icon = itemData.GetIcon();
			if ((Object)(object)_lastIcon != (Object)(object)icon)
			{
				_icon.sprite = icon;
				_lastIcon = icon;
			}
			if (WorldItemDropDisplayPlugin.ShowAmount.Value.IsOn() && shared.m_maxStackSize > 1)
			{
				int stack = itemData.m_stack;
				if (_lastStack != stack)
				{
					_amountText.text = stack.ToString();
					_lastStack = stack;
				}
				((Behaviour)_amountText).enabled = true;
			}
			else
			{
				((Behaviour)_amountText).enabled = false;
			}
			if (WorldItemDropDisplayPlugin.ShowQuality.Value.IsOn() && shared.m_maxQuality > 1)
			{
				int quality = itemData.m_quality;
				if (_lastQuality != quality)
				{
					_qualityText.text = quality.ToString();
					_lastQuality = quality;
				}
				((Behaviour)_qualityText).enabled = true;
			}
			else
			{
				((Behaviour)_qualityText).enabled = false;
			}
			if (WorldItemDropDisplayPlugin.ShowName.Value.IsOn() && !string.IsNullOrWhiteSpace(shared.m_name))
			{
				string name = shared.m_name;
				if (_lastName != name)
				{
					_bindingText.text = Localization.instance.Localize(name);
					_lastName = name;
				}
				((Behaviour)_bindingText).enabled = true;
			}
			else
			{
				((Behaviour)_bindingText).enabled = false;
			}
			float durabilityPercentage = itemData.GetDurabilityPercentage();
			bool flag = WorldItemDropDisplayPlugin.ShowDurability.Value.IsOn() && shared.m_useDurability && shared.m_maxDurability > 0f && durabilityPercentage < 1f;
			((Component)_durabilityBar).gameObject.SetActive(flag);
			if (flag && !Mathf.Approximately(_lastDurPct, durabilityPercentage))
			{
				_durabilityBar.SetValue(durabilityPercentage);
				_lastDurPct = durabilityPercentage;
			}
			bool enabled = WorldItemDropDisplayPlugin.ShowNoTeleport.Value.IsOn() && !shared.m_teleportable && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)29);
			((Behaviour)_noteleport).enabled = enabled;
			bool flag2 = WorldItemDropDisplayPlugin.ShowFoodIcon.Value.IsOn() && (int)shared.m_itemType == 2 && (shared.m_food > 0f || shared.m_foodStamina > 0f || shared.m_foodEitr > 0f);
			((Behaviour)_food).enabled = flag2;
			if (flag2)
			{
				Color val = ((shared.m_food < shared.m_foodEitr / 2f && shared.m_foodStamina < shared.m_foodEitr / 2f) ? ItemDropDisplayManager.Instance.m_foodEitrColor : ((shared.m_foodStamina < shared.m_food / 2f) ? ItemDropDisplayManager.Instance.m_foodHealthColor : ((!(shared.m_food < shared.m_foodStamina / 2f)) ? Color.white : ItemDropDisplayManager.Instance.m_foodStaminaColor)));
				if (_lastFoodColor != val)
				{
					((Graphic)_food).color = val;
					_lastFoodColor = val;
				}
			}
			((Behaviour)_equipped).enabled = itemData.m_equipped;
		}

		public void UpdatePosition(Vector3 playerPos, Camera cam, Vector3 offset, float maxDistSqr, bool hideAll)
		{
			//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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			if (hideAll)
			{
				if (_ui.activeSelf)
				{
					_ui.SetActive(false);
				}
				return;
			}
			Vector3 position = ((Component)_drop).transform.position;
			if ((int)_drop.m_itemData.m_shared.m_itemType == 21)
			{
				Fish component = ((Component)_drop).GetComponent<Fish>();
				if ((Object)(object)component != (Object)null && (!component.IsOutOfWater() || (component != null && component.m_isJumping && !component.m_jumpedFromLand)))
				{
					if (_ui.activeSelf)
					{
						_ui.SetActive(false);
					}
					return;
				}
			}
			Vector3 val = position - playerPos;
			if (((Vector3)(ref val)).sqrMagnitude > maxDistSqr)
			{
				if (_ui.activeSelf)
				{
					_ui.SetActive(false);
				}
				return;
			}
			Vector3 val2 = Utils.WorldToScreenPointScaled(cam, position + offset);
			bool flag = val2.z >= 0f;
			if (_ui.activeSelf != flag)
			{
				_ui.SetActive(flag);
			}
			if (flag)
			{
				((Transform)_rt).position = val2;
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "Start")]
	internal static class ItemDropDisplayAttachPatch
	{
		private static void Postfix(ItemDrop __instance)
		{
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<DataDisplayBehaviour>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<DataDisplayBehaviour>();
			}
		}
	}
	public static class StackPatch
	{
		[HarmonyPatch(typeof(ItemDrop), "SetStack")]
		private static class Patch_SetStack
		{
			private static void Postfix(ItemDrop __instance)
			{
				if (__instance.m_nview.IsValid() && __instance.m_nview.IsOwner())
				{
					StackPatch.OnStackChanged?.Invoke(__instance);
				}
			}
		}

		public static event Action<ItemDrop> OnStackChanged;
	}
	[HarmonyPatch(typeof(InventoryGrid), "Awake")]
	internal static class CloneInventoryElementInventoryGridAwakePatch
	{
		[HarmonyPriority(0)]
		private static void Postfix(InventoryGrid __instance)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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)
			Tutorial instance = Tutorial.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				RectTransform windowRoot = instance.m_windowRoot;
				obj = ((windowRoot != null) ? ((Transform)windowRoot).parent : null);
			}
			Transform val = (Transform)obj;
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Find("DataDisplayTemplate") != (Object)null))
			{
				GameObject val2 = Object.Instantiate<GameObject>(__instance.m_elementPrefab, val);
				((Object)val2).name = "DataDisplayTemplate";
				Object.Destroy((Object)(object)((Component)val2.transform.Find("queued")).gameObject);
				Object.Destroy((Object)(object)((Component)val2.transform.Find("selected")).gameObject);
				((Component)val2.transform.Find("binding")).GetComponent<RectTransform>().pivot = new Vector2(0f, 0f);
				if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.jewelcrafting"))
				{
					Object.Destroy((Object)(object)((Component)val2.transform.Find("JC_ItemBackground")).gameObject);
				}
				val2.SetActive(false);
				GameObject gameObject = ((Component)val2.transform.Find("binding")).gameObject;
				TMP_Text component = gameObject.GetComponent<TMP_Text>();
				if ((Object)(object)component != (Object)null)
				{
					gameObject.GetComponent<RectTransform>().anchorMax = new Vector2(0.5f, 1f);
					gameObject.GetComponent<RectTransform>().anchorMin = new Vector2(0f, 1f);
					component.enableAutoSizing = true;
					component.autoSizeTextContainer = true;
					component.textWrappingMode = (TextWrappingModes)0;
					component.fontSizeMax = 18f;
					component.fontSizeMin = 16f;
				}
				if ((Object)(object)Tutorial.instance != (Object)null && (Object)(object)((Component)Tutorial.instance).gameObject.GetComponent<ItemDropDisplayManager>() == (Object)null)
				{
					((Component)Tutorial.instance).gameObject.AddComponent<ItemDropDisplayManager>();
				}
			}
		}
	}
	public class ItemDropDisplayManager : MonoBehaviour
	{
		public const string TemplateName = "DataDisplayTemplate";

		public const string HideWidd = "WIDD";

		[Tooltip("How often (seconds) to refresh positions")]
		[SerializeField]
		private float positionInterval = WorldItemDropDisplayPlugin.ItemPositionInterval.Value;

		[Tooltip("Maximum distance to show the display")]
		[SerializeField]
		private float maxDisplayDistance = WorldItemDropDisplayPlugin.ItemMaxDisplayDistance.Value;

		[Tooltip("Vertical offset above the item")]
		[SerializeField]
		private Vector3 worldOffset = WorldItemDropDisplayPlugin.ItemWorldOffset.Value;

		private GameObject _template;

		private Transform _templateParent;

		private float _maxDistSqr;

		private float _posTimer;

		private Camera _cam;

		private Transform _playerTransform;

		public readonly Color m_foodEitrColor = new Color(0.6f, 0.6f, 1f, 1f);

		public readonly Color m_foodHealthColor = new Color(1f, 0.5f, 0.5f, 1f);

		public readonly Color m_foodStaminaColor = new Color(1f, 1f, 0.5f, 1f);

		public IObjectPool<GameObject> Pool;

		private readonly List<DataDisplayBehaviour> _behaviours = new List<DataDisplayBehaviour>();

		public static ItemDropDisplayManager Instance { get; private set; }

		public event Action SettingsChanged;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			_maxDistSqr = maxDisplayDistance * maxDisplayDistance;
			WorldItemDropDisplayPlugin.ShowUIBackground.SettingChanged += RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowAmount.SettingChanged += RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowQuality.SettingChanged += RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowDurability.SettingChanged += RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowNoTeleport.SettingChanged += RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowFoodIcon.SettingChanged += RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowName.SettingChanged += RaiseSettingsChanged;
		}

		private void Start()
		{
			_cam = Utils.GetMainCamera();
			if ((Object)(object)_cam == (Object)null)
			{
				_cam = Camera.main;
			}
			if ((Object)(object)_cam == (Object)null)
			{
				WorldItemDropDisplayPlugin.WorldItemDropDisplayLogger.LogError((object)"No camera found for ItemDropDisplayManager");
				return;
			}
			_template = ((Component)((Component)((Transform)Tutorial.instance.m_windowRoot).parent).transform.Find("DataDisplayTemplate")).gameObject;
			if ((Object)(object)_template == (Object)null)
			{
				WorldItemDropDisplayPlugin.WorldItemDropDisplayLogger.LogError((object)"[ItemDropDisplayManager] DataDisplayTemplate not found!");
				((Behaviour)this).enabled = false;
				return;
			}
			_templateParent = _template.transform.parent;
			Pool = (IObjectPool<GameObject>)(object)new ObjectPool<GameObject>((Func<GameObject>)CreatePooledItem, (Action<GameObject>)null, (Action<GameObject>)delegate(GameObject go)
			{
				go.SetActive(false);
			}, (Action<GameObject>)delegate(GameObject go)
			{
				Object.Destroy((Object)(object)go);
			}, false, 16, 512);
		}

		private void OnDestroy()
		{
			WorldItemDropDisplayPlugin.ShowUIBackground.SettingChanged -= RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowAmount.SettingChanged -= RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowQuality.SettingChanged -= RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowDurability.SettingChanged -= RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowNoTeleport.SettingChanged -= RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowFoodIcon.SettingChanged -= RaiseSettingsChanged;
			WorldItemDropDisplayPlugin.ShowName.SettingChanged -= RaiseSettingsChanged;
		}

		private GameObject CreatePooledItem()
		{
			//IL_0022: 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)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(_template, _templateParent);
			RectTransform component = obj.GetComponent<RectTransform>();
			component.pivot = new Vector2(0.5f, 0.5f);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			component.anchorMax = val;
			component.anchorMin = val;
			obj.SetActive(false);
			return obj;
		}

		public void RegisterBehaviour(DataDisplayBehaviour beh)
		{
			_behaviours.Add(beh);
		}

		public void UnregisterBehaviour(DataDisplayBehaviour beh)
		{
			_behaviours.Remove(beh);
		}

		public void UpdatePositionInterval(float v)
		{
			positionInterval = v;
		}

		public void UpdateMaxDisplayDistance(float v)
		{
			maxDisplayDistance = v;
			_maxDistSqr = v * v;
		}

		public void UpdateWorldOffset(Vector3 v)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			worldOffset = v;
		}

		private void Update()
		{
			_posTimer += Time.unscaledDeltaTime;
			while (_posTimer >= positionInterval)
			{
				_posTimer -= positionInterval;
				UpdatePositions();
			}
		}

		private void UpdatePositions()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_cam == (Object)null)
			{
				_cam = Utils.GetMainCamera();
			}
			if ((Object)(object)_playerTransform == (Object)null && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				_playerTransform = ((Component)Player.m_localPlayer).transform;
			}
			if (!((Object)(object)_cam == (Object)null) && !((Object)(object)_playerTransform == (Object)null) && _behaviours.Count != 0)
			{
				bool hideAll = InventoryGui.IsVisible() || Minimap.IsOpen() || StoreGui.IsVisible() || Hud.IsPieceSelectionVisible() || !((Character)Player.m_localPlayer).TakeInput() || Player.m_localPlayer.m_customData.ContainsKey("WIDD");
				Vector3 position = _playerTransform.position;
				int i = 0;
				for (int count = _behaviours.Count; i < count; i++)
				{
					_behaviours[i].UpdatePosition(position, _cam, worldOffset, _maxDistSqr, hideAll);
				}
			}
		}

		private void RaiseSettingsChanged(object _, EventArgs __)
		{
			this.SettingsChanged?.Invoke();
		}
	}
	[BepInPlugin("Azumatt.WorldItemDropDisplay", "WorldItemDropDisplay", "1.1.0")]
	public class WorldItemDropDisplayPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			Off,
			On
		}

		internal const string ModName = "WorldItemDropDisplay";

		internal const string ModVersion = "1.1.0";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.WorldItemDropDisplay";

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

		private static string ConfigFileFullPath = Path.Combine(Paths.ConfigPath, ConfigFileName);

		internal static string ConnectionError = "";

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

		public static readonly ManualLogSource WorldItemDropDisplayLogger = Logger.CreateLogSource("WorldItemDropDisplay");

		private FileSystemWatcher _watcher;

		private readonly object _reloadLock = new object();

		private DateTime _lastConfigReloadTime;

		private const long RELOAD_DELAY = 10000000L;

		internal static ConfigEntry<float> ItemPositionInterval = null;

		internal static ConfigEntry<float> ItemMaxDisplayDistance = null;

		internal static ConfigEntry<Vector3> ItemWorldOffset = null;

		internal static ConfigEntry<Toggle> ShowUIBackground = null;

		internal static ConfigEntry<Toggle> ShowAmount = null;

		internal static ConfigEntry<Toggle> ShowQuality = null;

		internal static ConfigEntry<Toggle> ShowDurability = null;

		internal static ConfigEntry<Toggle> ShowNoTeleport = null;

		internal static ConfigEntry<Toggle> ShowFoodIcon = null;

		internal static ConfigEntry<Toggle> ShowName = null;

		internal static ConfigEntry<KeyboardShortcut> ToggleHotkey = null;

		public void Awake()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			ItemPositionInterval = config("1 - General", "Position Interval", 0.01f, "How often (seconds) to refresh position");
			ItemMaxDisplayDistance = config("1 - General", "Max Display Distance", 10f, "Maximum distance to show the world item display");
			ItemWorldOffset = config<Vector3>("1 - General", "World Item Offset", new Vector3(0f, 0.5f, 0f), "Offset that the world item display will be relative to the item");
			ItemPositionInterval.SettingChanged += delegate
			{
				ItemDropDisplayManager.Instance.UpdatePositionInterval(ItemPositionInterval.Value);
			};
			ItemMaxDisplayDistance.SettingChanged += delegate
			{
				ItemDropDisplayManager.Instance.UpdateMaxDisplayDistance(ItemMaxDisplayDistance.Value);
			};
			ItemWorldOffset.SettingChanged += delegate
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				ItemDropDisplayManager.Instance.UpdateWorldOffset(ItemWorldOffset.Value);
			};
			ShowUIBackground = config("1 - UI", "Show Background", Toggle.Off, "Show the background behind the item, in the item drop display");
			ShowAmount = config("1 - UI", "Show Amount", Toggle.Off, "Show the stack-count text for stackable items, in the item drop display");
			ShowQuality = config("1 - UI", "Show Quality", Toggle.Off, "Show the quality number, in the item drop display");
			ShowDurability = config("1 - UI", "Show Durability", Toggle.Off, "Show the durability bar when applicable, in the item drop display");
			ShowNoTeleport = config("1 - UI", "Show No Teleport Icon", Toggle.Off, "Show icon when item cannot be teleported, in the item drop display");
			ShowFoodIcon = config("1 - UI", "Show Food Icon", Toggle.Off, "Show the food icon for consumables (eitr, health, stamina forks), in the item drop display");
			ShowName = config("1 - UI", "Show Name", Toggle.Off, "Show the item’s localized name");
			ToggleHotkey = config<KeyboardShortcut>("1 - Hotkeys", "Toggle ItemDrop Display", new KeyboardShortcut((KeyCode)102, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Toggle the item drop display on and off. The display will still turn off when other UI elements are open ignoring this.");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
			((BaseUnityPlugin)this).Config.Save();
			if (saveOnConfigSet)
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
			}
		}

		private void Update()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && ToggleHotkey.Value.IsKeyDown() && ((Character)localPlayer).TakeInput())
			{
				if (localPlayer.m_customData.TryGetValue("WIDD", out var _))
				{
					localPlayer.m_customData.Remove("WIDD");
				}
				else
				{
					localPlayer.m_customData.Add("WIDD", "1");
				}
			}
		}

		private void OnDestroy()
		{
			SaveWithRespectToConfigSet();
			_watcher?.Dispose();
		}

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

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			DateTime now = DateTime.Now;
			if (now.Ticks - _lastConfigReloadTime.Ticks < 10000000)
			{
				return;
			}
			lock (_reloadLock)
			{
				if (!File.Exists(ConfigFileFullPath))
				{
					WorldItemDropDisplayLogger.LogWarning((object)"Config file does not exist. Skipping reload.");
					return;
				}
				try
				{
					WorldItemDropDisplayLogger.LogDebug((object)"Reloading configuration...");
					SaveWithRespectToConfigSet(reload: true);
					WorldItemDropDisplayLogger.LogInfo((object)"Configuration reload complete.");
				}
				catch (Exception ex)
				{
					WorldItemDropDisplayLogger.LogError((object)("Error reloading configuration: " + ex.Message));
				}
			}
			_lastConfigReloadTime = now;
		}

		private void SaveWithRespectToConfigSet(bool reload = false)
		{
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			if (reload)
			{
				((BaseUnityPlugin)this).Config.Reload();
			}
			((BaseUnityPlugin)this).Config.Save();
			if (saveOnConfigSet)
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
			}
		}

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

		private 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>()));
		}
	}
	public static class ToggleExtensions
	{
		public static bool IsOn(this WorldItemDropDisplayPlugin.Toggle toggle)
		{
			return toggle == WorldItemDropDisplayPlugin.Toggle.On;
		}

		public static bool IsOff(this WorldItemDropDisplayPlugin.Toggle toggle)
		{
			return toggle == WorldItemDropDisplayPlugin.Toggle.Off;
		}
	}
	public static class KeyboardExtensions
	{
		public static bool IsKeyDown(this KeyboardShortcut shortcut)
		{
			//IL_0002: 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)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
			}
			return false;
		}

		public static bool IsKeyHeld(this KeyboardShortcut shortcut)
		{
			//IL_0002: 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)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
			}
			return false;
		}
	}
}