Decompiled source of OwnedItemRecovery v1.0.0

BepInEx/plugins/OwnedItemRecovery/OwnedItemRecovery.dll

Decompiled 17 hours 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using HowtoFishIdentityAPI.Api;
using HowtoFishLocalizationAPI.Api;
using Newtonsoft.Json;
using OwnedItemRecovery.Configuration;
using OwnedItemRecovery.Localization;
using OwnedItemRecovery.Runtime;
using OwnedItemRecovery.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OwnedItemRecovery")]
[assembly: AssemblyDescription("Owned Item Recovery for How to Fish by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("OwnedItemRecovery")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: ComVisible(false)]
[assembly: Guid("73f7f5bf-64e5-4e2a-9bbf-4e7a3f36dcf4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OwnedItemRecovery
{
	[BepInPlugin("IceBoxStudio.HowToFish.OwnedItemRecovery", "OwnedItemRecovery", "1.0.0")]
	[BepInDependency("IceBoxStudio.HowToFish.LocalizationAPI", "1.0.0")]
	[BepInDependency("IceBoxStudio.HowToFish.IdentityAPI", "1.0.0")]
	public sealed class OwnedItemRecoveryPlugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				Log.LogInfo((object)"=============================================");
				Log.LogInfo((object)("OwnedItemRecovery " + I18n.Text("plugin.initializing")));
				Log.LogInfo((object)(I18n.Text("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
				ConfigManager.Init(((BaseUnityPlugin)this).Config);
				OwnedItemRuntime.Init(((BaseUnityPlugin)this).Logger);
				_harmony = new Harmony("IceBoxStudio.HowToFish.OwnedItemRecovery");
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				Log.LogInfo((object)("OwnedItemRecovery " + I18n.Text("plugin.initialized")));
				Log.LogInfo((object)"=============================================");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to initialize OwnedItemRecovery: {arg}");
			}
		}

		private void Update()
		{
			OwnedItemRuntime.Update();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.HowToFish.OwnedItemRecovery";

		public const string PLUGIN_NAME = "OwnedItemRecovery";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace OwnedItemRecovery.UI
{
	internal sealed class OwnedItemUi : MonoBehaviour
	{
		private static readonly BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic;

		private static OwnedItemUi _current;

		private GameObject _pauseHolder;

		private GameObject _mainScreen;

		private GameObject _optionsScreen;

		private GameObject _serverScreen;

		private GameObject _root;

		private GameObject _buttonTemplate;

		private Transform _rows;

		private TextMeshProUGUI _title;

		private TextMeshProUGUI _summary;

		private TextMeshProUGUI _allLabel;

		private TextMeshProUGUI _closeLabel;

		private Button _allButton;

		private bool _open;

		private bool _built;

		internal static bool IsOpen
		{
			get
			{
				if (Object.op_Implicit((Object)(object)_current))
				{
					return _current._open;
				}
				return false;
			}
		}

		internal static void Attach()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_current))
			{
				Transform fXCanvasTrans = PlayerUI.FXCanvasTrans;
				if (Object.op_Implicit((Object)(object)fXCanvasTrans))
				{
					GameObject val = new GameObject("OwnedItemRecovery UI");
					val.transform.SetParent(fXCanvasTrans, false);
					_current = val.AddComponent<OwnedItemUi>();
					_current.TryBuild();
				}
			}
		}

		internal static void Open()
		{
			Attach();
			if (Object.op_Implicit((Object)(object)_current))
			{
				_current.Show();
			}
		}

		internal static void Toggle()
		{
			if (IsOpen)
			{
				_current.Hide();
			}
			else
			{
				Open();
			}
		}

		internal static void RefreshAll()
		{
			if (Object.op_Implicit((Object)(object)_current) && _current._open)
			{
				_current.Refresh();
			}
		}

		internal static void DestroyCurrent()
		{
			if (Object.op_Implicit((Object)(object)_current))
			{
				if (Object.op_Implicit((Object)(object)_current._root))
				{
					Object.Destroy((Object)(object)_current._root);
				}
				Object.Destroy((Object)(object)((Component)_current).gameObject);
			}
			_current = null;
		}

		private bool Build(PauseManager pause, GameObject holder)
		{
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: 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_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: 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_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Expected O, but got Unknown
			_pauseHolder = holder;
			_mainScreen = GetObject(pause, "_mainScreen");
			_optionsScreen = GetObject(pause, "_optionsScreen");
			_serverScreen = GetObject(pause, "_serverSettingsScreen");
			if (!Object.op_Implicit((Object)(object)_serverScreen))
			{
				return false;
			}
			_root = Object.Instantiate<GameObject>(_serverScreen, _pauseHolder.transform, false);
			((Object)_root).name = "OwnedItemRecoveryScreen";
			_root.SetActive(false);
			Transform val = _root.transform.Find("PausedText");
			Transform val2 = _root.transform.Find("ServerDisplay");
			Transform val3 = _root.transform.Find("LowerButtonHolder/BackButton");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3))
			{
				return false;
			}
			_title = ((Component)val).GetComponent<TextMeshProUGUI>();
			_buttonTemplate = ((Component)val3).gameObject;
			Button val4 = UseButton(_buttonTemplate);
			_closeLabel = GetText(_buttonTemplate);
			if ((Object)(object)_title == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)_closeLabel == (Object)null)
			{
				return false;
			}
			((UnityEvent)val4.onClick).AddListener(new UnityAction(Hide));
			DisableForeignComponents(((Component)_title).gameObject);
			GameObject gameObject = ((Component)val2).gameObject;
			TextMeshProUGUI componentInChildren = ((Component)val2).GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return false;
			}
			foreach (Transform item in _root.transform)
			{
				Transform val5 = item;
				if ((Object)(object)val5 != (Object)(object)val && (Object)(object)val5 != (Object)(object)val2 && (Object)(object)val5 != (Object)(object)val3.parent)
				{
					((Component)val5).gameObject.SetActive(false);
				}
			}
			foreach (Transform item2 in val2)
			{
				Transform val6 = item2;
				if (((Object)val6).name != "Outline")
				{
					((Component)val6).gameObject.SetActive(false);
				}
			}
			RectTransform component = gameObject.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = new Vector2(860f, 580f);
			GameObject val7 = new GameObject("OwnedItemContent");
			val7.transform.SetParent(val2, false);
			RectTransform val8 = val7.AddComponent<RectTransform>();
			val8.anchorMin = Vector2.zero;
			val8.anchorMax = Vector2.one;
			val8.offsetMin = new Vector2(28f, 24f);
			val8.offsetMax = new Vector2(-28f, -24f);
			((Transform)val8).localScale = Vector3.one;
			((Transform)val8).SetAsLastSibling();
			VerticalLayoutGroup obj = val7.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			_summary = AddText(componentInChildren, (Transform)(object)val8, "Summary", 20f, 32f, (TextAlignmentOptions)514);
			BuildRows((Transform)(object)val8, componentInChildren);
			GameObject val9 = new GameObject("Footer");
			val9.transform.SetParent((Transform)(object)val8, false);
			val9.AddComponent<LayoutElement>().preferredHeight = 48f;
			HorizontalLayoutGroup obj2 = val9.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			GameObject val10 = MakeButton(_buttonTemplate, val9.transform, "RecoverAll");
			_allButton = GetButton(val10);
			_allLabel = GetText(val10);
			if ((Object)(object)_allButton == (Object)null || (Object)(object)_allLabel == (Object)null)
			{
				return false;
			}
			ConfigureButtonText(_allLabel, 12f, Mathf.Max(18f, ((TMP_Text)_allLabel).fontSize));
			((UnityEvent)_allButton.onClick).AddListener(new UnityAction(RecoverAll));
			(val10.GetComponent<LayoutElement>() ?? val10.AddComponent<LayoutElement>()).preferredHeight = 48f;
			LocalizationApi.LanguageChanged += OnLanguageChanged;
			Refresh();
			return true;
		}

		private void BuildRows(Transform parent, TextMeshProUGUI nativeText)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_00a0: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_0103: 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)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("OwnedItemViewport");
			val.transform.SetParent(parent, false);
			val.AddComponent<LayoutElement>().preferredHeight = 390f;
			RectTransform val2 = val.GetComponent<RectTransform>() ?? val.AddComponent<RectTransform>();
			((Transform)val2).localScale = Vector3.one;
			((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.08f);
			val.AddComponent<RectMask2D>();
			ScrollRect obj = val.AddComponent<ScrollRect>();
			obj.horizontal = false;
			obj.vertical = true;
			obj.movementType = (MovementType)1;
			obj.scrollSensitivity = 30f;
			GameObject val3 = new GameObject("Rows");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.GetComponent<RectTransform>() ?? val3.AddComponent<RectTransform>();
			val4.anchorMin = new Vector2(0f, 1f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(0.5f, 1f);
			val4.anchoredPosition = Vector2.zero;
			val4.sizeDelta = new Vector2(0f, 0f);
			((Transform)val4).localScale = Vector3.one;
			VerticalLayoutGroup obj2 = val3.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			ContentSizeFitter obj3 = val3.AddComponent<ContentSizeFitter>();
			obj3.horizontalFit = (FitMode)0;
			obj3.verticalFit = (FitMode)2;
			obj.viewport = val2;
			obj.content = val4;
			_rows = val3.transform;
		}

		private bool TryBuild()
		{
			if (_built)
			{
				return true;
			}
			PauseManager val = Object.FindAnyObjectByType<PauseManager>();
			GameObject val2 = (Object.op_Implicit((Object)(object)val) ? GetObject(val, "_pauseHolder") : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
				_root = null;
			}
			if (!Build(val, val2))
			{
				if (Object.op_Implicit((Object)(object)_root))
				{
					Object.Destroy((Object)(object)_root);
					_root = null;
				}
				return false;
			}
			_built = true;
			return true;
		}

		private void Update()
		{
			if (Object.op_Implicit((Object)(object)Player.LocalPlayer) && !MainMenuManager.IsInMenu && (_built || TryBuild()) && _open && Input.GetKeyDown((KeyCode)27))
			{
				Hide();
			}
		}

		private void OnDestroy()
		{
			LocalizationApi.LanguageChanged -= OnLanguageChanged;
			if ((Object)(object)_current == (Object)(object)this)
			{
				_current = null;
			}
		}

		private void OnLanguageChanged(string language)
		{
			Refresh();
		}

		private void Show()
		{
			if (!_built && !TryBuild())
			{
				return;
			}
			if (_open)
			{
				Refresh();
				return;
			}
			_open = true;
			_root.SetActive(true);
			HideNativeScreens();
			PauseManager.TogglePause(true);
			HideNativeScreens();
			_root.SetActive(true);
			Refresh();
			if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)_allButton != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject(((Component)_allButton).gameObject);
			}
		}

		private void Hide()
		{
			if (_open)
			{
				_open = false;
				if (Object.op_Implicit((Object)(object)_root))
				{
					_root.SetActive(false);
				}
				PauseManager.TogglePause(false);
			}
		}

		private void HideNativeScreens()
		{
			if (Object.op_Implicit((Object)(object)_mainScreen))
			{
				_mainScreen.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_optionsScreen))
			{
				_optionsScreen.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_serverScreen))
			{
				_serverScreen.SetActive(false);
			}
		}

		private void RecoverAll()
		{
			OwnedItemRuntime.RecoverAll();
		}

		private void RecoverSingle(int objectId)
		{
			OwnedItemRuntime.RecoverSingle(objectId);
		}

		private void Refresh()
		{
			if ((Object)(object)_title == (Object)null || (Object)(object)_summary == (Object)null || (Object)(object)_allLabel == (Object)null || (Object)(object)_closeLabel == (Object)null || (Object)(object)_rows == (Object)null)
			{
				return;
			}
			List<OwnedItemStateBroadcast> clientStates = OwnedItemRuntime.GetClientStates();
			int num = 0;
			int num2 = 0;
			string text2 = default(string);
			string text = (((Object)(object)Player.LocalPlayer != (Object)null && IdentityApi.TryGetKey(Player.LocalPlayer, ref text2)) ? text2 : null);
			for (int i = 0; i < clientStates.Count; i++)
			{
				if (!string.IsNullOrEmpty(text) && clientStates[i].PlayerKey == text)
				{
					num++;
					if (clientStates[i].HolderSteamID == 0L)
					{
						num2++;
					}
				}
			}
			((TMP_Text)_title).text = I18n.Text("owned.ui.title");
			((TMP_Text)_summary).text = I18n.Text("owned.ui.summary", num, num2);
			((TMP_Text)_allLabel).text = I18n.Text("owned.ui.recover_all");
			((TMP_Text)_closeLabel).text = I18n.Text("owned.ui.close");
			((Selectable)_allButton).interactable = num2 > 0;
			RefreshRows(clientStates, text);
		}

		private void RefreshRows(List<OwnedItemStateBroadcast> states, string localKey)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Expected O, but got Unknown
			for (int num = _rows.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)_rows.GetChild(num)).gameObject);
			}
			bool flag = false;
			for (int i = 0; i < states.Count; i++)
			{
				OwnedItemStateBroadcast ownedItemStateBroadcast = states[i];
				if (string.IsNullOrEmpty(localKey) || ownedItemStateBroadcast.PlayerKey != localKey)
				{
					continue;
				}
				flag = true;
				GameObject val = new GameObject("OwnedItemRow " + ownedItemStateBroadcast.ObjectId);
				val.transform.SetParent(_rows, false);
				val.AddComponent<LayoutElement>().preferredHeight = 56f;
				HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)obj).spacing = 8f;
				((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
				string text = (string.IsNullOrWhiteSpace(ownedItemStateBroadcast.OwnerName) ? ownedItemStateBroadcast.PlayerKey : ownedItemStateBroadcast.OwnerName);
				string text2 = I18n.Text(ownedItemStateBroadcast.DeathDrop ? "owned.ui.death_drop" : "owned.ui.manual_drop");
				string text3 = ((ownedItemStateBroadcast.HolderSteamID == 0L) ? I18n.Text("owned.ui.on_ground") : I18n.Text("owned.ui.on_player", string.IsNullOrWhiteSpace(ownedItemStateBroadcast.HolderName) ? ownedItemStateBroadcast.HolderSteamID.ToString() : ownedItemStateBroadcast.HolderName));
				string text4 = I18n.Text("owned.ui.row", ownedItemStateBroadcast.ItemName, text, text2, text3);
				TextMeshProUGUI val2 = AddText(GetText(_buttonTemplate), val.transform, "Details", 17f, 56f, (TextAlignmentOptions)513);
				((TMP_Text)val2).text = text4;
				(((Component)val2).GetComponent<LayoutElement>() ?? ((Component)val2).gameObject.AddComponent<LayoutElement>()).flexibleWidth = 1f;
				if (ownedItemStateBroadcast.HolderSteamID != 0L)
				{
					continue;
				}
				GameObject val3 = MakeButton(_buttonTemplate, val.transform, "Recover");
				Button button = GetButton(val3);
				TextMeshProUGUI text5 = GetText(val3);
				if ((Object)(object)button == (Object)null || (Object)(object)text5 == (Object)null)
				{
					Object.Destroy((Object)(object)val3);
					continue;
				}
				((TMP_Text)text5).text = I18n.Text("owned.ui.recover");
				ConfigureButtonText(text5, 10f, Mathf.Max(18f, ((TMP_Text)text5).fontSize));
				LayoutElement obj2 = val3.GetComponent<LayoutElement>() ?? val3.AddComponent<LayoutElement>();
				obj2.preferredWidth = 120f;
				obj2.preferredHeight = 56f;
				int objectId = ownedItemStateBroadcast.ObjectId;
				((UnityEvent)button.onClick).AddListener((UnityAction)delegate
				{
					RecoverSingle(objectId);
				});
			}
			if (!flag)
			{
				((TMP_Text)AddText(GetText(_buttonTemplate), _rows, "Empty", 20f, 44f, (TextAlignmentOptions)514)).text = I18n.Text("owned.ui.empty");
			}
		}

		private static TextMeshProUGUI AddText(TextMeshProUGUI template, Transform parent, string name, float size, float height, TextAlignmentOptions alignment)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(template, parent, false);
			((Object)((Component)val).gameObject).name = name;
			((Component)val).gameObject.SetActive(true);
			DisableForeignComponents(((Component)val).gameObject);
			((TMP_Text)val).fontSize = size;
			((TMP_Text)val).alignment = alignment;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).textWrappingMode = (TextWrappingModes)1;
			(((Component)val).GetComponent<LayoutElement>() ?? ((Component)val).gameObject.AddComponent<LayoutElement>()).preferredHeight = height;
			return val;
		}

		private static GameObject MakeButton(GameObject template, Transform parent, string name)
		{
			GameObject obj = Object.Instantiate<GameObject>(template, parent, false);
			((Object)obj).name = name;
			obj.SetActive(true);
			UseButton(obj);
			TextMeshProUGUI text = GetText(obj);
			if ((Object)(object)text != (Object)null)
			{
				((TMP_Text)text).text = string.Empty;
			}
			return obj;
		}

		private static void ConfigureButtonText(TextMeshProUGUI text, float minSize, float maxSize)
		{
			//IL_0011: 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)
			//IL_0031: 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)
			if (!((Object)(object)text == (Object)null))
			{
				RectTransform rectTransform = ((TMP_Text)text).rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.one;
				rectTransform.offsetMin = new Vector2(4f, 2f);
				rectTransform.offsetMax = new Vector2(-4f, -2f);
				((TMP_Text)text).alignment = (TextAlignmentOptions)514;
				((TMP_Text)text).verticalAlignment = (VerticalAlignmentOptions)512;
				((TMP_Text)text).enableAutoSizing = true;
				((TMP_Text)text).fontSizeMin = minSize;
				((TMP_Text)text).fontSizeMax = maxSize;
				((TMP_Text)text).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)text).overflowMode = (TextOverflowModes)0;
				((TMP_Text)text).characterSpacing = 0f;
				((Graphic)text).raycastTarget = false;
			}
		}

		private static Button UseButton(GameObject buttonObject)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Button val = (((Object)(object)buttonObject == (Object)null) ? null : buttonObject.GetComponent<Button>());
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			val.onClick = new ButtonClickedEvent();
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)3;
			((Selectable)val).navigation = navigation;
			return val;
		}

		private static Button GetButton(GameObject root)
		{
			Button[] array = (((Object)(object)root == (Object)null) ? Array.Empty<Button>() : root.GetComponents<Button>());
			for (int num = array.Length - 1; num >= 0; num--)
			{
				if (((Behaviour)array[num]).enabled)
				{
					return array[num];
				}
			}
			return null;
		}

		private static TextMeshProUGUI GetText(GameObject root)
		{
			if (!((Object)(object)root == (Object)null))
			{
				return root.GetComponentInChildren<TextMeshProUGUI>(true);
			}
			return null;
		}

		private static void DisableForeignComponents(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (!(val is Graphic) && !(val is Selectable) && !(val is TMP_Text) && !(val is Shadow) && !(val is LayoutGroup) && !(val is LayoutElement) && !(val is ContentSizeFitter) && !(val is RectMask2D))
				{
					((Behaviour)val).enabled = false;
				}
			}
		}

		private static GameObject GetObject(PauseManager pause, string field)
		{
			object? obj = typeof(PauseManager).GetField(field, PrivateInstance)?.GetValue(pause);
			return (GameObject)((obj is GameObject) ? obj : null);
		}
	}
}
namespace OwnedItemRecovery.Runtime
{
	public struct OwnedItemStateBroadcast : IBroadcast
	{
		public int ObjectId;

		public string PlayerKey;

		public string OwnerName;

		public string ItemName;

		public bool DeathDrop;

		public bool Removed;

		public ulong HolderSteamID;

		public string HolderName;

		public OwnedItemStateBroadcast(int objectId, string playerKey, string ownerName, string itemName, bool deathDrop, bool removed, ulong holderSteamId = 0uL, string holderName = "")
		{
			ObjectId = objectId;
			PlayerKey = playerKey;
			OwnerName = ownerName;
			ItemName = itemName;
			DeathDrop = deathDrop;
			Removed = removed;
			HolderSteamID = holderSteamId;
			HolderName = holderName;
		}
	}
	public struct OwnedItemNoticeBroadcast : IBroadcast
	{
		public string Key;

		public string Arg0;

		public string Arg1;

		public OwnedItemNoticeBroadcast(string key, string arg0 = "", string arg1 = "")
		{
			Key = key;
			Arg0 = arg0;
			Arg1 = arg1;
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct RecoverOwnedItemsBroadcast : IBroadcast
	{
	}
	public struct RecoverSingleOwnedItemBroadcast : IBroadcast
	{
		public int ObjectId;

		public RecoverSingleOwnedItemBroadcast(int objectId)
		{
			ObjectId = objectId;
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct SyncOwnedItemsBroadcast : IBroadcast
	{
	}
	internal static class OwnedItemRuntime
	{
		private sealed class OwnedDrop
		{
			internal Item Item;

			internal string PlayerKey;

			internal string OwnerName;

			internal string ItemName;

			internal byte Island;

			internal float DroppedAt;

			internal bool DeathDrop;

			internal ulong HolderSteamID;

			internal string HolderName;
		}

		private sealed class OwnerMark
		{
			internal Item Item;

			internal string PlayerKey;

			internal string OwnerName;
		}

		[Serializable]
		private sealed class OwnedItemSave
		{
			public List<OwnedDropSave> Drops = new List<OwnedDropSave>();
		}

		[Serializable]
		private sealed class OwnedDropSave
		{
			public int WorldIndex;

			public SavedItem Item;

			public string PlayerKey;

			public string OwnerName;

			public string ItemName;

			public byte Island;

			public bool DeathDrop;

			public long DroppedAtUtcTicks;
		}

		private static readonly Dictionary<int, OwnedDrop> Drops = new Dictionary<int, OwnedDrop>();

		private static readonly Dictionary<int, OwnerMark> OwnerMarks = new Dictionary<int, OwnerMark>();

		private static readonly Dictionary<int, OwnedItemStateBroadcast> ClientStates = new Dictionary<int, OwnedItemStateBroadcast>();

		private static readonly List<OwnedDropSave> Pending = new List<OwnedDropSave>();

		private static ManualLogSource _log;

		private static bool _serializersReady;

		private static bool _clientRegistered;

		private static bool _serverRegistered;

		private static int _inputFrame = -1;

		private static bool _syncPending;

		private static bool _openPending;

		private static bool _serverReady;

		private static bool _pendingLoaded;

		private static bool _worldItemsLoaded;

		private static string _savePath;

		private static int _worldSpawnIndex;

		internal static void Init(ManualLogSource log)
		{
			_log = log;
			if (!_serializersReady)
			{
				GenericWriter<OwnedItemStateBroadcast>.SetWrite((Action<Writer, OwnedItemStateBroadcast>)WriteState);
				GenericReader<OwnedItemStateBroadcast>.SetRead((Func<Reader, OwnedItemStateBroadcast>)ReadState);
				GenericWriter<OwnedItemNoticeBroadcast>.SetWrite((Action<Writer, OwnedItemNoticeBroadcast>)WriteNotice);
				GenericReader<OwnedItemNoticeBroadcast>.SetRead((Func<Reader, OwnedItemNoticeBroadcast>)ReadNotice);
				GenericWriter<RecoverOwnedItemsBroadcast>.SetWrite((Action<Writer, RecoverOwnedItemsBroadcast>)delegate
				{
				});
				GenericReader<RecoverOwnedItemsBroadcast>.SetRead((Func<Reader, RecoverOwnedItemsBroadcast>)((Reader reader) => default(RecoverOwnedItemsBroadcast)));
				GenericWriter<RecoverSingleOwnedItemBroadcast>.SetWrite((Action<Writer, RecoverSingleOwnedItemBroadcast>)WriteSingleRequest);
				GenericReader<RecoverSingleOwnedItemBroadcast>.SetRead((Func<Reader, RecoverSingleOwnedItemBroadcast>)ReadSingleRequest);
				GenericWriter<SyncOwnedItemsBroadcast>.SetWrite((Action<Writer, SyncOwnedItemsBroadcast>)delegate
				{
				});
				GenericReader<SyncOwnedItemsBroadcast>.SetRead((Func<Reader, SyncOwnedItemsBroadcast>)((Reader reader) => default(SyncOwnedItemsBroadcast)));
				_serializersReady = true;
			}
		}

		internal static void Update()
		{
			EnsureNetwork();
			TickInput();
			if (_syncPending && InstanceFinder.IsClientStarted && (Object)(object)InstanceFinder.ClientManager != (Object)null)
			{
				InstanceFinder.ClientManager.Broadcast<SyncOwnedItemsBroadcast>(default(SyncOwnedItemsBroadcast), (Channel)0);
				_syncPending = false;
			}
			if (InstanceFinder.IsServerStarted)
			{
				Prune();
			}
		}

		internal static void TickInput()
		{
			if (_inputFrame == Time.frameCount)
			{
				return;
			}
			_inputFrame = Time.frameCount;
			EnsureNetwork();
			if (!Object.op_Implicit((Object)(object)Player.LocalPlayer) || ((NetworkBehaviour)Player.LocalPlayer).Owner == (NetworkConnection)null || !((NetworkBehaviour)Player.LocalPlayer).Owner.IsLocalClient || ChatManager.IsTyping)
			{
				return;
			}
			bool recoverPressed = ConfigManager.RecoverPressed;
			if (recoverPressed && OwnedItemUi.IsOpen)
			{
				OwnedItemUi.Toggle();
				_openPending = false;
				return;
			}
			if (recoverPressed && !PauseManager.IsPaused && !Player.LocalPlayer.BlockInputs && !MainMenuManager.IsInMenu)
			{
				_openPending = true;
			}
			if (_openPending && !PauseManager.IsPaused && !Player.LocalPlayer.BlockInputs && !MainMenuManager.IsInMenu)
			{
				OwnedItemUi.Open();
				if (OwnedItemUi.IsOpen)
				{
					_openPending = false;
				}
			}
		}

		internal static void PlayerStarted(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !(((NetworkBehaviour)player).Owner == (NetworkConnection)null) && ((NetworkBehaviour)player).Owner.IsLocalClient)
			{
				EnsureNetwork();
				ClientStates.Clear();
				OwnedItemUi.RefreshAll();
				_syncPending = true;
			}
		}

		internal static void PlayerStopped(Player player)
		{
			if (!((Object)(object)player == (Object)null) && !(((NetworkBehaviour)player).Owner == (NetworkConnection)null) && ((NetworkBehaviour)player).Owner.IsLocalClient)
			{
				ClientStates.Clear();
				_syncPending = false;
				_openPending = false;
				OwnedItemUi.DestroyCurrent();
			}
		}

		internal static void EnsureNetwork()
		{
			if (!_clientRegistered && InstanceFinder.IsClientStarted && (Object)(object)InstanceFinder.ClientManager != (Object)null)
			{
				InstanceFinder.ClientManager.RegisterBroadcast<OwnedItemStateBroadcast>((Action<OwnedItemStateBroadcast, Channel>)OnState);
				InstanceFinder.ClientManager.RegisterBroadcast<OwnedItemNoticeBroadcast>((Action<OwnedItemNoticeBroadcast, Channel>)OnNotice);
				_clientRegistered = true;
			}
			if (!_serverRegistered && (Object)(object)InstanceFinder.ServerManager != (Object)null)
			{
				InstanceFinder.ServerManager.RegisterBroadcast<RecoverOwnedItemsBroadcast>((Action<NetworkConnection, RecoverOwnedItemsBroadcast, Channel>)OnRecoverRequest, true);
				InstanceFinder.ServerManager.RegisterBroadcast<RecoverSingleOwnedItemBroadcast>((Action<NetworkConnection, RecoverSingleOwnedItemBroadcast, Channel>)OnRecoverSingleRequest, true);
				InstanceFinder.ServerManager.RegisterBroadcast<SyncOwnedItemsBroadcast>((Action<NetworkConnection, SyncOwnedItemsBroadcast, Channel>)OnSyncRequest, true);
				_serverRegistered = true;
			}
		}

		internal static void ServerStop()
		{
			Drops.Clear();
			OwnerMarks.Clear();
			ClientStates.Clear();
			_syncPending = false;
			_openPending = false;
			OwnedItemUi.DestroyCurrent();
			_serverRegistered = false;
			_serverReady = false;
			_pendingLoaded = false;
			_worldItemsLoaded = false;
			_savePath = null;
			_worldSpawnIndex = 0;
		}

		internal static void ServerStart()
		{
			Drops.Clear();
			OwnerMarks.Clear();
			Pending.Clear();
			ClientStates.Clear();
			_serverReady = true;
			_pendingLoaded = false;
			_worldSpawnIndex = 0;
			_savePath = SavePath();
			_worldItemsLoaded = SaveManager.CurServerSave == null || SaveManager.CurServerSave.WorldItems == null || SaveManager.CurServerSave.WorldItems.Count == 0;
			LoadPending();
		}

		internal static void DeleteSave(string name)
		{
			string path = SavePath(name);
			try
			{
				if (File.Exists(path))
				{
					File.Delete(path);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogError((object)("Failed to delete owned item save: " + ex));
				}
			}
		}

		internal static List<OwnedItemStateBroadcast> GetClientStates()
		{
			return ClientStates.Values.Where((OwnedItemStateBroadcast state) => !state.Removed).OrderBy<OwnedItemStateBroadcast, string>((OwnedItemStateBroadcast state) => state.OwnerName, StringComparer.OrdinalIgnoreCase).ThenBy<OwnedItemStateBroadcast, string>((OwnedItemStateBroadcast state) => state.ItemName, StringComparer.OrdinalIgnoreCase)
				.ToList();
		}

		internal static void RecoverSingle(int objectId)
		{
			EnsureNetwork();
			if (InstanceFinder.IsClientStarted && (Object)(object)InstanceFinder.ClientManager != (Object)null)
			{
				InstanceFinder.ClientManager.Broadcast<RecoverSingleOwnedItemBroadcast>(new RecoverSingleOwnedItemBroadcast(objectId), (Channel)0);
			}
		}

		internal static void RecoverAll()
		{
			EnsureNetwork();
			if (InstanceFinder.IsClientStarted && (Object)(object)InstanceFinder.ClientManager != (Object)null)
			{
				InstanceFinder.ClientManager.Broadcast<RecoverOwnedItemsBroadcast>(default(RecoverOwnedItemsBroadcast), (Channel)0);
			}
		}

		internal static void RegisterDrop(Item item, Player owner, bool deathDrop)
		{
			string text = default(string);
			if (!InstanceFinder.IsServerStarted || (Object)(object)item == (Object)null || (Object)(object)owner == (Object)null || !IdentityApi.TryGetKey(owner, ref text) || item.IsDestroying)
			{
				return;
			}
			int objectId = ((NetworkBehaviour)item).ObjectId;
			if (objectId >= 0)
			{
				Drops.TryGetValue(objectId, out var value);
				OwnerMarks.TryGetValue(objectId, out var value2);
				bool flag = value != null && (Object)(object)value.Item == (Object)(object)item;
				bool flag2 = !flag && value2 != null && (Object)(object)value2.Item == (Object)(object)item;
				string playerKey = (flag ? value.PlayerKey : (flag2 ? value2.PlayerKey : text));
				string ownerName = (flag ? value.OwnerName : (flag2 ? value2.OwnerName : owner.SteamName));
				OwnedDrop ownedDrop = new OwnedDrop
				{
					Item = item,
					PlayerKey = playerKey,
					OwnerName = ownerName,
					ItemName = (flag ? value.ItemName : item.GetName()),
					Island = CurrentIsland(),
					DroppedAt = Time.time,
					DeathDrop = deathDrop,
					HolderSteamID = 0uL,
					HolderName = ""
				};
				if (value != null && value.DeathDrop)
				{
					ownedDrop.DeathDrop = true;
				}
				Drops[objectId] = ownedDrop;
				OwnerMarks[objectId] = new OwnerMark
				{
					Item = item,
					PlayerKey = ownedDrop.PlayerKey,
					OwnerName = ownedDrop.OwnerName
				};
				Broadcast(State(ownedDrop));
			}
		}

		private static void LoadPending()
		{
			if (_pendingLoaded || string.IsNullOrEmpty(_savePath))
			{
				return;
			}
			_pendingLoaded = true;
			if (!File.Exists(_savePath))
			{
				return;
			}
			try
			{
				OwnedItemSave ownedItemSave = JsonConvert.DeserializeObject<OwnedItemSave>(File.ReadAllText(_savePath));
				if (ownedItemSave == null || ownedItemSave.Drops == null)
				{
					return;
				}
				foreach (OwnedDropSave drop in ownedItemSave.Drops)
				{
					if (drop != null && drop.Item != null && drop.Item.Exists && !string.IsNullOrEmpty(drop.PlayerKey))
					{
						Pending.Add(drop);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogError((object)("Failed to load owned item save: " + ex));
				}
			}
		}

		internal static void WorldItemSpawned(SavedWorldItem saved, Item item)
		{
			int worldIndex = _worldSpawnIndex++;
			if (SaveManager.CurServerSave != null && SaveManager.CurServerSave.WorldItems != null && _worldSpawnIndex >= SaveManager.CurServerSave.WorldItems.Count)
			{
				_worldItemsLoaded = true;
			}
			if (InstanceFinder.IsServerStarted && saved != null && saved.Item != null && !((Object)(object)item == (Object)null))
			{
				LoadPending();
				OwnedDropSave ownedDropSave = Pending.FirstOrDefault((OwnedDropSave entry) => entry.WorldIndex == worldIndex);
				if (ownedDropSave != null && ownedDropSave.Item != null && ownedDropSave.Island == CurrentIsland())
				{
					Pending.Remove(ownedDropSave);
					OwnedDrop ownedDrop = new OwnedDrop
					{
						Item = item,
						PlayerKey = ownedDropSave.PlayerKey,
						OwnerName = (ownedDropSave.OwnerName ?? ""),
						ItemName = (string.IsNullOrEmpty(ownedDropSave.ItemName) ? item.GetName() : ownedDropSave.ItemName),
						Island = ownedDropSave.Island,
						DroppedAt = Time.time - (float)(DateTime.UtcNow - new DateTime(ownedDropSave.DroppedAtUtcTicks, DateTimeKind.Utc)).TotalSeconds,
						DeathDrop = ownedDropSave.DeathDrop,
						HolderSteamID = 0uL,
						HolderName = ""
					};
					Drops[((NetworkBehaviour)item).ObjectId] = ownedDrop;
					OwnerMarks[((NetworkBehaviour)item).ObjectId] = new OwnerMark
					{
						Item = item,
						PlayerKey = ownedDrop.PlayerKey,
						OwnerName = ownedDrop.OwnerName
					};
					Broadcast(State(ownedDrop));
				}
			}
		}

		internal static bool TryGetOwner(Item item, out OwnedItemStateBroadcast state)
		{
			if ((Object)(object)item != (Object)null && ClientStates.TryGetValue(((NetworkBehaviour)item).ObjectId, out state))
			{
				return !state.Removed;
			}
			state = default(OwnedItemStateBroadcast);
			return false;
		}

		internal static string GetHoverText(Item item)
		{
			if (!ConfigManager.ShowOwnershipOnHover || !TryGetOwner(item, out var state))
			{
				return null;
			}
			string text = default(string);
			string key = (((Object)(object)Player.LocalPlayer != (Object)null && IdentityApi.TryGetKey(Player.LocalPlayer, ref text) && text == state.PlayerKey) ? "owned.hover.self" : "owned.hover.other");
			return item.GetName() + "\n" + SpriteManager.GetPickUpInput() + "\n" + I18n.Text(key, state.OwnerName);
		}

		internal static bool CanPick(Item item, Player picker)
		{
			if (!ConfigManager.RestrictOwnedItems || (Object)(object)item == (Object)null || (Object)(object)picker == (Object)null || !Drops.TryGetValue(((NetworkBehaviour)item).ObjectId, out var value))
			{
				return true;
			}
			string text = default(string);
			if (IdentityApi.TryGetKey(picker, ref text) && value.PlayerKey == text)
			{
				return true;
			}
			SendNotice(((NetworkBehaviour)picker).Owner, "owned.restrict.denied", value.OwnerName);
			return false;
		}

		internal static void Picked(Item item, Player picker)
		{
			if (InstanceFinder.IsServerStarted && !((Object)(object)item == (Object)null) && !((Object)(object)picker == (Object)null) && Drops.TryGetValue(((NetworkBehaviour)item).ObjectId, out var value) && !((Object)(object)item.SyncedHolder != (Object)(object)picker))
			{
				string text = default(string);
				if (!IdentityApi.TryGetKey(picker, ref text) || value.PlayerKey != text)
				{
					value.HolderSteamID = picker.SteamID;
					value.HolderName = picker.SteamName;
					Broadcast(State(value));
					SendNotice(((NetworkBehaviour)picker).Owner, "owned.item.picked_by", value.Item.ID.ToString(), value.OwnerName);
				}
				else
				{
					Drops.Remove(((NetworkBehaviour)item).ObjectId);
					OwnerMarks.Remove(((NetworkBehaviour)item).ObjectId);
					Broadcast(new OwnedItemStateBroadcast(((NetworkBehaviour)item).ObjectId, value.PlayerKey, value.OwnerName, value.ItemName, value.DeathDrop, removed: true, 0uL));
					SendNotice(((NetworkBehaviour)picker).Owner, "owned.item.recovered", value.Item.ID.ToString());
				}
			}
		}

		internal static void Destroyed(Item item)
		{
			if (!((Object)(object)item == (Object)null))
			{
				bool num = Drops.Remove(((NetworkBehaviour)item).ObjectId);
				OwnerMarks.Remove(((NetworkBehaviour)item).ObjectId);
				if (num)
				{
					Broadcast(new OwnedItemStateBroadcast(((NetworkBehaviour)item).ObjectId, null, "", "", deathDrop: false, removed: true, 0uL));
				}
			}
		}

		internal static void BirdCaught(Item item)
		{
			if (InstanceFinder.IsServerStarted && !((Object)(object)item == (Object)null))
			{
				bool num = Drops.Remove(((NetworkBehaviour)item).ObjectId);
				OwnerMarks.Remove(((NetworkBehaviour)item).ObjectId);
				if (num)
				{
					Broadcast(new OwnedItemStateBroadcast(((NetworkBehaviour)item).ObjectId, null, "", "", deathDrop: false, removed: true, 0uL));
				}
			}
		}

		internal static void SendAll(NetworkConnection connection)
		{
			if ((Object)(object)InstanceFinder.ServerManager == (Object)null || connection == (NetworkConnection)null)
			{
				return;
			}
			foreach (OwnedDrop value in Drops.Values)
			{
				InstanceFinder.ServerManager.Broadcast<OwnedItemStateBroadcast>(connection, State(value), true, (Channel)0);
			}
		}

		private static void OnRecoverRequest(NetworkConnection connection, RecoverOwnedItemsBroadcast message, Channel channel)
		{
			Player val = FindPlayer(connection);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Transform == (Object)null))
			{
				Recover(connection, val, null);
			}
		}

		private static void OnRecoverSingleRequest(NetworkConnection connection, RecoverSingleOwnedItemBroadcast message, Channel channel)
		{
			Player val = FindPlayer(connection);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.Transform == (Object)null))
			{
				Recover(connection, val, message.ObjectId);
			}
		}

		private static void Recover(NetworkConnection connection, Player player, int? objectId)
		{
			if (objectId.HasValue && !Drops.ContainsKey(objectId.Value))
			{
				SendNotice(connection, "owned.recover.missing");
				return;
			}
			byte island = CurrentIsland();
			float range = ConfigManager.RecoverRange;
			float rangeSq = range * range;
			List<OwnedDrop> list = Drops.Values.Where(delegate(OwnedDrop drop)
			{
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				string text = default(string);
				if ((!objectId.HasValue || ((Object)(object)drop.Item != (Object)null && ((NetworkBehaviour)drop.Item).ObjectId == objectId.Value)) && IdentityApi.TryGetKey(player, ref text) && drop.PlayerKey == text && drop.Island == island && (Object)(object)drop.Item != (Object)null && !drop.Item.IsDestroying && !((NetworkBehaviour)drop.Item).IsDeinitializing && drop.Item.IsInteractable && (Object)(object)drop.Item.SyncedHolder == (Object)null && ((Component)((Component)drop.Item).transform).gameObject.activeInHierarchy)
				{
					if (!(range <= 0f))
					{
						Vector3 val = ((Component)drop.Item).transform.position - player.Transform.position;
						if (!(((Vector3)(ref val)).sqrMagnitude <= rangeSq))
						{
							goto IL_0121;
						}
					}
					return !Expired(drop);
				}
				goto IL_0121;
				IL_0121:
				return false;
			}).OrderBy(delegate(OwnedDrop drop)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = ((Component)drop.Item).transform.position - player.Transform.position;
				return ((Vector3)(ref val)).sqrMagnitude;
			}).Take(objectId.HasValue ? 1 : ConfigManager.RecoverBatchLimit)
				.ToList();
			int num = 0;
			foreach (OwnedDrop item2 in list)
			{
				Item item = item2.Item;
				item.SetSyncedHolder(player, false);
				if (player.Inventory.ServerTryStoreHeldItem(item))
				{
					Drops.Remove(((NetworkBehaviour)item).ObjectId);
					OwnerMarks.Remove(((NetworkBehaviour)item).ObjectId);
					Broadcast(new OwnedItemStateBroadcast(((NetworkBehaviour)item).ObjectId, item2.PlayerKey, item2.OwnerName, item2.ItemName, item2.DeathDrop, removed: true, 0uL));
					num++;
				}
				else
				{
					item.SetSyncedHolder((Player)null, false);
				}
			}
			if (objectId.HasValue)
			{
				SendNotice(connection, (num == 1) ? "owned.recover.single" : ((list.Count == 0) ? "owned.recover.missing" : "owned.recover.no_space"));
				return;
			}
			string key = ((list.Count == 0) ? "owned.recover.empty" : ((num == 0) ? "owned.recover.no_space" : ((num == list.Count) ? "owned.recover.full" : "owned.recover.partial")));
			SendNotice(connection, key, num.ToString(), list.Count.ToString());
		}

		private static void OnSyncRequest(NetworkConnection connection, SyncOwnedItemsBroadcast message, Channel channel)
		{
			Prune();
			SendAll(connection);
		}

		private static void Prune()
		{
			byte b = CurrentIsland();
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, OwnedDrop> drop in Drops)
			{
				OwnedDrop value = drop.Value;
				if ((Object)(object)value.Item == (Object)null || value.Item.IsDestroying || ((NetworkBehaviour)value.Item).IsDeinitializing || (Object)(object)value.Item.BirdHolder != (Object)null || value.Island != b || Expired(value))
				{
					list.Add(drop.Key);
				}
			}
			foreach (int item in list)
			{
				Drops.Remove(item);
				OwnerMarks.Remove(item);
				Broadcast(new OwnedItemStateBroadcast(item, null, "", "", deathDrop: false, removed: true, 0uL));
			}
		}

		private static Player FindPlayer(string playerKey)
		{
			string text = default(string);
			foreach (Player player in PlayerManager.Players)
			{
				if ((Object)(object)player != (Object)null && IdentityApi.TryGetKey(player, ref text) && text == playerKey)
				{
					return player;
				}
			}
			return null;
		}

		private static Player FindPlayer(NetworkConnection connection)
		{
			if (connection == (NetworkConnection)null)
			{
				return null;
			}
			foreach (Player player in PlayerManager.Players)
			{
				if ((Object)(object)player != (Object)null && ((NetworkBehaviour)player).Owner != (NetworkConnection)null && ((NetworkBehaviour)player).Owner.ClientId == connection.ClientId)
				{
					return player;
				}
			}
			return null;
		}

		private static byte CurrentIsland()
		{
			if (!((Object)(object)OnlineIslandManager.Instance == (Object)null))
			{
				return OnlineIslandManager.CurIsland;
			}
			return byte.MaxValue;
		}

		private static void Broadcast(OwnedItemStateBroadcast message)
		{
			EnsureNetwork();
			if ((Object)(object)InstanceFinder.ServerManager != (Object)null)
			{
				InstanceFinder.ServerManager.Broadcast<OwnedItemStateBroadcast>(message, true, (Channel)0);
			}
		}

		private static void SendNotice(NetworkConnection connection, string key, string arg0 = "", string arg1 = "")
		{
			EnsureNetwork();
			if (connection != (NetworkConnection)null && (Object)(object)InstanceFinder.ServerManager != (Object)null)
			{
				InstanceFinder.ServerManager.Broadcast<OwnedItemNoticeBroadcast>(connection, new OwnedItemNoticeBroadcast(key, arg0, arg1), true, (Channel)0);
			}
		}

		private static void OnState(OwnedItemStateBroadcast message, Channel channel)
		{
			if (message.Removed)
			{
				ClientStates.Remove(message.ObjectId);
			}
			else
			{
				ClientStates[message.ObjectId] = message;
			}
			OwnedItemUi.RefreshAll();
		}

		private static void OnNotice(OwnedItemNoticeBroadcast message, Channel channel)
		{
			if (!string.IsNullOrWhiteSpace(message.Key))
			{
				string text = message.Arg0;
				if (IsItemNotice(message.Key) && byte.TryParse(text, out var result))
				{
					Item val = GameInfo.IDToItem(result);
					text = (((Object)(object)val == (Object)null) ? message.Arg0 : val.GetName());
				}
				ChatManager.ChatMessage("<i>" + I18n.Text(message.Key, text, message.Arg1) + "</i>");
			}
		}

		private static bool IsItemNotice(string key)
		{
			if (!(key == "owned.item.recovered") && !(key == "owned.item.picked_by"))
			{
				return key == "owned.item.lost";
			}
			return true;
		}

		private static void WriteState(Writer writer, OwnedItemStateBroadcast message)
		{
			writer.WriteInt32(message.ObjectId);
			writer.WriteString(message.PlayerKey);
			writer.WriteString(message.OwnerName);
			writer.WriteString(message.ItemName);
			writer.WriteBoolean(message.DeathDrop);
			writer.WriteBoolean(message.Removed);
			writer.WriteUInt64(message.HolderSteamID);
			writer.WriteString(message.HolderName);
		}

		private static OwnedItemStateBroadcast ReadState(Reader reader)
		{
			return new OwnedItemStateBroadcast(reader.ReadInt32(), reader.ReadStringAllocated(), reader.ReadStringAllocated(), reader.ReadStringAllocated(), reader.ReadBoolean(), reader.ReadBoolean(), reader.ReadUInt64(), reader.ReadStringAllocated());
		}

		private static void WriteSingleRequest(Writer writer, RecoverSingleOwnedItemBroadcast message)
		{
			writer.WriteInt32(message.ObjectId);
		}

		private static RecoverSingleOwnedItemBroadcast ReadSingleRequest(Reader reader)
		{
			return new RecoverSingleOwnedItemBroadcast(reader.ReadInt32());
		}

		private static void WriteNotice(Writer writer, OwnedItemNoticeBroadcast message)
		{
			writer.WriteString(message.Key);
			writer.WriteString(message.Arg0);
			writer.WriteString(message.Arg1);
		}

		private static OwnedItemNoticeBroadcast ReadNotice(Reader reader)
		{
			return new OwnedItemNoticeBroadcast(reader.ReadStringAllocated(), reader.ReadStringAllocated(), reader.ReadStringAllocated());
		}

		internal static void AfterNativeSave()
		{
			if (!InstanceFinder.IsServerStarted || !_serverReady || string.IsNullOrEmpty(_savePath) || SaveManager.CurServerSave == null || SaveManager.CurServerSave.WorldItems == null || !_worldItemsLoaded)
			{
				return;
			}
			try
			{
				List<OwnedDropSave> list = new List<OwnedDropSave>();
				HashSet<int> used = new HashSet<int>();
				List<SavedWorldItem> worldItems = SaveManager.CurServerSave.WorldItems;
				for (int i = 0; i < worldItems.Count; i++)
				{
					OwnedDrop ownedDrop = FindDrop(worldItems[i], used);
					if (ownedDrop != null)
					{
						list.Add(new OwnedDropSave
						{
							WorldIndex = i,
							Item = CaptureItem(ownedDrop.Item),
							PlayerKey = ownedDrop.PlayerKey,
							OwnerName = ownedDrop.OwnerName,
							ItemName = ownedDrop.ItemName,
							Island = ownedDrop.Island,
							DeathDrop = ownedDrop.DeathDrop,
							DroppedAtUtcTicks = DateTime.UtcNow.AddSeconds(0f - (Time.time - ownedDrop.DroppedAt)).Ticks
						});
					}
				}
				WriteSave(list);
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogError((object)("Failed to save owned item save: " + ex));
				}
			}
		}

		private static OwnedDrop FindDrop(SavedWorldItem worldItem, HashSet<int> used)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if (worldItem == null || worldItem.Item == null)
			{
				return null;
			}
			OwnedDrop ownedDrop = null;
			float num = float.PositiveInfinity;
			float num2 = float.PositiveInfinity;
			foreach (OwnedDrop value in Drops.Values)
			{
				if (!((Object)(object)value.Item == (Object)null) && !used.Contains(((NetworkBehaviour)value.Item).ObjectId) && CanSave(value.Item) && value.Item.ID == worldItem.Item.ItemID)
				{
					Vector3 val = ((Component)value.Item).transform.position - worldItem.Position;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					float num3 = Quaternion.Angle(((Component)value.Item).transform.rotation, worldItem.Rotation);
					if (sqrMagnitude < num || (sqrMagnitude == num && num3 < num2))
					{
						num = sqrMagnitude;
						num2 = num3;
						ownedDrop = value;
					}
				}
			}
			if (ownedDrop != null)
			{
				used.Add(((NetworkBehaviour)ownedDrop.Item).ObjectId);
			}
			return ownedDrop;
		}

		private static void WriteSave(List<OwnedDropSave> entries)
		{
			string directoryName = Path.GetDirectoryName(_savePath);
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			OwnedItemSave ownedItemSave = new OwnedItemSave();
			ownedItemSave.Drops.AddRange(entries);
			File.WriteAllText(_savePath, JsonConvert.SerializeObject((object)ownedItemSave));
		}

		private static bool CanSave(Item item)
		{
			if ((Object)(object)item == (Object)null || !((NetworkBehaviour)item).IsServerInitialized || item.IsDestroying || ((NetworkBehaviour)item).IsDeinitializing || (Object)(object)item.SyncedHolder != (Object)null || (Object)(object)item.Holder != (Object)null || item.IsInInventory || (Object)(object)item.BirdHolder != (Object)null || (Object)(object)item.AttachedRod != (Object)null || (Object)(object)item.DeadPlayer != (Object)null || item.IgnoredByCloseDots)
			{
				return false;
			}
			if (!((Object)(object)item.Creature == (Object)null))
			{
				return item.Creature.IsDead;
			}
			return true;
		}

		private static SavedItem CaptureItem(Item item)
		{
			//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_000c: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			return new SavedItem
			{
				Exists = true,
				ItemID = item.ID,
				Cookness = item.Cookness,
				BettingMultiplier = item.BettingMultiplier,
				IsDripCreature = ((Object)(object)item.Creature != (Object)null && item.Creature.IsDrip),
				Weight = (((Object)(object)item.Creature != (Object)null) ? ((Item)item.Creature).RandomizedWeight : 1f),
				KillScoreMultiplier = item.KillScoreMultiplier,
				SkinIndex = item.CurSkin,
				Sight = (byte)(((Object)(object)item.Weapon != (Object)null) ? item.Weapon.Attachments.Sight : 0),
				BarrelAttachment = (byte)(((Object)(object)item.Weapon != (Object)null) ? item.Weapon.Attachments.BarrelAttachment : 0),
				AmmoType = (byte)(((Object)(object)item.Weapon != (Object)null) ? item.Weapon.Attachments.AmmoType : 0),
				ExtendedMag = ((Object)(object)item.Weapon != (Object)null && item.Weapon.Attachments.ExtendedMag),
				LaserSight = ((Object)(object)item.Weapon != (Object)null && item.Weapon.Attachments.LaserSight),
				Sharpness = (byte)(((Object)(object)item.Melee != (Object)null) ? item.Melee.SharpnessIndex : 0)
			};
		}

		private static string SavePath()
		{
			return SavePath(SaveManager.CurServerSave.Name);
		}

		private static string SavePath(string name)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char oldChar in invalidFileNameChars)
			{
				name = name.Replace(oldChar, '_');
			}
			return Path.Combine(Application.persistentDataPath, "Saves", name + ".OwnedItemRecovery.json");
		}

		private static bool Expired(OwnedDrop drop)
		{
			float ownershipTimeout = ConfigManager.OwnershipTimeout;
			if (ownershipTimeout > 0f)
			{
				return Time.time - drop.DroppedAt > ownershipTimeout;
			}
			return false;
		}

		private static OwnedItemStateBroadcast State(OwnedDrop drop)
		{
			return new OwnedItemStateBroadcast(((NetworkBehaviour)drop.Item).ObjectId, drop.PlayerKey, drop.OwnerName, drop.ItemName, drop.DeathDrop, removed: false, drop.HolderSteamID, drop.HolderName);
		}
	}
}
namespace OwnedItemRecovery.Patches
{
	[HarmonyPatch(typeof(Item), "SetSyncedHolder")]
	internal static class ItemDropPatch
	{
		private static void Prefix(Item __instance, ref Player __state)
		{
			__state = (((Object)(object)__instance == (Object)null) ? null : __instance.SyncedHolder);
		}

		private static void Postfix(Item __instance, Player newHolder, Player __state)
		{
			if ((Object)(object)__instance != (Object)null && (Object)(object)newHolder == (Object)null && (Object)(object)__state != (Object)null && (Object)(object)__instance.SyncedHolder == (Object)null && !__instance.IsInInventory)
			{
				OwnedItemRuntime.RegisterDrop(__instance, __state, deathDrop: false);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerInventory), "ServerDropAll")]
	internal static class InventoryDeathDropPatch
	{
		private static void Prefix(PlayerInventory __instance, Player ____player)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)____player == (Object)null)
			{
				return;
			}
			if ((Object)(object)____player.Holding.HeldItem != (Object)null)
			{
				OwnedItemRuntime.RegisterDrop(____player.Holding.HeldItem, ____player, deathDrop: true);
			}
			foreach (KeyValuePair<byte, Item> item in __instance._items)
			{
				if ((Object)(object)item.Value != (Object)null)
				{
					OwnedItemRuntime.RegisterDrop(item.Value, ____player, deathDrop: true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Server), "RpcLogic___SetItemHolder___3876263354")]
	internal static class ItemPickupPatch
	{
		private static bool Prefix(Item __0, Player __1)
		{
			return OwnedItemRuntime.CanPick(__0, __1);
		}

		private static void Postfix(Item __0, Player __1)
		{
			OwnedItemRuntime.Picked(__0, __1);
		}
	}
	[HarmonyPatch(typeof(Item), "DestroyItem")]
	internal static class ItemDestroyPatch
	{
		private static void Prefix(Item __instance)
		{
			OwnedItemRuntime.Destroyed(__instance);
		}
	}
	[HarmonyPatch(typeof(Item), "TryCaughtByBird", new Type[] { typeof(Bird) })]
	internal static class ItemBirdCatchPatch
	{
		private static void Postfix(Item __instance, bool __result)
		{
			if (__result)
			{
				OwnedItemRuntime.BirdCaught(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(ItemManager), "SpawnSavedItem")]
	internal static class SavedWorldItemPatch
	{
		private static void Postfix(SavedWorldItem __0, Item __result)
		{
			OwnedItemRuntime.WorldItemSpawned(__0, __result);
		}
	}
	[HarmonyPatch(typeof(Item), "Hover")]
	internal static class ItemHoverPatch
	{
		private static void Postfix(Item __instance, ref string ____hoverString)
		{
			string hoverText = OwnedItemRuntime.GetHoverText(__instance);
			if (!string.IsNullOrEmpty(hoverText))
			{
				PlayerUI.UpdateLookAtText(hoverText);
				____hoverString = hoverText;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerDying), "ServerDie")]
	internal static class PlayerDeathDropPatch
	{
		private static void Prefix(PlayerDying __instance, Player ____player)
		{
			if ((Object)(object)__instance != (Object)null && (Object)(object)____player != (Object)null && (Object)(object)__instance.DeadPlayer == (Object)null && (Object)(object)____player.Holding.HeldItem != (Object)null)
			{
				OwnedItemRuntime.RegisterDrop(____player.Holding.HeldItem, ____player, deathDrop: true);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnStartClient")]
	internal static class PlayerStartPatch
	{
		private static void Postfix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)null && ((NetworkBehaviour)__instance).Owner != (NetworkConnection)null && ((NetworkBehaviour)__instance).Owner.IsLocalClient)
			{
				OwnedItemRuntime.PlayerStarted(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnStopClient")]
	internal static class PlayerStopPatch
	{
		private static void Postfix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)null && ((NetworkBehaviour)__instance).Owner != (NetworkConnection)null && ((NetworkBehaviour)__instance).Owner.IsLocalClient)
			{
				OwnedItemRuntime.PlayerStopped(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Server), "OnStopServer")]
	internal static class ServerStopPatch
	{
		private static void Postfix()
		{
			OwnedItemRuntime.ServerStop();
		}
	}
	[HarmonyPatch(typeof(MoneyManager), "OnStartServer")]
	internal static class ServerStartPatch
	{
		private static void Postfix()
		{
			OwnedItemRuntime.ServerStart();
		}
	}
	[HarmonyPatch(typeof(SaveManager), "SaveServer")]
	internal static class SaveServerPatch
	{
		private static void Postfix()
		{
			OwnedItemRuntime.AfterNativeSave();
		}
	}
	[HarmonyPatch(typeof(SaveManager), "DeleteServer")]
	internal static class DeleteServerPatch
	{
		private static string _name;

		private static void Prefix()
		{
			_name = ((SaveManager.CurServerSave == null) ? null : SaveManager.CurServerSave.Name);
		}

		private static void Postfix()
		{
			if (!string.IsNullOrEmpty(_name))
			{
				OwnedItemRuntime.DeleteSave(_name);
			}
			_name = null;
		}
	}
	[HarmonyPatch(typeof(PlayerUI), "Update")]
	internal static class OwnedItemInputPatch
	{
		private static void Postfix()
		{
			OwnedItemRuntime.TickInput();
		}
	}
}
namespace OwnedItemRecovery.Localization
{
	internal static class I18n
	{
		private const string FileName = "OwnedItemRecovery.Localization.json";

		private static readonly ModLocalizer _localizer = Load();

		internal static string Text(string key, params object[] args)
		{
			return _localizer.GetLocalizedText(key, args);
		}

		private static ModLocalizer Load()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			ModLocalizer obj = LocalizationApi.For("IceBoxStudio.HowToFish.OwnedItemRecovery");
			obj.RegisterJson(Path.Combine(directoryName, "OwnedItemRecovery.Localization.json"));
			return obj;
		}
	}
}
namespace OwnedItemRecovery.Configuration
{
	internal static class ConfigManager
	{
		private static ConfigEntry<KeyboardShortcut> _recoverKey;

		private static ConfigEntry<float> _recoverRange;

		private static ConfigEntry<int> _recoverBatchLimit;

		private static ConfigEntry<bool> _showOwnershipOnHover;

		private static ConfigEntry<bool> _notifyOwnerWhenPicked;

		private static ConfigEntry<bool> _restrictOwnedItems;

		private static ConfigEntry<float> _ownershipTimeout;

		internal static bool RecoverPressed
		{
			get
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				if (_recoverKey != null)
				{
					KeyboardShortcut value = _recoverKey.Value;
					return ((KeyboardShortcut)(ref value)).IsDown();
				}
				return false;
			}
		}

		internal static float RecoverRange => Mathf.Max(0f, (_recoverRange == null) ? 0f : _recoverRange.Value);

		internal static int RecoverBatchLimit => Mathf.Clamp((_recoverBatchLimit == null) ? 32 : _recoverBatchLimit.Value, 1, 128);

		internal static bool ShowOwnershipOnHover
		{
			get
			{
				if (_showOwnershipOnHover != null)
				{
					return _showOwnershipOnHover.Value;
				}
				return true;
			}
		}

		internal static bool NotifyOwnerWhenPicked
		{
			get
			{
				if (_notifyOwnerWhenPicked != null)
				{
					return _notifyOwnerWhenPicked.Value;
				}
				return true;
			}
		}

		internal static bool RestrictOwnedItems
		{
			get
			{
				if (_restrictOwnedItems != null)
				{
					return _restrictOwnedItems.Value;
				}
				return false;
			}
		}

		internal static float OwnershipTimeout
		{
			get
			{
				if (_ownershipTimeout != null)
				{
					return _ownershipTimeout.Value;
				}
				return 1800f;
			}
		}

		internal static void Init(ConfigFile config)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			_recoverKey = config.Bind<KeyboardShortcut>("Controls", "RecoverOwnedItems", new KeyboardShortcut((KeyCode)111, Array.Empty<KeyCode>()), I18n.Text("config.recover_key"));
			_recoverRange = config.Bind<float>("Gameplay", "RecoverRange", 0f, I18n.Text("config.recover_range"));
			_recoverBatchLimit = config.Bind<int>("Gameplay", "RecoverBatchLimit", 32, I18n.Text("config.recover_limit"));
			_showOwnershipOnHover = config.Bind<bool>("Gameplay", "ShowOwnershipOnHover", true, I18n.Text("config.show_hover"));
			_notifyOwnerWhenPicked = config.Bind<bool>("Gameplay", "NotifyOwnerWhenPicked", true, I18n.Text("config.notify_owner"));
			_restrictOwnedItems = config.Bind<bool>("Gameplay", "RestrictOwnedItems", false, I18n.Text("config.restrict"));
			_ownershipTimeout = config.Bind<float>("Gameplay", "OwnershipTimeout", 1800f, I18n.Text("config.timeout"));
		}
	}
}