Decompiled source of Portal List v1.0.1

DigiPortalList.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DigiCore;
using DigiShared;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PortalList;
using Splatform;
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: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("DigiPortalList")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DigiPortalList")]
[assembly: AssemblyTitle("DigiPortalList")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal static class SettingOrder
{
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;
	}

	internal static void Apply(ConfigFile config)
	{
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		FieldInfo fieldInfo = AccessTools.Field(typeof(ConfigEntryBase), "<Description>k__BackingField");
		if (fieldInfo == null)
		{
			return;
		}
		int num = 1000;
		foreach (ConfigDefinition item in config.Keys.ToList())
		{
			ConfigEntryBase val = config[item];
			ConfigDescription description = val.Description;
			object[] array = ((description != null) ? description.Tags : null) ?? new object[0];
			object obj = array.FirstOrDefault((object t) => t != null && t.GetType().Name == "ConfigurationManagerAttributes");
			if (obj != null)
			{
				FieldInfo fieldInfo2 = AccessTools.Field(obj.GetType(), "Order");
				if (fieldInfo2 != null && fieldInfo2.GetValue(obj) == null)
				{
					fieldInfo2.SetValue(obj, num);
				}
			}
			else
			{
				fieldInfo.SetValue(val, (object?)new ConfigDescription(((description != null) ? description.Description : null) ?? "", (description != null) ? description.AcceptableValues : null, array.Concat(new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Order = num
					}
				}).ToArray()));
			}
			num--;
		}
	}
}
internal static class StoreRules
{
	private static bool _resolved;

	private static MethodInfo _readMarker;

	private static PropertyInfo _settings;

	private static PropertyInfo _useMarkers;

	private static PropertyInfo _canDeposit;

	private static PropertyInfo _canWithdraw;

	private static MethodInfo _isProtected;

	private static void Resolve()
	{
		if (_resolved)
		{
			return;
		}
		_resolved = true;
		try
		{
			Type type = AccessTools.TypeByName("LocalCraftFromStoragePrime.ContainerPolicyApi");
			Type type2 = AccessTools.TypeByName("LocalCraftFromStoragePrime.ContainerMarkerPolicy");
			Type type3 = AccessTools.TypeByName("LocalCraftFromStoragePrime.Plugin");
			if (!(type == null) && !(type2 == null) && !(type3 == null))
			{
				_readMarker = AccessTools.Method(type, "ReadMarker", new Type[2]
				{
					typeof(Inventory),
					typeof(bool)
				}, (Type[])null);
				_settings = AccessTools.Property(type3, "Settings");
				_useMarkers = ((_settings != null) ? AccessTools.Property(_settings.PropertyType, "UseContainerMarkers") : null);
				_canDeposit = AccessTools.Property(type2, "CanDeposit");
				_canWithdraw = AccessTools.Property(type2, "CanWithdraw");
				_isProtected = AccessTools.Method(type2, "IsProtectedPosition", new Type[2]
				{
					typeof(int),
					typeof(int)
				}, (Type[])null);
			}
		}
		catch (Exception)
		{
			_readMarker = null;
		}
	}

	private static object Marker(Inventory inv)
	{
		Resolve();
		if (_readMarker == null || _canDeposit == null || _canWithdraw == null || _isProtected == null)
		{
			return null;
		}
		try
		{
			bool flag = true;
			if (_settings != null && _useMarkers != null)
			{
				flag = (bool)_useMarkers.GetValue(_settings.GetValue(null));
			}
			return _readMarker.Invoke(null, new object[2] { inv, flag });
		}
		catch (Exception)
		{
			return null;
		}
	}

	internal static bool CanDeposit(Inventory inv)
	{
		object obj = Marker(inv);
		if (obj != null)
		{
			return (bool)_canDeposit.GetValue(obj);
		}
		return true;
	}

	internal static bool CanWithdraw(Inventory inv)
	{
		object obj = Marker(inv);
		if (obj != null)
		{
			return (bool)_canWithdraw.GetValue(obj);
		}
		return true;
	}

	internal static bool IsProtected(Inventory inv, ItemData item)
	{
		return IsProtectedSlot(inv, item.m_gridPos.x, item.m_gridPos.y);
	}

	internal static bool IsProtectedSlot(Inventory inv, int x, int y)
	{
		object obj = Marker(inv);
		if (obj != null)
		{
			return (bool)_isProtected.Invoke(obj, new object[2] { x, y });
		}
		return false;
	}

	internal static Func<int, int, bool> ProtectedSlots(Inventory inv)
	{
		object m = Marker(inv);
		if (m == null)
		{
			return null;
		}
		return (int x, int y) => (bool)_isProtected.Invoke(m, new object[2] { x, y });
	}

	internal static Container PickOutputChest(List<Container> nearestFirst, GameObject prefab, int amount)
	{
		string shared = prefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_name;
		List<Container> source = nearestFirst.Where((Container c) => CanDeposit(c.GetInventory()) && c.GetInventory().CanAddItem(prefab, amount)).ToList();
		return ((IEnumerable<Container>)source).FirstOrDefault((Func<Container, bool>)((Container c) => c.GetInventory().GetAllItems().Any((ItemData i) => i?.m_shared != null && i.m_shared.m_name == shared && !IsProtected(c.GetInventory(), i)))) ?? source.FirstOrDefault();
	}

	internal static bool TakeOne(List<Container> nearestFirst, Func<ItemData, bool> match, out ItemData taken)
	{
		foreach (Container item in nearestFirst)
		{
			Inventory inv = item.GetInventory();
			if (CanWithdraw(inv))
			{
				ItemData val = ((IEnumerable<ItemData>)inv.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => match(i) && !IsProtected(inv, i)));
				if (val != null)
				{
					taken = val.Clone();
					inv.RemoveOneItem(val);
					return true;
				}
			}
		}
		taken = null;
		return false;
	}
}
namespace DigiShared
{
	internal class Windows : MonoBehaviour
	{
		internal sealed class Window
		{
			public GameObject Root;

			public RectTransform Panel;

			public RectTransform View;

			public RectTransform Content;

			public TMP_InputField Search;

			public float Width;

			public float Height;

			public float RowWidth;

			public float Step;

			public float Target;

			public bool Gliding;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__Close;
		}

		internal const float Pad = 24f;

		internal const float ScrollWidth = 14f;

		internal static readonly Color Gold = new Color(1f, 0.72f, 0.36f);

		internal static readonly Color Body = new Color(0.92f, 0.9f, 0.86f);

		internal static readonly Color Dim = new Color(0.6f, 0.58f, 0.55f);

		internal static readonly Color RowEven = new Color(1f, 1f, 1f, 0.035f);

		internal static readonly Color RowOdd = new Color(0f, 0f, 0f, 0.12f);

		internal static Window Current;

		private static TMP_FontAsset _font;

		private static Material _fontMaterial;

		private static bool _readingWheel;

		private static int _escapeFrame = -1;

		private static int _users;

		private static int _typingFrame = -10;

		internal static bool IsOpen
		{
			get
			{
				if (Current != null)
				{
					return (Object)(object)Current.Root != (Object)null;
				}
				return false;
			}
		}

		internal static bool Searching
		{
			get
			{
				if (IsOpen && (Object)(object)Current.Search != (Object)null)
				{
					return Current.Search.isFocused;
				}
				return false;
			}
		}

		private static bool Typing
		{
			get
			{
				if (!Searching)
				{
					return Time.frameCount - _typingFrame <= 1;
				}
				return true;
			}
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerController), "TakeInput", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Windows), "NoInput", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(GameCamera), "UpdateMouseCapture", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Windows), "FreeMouse", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(ZInput), "Internal_GetMouseScrollWheel", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Windows), "OwnWheel", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Menu), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Windows), "EscapeCloses", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(TextInput), "IsVisible", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Windows), "SearchTyping", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			HarmonyMethod val = new HarmonyMethod(typeof(Windows), "NoKeys", (Type[])null);
			string[] array = new string[6] { "GetKey", "GetKeyDown", "GetKeyUp", "GetButton", "GetButtonDown", "GetButtonUp" };
			MethodInfo[] methods = typeof(ZInput).GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.ReturnType == typeof(bool) && Array.IndexOf(array, methodInfo.Name) >= 0)
				{
					harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			Type type = AccessTools.TypeByName("UnityEngine.Input");
			if (!(type != null))
			{
				return;
			}
			methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (methodInfo2.ReturnType == typeof(bool) && methodInfo2.Name.StartsWith("GetKey", StringComparison.Ordinal) && Array.IndexOf(array, methodInfo2.Name) >= 0)
				{
					harmony.Patch((MethodBase)methodInfo2, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		private static bool NoKeys(ref bool __result)
		{
			if (!Typing)
			{
				return true;
			}
			__result = false;
			return false;
		}

		private void OnDestroy()
		{
			Close();
		}

		private void Update()
		{
			if (Searching)
			{
				_typingFrame = Time.frameCount;
			}
			if (IsOpen)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || InventoryGui.IsVisible() || Minimap.IsOpen() || StoreGui.IsVisible())
				{
					Close();
					return;
				}
				_readingWheel = true;
				float mouseScrollWheel = ZInput.GetMouseScrollWheel();
				_readingWheel = false;
				Scroll(Current, mouseScrollWheel, Time.unscaledDeltaTime);
			}
		}

		internal static Window Open(string title, string subtitle, float width, float height, string footer, float step, Action back = null, float listTop = 108f)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Expected O, but got Unknown
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Expected O, but got Unknown
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Expected O, but got Unknown
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Expected O, but got Unknown
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			Close();
			_font = instance.m_recipeName.font;
			_fontMaterial = instance.m_recipeName.fontSharedMaterial;
			Window window = new Window
			{
				Width = width,
				Height = height,
				Step = step
			};
			object obj;
			if (!((Object)(object)instance.m_crafting != (Object)null))
			{
				obj = null;
			}
			else
			{
				Canvas componentInParent = ((Component)instance.m_crafting).GetComponentInParent<Canvas>();
				obj = ((componentInParent != null) ? componentInParent.rootCanvas : null);
			}
			Canvas val = (Canvas)obj;
			window.Root = new GameObject("DigiCreative_Window", new Type[1] { typeof(RectTransform) });
			window.Root.transform.SetParent(((Component)instance).transform.parent, false);
			Canvas obj2 = window.Root.AddComponent<Canvas>();
			obj2.renderMode = (RenderMode)0;
			obj2.sortingOrder = (((Object)(object)val != (Object)null) ? val.sortingOrder : 0) + 5;
			CanvasScaler val2 = window.Root.AddComponent<CanvasScaler>();
			CanvasScaler val3 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<CanvasScaler>() : null);
			if ((Object)(object)val3 != (Object)null)
			{
				val2.uiScaleMode = val3.uiScaleMode;
				val2.scaleFactor = val3.scaleFactor;
				val2.referenceResolution = val3.referenceResolution;
				val2.screenMatchMode = val3.screenMatchMode;
				val2.matchWidthOrHeight = val3.matchWidthOrHeight;
				val2.referencePixelsPerUnit = val3.referencePixelsPerUnit;
			}
			window.Root.AddComponent<GraphicRaycaster>();
			RectTransform val4 = (window.Panel = Rect("Window", window.Root.transform));
			Vector2 val5 = default(Vector2);
			((Vector2)(ref val5))..ctor(0.5f, 0.5f);
			val4.pivot = val5;
			Vector2 anchorMin = (val4.anchorMax = val5);
			val4.anchorMin = anchorMin;
			val4.sizeDelta = new Vector2(width, height);
			val4.anchoredPosition = Vector2.zero;
			Image val7 = ((Component)val4).gameObject.AddComponent<Image>();
			Image val8 = (((Object)(object)instance.m_crafting != (Object)null) ? ((IEnumerable<Image>)((Component)instance.m_crafting).GetComponentsInChildren<Image>(true)).FirstOrDefault((Func<Image, bool>)((Image i) => ((Object)i).name == "Bkg")) : null);
			if ((Object)(object)val8 != (Object)null && (Object)(object)val8.sprite != (Object)null)
			{
				val7.sprite = val8.sprite;
				val7.type = val8.type;
				((Graphic)val7).material = ((Graphic)val8).material;
				((Graphic)val7).color = ((Graphic)val8).color;
				val7.pixelsPerUnitMultiplier = val8.pixelsPerUnitMultiplier;
			}
			else
			{
				((Graphic)val7).color = new Color(0.08f, 0.07f, 0.06f, 0.96f);
			}
			Place(((TMP_Text)Text((Transform)(object)val4, title, 34f, Gold, (TextAlignmentOptions)513)).rectTransform, 24f, 14f, width - 120f, 44f);
			TextMeshProUGUI obj3 = Text((Transform)(object)val4, "X", 28f, Body, (TextAlignmentOptions)514);
			Place(((TMP_Text)obj3).rectTransform, width - 24f - 36f, 14f, 36f, 36f);
			((Graphic)obj3).raycastTarget = true;
			ButtonClickedEvent onClick = ((Component)obj3).gameObject.AddComponent<Button>().onClick;
			object obj4 = <>O.<0>__Close;
			if (obj4 == null)
			{
				UnityAction val9 = Close;
				<>O.<0>__Close = val9;
				obj4 = (object)val9;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj4);
			if (back != null)
			{
				Button(val4, "Back", width - 24f - 36f - 12f - 116f, 15f, 116f, 36f, (UnityAction)delegate
				{
					back();
				});
			}
			Place(((TMP_Text)Text((Transform)(object)val4, subtitle, 20f, Dim, (TextAlignmentOptions)513)).rectTransform, 24f, 62f, width - 48f, 30f);
			float height2 = height - listTop - 52f;
			window.View = Rect("List", (Transform)(object)val4);
			Place(window.View, 24f, listTop, width - 48f - 14f - 6f, height2);
			((Graphic)((Component)window.View).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.28f);
			((Component)window.View).gameObject.AddComponent<RectMask2D>();
			window.Content = Rect("Content", (Transform)(object)window.View);
			window.Content.anchorMin = new Vector2(0f, 1f);
			window.Content.anchorMax = new Vector2(1f, 1f);
			window.Content.pivot = new Vector2(0.5f, 1f);
			window.Content.anchoredPosition = Vector2.zero;
			ScrollRect val10 = ((Component)window.View).gameObject.AddComponent<ScrollRect>();
			val10.content = window.Content;
			val10.viewport = window.View;
			val10.horizontal = false;
			val10.vertical = true;
			val10.movementType = (MovementType)2;
			val10.scrollSensitivity = 0f;
			val10.inertia = false;
			if ((Object)(object)instance.m_recipeListScroll != (Object)null)
			{
				Scrollbar component = Object.Instantiate<GameObject>(((Component)instance.m_recipeListScroll).gameObject, (Transform)(object)val4, false).GetComponent<Scrollbar>();
				((Object)component).name = "Scrollbar";
				component.onValueChanged = new ScrollEvent();
				component.direction = (Direction)2;
				Place((RectTransform)((Component)component).transform, width - 24f - 14f, listTop, 14f, height2);
				val10.verticalScrollbar = component;
				val10.verticalScrollbarVisibility = (ScrollbarVisibility)0;
			}
			window.RowWidth = width - 48f - 14f - 6f;
			Place(((TMP_Text)Text((Transform)(object)val4, footer, 18f, Dim, (TextAlignmentOptions)513)).rectTransform, 24f, height - 42f, width - 48f, 28f);
			Current = window;
			return window;
		}

		internal static void Done(Window w, float contentHeight)
		{
			//IL_000c: 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)
			w.Content.sizeDelta = new Vector2(0f, contentHeight);
			w.Content.anchoredPosition = Vector2.zero;
			w.Gliding = false;
		}

		internal static void Close()
		{
			if (Current != null && (Object)(object)Current.Root != (Object)null)
			{
				Object.Destroy((Object)(object)Current.Root);
			}
			Current = null;
		}

		private static void Scroll(Window w, float wheel, float dt)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)w.Content == (Object)null || (Object)(object)w.View == (Object)null)
			{
				return;
			}
			Rect rect = w.Content.rect;
			float height = ((Rect)(ref rect)).height;
			rect = w.View.rect;
			float num = Mathf.Max(0f, height - ((Rect)(ref rect)).height);
			float y = w.Content.anchoredPosition.y;
			if (Mathf.Abs(wheel) > 0.0001f && num > 0f)
			{
				if (!w.Gliding)
				{
					w.Target = y;
				}
				w.Target = Mathf.Clamp(w.Target - Mathf.Sign(wheel) * w.Step, 0f, num);
				w.Gliding = true;
			}
			if (w.Gliding)
			{
				float num2 = Mathf.Lerp(y, w.Target, 1f - Mathf.Exp((0f - dt) * 16f));
				if (Mathf.Abs(num2 - w.Target) < 0.5f)
				{
					num2 = w.Target;
					w.Gliding = false;
				}
				w.Content.anchoredPosition = new Vector2(w.Content.anchoredPosition.x, num2);
			}
		}

		private static void NoInput(ref bool __result)
		{
			if (IsOpen)
			{
				__result = false;
			}
		}

		private static void FreeMouse()
		{
			if (IsOpen)
			{
				ZCursor.LockState = (CursorLockMode)0;
				ZCursor.Show();
			}
		}

		private static void OwnWheel(ref float __result)
		{
			if (IsOpen && !_readingWheel)
			{
				__result = 0f;
			}
		}

		private static bool EscapeCloses()
		{
			if (_escapeFrame == Time.frameCount)
			{
				return false;
			}
			if (!IsOpen)
			{
				return true;
			}
			if (Searching)
			{
				return false;
			}
			if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("Menu"))
			{
				Close();
				_escapeFrame = Time.frameCount;
			}
			return false;
		}

		internal static void Use(GameObject host)
		{
			_users++;
			if ((Object)(object)host.GetComponent<Windows>() == (Object)null)
			{
				host.AddComponent<Windows>();
			}
		}

		internal static void Release(GameObject host)
		{
			if (--_users <= 0)
			{
				_users = 0;
				Windows windows = (((Object)(object)host != (Object)null) ? host.GetComponent<Windows>() : null);
				if ((Object)(object)windows != (Object)null)
				{
					Object.Destroy((Object)(object)windows);
				}
			}
		}

		private static void SearchTyping(ref bool __result)
		{
			if (Typing)
			{
				__result = true;
			}
		}

		internal static RectTransform Rect(string name, Transform parent)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			return (RectTransform)val.transform;
		}

		internal static void Place(RectTransform rect, float x, float y, float width, float height)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			rect.anchorMax = val;
			rect.anchorMin = val;
			rect.pivot = new Vector2(0f, 1f);
			rect.anchoredPosition = new Vector2(x, 0f - y);
			rect.sizeDelta = new Vector2(width, height);
		}

		internal static TextMeshProUGUI Text(Transform parent, string text, float size, Color color, TextAlignmentOptions align)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = ((Component)Rect("Text", parent)).gameObject.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)_font != (Object)null)
			{
				((TMP_Text)val).font = _font;
			}
			if ((Object)(object)_fontMaterial != (Object)null)
			{
				((TMP_Text)val).fontSharedMaterial = _fontMaterial;
			}
			((TMP_Text)val).fontSize = size;
			((Graphic)val).color = color;
			((TMP_Text)val).alignment = align;
			((TMP_Text)val).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)val).overflowMode = (TextOverflowModes)1;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).richText = true;
			((TMP_Text)val).text = text;
			return val;
		}

		internal static Image Picture(RectTransform parent, Sprite sprite, float x, float y, float width, float height)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Rect("Picture", (Transform)(object)parent);
			Place(obj, x, y, width, height);
			Image obj2 = ((Component)obj).gameObject.AddComponent<Image>();
			obj2.sprite = sprite;
			obj2.preserveAspect = true;
			((Graphic)obj2).raycastTarget = false;
			((Graphic)obj2).color = (Color)(((Object)(object)sprite != (Object)null) ? Color.white : new Color(0f, 0f, 0f, 0.3f));
			return obj2;
		}

		internal static Button Button(RectTransform parent, string label, float x, float y, float width, float height, UnityAction click)
		{
			//IL_007c: 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_00b1: 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_00dd: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			InventoryGui instance = InventoryGui.instance;
			GameObject val;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_tabCraft != (Object)null)
			{
				val = Object.Instantiate<GameObject>(((Component)instance.m_tabCraft).gameObject, (Transform)(object)parent, false);
				TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].text = label;
				}
			}
			else
			{
				val = ((Component)Rect("Button", (Transform)(object)parent)).gameObject;
				((Graphic)val.AddComponent<Image>()).color = new Color(0.3f, 0.25f, 0.2f, 0.9f);
				val.AddComponent<Button>();
				((TMP_Text)Text(val.transform, label, 18f, Body, (TextAlignmentOptions)514)).rectTransform.sizeDelta = new Vector2(width, height);
			}
			((Object)val).name = "Button " + label;
			Button component = val.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener(click);
			((Selectable)component).interactable = true;
			Place((RectTransform)val.transform, x, y, width, height);
			return component;
		}

		internal static TMP_InputField SearchBox(RectTransform parent, float x, float y, float width, float height, string hint)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			RectTransform val = Rect("Search", (Transform)(object)parent);
			Place(val, x, y, width, height);
			((Component)val).gameObject.SetActive(false);
			Image val2 = ((Component)val).gameObject.AddComponent<Image>();
			Sprite val3 = SlotSprite();
			if ((Object)(object)val3 != (Object)null)
			{
				val2.sprite = val3;
				val2.type = (Type)1;
			}
			((Graphic)val2).color = new Color(0f, 0f, 0f, 0.6f);
			RectTransform val4 = Rect("Text Area", (Transform)(object)val);
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = new Vector2(12f, 2f);
			val4.offsetMax = new Vector2(-34f, -2f);
			((Component)val4).gameObject.AddComponent<RectMask2D>();
			TextMeshProUGUI val5 = Text((Transform)(object)val4, hint, 19f, Dim, (TextAlignmentOptions)513);
			Stretch(((TMP_Text)val5).rectTransform);
			((TMP_Text)val5).fontStyle = (FontStyles)2;
			TextMeshProUGUI val6 = Text((Transform)(object)val4, "", 19f, Body, (TextAlignmentOptions)513);
			Stretch(((TMP_Text)val6).rectTransform);
			((TMP_Text)val6).richText = false;
			TMP_InputField field = ((Component)val).gameObject.AddComponent<TMP_InputField>();
			field.textViewport = val4;
			field.textComponent = (TMP_Text)(object)val6;
			field.placeholder = (Graphic)(object)val5;
			((Selectable)field).targetGraphic = (Graphic)(object)val2;
			if ((Object)(object)_font != (Object)null)
			{
				field.fontAsset = _font;
			}
			field.pointSize = 19f;
			field.characterLimit = 40;
			field.richText = false;
			field.customCaretColor = true;
			field.caretColor = Body;
			field.caretWidth = 2;
			field.selectionColor = new Color(1f, 0.72f, 0.36f, 0.35f);
			((Component)val).gameObject.SetActive(true);
			TextMeshProUGUI obj = Text((Transform)(object)val, "x", 22f, Dim, (TextAlignmentOptions)514);
			Place(((TMP_Text)obj).rectTransform, width - 32f, 0f, 30f, height);
			((Graphic)obj).raycastTarget = true;
			((UnityEvent)((Component)obj).gameObject.AddComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				field.text = "";
			});
			return field;
		}

		private static Sprite SlotSprite()
		{
			GameObject val = InventoryGui.instance?.m_playerGrid?.m_elementPrefab;
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
			foreach (Image val2 in componentsInChildren)
			{
				if ((Object)(object)val2.sprite != (Object)null && ((Object)val2.sprite).name == "item_background")
				{
					return val2.sprite;
				}
			}
			return null;
		}

		internal static void Stretch(RectTransform rect)
		{
			//IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}

		internal static void SetLabel(Button button, string label)
		{
			TMP_Text[] componentsInChildren = ((Component)button).GetComponentsInChildren<TMP_Text>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].text = label;
			}
		}
	}
}
namespace DigiCore
{
	public static class ChestFlags
	{
		public const string NoStore = "digi_nostore";

		public static bool StoreBlocked(Container chest)
		{
			if ((Object)(object)chest == (Object)null)
			{
				return false;
			}
			ZNetView component = ((Component)chest).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				return component.GetZDO().GetBool("digi_nostore", false);
			}
			return false;
		}
	}
	public sealed class ModuleInfo
	{
		public readonly Type Type;

		public readonly string Title;

		public readonly string OldGuid;

		public readonly string Description;

		public readonly string[] Requires;

		public readonly bool DefaultOn;

		public readonly bool OffOnce;

		public readonly string FormerTitle;

		public ModuleInfo(Type type, string title, string oldGuid, string description, string[] requires = null, bool defaultOn = true, bool offOnce = false, string formerTitle = null)
		{
			OffOnce = offOnce;
			FormerTitle = formerTitle;
			Type = type;
			Title = title;
			OldGuid = oldGuid;
			Description = description;
			Requires = requires ?? new string[0];
			DefaultOn = defaultOn;
		}
	}
	public abstract class DigiPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<string, string> <>9__15_0;

			public static Func<string, bool> <>9__15_1;

			public static Func<string, bool> <>9__15_2;

			public static Func<string, string> <>9__15_3;

			public static Func<string, bool> <>9__15_4;

			public static Func<string, string> <>9__15_5;

			public static Func<string, string[]> <>9__24_0;

			public static Func<string[], string> <>9__24_1;

			public static Func<string[], string> <>9__24_4;

			public static Func<IGrouping<string, string[]>, string> <>9__24_2;

			public static PopupButtonCallback <>9__24_3;

			public static Func<string, bool> <>9__29_0;

			internal string <Awake>b__15_0(string l)
			{
				return l.Trim();
			}

			internal bool <Awake>b__15_1(string l)
			{
				return l.Length > 0;
			}

			internal bool <Awake>b__15_2(string r)
			{
				return !Chainloader.PluginInfos.ContainsKey(r);
			}

			internal string <Awake>b__15_3(string r)
			{
				if (!RequirementNames.TryGetValue(r, out var value))
				{
					return r;
				}
				return value;
			}

			internal bool <Awake>b__15_4(string r)
			{
				return !Chainloader.PluginInfos.ContainsKey(r);
			}

			internal string <Awake>b__15_5(string r)
			{
				if (!RequirementNames.TryGetValue(r, out var value))
				{
					return r;
				}
				return value;
			}

			internal string[] <ShowDuplicates>b__24_0(string d)
			{
				return d.Split(new char[1] { '|' });
			}

			internal string <ShowDuplicates>b__24_1(string[] d)
			{
				return d[0];
			}

			internal string <ShowDuplicates>b__24_2(IGrouping<string, string[]> g)
			{
				return "<b>" + g.Key + ":</b> " + string.Join(", ", g.Select((string[] d) => d[1]));
			}

			internal string <ShowDuplicates>b__24_4(string[] d)
			{
				return d[1];
			}

			internal void <ShowDuplicates>b__24_3()
			{
				UnifiedPopup.Pop();
			}

			internal bool <Apply>b__29_0(string r)
			{
				return !Chainloader.PluginInfos.ContainsKey(r);
			}
		}

		public const string ModulesSection = "0 - Sub-mods";

		internal static DigiPlugin StartingHost;

		internal static ModuleInfo StartingModule;

		private static readonly Dictionary<string, string> RequirementNames = new Dictionary<string, string>
		{
			{ "randyknapp.mods.epicloot", "Epic Loot" },
			{ "com.jotunn.jotunn", "Jotunn" },
			{ "ValheimLegends", "Valheim Legends" },
			{ "vapok.mods.adventurebackpacks", "Adventure Backpacks" },
			{ "MidnightsFX.StarLevelSystem", "Star Level System" },
			{ "sosal.nordicrugs", "Nordic Rugs" },
			{ "LuminairPrime.valheim.localcraftfromstorageprime", "Local Craft From Storage Prime" }
		};

		private readonly Dictionary<ModuleInfo, DigiModule> _running = new Dictionary<ModuleInfo, DigiModule>();

		private readonly Dictionary<ModuleInfo, ConfigEntry<bool>> _switches = new Dictionary<ModuleInfo, ConfigEntry<bool>>();

		private HashSet<string> _migrated;

		private const string DuplicatesKey = "digi.valheim.duplicates";

		private const string DuplicatesShownKey = "digi.valheim.duplicates.shown";

		protected abstract ModuleInfo[] Modules { get; }

		protected virtual bool Standalone => false;

		internal bool IsStandalone => Standalone;

		private string MigratedFile => Path.Combine(Paths.ConfigPath, ((BaseUnityPlugin)this).Info.Metadata.GUID + ".migrated.txt");

		private static List<string> Duplicates
		{
			get
			{
				List<string> list = AppDomain.CurrentDomain.GetData("digi.valheim.duplicates") as List<string>;
				if (list == null)
				{
					list = new List<string>();
					AppDomain.CurrentDomain.SetData("digi.valheim.duplicates", list);
				}
				return list;
			}
		}

		protected virtual void Awake()
		{
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			((BaseUnityPlugin)this).Config.Save();
			_migrated = (File.Exists(MigratedFile) ? new HashSet<string>(from l in File.ReadAllLines(MigratedFile)
				select l.Trim() into l
				where l.Length > 0
				select l) : new HashSet<string>());
			bool flag = !_migrated.Contains("#switches");
			ModuleInfo[] modules;
			if (Standalone)
			{
				modules = Modules;
				foreach (ModuleInfo moduleInfo in modules)
				{
					List<string> list = moduleInfo.Requires.Where((string r) => !Chainloader.PluginInfos.ContainsKey(r)).ToList();
					if (list.Count > 0)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)(moduleInfo.Title + ": not started, needs " + string.Join(" and ", list.Select((string r) => (!RequirementNames.TryGetValue(r, out var value2)) ? r : value2)) + "."));
					}
					else
					{
						StartModule(moduleInfo);
					}
				}
				return;
			}
			modules = Modules;
			foreach (ModuleInfo moduleInfo2 in modules)
			{
				List<string> list2 = moduleInfo2.Requires.Where((string r) => !Chainloader.PluginInfos.ContainsKey(r)).ToList();
				string value2;
				string text = ((moduleInfo2.Requires.Length == 0) ? "" : (" Needs " + string.Join(" and ", moduleInfo2.Requires.Select((string r) => (!RequirementNames.TryGetValue(r, out value2)) ? r : value2)) + "."));
				ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Sub-mods", moduleInfo2.Title, moduleInfo2.DefaultOn, moduleInfo2.Description + text);
				if (flag && !moduleInfo2.DefaultOn && File.Exists(OldConfigPath(moduleInfo2)))
				{
					val.Value = true;
				}
				if (moduleInfo2.FormerTitle != null && !_migrated.Contains("#renamed:" + moduleInfo2.FormerTitle))
				{
					if (File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) && ReadCfg(((BaseUnityPlugin)this).Config.ConfigFilePath).TryGetValue("0 - Sub-mods\n" + moduleInfo2.FormerTitle, out var value) && bool.TryParse(value, out var result))
					{
						val.Value = result;
					}
					Remember("#renamed:" + moduleInfo2.FormerTitle);
				}
				if (moduleInfo2.OffOnce && !_migrated.Contains("#off:" + moduleInfo2.OldGuid))
				{
					val.Value = false;
					Remember("#off:" + moduleInfo2.OldGuid);
				}
				_switches[moduleInfo2] = val;
				ModuleInfo captured = moduleInfo2;
				val.SettingChanged += delegate
				{
					Apply(captured);
				};
				if (list2.Count > 0)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)(moduleInfo2.Title + ": off, needs " + string.Join(", ", list2) + "."));
				}
			}
			if (flag)
			{
				Remember("#switches");
			}
			modules = Modules;
			foreach (ModuleInfo module in modules)
			{
				Apply(module);
			}
		}

		private void Start()
		{
			foreach (KeyValuePair<ModuleInfo, DigiModule> item in _running.ToList())
			{
				if (!((Object)(object)item.Value == (Object)null) && !(item.Key.OldGuid == ((BaseUnityPlugin)this).Info.Metadata.GUID) && Chainloader.PluginInfos.ContainsKey(item.Key.OldGuid))
				{
					item.Value.Teardown();
					_running.Remove(item.Key);
					Forget(item.Key.OldGuid);
					ReportDuplicate(item.Key);
				}
			}
			SettingOrder.Apply(((BaseUnityPlugin)this).Config);
			if (!Application.isBatchMode)
			{
				((MonoBehaviour)this).StartCoroutine(ShowDuplicates());
			}
		}

		private void ReportDuplicate(ModuleInfo module)
		{
			if (IsOurSingle(module.OldGuid))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)(module.Title + ": runs as its own mod (" + module.OldGuid + "), so the copy in " + ((BaseUnityPlugin)this).Info.Metadata.Name + " stays off."));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)(module.Title + ": not started, because the separate mod (" + module.OldGuid + ") is installed too. Remove that one."));
				string item = ((BaseUnityPlugin)this).Info.Metadata.Name.Replace("Digi's ", "") + "|" + module.Title;
				if (!Duplicates.Contains(item))
				{
					Duplicates.Add(item);
				}
			}
		}

		private static bool IsOurSingle(string guid)
		{
			if (!Chainloader.PluginInfos.TryGetValue(guid, out var value) || (Object)(object)value.Instance == (Object)null)
			{
				return false;
			}
			Type type = ((object)value.Instance).GetType();
			while (type != null)
			{
				if (type.FullName == "DigiCore.DigiPlugin")
				{
					return true;
				}
				type = type.BaseType;
			}
			return false;
		}

		internal void ReportReplaced(string what)
		{
			string item = ((BaseUnityPlugin)this).Info.Metadata.Name.Replace("Digi's ", "") + "|" + what;
			if (!Duplicates.Contains(item))
			{
				Duplicates.Add(item);
			}
		}

		private IEnumerator ShowDuplicates()
		{
			while ((Object)(object)FejdStartup.instance == (Object)null || !UnifiedPopup.IsAvailable())
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			yield return (object)new WaitForSeconds(1f);
			if (Duplicates.Count == 0 || AppDomain.CurrentDomain.GetData("digi.valheim.duplicates.shown") != null)
			{
				yield break;
			}
			AppDomain.CurrentDomain.SetData("digi.valheim.duplicates.shown", true);
			IEnumerable<string> values = from d in Duplicates
				select d.Split(new char[1] { '|' }) into d
				group d by d[0] into g
				select "<b>" + g.Key + ":</b> " + string.Join(", ", g.Select((string[] d) => d[1]));
			string text = "These mods are installed twice: on their own and inside one of our combined mods.\n\n" + string.Join("\n", values) + "\n\nThe copy in the combined mod stays off until you remove the separate ones in your mod manager (or make a new profile with Digi Modpack). Your settings are copied over.";
			object obj = <>c.<>9__24_3;
			if (obj == null)
			{
				PopupButtonCallback val = delegate
				{
					UnifiedPopup.Pop();
				};
				<>c.<>9__24_3 = val;
				obj = (object)val;
			}
			UnifiedPopup.Push((PopupBase)new WarningPopup("Mods installed twice", text, (PopupButtonCallback)obj, false));
		}

		private static string OldConfigPath(ModuleInfo module)
		{
			return Path.Combine(Paths.ConfigPath, module.OldGuid + ".cfg");
		}

		internal bool FirstTime(string key)
		{
			if (_migrated == null || _migrated.Contains(key))
			{
				return false;
			}
			Remember(key);
			return true;
		}

		private void Remember(string key)
		{
			if (!_migrated.Add(key))
			{
				return;
			}
			try
			{
				File.AppendAllText(MigratedFile, key + Environment.NewLine);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not write " + MigratedFile + ": " + ex.Message));
			}
		}

		private void Forget(string key)
		{
			if (!_migrated.Remove(key))
			{
				return;
			}
			try
			{
				File.WriteAllLines(MigratedFile, _migrated.ToArray());
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not write " + MigratedFile + ": " + ex.Message));
			}
		}

		private void Apply(ModuleInfo module)
		{
			bool value = _switches[module].Value;
			_running.TryGetValue(module, out var value2);
			if (value && (Object)(object)value2 == (Object)null)
			{
				if (!module.Requires.Any((string r) => !Chainloader.PluginInfos.ContainsKey(r)))
				{
					if (module.OldGuid != ((BaseUnityPlugin)this).Info.Metadata.GUID && Chainloader.PluginInfos.ContainsKey(module.OldGuid))
					{
						ReportDuplicate(module);
					}
					else
					{
						StartModule(module);
					}
				}
			}
			else if (!value && (Object)(object)value2 != (Object)null)
			{
				value2.Teardown();
				_running.Remove(module);
				((BaseUnityPlugin)this).Logger.LogInfo((object)(module.Title + ": switched off."));
			}
		}

		private void StartModule(ModuleInfo module)
		{
			StartingHost = this;
			StartingModule = module;
			try
			{
				DigiModule digiModule = (DigiModule)(object)((Component)this).gameObject.AddComponent(module.Type);
				digiModule.Host = this;
				digiModule.Info2 = module;
				_running[module] = digiModule;
				MigrateOldSettings(module, digiModule);
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"{module.Title} could not start: {arg}");
			}
			finally
			{
				StartingHost = null;
				StartingModule = null;
			}
			SettingOrder.Apply(((BaseUnityPlugin)this).Config);
		}

		private void MigrateOldSettings(ModuleInfo module, DigiModule component)
		{
			if (_migrated.Contains(module.OldGuid) || module.OldGuid == ((BaseUnityPlugin)this).Info.Metadata.GUID)
			{
				return;
			}
			string path = OldConfigPath(module);
			if (File.Exists(path) && component.ConfigOrNull != null)
			{
				Dictionary<string, string> dictionary = ReadCfg(path);
				int num = 0;
				foreach (ModuleConfig.Bound entry in component.ConfigOrNull.Entries)
				{
					if (dictionary.TryGetValue(entry.Section + "\n" + entry.Key, out var value))
					{
						try
						{
							entry.Entry.SetSerializedValue(value);
							num++;
						}
						catch (Exception ex)
						{
							((BaseUnityPlugin)this).Logger.LogWarning((object)(module.Title + ": could not copy '" + entry.Key + "': " + ex.Message));
						}
					}
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"{module.Title}: copied {num} setting(s) from {Path.GetFileName(path)}.");
			}
			Remember(module.OldGuid);
		}

		private static Dictionary<string, string> ReadCfg(string path)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			string text = "";
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length == 0 || text2.StartsWith("#"))
				{
					continue;
				}
				if (text2.StartsWith("[") && text2.EndsWith("]"))
				{
					text = text2.Substring(1, text2.Length - 2);
					continue;
				}
				int num = text2.IndexOf(" = ", StringComparison.Ordinal);
				if (num > 0)
				{
					dictionary[text + "\n" + text2.Substring(0, num).Trim()] = text2.Substring(num + 3);
				}
			}
			return dictionary;
		}

		protected virtual void OnDestroy()
		{
			foreach (DigiModule item in _running.Values.ToList())
			{
				item?.Teardown();
			}
			_running.Clear();
		}

		public bool IsRunning(Type moduleType)
		{
			return _running.Any((KeyValuePair<ModuleInfo, DigiModule> p) => p.Key.Type == moduleType && (Object)(object)p.Value != (Object)null);
		}
	}
	public abstract class DigiModule : MonoBehaviour
	{
		internal DigiPlugin Host;

		internal ModuleInfo Info2;

		private ModuleConfig _config;

		private ManualLogSource _logger;

		private Harmony _harmony;

		internal ModuleConfig ConfigOrNull => _config;

		protected ModuleConfig Config => _config ?? (_config = new ModuleConfig(((BaseUnityPlugin)(Host ?? DigiPlugin.StartingHost)).Config, (Host ?? DigiPlugin.StartingHost).IsStandalone ? null : (Info2 ?? DigiPlugin.StartingModule).Title));

		protected ManualLogSource Logger => _logger ?? (_logger = Logger.CreateLogSource("Digi's " + (Info2 ?? DigiPlugin.StartingModule)?.Title));

		protected Harmony ModuleHarmony
		{
			get
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Expected O, but got Unknown
				//IL_004a: Expected O, but got Unknown
				Harmony obj = _harmony;
				if (obj == null)
				{
					Harmony val = new Harmony(((object)this).GetType().Namespace?.ToLowerInvariant() + "." + Guid.NewGuid().ToString("N"));
					Harmony val2 = val;
					_harmony = val;
					obj = val2;
				}
				return obj;
			}
		}

		protected void ReportReplacedMod(string what)
		{
			(Host ?? DigiPlugin.StartingHost)?.ReportReplaced(what);
		}

		protected bool FirstTime(string key)
		{
			return (Host ?? DigiPlugin.StartingHost)?.FirstTime("#once:" + (Info2 ?? DigiPlugin.StartingModule)?.Title + ":" + key) ?? false;
		}

		protected Harmony PatchModule(Type type)
		{
			ModuleHarmony.PatchAll(type);
			return ModuleHarmony;
		}

		protected Harmony PatchModuleNamespace()
		{
			string text = ((object)this).GetType().Namespace;
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(((object)this).GetType().Assembly);
			foreach (Type type in typesFromAssembly)
			{
				if (type.Namespace == text || (type.Namespace != null && text != null && type.Namespace.StartsWith(text + ".")))
				{
					ModuleHarmony.CreateClassProcessor(type).Patch();
				}
			}
			return ModuleHarmony;
		}

		internal void Teardown()
		{
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Unpatch: " + ex.Message));
			}
			Object.Destroy((Object)(object)this);
		}
	}
	public sealed class ModuleConfig
	{
		public sealed class Bound
		{
			public string Section;

			public string Key;

			public ConfigEntryBase Entry;
		}

		private readonly ConfigFile _file;

		private readonly string _prefix;

		internal readonly List<Bound> Entries = new List<Bound>();

		private static readonly char[] Invalid = new char[8] { '=', '\n', '\t', '\\', '"', '\'', '[', ']' };

		public ConfigFile File => _file;

		public string ConfigFilePath => _file.ConfigFilePath;

		internal ModuleConfig(ConfigFile file, string title)
		{
			_file = file;
			_prefix = ((title == null) ? "" : (title + " - "));
		}

		public void Reload()
		{
		}

		public void Save()
		{
			_file.Save();
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, ConfigDescription configDescription = null)
		{
			section = Clean(section);
			key = Clean(key);
			ConfigEntry<T> val = _file.Bind<T>(_prefix + section, key, defaultValue, configDescription);
			if (!Entries.Any((Bound b) => b.Section == section && b.Key == key))
			{
				Entries.Add(new Bound
				{
					Section = section,
					Key = key,
					Entry = (ConfigEntryBase)(object)val
				});
			}
			return val;
		}

		private static string Clean(string name)
		{
			if (name.IndexOfAny(Invalid) < 0)
			{
				return name;
			}
			string[] value = name.Split(Invalid, StringSplitOptions.None);
			return string.Join("", value).Trim();
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Bind(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public ConfigEntry<T> Bind<T>(ConfigDefinition definition, T defaultValue, ConfigDescription configDescription = null)
		{
			return Bind(definition.Section, definition.Key, defaultValue, configDescription);
		}

		public bool TryGetEntry<T>(ConfigDefinition definition, out ConfigEntry<T> entry)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			return _file.TryGetEntry<T>(new ConfigDefinition(_prefix + definition.Section, definition.Key), ref entry);
		}
	}
}
namespace DigiPortalList
{
	[BepInPlugin("digi.valheim.portallist", "Digi's Portal List", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : DigiPlugin
	{
		public const string Guid = "digi.valheim.portallist";

		public const string Name = "Digi's Portal List";

		public const string Version = "1.0.1";

		protected override ModuleInfo[] Modules { get; } = new ModuleInfo[1]
		{
			new ModuleInfo(typeof(PortalList.Plugin), "Portal List", "digi.valheim.portallist", "Walk into a portal and pick any portal in the world from a list: search, sort, favourites; a name, colour and icon per portal; in multiplayer private until you share it.")
		};
	}
}
namespace PortalList
{
	public class Plugin : DigiModule
	{
		public enum SortBy
		{
			Recent,
			Name,
			Nearest,
			Biome
		}

		private sealed class Entry
		{
			public ZDOID Id;

			public string Name;

			public string Prefab;

			public Vector3 Position;

			public Quaternion Rotation;

			public int Color;

			public int Icon;

			public long Creator;

			public bool Shared;
		}

		private sealed class SortAgain : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
		{
			public void OnPointerClick(PointerEventData data)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				if (_sort.Value == SortBy.Name && Time.frameCount != _sortClickFrame)
				{
					_zToA.Value = !_zToA.Value;
					_editing = ZDOID.None;
					UpdateSortButtons();
					FillList(keepScroll: false);
				}
			}
		}

		private sealed class RowParts
		{
			public Entry E;

			public RectTransform Rect;

			public Image Background;

			public Image Stripe;

			public Image Icon;

			public Image Kind;

			public RowHover Hover;

			public TextMeshProUGUI Star;

			public TextMeshProUGUI Name;

			public TextMeshProUGUI Biome;

			public TextMeshProUGUI Far;

			public Button Edit;

			public Button Share;
		}

		private sealed class RowHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
		{
			public Image Image;

			public Color Normal;

			public Color Over;

			public void OnPointerEnter(PointerEventData data)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Image != (Object)null)
				{
					((Graphic)Image).color = Over;
				}
			}

			public void OnPointerExit(PointerEventData data)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Image != (Object)null)
				{
					((Graphic)Image).color = Normal;
				}
			}
		}

		private const string AskRpc = "Digi_PortalList_Ask";

		private const string ListRpc = "Digi_PortalList";

		private const string EditRpc = "Digi_PortalList_Edit";

		private const string ColorKey = "digi_portal_color";

		private const string IconKey = "digi_portal_icon";

		private const string SharedKey = "digi_portal_shared";

		private const int NameLimit = 32;

		private const int EditName = 0;

		private const int EditColor = 1;

		private const int EditIcon = 2;

		private const int EditShared = 3;

		private const float Width = 900f;

		private const float Height = 760f;

		private const float ListTop = 160f;

		private const float RowHeight = 50f;

		private const float HeaderHeight = 34f;

		private const float Cell = 46f;

		private static readonly Biome[] BiomeOrder;

		private static ConfigEntry<bool> _onEnter;

		private static ConfigEntry<bool> _glow;

		private static ConfigEntry<bool> _zToA;

		private static ConfigEntry<SortBy> _sort;

		private static readonly Color[] Colors;

		private static readonly int[] ColorOrder;

		private static readonly string[] IconItems;

		private static readonly string[] AfterTrophies;

		private static readonly HashSet<string> Hidden;

		private static List<Entry> _entries;

		private static bool _fromServer;

		private static bool _asking;

		private static float _askedAt;

		private static TeleportWorld _source;

		private static Windows.Window _window;

		private static TMP_InputField _searchBox;

		private static TextMeshProUGUI _subtitle;

		private static readonly List<KeyValuePair<SortBy, Button>> SortButtons;

		private static string _search;

		private static ZDOID _editing;

		private static List<ZDOID> _frozenFavourites;

		private static List<ZDOID> _frozenRest;

		private static string _startName;

		private static int _startColor;

		private static int _startIcon;

		private static Entry _typing;

		private static string _typed;

		private static float _typedAt;

		private static readonly HashSet<ZDOID> Favourites;

		private static readonly Dictionary<ZDOID, long> Trips;

		private static string _loadedKey;

		private static int _sortClickFrame;

		private static readonly Dictionary<ZDOID, RowParts> Rows;

		private static readonly List<GameObject> Extras;

		private static bool IsOpen
		{
			get
			{
				if (Windows.IsOpen)
				{
					return Windows.Current == _window;
				}
				return false;
			}
		}

		private static long Me
		{
			get
			{
				if (!((Object)(object)Player.m_localPlayer != (Object)null))
				{
					return 0L;
				}
				return Player.m_localPlayer.GetPlayerID();
			}
		}

		private static string DataKey
		{
			get
			{
				if (!((Object)(object)ZNet.instance != (Object)null))
				{
					return null;
				}
				return "digi.portallist." + ZNet.instance.GetWorldUID().ToString(CultureInfo.InvariantCulture);
			}
		}

		private static bool Offered(int i, int current)
		{
			if (i == current || i == 0)
			{
				return true;
			}
			string text = IconItems[i];
			if (Hidden.Contains(text))
			{
				return false;
			}
			if (!(text != "Flametal"))
			{
				return (Object)(object)ItemIcon("FlametalNew") == (Object)null;
			}
			return true;
		}

		private static IEnumerable<int> IconOrder()
		{
			yield return 0;
			for (int i = 1; i < IconItems.Length; i++)
			{
				if (IconItems[i].StartsWith("loc:", StringComparison.Ordinal))
				{
					yield return i;
				}
			}
			for (int i = 1; i < IconItems.Length; i++)
			{
				if (IconItems[i].StartsWith("pin:", StringComparison.Ordinal) || IconItems[i].StartsWith("piece:", StringComparison.Ordinal))
				{
					yield return i;
				}
			}
			for (int i = 1; i < IconItems.Length; i++)
			{
				if (IconItems[i].IndexOf(':') >= 0 || Array.IndexOf(AfterTrophies, IconItems[i]) >= 0)
				{
					continue;
				}
				yield return i;
				if (IconItems[i] == "TrophyFader")
				{
					string[] afterTrophies = AfterTrophies;
					foreach (string value in afterTrophies)
					{
						yield return Array.IndexOf(IconItems, value);
					}
				}
			}
		}

		private void Awake()
		{
			_onEnter = base.Config.Bind("General", "Open the list when walking into a portal", defaultValue: true, "Walking into a portal opens the list of every portal in the world: click one to go there. Off: the game's tag pairing as before; Shift+E on a portal still opens the list.");
			_glow = base.Config.Bind("General", "Portals glow without a matching tag", defaultValue: true, "With the list any portal can lead anywhere, so portals light up as ready even when no other portal has the same name.");
			_sort = base.Config.Bind("General", "Sort", SortBy.Recent, "How the list is sorted (the buttons in the list change it): Recent = the portals you went to last first, Name = A to Z, Nearest = closest to the portal you stand at first, Biome = by biome in the order you meet them (A to Z within each). Favourites always come first.");
			_zToA = base.Config.Bind("General", "Name sorting Z to A", defaultValue: false, "The name sorting from Z to A instead of A to Z (clicking the name sort button again switches it).");
			PatchModule(typeof(Plugin));
			Windows.Patch(base.ModuleHarmony);
			Windows.Use(((Component)this).gameObject);
			RegisterRpcs();
		}

		private void OnDestroy()
		{
			if (IsOpen)
			{
				Windows.Close();
			}
			Windows.Release(((Component)this).gameObject);
			_window = null;
			_source = null;
		}

		[HarmonyPatch(typeof(TeleportWorld), "Teleport")]
		[HarmonyPrefix]
		private static bool Entered(TeleportWorld __instance, Player player)
		{
			if (!_onEnter.Value || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || ((Character)player).IsTeleporting())
			{
				return true;
			}
			Open(__instance);
			return false;
		}

		[HarmonyPatch(typeof(TeleportWorld), "Interact")]
		[HarmonyPrefix]
		private static bool Interacted(TeleportWorld __instance, Humanoid human, bool hold, bool alt, ref bool __result)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (hold)
			{
				return true;
			}
			__result = true;
			if (alt)
			{
				if ((Object)(object)human == (Object)(object)Player.m_localPlayer)
				{
					Open(__instance);
				}
				return false;
			}
			if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false))
			{
				((Character)human).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false);
				return false;
			}
			TextInput.instance.RequestText((TextReceiver)(object)__instance, "$piece_portal_tag", 32);
			return false;
		}

		[HarmonyPatch(typeof(TeleportWorld), "GetHoverText")]
		[HarmonyPostfix]
		private static void Hover(ref string __result)
		{
			__result = __result + Localization.instance.Localize("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Portal list") + (_onEnter.Value ? "  (or walk in)" : "");
		}

		[HarmonyPatch(typeof(TeleportWorld), "UpdatePortal")]
		[HarmonyPostfix]
		private static void Glow(TeleportWorld __instance)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (_glow.Value && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && !((Object)(object)__instance.m_proximityRoot == (Object)null))
			{
				__instance.m_hadTarget = true;
				Player closestPlayer = Player.GetClosestPlayer(__instance.m_proximityRoot.position, __instance.m_activationRange);
				__instance.m_target_found.SetActive((Object)(object)closestPlayer != (Object)null && ((Humanoid)closestPlayer).IsTeleportable(__instance.m_allowAllItems));
			}
		}

		[HarmonyPatch(typeof(Game), "Start")]
		[HarmonyPostfix]
		private static void RegisterRpcs()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null)
			{
				IDictionary dictionary = AccessTools.Field(typeof(ZRoutedRpc), "m_functions")?.GetValue(instance) as IDictionary;
				string[] array = new string[3] { "Digi_PortalList_Ask", "Digi_PortalList", "Digi_PortalList_Edit" };
				foreach (string text in array)
				{
					dictionary?.Remove(StringExtensionMethods.GetStableHashCode(text));
				}
				instance.Register<ZPackage>("Digi_PortalList_Ask", (Action<long, ZPackage>)OnAsk);
				instance.Register<ZPackage>("Digi_PortalList", (Action<long, ZPackage>)OnList);
				instance.Register<ZPackage>("Digi_PortalList_Edit", (Action<long, ZPackage>)OnEdit);
			}
		}

		private static void OnAsk(long sender, ZPackage ask)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			long who = ask.ReadLong();
			List<Entry> list = (from e in Known()
				where Visible(e, who)
				select e).ToList();
			ZPackage val = new ZPackage();
			val.Write(list.Count);
			foreach (Entry item in list)
			{
				val.Write(item.Id);
				val.Write(item.Name ?? "");
				val.Write(item.Prefab ?? "");
				val.Write(item.Position);
				val.Write(item.Rotation);
				val.Write(item.Color);
				val.Write(item.Icon);
				val.Write(item.Creator);
				val.Write(item.Shared);
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Digi_PortalList", new object[1] { val });
		}

		private static void OnList(long sender, ZPackage package)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			List<Entry> list = new List<Entry>();
			int num = package.ReadInt();
			for (int i = 0; i < num; i++)
			{
				list.Add(new Entry
				{
					Id = package.ReadZDOID(),
					Name = package.ReadString(),
					Prefab = package.ReadString(),
					Position = package.ReadVector3(),
					Rotation = package.ReadQuaternion(),
					Color = package.ReadInt(),
					Icon = package.ReadInt(),
					Creator = package.ReadLong(),
					Shared = package.ReadBool()
				});
			}
			_entries = list;
			_fromServer = true;
			_asking = false;
			if (IsOpen)
			{
				FillList();
			}
		}

		private static List<Entry> Known()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			List<Entry> list = new List<Entry>();
			HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
			if (ZDOMan.instance != null)
			{
				foreach (ZDO portal in ZDOMan.instance.GetPortalList())
				{
					if (portal != null && hashSet.Add(portal.m_uid))
					{
						list.Add(FromZdo(portal));
					}
				}
			}
			TeleportWorld[] array = Object.FindObjectsByType<TeleportWorld>((FindObjectsSortMode)0);
			foreach (TeleportWorld val in array)
			{
				ZDO val2 = (((Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid()) ? val.m_nview.GetZDO() : null);
				if (val2 != null && hashSet.Add(val2.m_uid))
				{
					list.Add(FromZdo(val2));
				}
			}
			return list;
		}

		private static Entry FromZdo(ZDO zdo)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(zdo.GetPrefab()) : null);
			return new Entry
			{
				Id = zdo.m_uid,
				Name = zdo.GetString(ZDOVars.s_tag, ""),
				Prefab = (((Object)(object)val != (Object)null) ? ((Object)val).name : ""),
				Position = zdo.GetPosition(),
				Rotation = zdo.GetRotation(),
				Color = zdo.GetInt("digi_portal_color", 0),
				Icon = zdo.GetInt("digi_portal_icon", 0),
				Creator = zdo.GetLong(ZDOVars.s_creator, 0L),
				Shared = (zdo.GetInt("digi_portal_shared", 0) == 1)
			};
		}

		private static bool Visible(Entry e, long who)
		{
			if (e.Creator != 0L && !e.Shared)
			{
				return e.Creator == who;
			}
			return true;
		}

		private static bool MayShare(Entry e)
		{
			if (Me != 0L)
			{
				return e.Creator == Me;
			}
			return false;
		}

		private static bool Open(ZDO zdo)
		{
			if (zdo.GetLong(ZDOVars.s_creator, 0L) != 0L)
			{
				return zdo.GetInt("digi_portal_shared", 0) == 1;
			}
			return true;
		}

		private static bool MayPair(ZDO a, ZDO b)
		{
			if (a != null && b != null && a.GetLong(ZDOVars.s_creator, 0L) != b.GetLong(ZDOVars.s_creator, 0L))
			{
				if (Open(a))
				{
					return Open(b);
				}
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Game), "FindRandomUnconnectedPortal")]
		[HarmonyPrefix]
		private static bool PairAllowed(Game __instance, List<ZDO> portals, ZDO skip, string tag, ref ZDO __result)
		{
			//IL_0035: 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)
			List<ZDO> list = new List<ZDO>();
			foreach (ZDO portal in portals)
			{
				if (portal != skip && portal.GetString(ZDOVars.s_tag, "") == tag && portal.GetConnectionZDOID((ConnectionType)1) == ZDOID.None && !__instance.IsCurrentlyConnectingPortal(portal) && MayPair(skip, portal))
				{
					list.Add(portal);
				}
			}
			__result = ((list.Count == 0) ? null : list[Random.Range(0, list.Count)]);
			return false;
		}

		[HarmonyPatch(typeof(Game), "ConnectPortals")]
		[HarmonyPrefix]
		private static void UndoPairs(Game __instance)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (ZDOMan.instance == null)
			{
				return;
			}
			foreach (ZDO portal in ZDOMan.instance.GetPortalList())
			{
				ZDOID connectionZDOID = portal.GetConnectionZDOID((ConnectionType)1);
				if (!((ZDOID)(ref connectionZDOID)).IsNone())
				{
					ZDO zDO = ZDOMan.instance.GetZDO(connectionZDOID);
					if (zDO != null && !MayPair(portal, zDO))
					{
						__instance.SetConnection(portal, ZDOID.None, false);
					}
				}
			}
		}

		private static TeleportWorld Loaded(ZDOID id)
		{
			//IL_0035: 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)
			TeleportWorld[] array = Object.FindObjectsByType<TeleportWorld>((FindObjectsSortMode)0);
			foreach (TeleportWorld val in array)
			{
				if ((Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid() && val.m_nview.GetZDO().m_uid == id)
				{
					return val;
				}
			}
			return null;
		}

		private static bool MayEdit(Entry e)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				return true;
			}
			if (e.Creator == 0L || e.Creator == localPlayer.GetPlayerID())
			{
				return true;
			}
			TeleportWorld val = Loaded(e.Id);
			if ((Object)(object)val != (Object)null)
			{
				return PrivateArea.CheckAccess(((Component)val).transform.position, 0f, false, false);
			}
			return false;
		}

		private static void Change(Entry e, int what, string text, int value)
		{
			//IL_004a: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (e != null && MayEdit(e) && (what != 3 || MayShare(e)))
			{
				switch (what)
				{
				case 0:
					e.Name = text;
					break;
				case 1:
					e.Color = value;
					break;
				case 3:
					e.Shared = value == 1;
					break;
				default:
					e.Icon = value;
					break;
				}
				TeleportWorld val = Loaded(e.Id);
				if ((Object)(object)val != (Object)null || (Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer())
				{
					Apply(e.Id, what, text, value, val);
				}
				else if (ZRoutedRpc.instance != null)
				{
					ZPackage val2 = new ZPackage();
					val2.Write(e.Id);
					val2.Write(what);
					val2.Write(text ?? "");
					val2.Write(value);
					ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "Digi_PortalList_Edit", new object[1] { val2 });
				}
			}
		}

		private static void SaveTyped()
		{
			Entry typing = _typing;
			_typing = null;
			if (typing != null)
			{
				string text = (_typed ?? "").Trim();
				if (text != (typing.Name ?? ""))
				{
					Change(typing, 0, text, 0);
				}
			}
		}

		private static void OnEdit(long sender, ZPackage package)
		{
			//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_0036: 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)
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				ZDOID id = package.ReadZDOID();
				int what = package.ReadInt();
				string text = package.ReadString();
				int value = package.ReadInt();
				Apply(id, what, text, value, Loaded(id));
			}
		}

		private static void Apply(ZDOID id, int what, string text, int value, TeleportWorld portal)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (what == 0 && (Object)(object)portal != (Object)null)
			{
				portal.SetText(text);
				return;
			}
			ZDO val;
			if ((Object)(object)portal != (Object)null)
			{
				if (!portal.m_nview.IsOwner())
				{
					portal.m_nview.ClaimOwnership();
				}
				val = portal.m_nview.GetZDO();
			}
			else
			{
				val = ((ZDOMan.instance != null) ? ZDOMan.instance.GetZDO(id) : null);
				if (val == null)
				{
					return;
				}
				if (!val.IsOwner())
				{
					val.SetOwner(ZDOMan.GetSessionID());
				}
			}
			if (what == 0)
			{
				val.Set(ZDOVars.s_tag, text ?? "");
				val.Set(ZDOVars.s_tagauthor, ((object)((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID/*cast due to .constrained prefix*/).ToString());
			}
			else
			{
				val.Set(what switch
				{
					3 => "digi_portal_shared", 
					1 => "digi_portal_color", 
					_ => "digi_portal_icon", 
				}, value);
			}
		}

		private static void LoadMine()
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			string dataKey = DataKey;
			if ((Object)(object)localPlayer == (Object)null || dataKey == null || dataKey + localPlayer.GetPlayerID() == _loadedKey)
			{
				return;
			}
			_loadedKey = dataKey + localPlayer.GetPlayerID();
			Favourites.Clear();
			Trips.Clear();
			if (!localPlayer.m_customData.TryGetValue(dataKey, out var value) || string.IsNullOrEmpty(value))
			{
				return;
			}
			string[] array = value.Split(new char[1] { ';' });
			ZDOID val = default(ZDOID);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ':' });
				if (array2.Length >= 3 && long.TryParse(array2[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && uint.TryParse(array2[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
				{
					((ZDOID)(ref val))..ctor(result, result2);
					long result3;
					if (array2[0] == "f")
					{
						Favourites.Add(val);
					}
					else if (array2[0] == "t" && array2.Length > 3 && long.TryParse(array2[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out result3))
					{
						Trips[val] = result3;
					}
				}
			}
		}

		private static void SaveMine()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			string dataKey = DataKey;
			if ((Object)(object)localPlayer == (Object)null || dataKey == null)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (ZDOID favourite in Favourites)
			{
				ZDOID current = favourite;
				stringBuilder.Append("f:").Append(((ZDOID)(ref current)).UserID.ToString(CultureInfo.InvariantCulture)).Append(':')
					.Append(((ZDOID)(ref current)).ID.ToString(CultureInfo.InvariantCulture))
					.Append(';');
			}
			foreach (KeyValuePair<ZDOID, long> item in Trips.OrderByDescending((KeyValuePair<ZDOID, long> t) => t.Value).Take(200))
			{
				StringBuilder stringBuilder2 = stringBuilder.Append("t:");
				ZDOID key = item.Key;
				StringBuilder stringBuilder3 = stringBuilder2.Append(((ZDOID)(ref key)).UserID.ToString(CultureInfo.InvariantCulture)).Append(':');
				key = item.Key;
				stringBuilder3.Append(((ZDOID)(ref key)).ID.ToString(CultureInfo.InvariantCulture)).Append(':').Append(item.Value.ToString(CultureInfo.InvariantCulture))
					.Append(';');
			}
			localPlayer.m_customData[dataKey] = stringBuilder.ToString();
		}

		private static void Open(TeleportWorld source)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00a6: Expected O, but got Unknown
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)source == (Object)null) && !((Character)localPlayer).IsDead() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && (!IsOpen || !((Object)(object)_source == (Object)(object)source)))
			{
				LoadMine();
				_source = source;
				_editing = ZDOID.None;
				_entries = Known();
				_fromServer = (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer();
				if (!_fromServer && ZRoutedRpc.instance != null)
				{
					_asking = true;
					_askedAt = Time.unscaledTime;
					ZPackage val = new ZPackage();
					val.Write(Me);
					ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "Digi_PortalList_Ask", new object[1] { val });
				}
				OpenWindow();
			}
		}

		private void Update()
		{
			if (_typing != null && (!IsOpen || Time.unscaledTime - _typedAt > 0.5f))
			{
				SaveTyped();
			}
			if (_asking && Time.unscaledTime - _askedAt > 3f)
			{
				_asking = false;
				if (IsOpen)
				{
					FillList();
				}
			}
		}

		private static void OpenWindow()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			Windows.Window window = Windows.Open("Portals", "", 900f, 760f, "Click a portal to go there. Private: only you see it; Shared: everyone can go there. Esc closes.", 100f, null, 160f);
			if (window == null)
			{
				return;
			}
			_window = window;
			_subtitle = Windows.Text((Transform)(object)window.Panel, "", 20f, Windows.Dim, (TextAlignmentOptions)513);
			Windows.Place(((TMP_Text)_subtitle).rectTransform, 24f, 62f, 852f, 30f);
			UpdateSubtitle();
			Rows.Clear();
			Extras.Clear();
			SortButtons.Clear();
			float num = 24f;
			SortBy[] array = new SortBy[4]
			{
				SortBy.Recent,
				SortBy.Name,
				SortBy.Nearest,
				SortBy.Biome
			};
			foreach (SortBy sort in array)
			{
				string label = ((sort == SortBy.Recent) ? "Recent" : ((sort == SortBy.Name) ? "A - Z" : ((sort == SortBy.Nearest) ? "Nearest" : "Biome")));
				Button val = Windows.Button(window.Panel, label, num, 104f, 104f, 40f, (UnityAction)delegate
				{
					//IL_001a: Unknown result type (might be due to invalid IL or missing references)
					//IL_001f: Unknown result type (might be due to invalid IL or missing references)
					_sortClickFrame = Time.frameCount;
					_sort.Value = sort;
					_editing = ZDOID.None;
					UpdateSortButtons();
					FillList(keepScroll: false);
				});
				Instant((Selectable)(object)val);
				if (sort == SortBy.Name)
				{
					((Component)val).gameObject.AddComponent<SortAgain>();
				}
				SortButtons.Add(new KeyValuePair<SortBy, Button>(sort, val));
				num += 110f;
			}
			UpdateSortButtons();
			_searchBox = Windows.SearchBox(window.Panel, 576f, 105f, 300f, 38f, "Search a name or biome...");
			_searchBox.SetTextWithoutNotify(_search);
			((UnityEvent<string>)(object)_searchBox.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
			{
				_search = text ?? "";
				FillList(keepScroll: false);
			});
			((UnityEvent<string>)(object)_searchBox.onSelect).AddListener((UnityAction<string>)delegate
			{
				if (_window != null)
				{
					_window.Search = _searchBox;
				}
			});
			window.Search = _searchBox;
			FillList(keepScroll: false);
		}

		private static void UpdateSubtitle(string typing = null)
		{
			if (!((Object)(object)_subtitle == (Object)null))
			{
				string text = "You are at: " + Display(typing ?? SourceEntry()?.Name);
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null && !((Humanoid)localPlayer).IsTeleportable((Object)(object)_source != (Object)null && _source.m_allowAllItems))
				{
					text += "  <color=#ff7060>- you carry something that cannot go through portals</color>";
				}
				((TMP_Text)_subtitle).text = text;
			}
		}

		private static void UpdateSortButtons()
		{
			foreach (KeyValuePair<SortBy, Button> sortButton in SortButtons)
			{
				if (!((Object)(object)sortButton.Value == (Object)null))
				{
					((Selectable)sortButton.Value).interactable = sortButton.Key != _sort.Value;
					if (sortButton.Key == SortBy.Name)
					{
						Windows.SetLabel(sortButton.Value, _zToA.Value ? "Z - A" : "A - Z");
					}
				}
			}
		}

		private static void Instant(Selectable button)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)button == (Object)null))
			{
				ColorBlock colors = button.colors;
				((ColorBlock)(ref colors)).fadeDuration = 0f;
				button.colors = colors;
			}
		}

		private static void FillList(bool keepScroll = true)
		{
			//IL_0023: 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_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_0103: Unknown result type (might be due to invalid IL or missing references)
			Windows.Window window = _window;
			if (window == null || (Object)(object)window.Content == (Object)null)
			{
				return;
			}
			SaveTyped();
			float y = window.Content.anchoredPosition.y;
			foreach (GameObject extra in Extras)
			{
				if ((Object)(object)extra != (Object)null)
				{
					extra.SetActive(false);
					Object.Destroy((Object)(object)extra);
				}
			}
			Extras.Clear();
			if ((Object)(object)window.Search != (Object)(object)_searchBox)
			{
				window.Search = _searchBox;
			}
			float num = Layout(window);
			UpdateSubtitle();
			window.Content.sizeDelta = new Vector2(0f, num);
			Rect rect = window.View.rect;
			float num2 = Mathf.Max(0f, num - ((Rect)(ref rect)).height);
			window.Content.anchoredPosition = new Vector2(0f, keepScroll ? Mathf.Clamp(y, 0f, num2) : 0f);
			window.Gliding = false;
		}

		private static Entry SourceEntry()
		{
			ZDO zdo = (((Object)(object)_source != (Object)null && (Object)(object)_source.m_nview != (Object)null && _source.m_nview.IsValid()) ? _source.m_nview.GetZDO() : null);
			if (zdo == null)
			{
				return null;
			}
			return _entries.FirstOrDefault((Entry e) => e.Id == zdo.m_uid) ?? FromZdo(zdo);
		}

		private static string Display(string name)
		{
			if (!string.IsNullOrWhiteSpace(name))
			{
				return StringExtensionMethods.RemoveRichTextTags(name);
			}
			return "(no name)";
		}

		private static Color ColorOf(int index)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (index <= 0 || index >= Colors.Length)
			{
				return Windows.Body;
			}
			return Colors[index];
		}

		private static Sprite IconOf(Entry e)
		{
			if (e.Icon > 0 && e.Icon < IconItems.Length)
			{
				Sprite val = IconSprite(IconItems[e.Icon]);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return PortalIcon(e.Prefab);
		}

		private static Sprite PortalIcon(string prefabName)
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null && !string.IsNullOrEmpty(prefabName)) ? ZNetScene.instance.GetPrefab(prefabName) : null);
			Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.m_icon;
		}

		private static Sprite IconSprite(string key)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(key))
			{
				return null;
			}
			if (key.StartsWith("piece:", StringComparison.Ordinal))
			{
				return PortalIcon(key.Substring(6));
			}
			if (key.StartsWith("loc:", StringComparison.Ordinal))
			{
				if (!((Object)(object)Minimap.instance != (Object)null))
				{
					return null;
				}
				return Minimap.instance.GetLocationIcon(key.Substring(4));
			}
			if (key.StartsWith("pin:", StringComparison.Ordinal))
			{
				if (!((Object)(object)Minimap.instance != (Object)null) || !Enum.TryParse<PinType>(key.Substring(4), out PinType result))
				{
					return null;
				}
				return Minimap.instance.GetSprite(result);
			}
			return ItemIcon(key);
		}

		private static Sprite ItemIcon(string item)
		{
			if (string.IsNullOrEmpty(item) || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item);
			ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val != (Object)null) || val.m_itemData.m_shared.m_icons == null || val.m_itemData.m_shared.m_icons.Length == 0)
			{
				return null;
			}
			return val.m_itemData.GetIcon();
		}

		private unsafe static string Biome(Vector3 p)
		{
			//IL_0012: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			if (WorldGenerator.instance == null)
			{
				return "";
			}
			Biome biome = WorldGenerator.instance.GetBiome(p.x, p.z, 0.02f, false);
			return Localization.instance.Localize("$biome_" + ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant());
		}

		private static int BiomeRank(Vector3 p)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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 (WorldGenerator.instance == null)
			{
				return 99;
			}
			int num = Array.IndexOf(BiomeOrder, WorldGenerator.instance.GetBiome(p.x, p.z, 0.02f, false));
			if (num >= 0)
			{
				return num;
			}
			return 98;
		}

		private static string Distance(float meters)
		{
			if (!(meters >= 1000f))
			{
				return Mathf.RoundToInt(meters) + " m";
			}
			return (meters / 1000f).ToString("0.0", CultureInfo.InvariantCulture) + " km";
		}

		private static float Layout(Windows.Window w)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_074d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_0626: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0772: Unknown result type (might be due to invalid IL or missing references)
			//IL_0777: Unknown result type (might be due to invalid IL or missing references)
			//IL_077e: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0798: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d2: Unknown result type (might be due to invalid IL or missing references)
			Entry here = SourceEntry();
			Vector3 from = (((Object)(object)_source != (Object)null) ? ((Component)_source).transform.position : (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero));
			ZDO val = (((Object)(object)_source != (Object)null && (Object)(object)_source.m_nview != (Object)null && _source.m_nview.IsValid()) ? _source.m_nview.GetZDO() : null);
			ZDOID val2 = ((val != null) ? val.GetConnectionZDOID((ConnectionType)1) : ZDOID.None);
			string search = (_search ?? "").Trim();
			long me = Me;
			List<Entry> source = (from e in _entries
				where here == null || e.Id != here.Id
				where Visible(e, me)
				where search.Length == 0 || Display(e.Name).IndexOf(search, StringComparison.CurrentCultureIgnoreCase) >= 0 || Biome(e.Position).IndexOf(search, StringComparison.CurrentCultureIgnoreCase) >= 0
				select e).ToList();
			IEnumerable<Entry> source2;
			switch (_sort.Value)
			{
			case SortBy.Name:
			{
				IOrderedEnumerable<Entry> source3 = source.OrderBy((Entry e) => string.IsNullOrWhiteSpace(e.Name) ? 1 : 0);
				source2 = (_zToA.Value ? source3.ThenByDescending<Entry, string>((Entry e) => Display(e.Name), StringComparer.CurrentCultureIgnoreCase) : source3.ThenBy<Entry, string>((Entry e) => Display(e.Name), StringComparer.CurrentCultureIgnoreCase));
				break;
			}
			case SortBy.Nearest:
				source2 = source.OrderBy(delegate(Entry e)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val3 = e.Position - from;
					return ((Vector3)(ref val3)).sqrMagnitude;
				});
				break;
			case SortBy.Biome:
				source2 = (from e in source
					orderby BiomeRank(e.Position), string.IsNullOrWhiteSpace(e.Name) ? 1 : 0
					select e).ThenBy<Entry, string>((Entry e) => Display(e.Name), StringComparer.CurrentCultureIgnoreCase);
				break;
			default:
			{
				source2 = source.OrderByDescending((Entry e) => (!Trips.TryGetValue(e.Id, out var value)) ? 0 : value).ThenBy<Entry, string>((Entry e) => Display(e.Name), StringComparer.CurrentCultureIgnoreCase);
				break;
			}
			}
			List<Entry> list = source2.ToList();
			List<Entry> list2 = list.Where((Entry e) => Favourites.Contains(e.Id)).ToList();
			List<Entry> list3 = list.Where((Entry e) => !Favourites.Contains(e.Id)).ToList();
			Dictionary<ZDOID, Entry> byId;
			HashSet<ZDOID> placed;
			if (_editing == ZDOID.None)
			{
				_frozenFavourites = (_frozenRest = null);
			}
			else if (_frozenFavourites == null)
			{
				_frozenFavourites = list2.Select((Entry e) => e.Id).ToList();
				_frozenRest = list3.Select((Entry e) => e.Id).ToList();
			}
			else
			{
				byId = list.ToDictionary((Entry e) => e.Id);
				placed = new HashSet<ZDOID>();
				List<Entry> list4 = Keep(_frozenFavourites, list2);
				List<Entry> list5 = Keep(_frozenRest, list3);
				foreach (Entry item in list2)
				{
					if (placed.Add(item.Id))
					{
						list4.Add(item);
					}
				}
				foreach (Entry item2 in list3)
				{
					if (placed.Add(item2.Id))
					{
						list5.Add(item2);
					}
				}
				list2 = list4;
				list3 = list5;
			}
			HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
			float num = 0f;
			if (_asking)
			{
				num = Note(w, "Asking the server for every portal...", num);
			}
			else if (!_fromServer)
			{
				num = Note(w, "The server does not have Portal List: these are the portals your game knows (those you were near).", num);
			}
			int num2 = 0;
			if (here != null)
			{
				num = Place(w, here, from, linked: false, isHere: true, num, num2++, hashSet);
			}
			if (list.Count == 0)
			{
				num = Note(w, (search.Length > 0) ? ("No portal matches \"" + search + "\".") : "There is no other portal yet.", num + 4f);
			}
			if (list2.Count > 0)
			{
				num = Header(w, "Favourites", num + 4f);
				foreach (Entry item3 in list2)
				{
					num = Place(w, item3, from, item3.Id == val2, isHere: false, num, num2++, hashSet);
				}
			}
			if (list3.Count > 0 && _sort.Value == SortBy.Biome)
			{
				int num3 = -1;
				foreach (Entry item4 in list3)
				{
					int num4 = BiomeRank(item4.Position);
					if (num4 != num3)
					{
						num = Header(w, Biome(item4.Position), num + 4f);
						num3 = num4;
					}
					num = Place(w, item4, from, item4.Id == val2, isHere: false, num, num2++, hashSet);
				}
			}
			else if (list3.Count > 0)
			{
				num = Header(w, (_sort.Value == SortBy.Recent) ? "All portals, last visited first" : ((_sort.Value != SortBy.Name) ? "All portals, nearest first" : (_zToA.Value ? "All portals, Z - A" : "All portals, A - Z")), num + 4f);
				foreach (Entry item5 in list3)
				{
					num = Place(w, item5, from, item5.Id == val2, isHere: false, num, num2++, hashSet);
				}
			}
			HashSet<ZDOID> hashSet2 = new HashSet<ZDOID>(_entries.Select((Entry e) => e.Id));
			if (here != null)
			{
				hashSet2.Add(here.Id);
			}
			foreach (ZDOID item6 in Rows.Keys.ToList())
			{
				RowParts rowParts = Rows[item6];
				if ((Object)(object)rowParts.Rect == (Object)null || !hashSet2.Contains(item6))
				{
					if ((Object)(object)rowParts.Rect != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)rowParts.Rect).gameObject);
					}
					Rows.Remove(item6);
				}
				else if (!hashSet.Contains(item6))
				{
					((Component)rowParts.Rect).gameObject.SetActive(false);
				}
			}
			return num + 6f;
			List<Entry> Keep(List<ZDOID> order, List<Entry> fresh)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				List<Entry> list6 = new List<Entry>();
				foreach (ZDOID item7 in order)
				{
					if (byId.TryGetValue(item7, out var value) && placed.Add(item7))
					{
						list6.Add(value);
					}
				}
				return list6;
			}
		}

		private static float Note(Windows.Window w, string text, float y)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Windows.Text((Transform)(object)w.Content, text, 19f, Windows.Dim, (TextAlignmentOptions)513);
			Windows.Place(((TMP_Text)val).rectTransform, 14f, y + 6f, w.RowWidth - 28f, 30f);
			Extras.Add(((Component)val).gameObject);
			return y + 40f;
		}

		private static float Header(Windows.Window w, string text, float y)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Windows.Text((Transform)(object)w.Content, text, 21f, Windows.Gold, (TextAlignmentOptions)513);
			Windows.Place(((TMP_Text)val).rectTransform, 14f, y + 4f, w.RowWidth - 28f, 30f);
			Extras.Add(((Component)val).gameObject);
			return y + 34f;
		}

		private static float Place(Windows.Window w, Entry e, Vector3 from, bool linked, bool isHere, float y, int index, HashSet<ZDOID> shown)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: 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_0286: Unknown result typ