Decompiled source of PortalManager v0.1.7

plugins/PortalManager.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("Splatform")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("PortalManager")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.7.0")]
[assembly: AssemblyInformationalVersion("0.1.7+de87fd95bc8e92ae5db9e311e08ce1fb23ceae5c")]
[assembly: AssemblyProduct("PortalManager")]
[assembly: AssemblyTitle("PortalManager")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PortalManagerMod
{
	internal static class BiomeNames
	{
		public static Biome At(Vector3 position)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			WorldGenerator instance = WorldGenerator.instance;
			if (instance == null)
			{
				return (Biome)0;
			}
			return instance.GetBiome(position.x, position.z, 0.02f, false);
		}

		public static string Token(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_0005: 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_001d: Expected I4, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				default:
					if ((int)biome != 8)
					{
						if ((int)biome != 16)
						{
							break;
						}
						return "$biome_plains";
					}
					return "$biome_blackforest";
				case 0:
					return "$biome_meadows";
				case 1:
					return "$biome_swamp";
				case 3:
					return "$biome_mountain";
				case 2:
					break;
				}
			}
			else if ((int)biome <= 64)
			{
				if ((int)biome == 32)
				{
					return "$biome_ashlands";
				}
				if ((int)biome == 64)
				{
					return "$biome_deepnorth";
				}
			}
			else
			{
				if ((int)biome == 256)
				{
					return "$biome_ocean";
				}
				if ((int)biome == 512)
				{
					return "$biome_mistlands";
				}
			}
			return "$portalmanager_biome_unknown";
		}

		public static string Localized(Biome biome)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Localization instance = Localization.instance;
			string text = Token(biome);
			if (instance == null)
			{
				return text;
			}
			return instance.Localize(text);
		}
	}
	internal static class Loc
	{
		public static string T(string token)
		{
			Localization instance = Localization.instance;
			if (instance == null)
			{
				return token;
			}
			return instance.Localize(token);
		}

		public static string T(string token, params string[] words)
		{
			Localization instance = Localization.instance;
			if (instance == null)
			{
				return token;
			}
			return instance.Localize(token, words);
		}
	}
	internal sealed class PortalEntry
	{
		public ZDOID Id;

		public string Name = string.Empty;

		public string Author = string.Empty;

		public Vector3 Position;

		public Quaternion Rotation;

		public int Icon = -1;

		public Biome Biome;

		private string m_filteredName;

		public bool HasName => !string.IsNullOrEmpty(Name);

		public string FilteredName
		{
			get
			{
				if (m_filteredName == null)
				{
					m_filteredName = StringExtensionMethods.RemoveRichTextTags(Filter(Name, Author));
				}
				return m_filteredName;
			}
		}

		public string DisplayName
		{
			get
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				if (!HasName)
				{
					return BiomeNames.Localized(Biome);
				}
				return FilteredName;
			}
		}

		public Vector3 ArrivalPosition(float exitDistance)
		{
			//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)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			return Position + Rotation * Vector3.forward * exitDistance + Vector3.up;
		}

		public void Serialize(ZPackage pkg)
		{
			//IL_0002: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			pkg.Write(Id);
			pkg.Write(Name ?? string.Empty);
			pkg.Write(Author ?? string.Empty);
			pkg.Write(Position);
			pkg.Write(Rotation);
			pkg.Write(Icon);
		}

		public static PortalEntry Deserialize(ZPackage pkg)
		{
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//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_0059: Unknown result type (might be due to invalid IL or missing references)
			PortalEntry obj = new PortalEntry
			{
				Id = pkg.ReadZDOID(),
				Name = pkg.ReadString(),
				Author = pkg.ReadString(),
				Position = pkg.ReadVector3(),
				Rotation = pkg.ReadQuaternion(),
				Icon = pkg.ReadInt()
			};
			obj.Biome = BiomeNames.At(obj.Position);
			return obj;
		}

		private static string Filter(string tag, string author)
		{
			//IL_001f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(tag))
			{
				return string.Empty;
			}
			try
			{
				PlatformUserID val = (PlatformUserID)(string.IsNullOrEmpty(author) ? PlatformUserID.None : new PlatformUserID(author));
				return CensorShittyWords.FilterUGC(tag, (UGCType)4, val, 0L, (GetUserProfileCompletedHandler)null);
			}
			catch
			{
				return tag;
			}
		}
	}
	internal static class PortalFavourites
	{
		private const string FileName = "PortalManager.favourites.txt";

		private static readonly Dictionary<string, HashSet<string>> ByWorld = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);

		private static bool Loaded;

		private static string Path => System.IO.Path.Combine(Paths.ConfigPath, "PortalManager.favourites.txt");

		private static string World
		{
			get
			{
				if (!((Object)(object)ZNet.instance != (Object)null))
				{
					return string.Empty;
				}
				return ZNet.instance.GetWorldName() ?? string.Empty;
			}
		}

		private static string Key(ZDOID id)
		{
			return $"{((ZDOID)(ref id)).UserID}:{((ZDOID)(ref id)).ID}";
		}

		public static bool IsFavourite(ZDOID id)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			EnsureLoaded();
			if (ByWorld.TryGetValue(World, out var value))
			{
				return value.Contains(Key(id));
			}
			return false;
		}

		public static void Toggle(ZDOID id)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			EnsureLoaded();
			string world = World;
			if (!ByWorld.TryGetValue(world, out var value))
			{
				value = new HashSet<string>(StringComparer.Ordinal);
				ByWorld[world] = value;
			}
			string text = Key(id);
			if (!value.Remove(text))
			{
				value.Add(text);
			}
			Logger.LogInfo((object)("PortalManager: favourite " + (value.Contains(text) ? "set" : "cleared") + " for " + $"{text} in world '{world}' ({value.Count} starred here)."));
			Save();
		}

		private static void EnsureLoaded()
		{
			if (Loaded)
			{
				return;
			}
			Loaded = true;
			try
			{
				if (!File.Exists(Path))
				{
					return;
				}
				string[] array = File.ReadAllLines(Path);
				foreach (string text in array)
				{
					int num = text.IndexOf('\t');
					if (num > 0 && num != text.Length - 1)
					{
						string key = text.Substring(0, num);
						string item = text.Substring(num + 1);
						if (!ByWorld.TryGetValue(key, out var value))
						{
							value = new HashSet<string>(StringComparer.Ordinal);
							ByWorld[key] = value;
						}
						value.Add(item);
					}
				}
				Logger.LogInfo((object)$"PortalManager: loaded favourites for {ByWorld.Count} world(s).");
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("PortalManager: could not read favourites: " + ex.Message));
			}
		}

		private static void Save()
		{
			try
			{
				List<string> list = new List<string>();
				foreach (KeyValuePair<string, HashSet<string>> item in ByWorld)
				{
					foreach (string item2 in item.Value)
					{
						list.Add(item.Key + "\t" + item2);
					}
				}
				File.WriteAllLines(Path, list.ToArray());
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("PortalManager: could not save favourites: " + ex.Message));
			}
		}
	}
	internal static class PortalIcons
	{
		public const int NoIcon = -1;

		private static readonly List<int> Cache = new List<int>();

		private static int CachedCount = -1;

		public static IReadOnlyList<int> All()
		{
			//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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected I4, but got Unknown
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || instance.m_icons == null)
			{
				return Cache;
			}
			if (CachedCount == instance.m_icons.Count)
			{
				return Cache;
			}
			Cache.Clear();
			foreach (SpriteData icon in instance.m_icons)
			{
				if ((Object)(object)icon.m_icon != (Object)null)
				{
					Cache.Add((int)icon.m_name);
				}
			}
			CachedCount = instance.m_icons.Count;
			return Cache;
		}

		public static Sprite Sprite(int icon)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0041: 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_0048: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if (icon == -1 || (Object)(object)instance == (Object)null || instance.m_icons == null)
			{
				return null;
			}
			foreach (SpriteData icon2 in instance.m_icons)
			{
				if ((Object)(object)icon2.m_icon != (Object)null && (int)icon2.m_name == icon)
				{
					return icon2.m_icon;
				}
			}
			return null;
		}

		public static bool IsKnown(int icon)
		{
			if (icon != -1)
			{
				return (Object)(object)Sprite(icon) != (Object)null;
			}
			return true;
		}
	}
	internal static class PortalListPanel
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__Rebuild;

			public static UnityAction <1>__Close;
		}

		private const int PanelWidth = 760;

		private const int PanelHeight = 660;

		private const int RowHeight = 66;

		private const int IconSize = 42;

		private const int StarSize = 38;

		private static GameObject Panel;

		private static RectTransform RowContainer;

		private static ScrollRect Scroller;

		private static Text StatusText;

		private static TeleportWorld Current;

		private static readonly List<GameObject> Rows = new List<GameObject>();

		private static readonly List<PortalEntry> Visible = new List<PortalEntry>();

		public static bool IsOpen
		{
			get
			{
				if ((Object)(object)Panel != (Object)null)
				{
					return Panel.activeSelf;
				}
				return false;
			}
		}

		public static void Open(TeleportWorld portal)
		{
			if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				Logger.LogWarning((object)"PortalManager: GUIManager not ready; cannot open the list.");
				return;
			}
			Current = portal;
			if ((Object)(object)Panel == (Object)null)
			{
				try
				{
					Build();
				}
				catch (Exception arg)
				{
					Logger.LogError((object)$"PortalManager: building the list window failed: {arg}");
					if ((Object)(object)Panel != (Object)null)
					{
						Object.Destroy((Object)(object)Panel);
					}
					Panel = null;
					RowContainer = null;
					Scroller = null;
					StatusText = null;
					Rows.Clear();
				}
			}
			if (!((Object)(object)Panel == (Object)null))
			{
				if ((Object)(object)Scroller != (Object)null)
				{
					Scroller.scrollSensitivity = 72f * Mathf.Max(1f, PortalManagerConfig.ScrollRowsPerNotch.Value);
				}
				Panel.SetActive(true);
				GUIManager.BlockInput(true);
				PortalRegistry.Updated = (Action)Delegate.Remove(PortalRegistry.Updated, new Action(Rebuild));
				PortalRegistry.Updated = (Action)Delegate.Combine(PortalRegistry.Updated, new Action(Rebuild));
				Logger.LogInfo((object)($"PortalManager: opening list. Known portals: {PortalRegistry.Known.Count}, " + $"answered: {PortalRegistry.HasEverAnswered}, stale: {PortalRegistry.IsStale}"));
				PortalRegistry.RequestIfStale();
				Rebuild();
			}
		}

		public static void Close()
		{
			PortalRegistry.Updated = (Action)Delegate.Remove(PortalRegistry.Updated, new Action(Rebuild));
			if ((Object)(object)Panel != (Object)null)
			{
				Panel.SetActive(false);
			}
			Current = null;
			GUIManager.BlockInput(false);
		}

		internal static void Tick()
		{
			//IL_005c: 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)
			if (!IsOpen)
			{
				return;
			}
			if ((Object)(object)Current == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				Close();
				return;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				Close();
				return;
			}
			float num = Mathf.Max(PortalManagerConfig.TravelRange.Value, 5f) + 4f;
			if (Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)Current).transform.position) > num)
			{
				Close();
			}
		}

		private static void Build()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Expected O, but got Unknown
			GUIManager instance = GUIManager.Instance;
			Rows.Clear();
			Panel = instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 760f, 660f, true);
			((Object)Panel).name = "PortalManagerPanel";
			Panel.AddComponent<PortalListPanelBehaviour>();
			instance.CreateText(Loc.T("$portalmanager_title"), Panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -36f), instance.AveriaSerifBold, 26, instance.ValheimOrange, true, Color.black, 680f, 44f, false);
			GameObject obj = instance.CreateScrollView(Panel.transform, false, true, 8f, 10f, instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.4f), 680f, 470f);
			RectTransform component = obj.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 1f);
			component.anchorMax = new Vector2(0.5f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.anchoredPosition = new Vector2(0f, -72f);
			ScrollRect componentInChildren = obj.GetComponentInChildren<ScrollRect>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.content == (Object)null)
			{
				Logger.LogError((object)"PortalManager: scroll view has no content; list cannot draw.");
				return;
			}
			Scroller = componentInChildren;
			RowContainer = componentInChildren.content;
			VerticalLayoutGroup obj2 = ((Component)RowContainer).GetComponent<VerticalLayoutGroup>() ?? ((Component)RowContainer).gameObject.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((LayoutGroup)obj2).padding = new RectOffset(4, 4, 4, 4);
			(((Component)RowContainer).GetComponent<ContentSizeFitter>() ?? ((Component)RowContainer).gameObject.AddComponent<ContentSizeFitter>()).verticalFit = (FitMode)2;
			StatusText = instance.CreateText(string.Empty, Panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 84f), instance.AveriaSerifBold, 16, instance.ValheimBeige, true, Color.black, 680f, 28f, false).GetComponent<Text>();
			ButtonClickedEvent onClick = instance.CreateButton(Loc.T("$portalmanager_close"), Panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 42f), 220f, 40f).GetComponent<Button>().onClick;
			object obj3 = <>O.<1>__Close;
			if (obj3 == null)
			{
				UnityAction val = Close;
				<>O.<1>__Close = val;
				obj3 = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj3);
		}

		private static void Rebuild()
		{
			if ((Object)(object)Panel == (Object)null || (Object)(object)RowContainer == (Object)null)
			{
				return;
			}
			CollectVisible();
			while (Rows.Count < Visible.Count)
			{
				Rows.Add(CreateRow());
			}
			for (int i = 0; i < Rows.Count; i++)
			{
				if (i < Visible.Count)
				{
					Rows[i].SetActive(true);
					BindRow(Rows[i], Visible[i]);
				}
				else
				{
					Rows[i].SetActive(false);
				}
			}
			UpdateStatus();
		}

		private static void CollectVisible()
		{
			//IL_002f: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			Visible.Clear();
			Vector3 origin = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero);
			foreach (PortalEntry item in PortalRegistry.Known)
			{
				if (item.HasName || PortalManagerConfig.ShowUnnamedPortals.Value)
				{
					Visible.Add(item);
				}
			}
			Visible.Sort(delegate(PortalEntry a, PortalEntry b)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: 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_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				bool flag = PortalFavourites.IsFavourite(a.Id);
				bool flag2 = PortalFavourites.IsFavourite(b.Id);
				if (flag != flag2)
				{
					if (!flag)
					{
						return 1;
					}
					return -1;
				}
				switch (PortalManagerConfig.Sort.Value)
				{
				case PortalManagerConfig.SortMode.Name:
					return string.Compare(a.DisplayName, b.DisplayName, StringComparison.CurrentCultureIgnoreCase);
				case PortalManagerConfig.SortMode.Biome:
				{
					int num = string.Compare(BiomeNames.Localized(a.Biome), BiomeNames.Localized(b.Biome), StringComparison.CurrentCultureIgnoreCase);
					if (num == 0)
					{
						return Vector3.Distance(origin, a.Position).CompareTo(Vector3.Distance(origin, b.Position));
					}
					return num;
				}
				default:
					return Vector3.Distance(origin, a.Position).CompareTo(Vector3.Distance(origin, b.Position));
				}
			});
		}

		private static GameObject CreateRow()
		{
			//IL_0019: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_0205: 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_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GUIManager.Instance.CreateButton(string.Empty, (Transform)(object)RowContainer, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), Vector2.zero, 640f, 66f);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.minHeight = 66f;
			obj.preferredHeight = 66f;
			GameObject val2 = new GameObject("Icon", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0.5f);
			component.anchorMax = new Vector2(0f, 0.5f);
			component.pivot = new Vector2(0f, 0.5f);
			component.anchoredPosition = new Vector2(16f, 0f);
			component.sizeDelta = new Vector2(42f, 42f);
			val2.GetComponent<Image>().preserveAspect = true;
			GameObject val3 = new GameObject("Star", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Button)
			});
			val3.transform.SetParent(val.transform, false);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(1f, 0.5f);
			component2.anchorMax = new Vector2(1f, 0.5f);
			component2.pivot = new Vector2(1f, 0.5f);
			component2.anchoredPosition = new Vector2(-16f, 0f);
			component2.sizeDelta = new Vector2(38f, 38f);
			Image component3 = val3.GetComponent<Image>();
			component3.sprite = StarSprite.Get();
			component3.preserveAspect = true;
			Text componentInChildren = val.GetComponentInChildren<Text>(true);
			componentInChildren.alignment = (TextAnchor)3;
			componentInChildren.fontSize = 20;
			RectTransform component4 = ((Component)componentInChildren).GetComponent<RectTransform>();
			component4.anchorMin = new Vector2(0f, 0f);
			component4.anchorMax = new Vector2(1f, 1f);
			component4.offsetMin = new Vector2(70f, 0f);
			component4.offsetMax = new Vector2(-64f, 0f);
			return val;
		}

		private static void BindRow(GameObject row, PortalEntry entry)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_012c: 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)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			Image component = ((Component)row.transform.Find("Icon")).GetComponent<Image>();
			Sprite val = (component.sprite = PortalIcons.Sprite(entry.Icon));
			((Behaviour)component).enabled = (Object)(object)val != (Object)null;
			bool flag = (Object)(object)Current != (Object)null && entry.Id == PortalTravel.PortalOf(Current);
			bool flag2 = PortalFavourites.IsFavourite(entry.Id);
			float metres = (((Object)(object)Player.m_localPlayer != (Object)null) ? Vector3.Distance(((Component)Player.m_localPlayer).transform.position, entry.Position) : 0f);
			string text = (flag ? Loc.T("$portalmanager_you_are_here") : (BiomeNames.Localized(entry.Biome) + "   ·   " + Distance(metres)));
			Text componentInChildren = row.GetComponentInChildren<Text>(true);
			componentInChildren.supportRichText = true;
			componentInChildren.text = entry.DisplayName + "\n<size=15><color=#B0A48C>" + text + "</color></size>";
			Transform obj = row.transform.Find("Star");
			((Graphic)((Component)obj).GetComponent<Image>()).color = (Color)(flag2 ? GUIManager.Instance.ValheimYellow : new Color(1f, 1f, 1f, 0.22f));
			Button component2 = ((Component)obj).GetComponent<Button>();
			((UnityEventBase)component2.onClick).RemoveAllListeners();
			PortalEntry starred = entry;
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				PortalFavourites.Toggle(starred.Id);
				Rebuild();
			});
			Button component3 = row.GetComponent<Button>();
			((Selectable)component3).interactable = !flag && PortalManagerConfig.EnableDirectTravel.Value;
			((UnityEventBase)component3.onClick).RemoveAllListeners();
			PortalEntry captured = entry;
			((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
			{
				Travel(captured);
			});
		}

		private static string Distance(float metres)
		{
			if (!(metres >= 1000f))
			{
				return $"{metres:0} m";
			}
			return $"{metres / 1000f:0.0} km";
		}

		private static void Travel(PortalEntry destination)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogInfo((object)("PortalManager: travel requested to '" + destination.DisplayName + "' at " + $"{destination.Position}."));
			if (PortalTravel.TryTravel(Current, destination, out var messageToken))
			{
				Close();
				return;
			}
			Logger.LogInfo((object)("PortalManager: travel refused (" + (messageToken ?? "no reason given") + ")."));
			if (!string.IsNullOrEmpty(messageToken) && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, Loc.T(messageToken), 0, (Sprite)null, false);
			}
		}

		private static void UpdateStatus()
		{
			if (!((Object)(object)StatusText == (Object)null))
			{
				if (!PortalRegistry.HasEverAnswered)
				{
					StatusText.text = (PortalRegistry.LastRequestTimedOut ? Loc.T("$portalmanager_no_reply") : Loc.T("$portalmanager_loading"));
				}
				else if (PortalRegistry.Known.Count == 0)
				{
					StatusText.text = Loc.T("$portalmanager_empty");
				}
				else
				{
					StatusText.text = ((Visible.Count == PortalRegistry.Known.Count) ? string.Format("{0} {1}", Loc.T("$portalmanager_count"), Visible.Count) : string.Format("{0} {1} / {2}", Loc.T("$portalmanager_count"), Visible.Count, PortalRegistry.Known.Count));
				}
			}
		}
	}
	internal class PortalListPanelBehaviour : MonoBehaviour
	{
		private void Update()
		{
			PortalListPanel.Tick();
		}
	}
	internal static class PortalManagerConfig
	{
		internal enum SortMode
		{
			Distance,
			Name,
			Biome
		}

		public static ConfigEntry<bool> EnableDirectTravel;

		public static ConfigEntry<float> TravelRange;

		public static ConfigEntry<bool> KeepVanillaTagPairing;

		public static ConfigEntry<bool> OpenOnInteract;

		public static ConfigEntry<SortMode> Sort;

		public static ConfigEntry<bool> ShowUnnamedPortals;

		public static ConfigEntry<float> RefreshSeconds;

		public static ConfigEntry<float> ScrollRowsPerNotch;

		public static void Bind(ConfigFile config)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			EnableDirectTravel = config.Bind<bool>("Travel", "EnableDirectTravel", true, new ConfigDescription("Picking a portal from the list teleports you straight to it. Off leaves the list as a directory you can read, name and give icons to, while travel stays whatever the pairing rules make it.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					IsAdminOnly = true
				}
			}));
			TravelRange = config.Bind<float>("Travel", "TravelRange", 4f, new ConfigDescription("How close you must be to a portal to travel from it, in metres. This is not cosmetic. ServersideQoL's PortalProgression hands a player their ore back only once they leave a radius around a portal, and takes it only once they enter one — its own PortalRange, 4 by default. Travelling from further out than that means the ore has not been taken yet, so the game's own teleport check refuses a trip the server meant to allow. Keep this at or below that mod's PortalRange. The game lets you reach a portal from 5m, which is why this cannot simply be 'interaction range'.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					IsAdminOnly = true
				}
			}));
			KeepVanillaTagPairing = config.Bind<bool>("Travel", "KeepVanillaTagPairing", false, new ConfigDescription("Leave the game's matching-tag pairing running underneath the list. Off — the default — makes a portal's tag a name and nothing more, so two portals may share one without linking to each other. On restores vanilla pairing as well, which means duplicate names go back to meaning something.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					IsAdminOnly = true
				}
			}));
			OpenOnInteract = config.Bind<bool>("Interface", "OpenOnInteract", true, new ConfigDescription("Use opens the portal list, and Shift + use opens the name and icon screen for the portal you are standing at. Off hands both back to the game, leaving its plain tag box and no list at all.", (AcceptableValueBase)null, Array.Empty<object>()));
			Sort = config.Bind<SortMode>("Interface", "Sort", SortMode.Distance, new ConfigDescription("How the list is ordered.", (AcceptableValueBase)null, Array.Empty<object>()));
			ShowUnnamedPortals = config.Bind<bool>("Interface", "ShowUnnamedPortals", true, new ConfigDescription("Include portals nobody has named. They are listed by the biome they stand in. Off hides them, which is worth having on a server where half the portals are someone's unlabelled scaffolding.", (AcceptableValueBase)null, Array.Empty<object>()));
			ScrollRowsPerNotch = config.Bind<float>("Interface", "ScrollRowsPerNotch", 6f, new ConfigDescription("How many rows one notch of the mouse wheel moves the list. Applied every time the window opens, so a change here takes effect without restarting the game.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			RefreshSeconds = config.Bind<float>("Interface", "RefreshSeconds", 5f, new ConfigDescription("How stale the list may get before opening it asks the server for a fresh one. The list is only rebuilt on request, so this is the whole cost of keeping it current.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
		}
	}
	internal class ConfigurationManagerAttributes
	{
		public bool? IsAdminOnly;

		public bool? Browsable;

		public bool? ReadOnly;

		public int? Order;

		public string Category;
	}
	[BepInPlugin("com.noodle.portalmanager", "PortalManager", "0.1.7")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class PortalManagerPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.noodle.portalmanager";

		public const string PluginName = "PortalManager";

		public const string PluginVersion = "0.1.7";

		private Harmony m_harmony;

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			PortalManagerConfig.Bind(((BaseUnityPlugin)this).Config);
			AddLocalizations();
			m_harmony = new Harmony("com.noodle.portalmanager");
			m_harmony.PatchAll(typeof(PortalPatches).Assembly);
			Logger.LogInfo((object)"PortalManager 0.1.7 loaded.");
		}

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

		private static void AddLocalizations()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			Dictionary<string, string> dictionary = new Dictionary<string, string>
			{
				{ "portalmanager_title", "Portals" },
				{ "portalmanager_close", "Close" },
				{ "portalmanager_rename_title", "Name this portal" },
				{ "portalmanager_icon_label", "Icon" },
				{ "portalmanager_save", "Save" },
				{ "portalmanager_cancel", "Cancel" },
				{ "portalmanager_loading", "Asking the server..." },
				{ "portalmanager_empty", "No portals in this world yet." },
				{ "portalmanager_count", "Portals:" },
				{ "portalmanager_you_are_here", "you are here" },
				{ "portalmanager_hover_open", "Portals" },
				{ "portalmanager_hover_rename", "Name this portal" },
				{ "portalmanager_no_reply", "No answer from the server. Is PortalManager installed there?" },
				{ "portalmanager_biome_unknown", "Unknown" },
				{ "portalmanager_travel_disabled", "Travelling from the list is switched off on this server" },
				{ "portalmanager_already_here", "You are already standing at that portal" },
				{ "portalmanager_step_closer", "Step closer to the portal" },
				{ "portalmanager_travel_failed", "You are already travelling" }
			};
			string text = "English";
			localization.AddTranslation(ref text, dictionary);
		}
	}
	internal static class PortalPatches
	{
		[HarmonyPatch(typeof(ZNet), "Awake")]
		internal static class ZNetAwakePatch
		{
			private static void Postfix()
			{
				PortalRegistry.RegisterRpcs();
			}
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		internal static class ZNetShutdownPatch
		{
			private static void Prefix()
			{
				PortalListPanel.Close();
				PortalRegistry.Reset();
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "Interact")]
		internal static class InteractPatch
		{
			private static bool Prefix(TeleportWorld __instance, Humanoid human, bool hold, bool alt, ref bool __result)
			{
				if (hold || (Object)(object)((human is Player) ? human : null) == (Object)null || (Object)(object)human != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				if (!PortalManagerConfig.OpenOnInteract.Value)
				{
					return true;
				}
				Logger.LogInfo((object)$"PortalManager: portal interact, alt={alt}.");
				if (alt)
				{
					PortalRenameDialog.Open(__instance);
				}
				else
				{
					PortalListPanel.Open(__instance);
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "GetHoverText")]
		internal static class HoverTextPatch
		{
			private static bool Prefix(TeleportWorld __instance, ref string __result)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				if (!PortalManagerConfig.OpenOnInteract.Value)
				{
					return true;
				}
				string text = __instance.GetText();
				string text2 = (string.IsNullOrEmpty(text) ? Localization.instance.Localize(BiomeNames.Token(BiomeNames.At(((Component)__instance).transform.position))) : StringExtensionMethods.RemoveRichTextTags(text));
				string text3 = Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] $portalmanager_hover_open\n[<color=yellow><b>L.Shift + $KEY_Use</b></color>] $portalmanager_hover_rename");
				__result = text2 + "\n" + text3;
				return false;
			}
		}

		[HarmonyPatch(typeof(TextInput), "Hide")]
		internal static class TextInputHidePatch
		{
			private static void Postfix()
			{
				PortalRenameDialog.Close();
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "SetText")]
		internal static class SetTextPatch
		{
			private static void Prefix(TeleportWorld __instance)
			{
				if (PortalRenameDialog.IsEditing(__instance))
				{
					ZNetView nview = __instance.m_nview;
					if ((Object)(object)nview != (Object)null && nview.IsValid() && !nview.IsOwner())
					{
						nview.ClaimOwnership();
					}
				}
			}

			private static void Postfix(TeleportWorld __instance)
			{
				if (!PortalRenameDialog.IsEditing(__instance))
				{
					return;
				}
				ZNetView nview = __instance.m_nview;
				ZDO val = (((Object)(object)nview != (Object)null && nview.IsValid()) ? nview.GetZDO() : null);
				if (val != null)
				{
					val.Set("pm_icon", PortalRenameDialog.PendingIcon);
					ZDOMan instance = ZDOMan.instance;
					if (instance != null)
					{
						instance.SetDirtyPortals();
					}
					Logger.LogInfo((object)($"PortalManager: icon {PortalRenameDialog.PendingIcon} saved on the " + "portal, portal chunk marked dirty."));
					PortalRegistry.Request();
				}
			}
		}

		[HarmonyPatch(typeof(Game), "ConnectPortals")]
		internal static class ConnectPortalsPatch
		{
			private static bool Prefix(Game __instance)
			{
				//IL_0047: 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_0059: Unknown result type (might be due to invalid IL or missing references)
				if (PortalManagerConfig.KeepVanillaTagPairing.Value)
				{
					return true;
				}
				__instance.ClearCurrentlyConnectingPortals();
				ZDOMan instance = ZDOMan.instance;
				if (instance == null)
				{
					return false;
				}
				instance.SetDirtyPortals();
				List<ZDO> portalList = instance.GetPortalList();
				if (portalList == null)
				{
					return false;
				}
				foreach (ZDO item in portalList)
				{
					if (item != null)
					{
						ZDOID connectionZDOID = item.GetConnectionZDOID((ConnectionType)1);
						if (!((ZDOID)(ref connectionZDOID)).IsNone())
						{
							__instance.SetConnection(item, ZDOID.None, false);
						}
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "HaveTarget")]
		internal static class HaveTargetPatch
		{
			private static void Postfix(ref bool __result)
			{
				if (!PortalManagerConfig.KeepVanillaTagPairing.Value)
				{
					__result = true;
				}
			}
		}
	}
	internal static class PortalRegistry
	{
		private const string RpcRequest = "PortalManager_Request";

		private const string RpcList = "PortalManager_List";

		public const string IconKey = "pm_icon";

		private const int MaxPortalsPerResponse = 4000;

		private const float RequestTimeoutSeconds = 10f;

		public static readonly List<PortalEntry> Known = new List<PortalEntry>();

		private static float LastResponseTime = float.NegativeInfinity;

		private static float LastRequestTime = float.NegativeInfinity;

		private static bool WarnedAboutTruncation;

		public static Action Updated;

		public static bool HasEverAnswered { get; private set; }

		public static bool AwaitingResponse { get; private set; }

		public static bool LastRequestTimedOut
		{
			get
			{
				if (AwaitingResponse)
				{
					return Time.realtimeSinceStartup - LastRequestTime >= 10f;
				}
				return false;
			}
		}

		public static bool IsStale
		{
			get
			{
				if (HasEverAnswered)
				{
					return Time.realtimeSinceStartup - LastResponseTime > Mathf.Max(0f, PortalManagerConfig.RefreshSeconds.Value);
				}
				return true;
			}
		}

		private static bool IsServer
		{
			get
			{
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					return ZNet.instance.IsServer();
				}
				return false;
			}
		}

		public static void RegisterRpcs()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance == null)
			{
				Logger.LogError((object)"PortalManager: ZRoutedRpc missing at ZNet.Awake; the portal list will not work this session.");
				return;
			}
			instance.Register("PortalManager_Request", (Action<long>)OnRequestReceived);
			instance.Register<ZPackage>("PortalManager_List", (Action<long, ZPackage>)OnListReceived);
			Reset();
			ZNet instance2 = ZNet.instance;
			string text = $"PortalManager: RPCs registered. IsServer={((instance2 != null) ? new bool?(instance2.IsServer()) : ((bool?)null))}, ";
			ZNet instance3 = ZNet.instance;
			Logger.LogInfo((object)(text + $"IsDedicated={((instance3 != null) ? new bool?(instance3.IsDedicated()) : ((bool?)null))}."));
		}

		public static void Reset()
		{
			Known.Clear();
			HasEverAnswered = false;
			AwaitingResponse = false;
			LastResponseTime = float.NegativeInfinity;
			LastRequestTime = float.NegativeInfinity;
			WarnedAboutTruncation = false;
		}

		public static void Request()
		{
			if (AwaitingResponse && Time.realtimeSinceStartup - LastRequestTime < 10f)
			{
				return;
			}
			if (IsServer)
			{
				ZPackage obj = BuildList();
				obj.SetPos(0);
				LastRequestTime = Time.realtimeSinceStartup;
				AwaitingResponse = true;
				ApplyList(obj);
				return;
			}
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance == null)
			{
				Logger.LogWarning((object)"PortalManager: no ZRoutedRpc; cannot ask for the list.");
				return;
			}
			long serverPeerID = instance.GetServerPeerID();
			AwaitingResponse = true;
			LastRequestTime = Time.realtimeSinceStartup;
			Logger.LogInfo((object)$"PortalManager: requesting the portal list from peer {serverPeerID}.");
			instance.InvokeRoutedRPC(serverPeerID, "PortalManager_Request", new object[0]);
		}

		public static void RequestIfStale()
		{
			if (IsStale)
			{
				Request();
			}
		}

		private static void OnListReceived(long sender, ZPackage pkg)
		{
			Logger.LogInfo((object)$"PortalManager: portal list received from peer {sender}.");
			ApplyList(pkg);
		}

		private static void ApplyList(ZPackage pkg)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			AwaitingResponse = false;
			LastResponseTime = Time.realtimeSinceStartup;
			HasEverAnswered = true;
			Known.Clear();
			if (pkg != null)
			{
				int num = pkg.ReadInt();
				for (int i = 0; i < num; i++)
				{
					Known.Add(PortalEntry.Deserialize(pkg));
				}
			}
			Logger.LogInfo((object)$"PortalManager: list now holds {Known.Count} portal(s).");
			for (int j = 0; j < Known.Count; j++)
			{
				PortalEntry portalEntry = Known[j];
				Logger.LogInfo((object)(string.Format("  [{0}] '{1}' ", j + 1, portalEntry.HasName ? portalEntry.Name : "<unnamed>") + BiomeNames.Localized(portalEntry.Biome) + " at " + $"{portalEntry.Position.x:0}, {portalEntry.Position.z:0}"));
			}
			Updated?.Invoke();
		}

		private static void OnRequestReceived(long sender)
		{
			Logger.LogInfo((object)$"PortalManager: portal list requested by peer {sender}.");
			if (!IsServer)
			{
				Logger.LogWarning((object)"PortalManager: asked for the portal list but this peer is not the server; ignoring.");
				return;
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(sender, "PortalManager_List", new object[1] { BuildList() });
		}

		private static ZPackage BuildList()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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)
			ZPackage val = new ZPackage();
			ZDOMan instance = ZDOMan.instance;
			List<ZDO> list = ((instance != null) ? instance.GetPortalList() : null);
			if (list == null)
			{
				Logger.LogWarning((object)"PortalManager: ZDOMan has no portal list; sending none.");
				val.Write(0);
				return val;
			}
			Logger.LogInfo((object)$"PortalManager: ZDOMan reports {list.Count} portal ZDO(s).");
			List<PortalEntry> list2 = new List<PortalEntry>();
			foreach (ZDO item in list)
			{
				if (list2.Count >= 4000)
				{
					break;
				}
				if (item != null)
				{
					list2.Add(new PortalEntry
					{
						Id = item.m_uid,
						Name = item.GetString(ZDOVars.s_tag, string.Empty),
						Author = item.GetString(ZDOVars.s_tagauthor, string.Empty),
						Position = item.GetPosition(),
						Rotation = item.GetRotation(),
						Icon = item.GetInt("pm_icon", -1)
					});
				}
			}
			if (list.Count > 4000 && !WarnedAboutTruncation)
			{
				WarnedAboutTruncation = true;
				Logger.LogWarning((object)($"PortalManager: {list.Count} portals in this world exceeds the " + $"{4000} sent in one list; it was truncated."));
			}
			val.Write(list2.Count);
			foreach (PortalEntry item2 in list2)
			{
				item2.Serialize(val);
			}
			Logger.LogInfo((object)$"PortalManager: sending {list2.Count} portal(s).");
			return val;
		}
	}
	internal static class PortalRenameDialog
	{
		private const int TagCharacterLimit = 10;

		private const int IconSize = 38;

		private const int Columns = 9;

		private static GameObject Tray;

		private static RectTransform Grid;

		private static readonly List<GameObject> IconButtons = new List<GameObject>();

		private static readonly List<int> IconValues = new List<int>();

		private static TeleportWorld Target;

		private static int Chosen = -1;

		public static bool IsOpen => (Object)(object)Target != (Object)null;

		public static int PendingIcon => Chosen;

		public static bool IsEditing(TeleportWorld portal)
		{
			if ((Object)(object)Target != (Object)null && (Object)(object)portal != (Object)null)
			{
				return (Object)(object)Target == (Object)(object)portal;
			}
			return false;
		}

		public static void Open(TeleportWorld portal)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portal == (Object)null)
			{
				return;
			}
			TextInput instance = TextInput.instance;
			if ((Object)(object)instance == (Object)null)
			{
				Logger.LogWarning((object)"PortalManager: TextInput is unavailable; cannot rename.");
				return;
			}
			if (!PrivateArea.CheckAccess(((Component)portal).transform.position, 0f, true, false))
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, Loc.T("$piece_noaccess"), 0, (Sprite)null, false);
				}
				return;
			}
			Target = portal;
			Chosen = CurrentIcon(portal);
			Logger.LogInfo((object)$"PortalManager: opening rename, current icon {Chosen}.");
			instance.RequestText((TextReceiver)(object)portal, "$piece_portal_tag", 10);
			BuildTray(instance);
			RefreshIcons();
			if ((Object)(object)Tray != (Object)null)
			{
				Tray.SetActive(true);
				Tray.transform.SetAsLastSibling();
			}
		}

		public static void Close()
		{
			if ((Object)(object)Target != (Object)null)
			{
				Logger.LogInfo((object)"PortalManager: rename dialog closed.");
			}
			Target = null;
			if ((Object)(object)Tray != (Object)null)
			{
				Tray.SetActive(false);
			}
		}

		private static int CurrentIcon(TeleportWorld portal)
		{
			ZDO val = (((Object)(object)portal.m_nview != (Object)null) ? portal.m_nview.GetZDO() : null);
			if (val == null)
			{
				return -1;
			}
			return val.GetInt("pm_icon", -1);
		}

		private static void BuildTray(TextInput input)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Tray != (Object)null))
			{
				if ((Object)(object)input.m_panel == (Object)null)
				{
					Logger.LogWarning((object)"PortalManager: TextInput has no panel; no icon tray.");
					return;
				}
				float num = (float)Mathf.CeilToInt((float)(PortalIcons.All().Count + 1) / 9f) * 44f + 42f;
				float num2 = 412f;
				Tray = new GameObject("PortalManagerIconTray", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				Tray.transform.SetParent(input.m_panel.transform, false);
				RectTransform component = Tray.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.5f, 0f);
				component.anchorMax = new Vector2(0.5f, 0f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = new Vector2(0f, -12f);
				component.sizeDelta = new Vector2(num2, num);
				((Graphic)Tray.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.82f);
				GUIManager instance = GUIManager.Instance;
				instance.CreateText(Loc.T("$portalmanager_icon_label"), Tray.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -18f), instance.AveriaSerifBold, 16, instance.ValheimOrange, true, Color.black, num2 - 20f, 24f, false);
				GameObject val = new GameObject("Grid", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(Tray.transform, false);
				Grid = val.GetComponent<RectTransform>();
				Grid.anchorMin = new Vector2(0f, 1f);
				Grid.anchorMax = new Vector2(1f, 1f);
				Grid.pivot = new Vector2(0.5f, 1f);
				Grid.anchoredPosition = new Vector2(0f, -34f);
				Grid.sizeDelta = new Vector2(-16f, num - 42f);
				GridLayoutGroup obj = val.AddComponent<GridLayoutGroup>();
				obj.cellSize = new Vector2(38f, 38f);
				obj.spacing = new Vector2(6f, 6f);
				obj.constraint = (Constraint)1;
				obj.constraintCount = 9;
				((LayoutGroup)obj).childAlignment = (TextAnchor)1;
			}
		}

		private static void RefreshIcons()
		{
			if ((Object)(object)Grid == (Object)null)
			{
				return;
			}
			foreach (GameObject iconButton in IconButtons)
			{
				if (!((Object)(object)iconButton == (Object)null))
				{
					iconButton.transform.SetParent((Transform)null, false);
					Object.Destroy((Object)(object)iconButton);
				}
			}
			IconButtons.Clear();
			IconValues.Clear();
			AddIconButton(-1, null);
			foreach (int item in PortalIcons.All())
			{
				AddIconButton(item, PortalIcons.Sprite(item));
			}
			Logger.LogInfo((object)$"PortalManager: icon tray built with {IconButtons.Count} option(s).");
			HighlightChosen();
		}

		private static void AddIconButton(int icon, Sprite sprite)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			GameObject val = new GameObject($"Icon{icon}", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Button),
				typeof(Outline)
			});
			val.transform.SetParent((Transform)(object)Grid, false);
			Image component = val.GetComponent<Image>();
			component.sprite = sprite;
			component.preserveAspect = true;
			((Graphic)component).color = (Color)(((Object)(object)sprite != (Object)null) ? Color.white : new Color(1f, 1f, 1f, 0.18f));
			Outline component2 = val.GetComponent<Outline>();
			((Shadow)component2).effectColor = GUIManager.Instance.ValheimOrange;
			((Shadow)component2).effectDistance = new Vector2(2.5f, 2.5f);
			((Behaviour)component2).enabled = false;
			int captured = icon;
			((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				Chosen = captured;
				HighlightChosen();
			});
			IconButtons.Add(val);
			IconValues.Add(icon);
		}

		private static void HighlightChosen()
		{
			for (int i = 0; i < IconButtons.Count && i < IconValues.Count; i++)
			{
				((Behaviour)IconButtons[i].GetComponent<Outline>()).enabled = IconValues[i] == Chosen;
			}
		}
	}
	internal static class PortalTravel
	{
		public static bool TryTravel(TeleportWorld from, PortalEntry destination, out string messageToken)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			messageToken = null;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)from == (Object)null || destination == null)
			{
				return false;
			}
			if (!PortalManagerConfig.EnableDirectTravel.Value)
			{
				messageToken = "$portalmanager_travel_disabled";
				return false;
			}
			if (destination.Id == PortalOf(from))
			{
				messageToken = "$portalmanager_already_here";
				return false;
			}
			float value = PortalManagerConfig.TravelRange.Value;
			if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)from).transform.position) > value)
			{
				messageToken = "$portalmanager_step_closer";
				return false;
			}
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance != (Object)null && instance.GetGlobalKey((GlobalKeys)32))
			{
				messageToken = "$msg_blocked";
				return false;
			}
			if ((Object)(object)instance != (Object)null && instance.GetGlobalKey((GlobalKeys)33) && BossActive(instance))
			{
				messageToken = "$msg_blockedbyboss";
				return false;
			}
			if (!((Humanoid)localPlayer).IsTeleportable(from.m_allowAllItems))
			{
				messageToken = "$msg_noteleport";
				return false;
			}
			if (!((Character)localPlayer).TeleportTo(destination.ArrivalPosition(from.m_exitDistance), destination.Rotation, true))
			{
				messageToken = "$portalmanager_travel_failed";
				return false;
			}
			Game instance2 = Game.instance;
			if (instance2 != null)
			{
				instance2.IncrementPlayerStat((PlayerStatType)15, 1f, false);
			}
			return true;
		}

		private static bool BossActive(ZoneSystem zones)
		{
			if ((Object)(object)RandEventSystem.instance != (Object)null && RandEventSystem.instance.GetBossEvent() != null)
			{
				return true;
			}
			float num = default(float);
			if (zones.GetGlobalKey((GlobalKeys)47, ref num))
			{
				return num > 0f;
			}
			return false;
		}

		public static ZDOID PortalOf(TeleportWorld portal)
		{
			//IL_0030: 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)
			ZNetView val = (((Object)(object)portal != (Object)null) ? portal.m_nview : null);
			return (((Object)(object)val != (Object)null) ? val.GetZDO() : null)?.m_uid ?? ZDOID.None;
		}
	}
	internal static class StarSprite
	{
		private const int Size = 64;

		private const float InnerRatio = 0.382f;

		private const int Supersample = 3;

		private static Sprite Cached;

		public static Sprite Get()
		{
			//IL_001f: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0112: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Cached != (Object)null)
			{
				return Cached;
			}
			Vector2[] polygon = BuildStar();
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[4096];
			float num = 0.25f;
			Vector2 point = default(Vector2);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num2 = 0;
					for (int k = 1; k <= 3; k++)
					{
						for (int l = 1; l <= 3; l++)
						{
							((Vector2)(ref point))..ctor((float)j + (float)l * num, (float)i + (float)k * num);
							if (Contains(polygon, point))
							{
								num2++;
							}
						}
					}
					byte b = (byte)(255 * num2 / 9);
					array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(array);
			val.Apply();
			Cached = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
			return Cached;
		}

		private static Vector2[] BuildStar()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(32f, 32f);
			float num = 30f;
			float num2 = num * 0.382f;
			Vector2[] array = (Vector2[])(object)new Vector2[10];
			for (int i = 0; i < 10; i++)
			{
				float num3 = ((i % 2 == 0) ? num : num2);
				float num4 = (float)Math.PI / 2f + (float)i * (float)Math.PI / 5f;
				array[i] = val + new Vector2(Mathf.Cos(num4) * num3, Mathf.Sin(num4) * num3);
			}
			return array;
		}

		private static bool Contains(Vector2[] polygon, Vector2 point)
		{
			//IL_001b: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			int num = 0;
			int num2 = polygon.Length - 1;
			while (num < polygon.Length)
			{
				if (polygon[num].y > point.y != polygon[num2].y > point.y && point.x < (polygon[num2].x - polygon[num].x) * (point.y - polygon[num].y) / (polygon[num2].y - polygon[num].y) + polygon[num].x)
				{
					flag = !flag;
				}
				num2 = num++;
			}
			return flag;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}