Decompiled source of PortalHeim SG1 v0.5.13

plugins/PortalHeimSG1.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PortalHeimSG1.Art;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PortalHeimSG1")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d326f478968bb23739ab9378966ddea0bfa166f4")]
[assembly: AssemblyProduct("PortalHeimSG1")]
[assembly: AssemblyTitle("PortalHeimSG1")]
[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;
		}
	}
}
namespace PortalHeimSG1
{
	internal static class CartFollow
	{
		private class Trip
		{
			public ZDOID Cart;

			public Vector3 Relative;

			public Quaternion RelativeRotation;

			public float Started;

			public bool SawTeleport;

			public float ArrivedAt = -1f;
		}

		private static Trip _candidate;

		private static Trip _trip;

		public static bool Enabled
		{
			get
			{
				if (PortalHeimSG1Plugin.CartsFollow.Value)
				{
					return GateClient.ServerHasMod;
				}
				return false;
			}
		}

		public static bool HasCandidate => _candidate != null;

		public static float ExtraExitDistance
		{
			get
			{
				if (!HasCandidate)
				{
					return 0f;
				}
				return PortalHeimSG1Plugin.CartExitDistance.Value;
			}
		}

		private static Vagon PulledBy(Player player)
		{
			foreach (Vagon instance in Vagon.m_instances)
			{
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_attachedObject == (Object)(object)((Component)player).gameObject && (Object)(object)instance.m_nview != (Object)null && instance.m_nview.IsValid() && instance.IsAttached())
				{
					return instance;
				}
			}
			return null;
		}

		public static void Prepare(Player player)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			_candidate = null;
			if (Enabled && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer))
			{
				Vagon val = PulledBy(player);
				if (!((Object)(object)val == (Object)null))
				{
					_candidate = new Trip
					{
						Cart = val.m_nview.GetZDO().m_uid,
						Relative = ((Component)player).transform.InverseTransformPoint(((Component)val).transform.position),
						RelativeRotation = Quaternion.Inverse(((Component)player).transform.rotation) * ((Component)val).transform.rotation,
						Started = Time.time
					};
				}
			}
		}

		public static void Settle(bool started)
		{
			_trip = (started ? _candidate : _trip);
			_candidate = null;
		}

		public static void Tick()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (_trip == null || (Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (((Character)localPlayer).IsTeleporting())
			{
				_trip.SawTeleport = true;
				return;
			}
			if (!_trip.SawTeleport)
			{
				if (Time.time - _trip.Started > 5f)
				{
					_trip = null;
				}
				return;
			}
			if (_trip.ArrivedAt < 0f)
			{
				_trip.ArrivedAt = Time.time;
			}
			if (!(Time.time - _trip.ArrivedAt < 1f))
			{
				Trip trip = _trip;
				_trip = null;
				Vector3 position = ((Component)localPlayer).transform.TransformPoint(trip.Relative);
				Quaternion rotation = ((Component)localPlayer).transform.rotation * trip.RelativeRotation;
				GateNet.RequestMoveCart(trip.Cart, position, rotation);
				((MonoBehaviour)PortalHeimSG1Plugin.Instance).StartCoroutine(Reattach(trip.Cart, localPlayer));
			}
		}

		private static IEnumerator Reattach(ZDOID id, Player player)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			float end = Time.time + 12f;
			while (Time.time < end && (Object)(object)player != (Object)null)
			{
				yield return (object)new WaitForSeconds(0.25f);
				Vagon val = null;
				foreach (Vagon instance in Vagon.m_instances)
				{
					if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_nview != (Object)null && instance.m_nview.IsValid() && instance.m_nview.GetZDO().m_uid == id)
					{
						val = instance;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if (!val.m_nview.IsOwner())
				{
					val.m_nview.ClaimOwnership();
					continue;
				}
				if ((Object)(object)val.m_body != (Object)null)
				{
					val.m_body.velocity = Vector3.zero;
					val.m_body.angularVelocity = Vector3.zero;
				}
				ZDO zDO = val.m_nview.GetZDO();
				if (zDO.GetBool(ZDOVars.s_attachJointHash, false))
				{
					zDO.Set(ZDOVars.s_attachJointHash, false);
				}
				Vector3 val2 = ((Component)player).transform.position + val.m_attachOffset - val.m_attachPoint.position;
				Transform transform = ((Component)val).transform;
				transform.position += val2;
				if ((Object)(object)val.m_body != (Object)null)
				{
					val.m_body.position = ((Component)val).transform.position;
				}
				val.AttachTo(((Component)player).gameObject);
				break;
			}
		}

		public static void ServerMove(long sender, ZDOID id, Vector3 position, Quaternion rotation)
		{
			//IL_0005: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = ZDOMan.instance.GetZDO(id);
			if (zDO != null && !((Object)(object)ZNetScene.instance == (Object)null))
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(zDO.GetPrefab());
				if (!((Object)(object)prefab == (Object)null) && !((Object)(object)prefab.GetComponent<Vagon>() == (Object)null) && (!GateServer.TryGetPlayerPosition(sender, out var position2) || !(Vector3.Distance(position2, position) > 25f)))
				{
					zDO.SetOwner(ZDOMan.GetSessionID());
					zDO.SetPosition(position);
					zDO.SetRotation(rotation);
					zDO.SetOwner(0L);
					ZDOMan.instance.ForceSendZDO(id);
				}
			}
		}
	}
	[HarmonyPatch(typeof(TeleportWorld))]
	internal static class CartPortalPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("Teleport")]
		private static void Teleport_Prefix(Player player)
		{
			CartFollow.Prepare(player);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Teleport")]
		private static void Teleport_Postfix(Player player)
		{
			CartFollow.Settle(CartFollow.HasCandidate && (Object)(object)player != (Object)null && ((Character)player).IsTeleporting());
		}
	}
	[HarmonyPatch(typeof(Player), "TeleportTo")]
	internal static class CartExitPatch
	{
		private static void Prefix(Player __instance, ref Vector3 pos, Quaternion rot)
		{
			//IL_001d: 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)
			//IL_0023: 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_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_0038: Unknown result type (might be due to invalid IL or missing references)
			float extraExitDistance = CartFollow.ExtraExitDistance;
			if (extraExitDistance > 0f && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				pos += rot * Vector3.forward * extraExitDistance;
			}
		}
	}
	internal static class Diagnostics
	{
		public static int Attached;

		public static int Failures;

		public static string LastError;

		public static void RecordFailure(string what, Exception e)
		{
			Failures++;
			string text = ((e != null) ? e.Message : "");
			LastError = what + ": " + ((text.Length > 70) ? (text.Substring(0, 70) + "...") : text);
		}

		public static IEnumerator ReportSoon()
		{
			yield return (object)new WaitForSeconds(12f);
			Report();
		}

		public static void Report()
		{
			int num = Object.FindObjectsByType<TeleportWorld>((FindObjectsSortMode)0).Length;
			int num2 = Object.FindObjectsByType<GateRing>((FindObjectsSortMode)0).Length;
			string text = ((PortalHeimSG1Plugin.Interior.Value != InteriorMode.Water) ? "water off" : (WaterSurface.Failed ? "water FAILED" : (WaterSurface.Ready ? "water ready" : "water loading")));
			string text2 = ((PortalHeimSG1Plugin.Travel.Value == TravelMode.Tunnel) ? (", tunnel " + TunnelSurface.Status) : "");
			string text3 = string.Format("PortalHeim SG1 {0}: {1} of {2} portals are gates, {3}, {4}{5}", "0.5.13", num2, num, text, GateSounds.Summary, text2);
			if (Failures > 0)
			{
				text3 = text3 + " | ERROR: " + LastError;
			}
			else if (num > 0 && num2 == 0 && PortalHeimSG1Plugin.Reskin.Value)
			{
				text3 += " | no gates attached, see BepInEx log";
			}
			PortalHeimSG1Plugin.Log.LogInfo((object)text3);
			bool flag = Failures > 0;
			if ((PortalHeimSG1Plugin.ShowStatus.Value || flag) && (Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage((MessageType)1, text3, 0, (Sprite)null, false, true);
			}
		}
	}
	internal static class DialMenu
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DrawWindow;
		}

		private const int WindowId = 1473;

		private const float CloseDistance = 10f;

		private static TeleportWorld _source;

		private static Vector2 _scroll;

		private static string _selected = "";

		private static bool _hadDefault;

		private static CursorLockMode _lockBefore;

		private static bool _visibleBefore;

		private static GUIStyle _title;

		private static GUIStyle _label;

		private static GUIStyle _small;

		private static GUIStyle _row;

		private static GUIStyle _rowSelected;

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

		public static void Open(TeleportWorld portal)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)portal == (Object)null))
			{
				_source = portal;
				_scroll = Vector2.zero;
				_selected = "";
				_hadDefault = false;
				_lockBefore = Cursor.lockState;
				_visibleBefore = Cursor.visible;
				GateNet.RequestGates();
			}
		}

		public static void Close()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_source == (Object)null))
			{
				_source = null;
				Cursor.lockState = _lockBefore;
				Cursor.visible = _visibleBefore;
			}
		}

		public static bool DialFrom(TeleportWorld portal, GateInfo target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0008: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			ZDOID val = GateRegistry.IdOf(portal);
			if (val == ZDOID.None)
			{
				return false;
			}
			GateNet.RequestDial(val, target.Id);
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, "Dialing " + DisplayName(target) + "...", 0, (Sprite)null, false);
			}
			return true;
		}

		public static string DisplayName(GateInfo gate)
		{
			if (!string.IsNullOrWhiteSpace(gate.Name))
			{
				return gate.Name;
			}
			return "(unnamed gate)";
		}

		public static void Draw()
		{
			//IL_002b: 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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_0101: 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)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Invalid comparison between Unknown and I4
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Invalid comparison between Unknown and I4
			if ((Object)(object)_source == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_source).transform.position) > 10f)
			{
				Close();
				return;
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			Event current = Event.current;
			if ((int)current.type == 4)
			{
				if ((int)current.keyCode == 27)
				{
					current.Use();
					Close();
					return;
				}
				if (((int)current.keyCode == 13 || (int)current.keyCode == 271) && TryDialSelected())
				{
					current.Use();
					return;
				}
			}
			float num = Mathf.Clamp((float)Screen.height / 1080f, 0.8f, 2.5f);
			EnsureStyles(num);
			float num2 = 520f * num;
			float num3 = 520f * num;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((float)Screen.width - num2) / 2f, ((float)Screen.height - num3) / 2f, num2, num3);
			GUI.Box(val, GUIContent.none);
			Rect val2 = val;
			object obj = <>O.<0>__DrawWindow;
			if (obj == null)
			{
				WindowFunction val3 = DrawWindow;
				<>O.<0>__DrawWindow = val3;
				obj = (object)val3;
			}
			GUI.Window(1473, val2, (WindowFunction)obj, "Gate");
		}

		private static void DrawWindow(int id)
		{
			//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)
			//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_01c5: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp((float)Screen.height / 1080f, 0.8f, 2.5f);
			ZDOID val = GateRegistry.IdOf(_source);
			GateInfo? gateInfo = null;
			foreach (GateInfo gate in GateClient.Gates)
			{
				if (gate.Id == val)
				{
					gateInfo = gate;
				}
			}
			GUILayout.Space(8f * num);
			GUILayout.Label(gateInfo.HasValue ? DisplayName(gateInfo.Value) : "(this gate)", _title, Array.Empty<GUILayoutOption>());
			if (!gateInfo.HasValue)
			{
				GUILayout.Label("Asking the server...", _label, Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f * num) }))
				{
					Close();
				}
				return;
			}
			if (gateInfo.Value.State == GateState.Dialing)
			{
				string text = "";
				foreach (GateInfo gate2 in GateClient.Gates)
				{
					if (gate2.Id == gateInfo.Value.Partner)
					{
						text = DisplayName(gate2);
					}
				}
				GUILayout.Label((text.Length > 0) ? ("Connected to " + text + ". It closes by itself once everyone has gone.") : "This gate is set aside while another dial is open. It goes back to normal when that dial closes.", _label, Array.Empty<GUILayoutOption>());
				GUILayout.Space(8f * num);
				if (GUILayout.Button("Hang up", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f * num) }))
				{
					GateNet.RequestHangUp(val);
					Close();
					return;
				}
			}
			else
			{
				DrawList(val, gateInfo.Value, num);
			}
			GUILayout.FlexibleSpace();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (gateInfo.Value.State != GateState.Dialing && GUILayout.Button("Pick on map", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f * num) }))
			{
				TeleportWorld source = _source;
				Close();
				DialMap.BeginPick(source);
				return;
			}
			if (gateInfo.Value.State != GateState.Dialing && GUILayout.Button("Rename this gate", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f * num) }))
			{
				Rename();
			}
			if (GUILayout.Button("Close (Esc)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f * num) }))
			{
				Close();
			}
			GUILayout.EndHorizontal();
		}

		private static void DrawList(ZDOID here, GateInfo self, float scale)
		{
			//IL_0026: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: 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_01ff: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: 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)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			List<GateInfo> list = new List<GateInfo>();
			int num = 0;
			foreach (GateInfo gate in GateClient.Gates)
			{
				if (!(gate.Id == here))
				{
					if (GateClient.IsVisible(gate.Id))
					{
						list.Add(gate);
					}
					else
					{
						num++;
					}
				}
			}
			Vector3 origin = self.Position;
			list.Sort((GateInfo a, GateInfo b) => Vector3.Distance(a.Position, origin).CompareTo(Vector3.Distance(b.Position, origin)));
			if (!_hadDefault)
			{
				_hadDefault = true;
				foreach (GateInfo item in list)
				{
					if (GateClient.IsHome(item.Id) && GateClient.Dialable(item.State))
					{
						_selected = GateClient.Key(item.Id);
					}
				}
				if (_selected.Length == 0)
				{
					foreach (GateInfo item2 in list)
					{
						if (item2.State == GateState.Idle)
						{
							_selected = GateClient.Key(item2.Id);
							break;
						}
					}
				}
			}
			if (self.State == GateState.Linked)
			{
				string text = "another gate";
				foreach (GateInfo gate2 in GateClient.Gates)
				{
					if (gate2.Id == self.Partner)
					{
						text = DisplayName(gate2);
					}
				}
				GUILayout.Label("Paired with " + text + ". Dialing another gate sets that pair aside until the dial closes.", _small, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Label((list.Count == 0) ? "No other gates to dial yet. Visit a gate and it will appear here." : "Pick a gate and press Dial (or Enter). The star marks your home gate.", _small, Array.Empty<GUILayoutOption>());
			_scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(300f * scale) });
			foreach (GateInfo item3 in list)
			{
				string text2 = GateClient.Key(item3.Id);
				bool flag = GateClient.Dialable(item3.State);
				bool num2 = text2 == _selected;
				int num3 = Mathf.RoundToInt(Vector3.Distance(item3.Position, self.Position));
				GUILayout.BeginHorizontal(num2 ? _rowSelected : _row, Array.Empty<GUILayoutOption>());
				string text3 = (GateClient.IsHome(item3.Id) ? "* " : "");
				string text4 = ((item3.State == GateState.Dialing) ? "  (in use)" : ((item3.State == GateState.Linked) ? "  (paired)" : ""));
				if (GUILayout.Button(text3 + DisplayName(item3) + "  -  " + num3 + " m" + text4, _label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }) && flag)
				{
					_selected = text2;
				}
				bool flag2 = GateClient.IsHome(item3.Id);
				if (GUILayout.Button(flag2 ? "Unset home" : "Set home", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f * scale) }))
				{
					GateClient.SetHome(item3.Id, !flag2);
				}
				GUI.enabled = flag;
				if (GUILayout.Button("Dial", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f * scale) }))
				{
					_selected = text2;
					TryDialSelected();
				}
				GUI.enabled = true;
				GUILayout.EndHorizontal();
			}
			GUILayout.EndScrollView();
			if (num > 0 && PortalHeimSG1Plugin.OnlyVisited.Value)
			{
				GUILayout.Label(num + ((num == 1) ? " gate" : " gates") + " you haven't visited yet.", _small, Array.Empty<GUILayoutOption>());
			}
		}

		private static bool TryDialSelected()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_source == (Object)null || _selected.Length == 0)
			{
				return false;
			}
			foreach (GateInfo gate in GateClient.Gates)
			{
				if (!(GateClient.Key(gate.Id) != _selected) && GateClient.Dialable(gate.State))
				{
					TeleportWorld source = _source;
					Close();
					return DialFrom(source, gate);
				}
			}
			return false;
		}

		private static void Rename()
		{
			TeleportWorld source = _source;
			Close();
			if ((Object)(object)source == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			DialPatches.Bypass = true;
			try
			{
				source.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
			}
			finally
			{
				DialPatches.Bypass = false;
			}
		}

		private static void EnsureStyles(float scale)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0036: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0092: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			if (_title == null)
			{
				_title = new GUIStyle(GUI.skin.label)
				{
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_label = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true,
					alignment = (TextAnchor)3
				};
				_small = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true
				};
				_row = new GUIStyle();
				Texture2D val = new Texture2D(1, 1);
				val.SetPixel(0, 0, new Color(1f, 0.45f, 0.1f, 0.35f));
				val.Apply();
				GUIStyle val2 = new GUIStyle();
				val2.normal.background = val;
				_rowSelected = val2;
			}
			_title.fontSize = Mathf.RoundToInt(24f * scale);
			_label.fontSize = Mathf.RoundToInt(17f * scale);
			_small.fontSize = Mathf.RoundToInt(15f * scale);
			GUI.skin.button.fontSize = Mathf.RoundToInt(16f * scale);
		}
	}
	[HarmonyPatch(typeof(Player), "TakeInput")]
	internal static class TakeInputPatch
	{
		private static void Postfix(ref bool __result)
		{
			if (DialMenu.IsOpen)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerController), "TakeInput")]
	internal static class ControllerTakeInputPatch
	{
		private static void Postfix(ref bool __result)
		{
			if (DialMenu.IsOpen)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(TeleportWorld))]
	internal static class DialPatches
	{
		public static bool Bypass;

		private static bool Active
		{
			get
			{
				if (PortalHeimSG1Plugin.DialingEnabled.Value)
				{
					return GateClient.ServerHasMod;
				}
				return false;
			}
		}

		private static bool TryGetInfo(TeleportWorld portal, out GateInfo info)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			ZDOID val = GateRegistry.IdOf(portal);
			foreach (GateInfo gate in GateClient.Gates)
			{
				if (gate.Id == val)
				{
					info = gate;
					return true;
				}
			}
			info = default(GateInfo);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Interact")]
		private static bool Interact_Prefix(TeleportWorld __instance, Humanoid human, bool hold, bool alt, ref bool __result)
		{
			//IL_002e: 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_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)
			if (Bypass || hold || !Active || (Object)(object)human == (Object)null || (Object)(object)human != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false))
			{
				return true;
			}
			if (!TryGetInfo(__instance, out var info) || (info.State == GateState.Linked && !GateClient.Dialable(info.State)))
			{
				return true;
			}
			if (alt && info.State == GateState.Dialing)
			{
				GateNet.RequestHangUp(info.Id);
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "Hanging up", 0, (Sprite)null, false);
				}
				__result = true;
				return false;
			}
			if (alt && GateClient.Dialable(info.State) && GateClient.TryGetHome(out var home) && GateClient.Dialable(home.State) && home.Id != info.Id)
			{
				DialMenu.DialFrom(__instance, home);
				__result = true;
				return false;
			}
			DialMenu.Open(__instance);
			__result = true;
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		private static void HoverText_Postfix(TeleportWorld __instance, ref string __result)
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (!Active || !TryGetInfo(__instance, out var info) || (info.State == GateState.Linked && !GateClient.Dialable(info.State)))
			{
				return;
			}
			int num = __result.LastIndexOf('\n');
			if (num >= 0)
			{
				string text = Localization.instance.Localize("$KEY_Use");
				string text2 = __result.Substring(0, num);
				string text3 = __instance.GetText();
				if (!string.IsNullOrEmpty(text3) && text3.StartsWith("~sg1:") && !string.IsNullOrEmpty(info.Name))
				{
					text2 = text2.Replace(text3, info.Name);
				}
				text2 += ((info.State == GateState.Dialing) ? ("\n[<color=yellow><b>" + text + "</b></color>] Gate options\n[<color=yellow><b>Shift+" + text + "</b></color>] Hang up") : ("\n[<color=yellow><b>" + text + "</b></color>] Dial a gate"));
				if (GateClient.Dialable(info.State) && GateClient.TryGetHome(out var home) && GateClient.Dialable(home.State) && home.Id != info.Id)
				{
					text2 = text2 + "\n[<color=yellow><b>Shift+" + text + "</b></color>] Dial home (" + DialMenu.DisplayName(home) + ")";
				}
				__result = text2;
			}
		}
	}
	internal static class DialMap
	{
		private static readonly Dictionary<string, PinData> Pins = new Dictionary<string, PinData>();

		private static Minimap _forMap;

		private static bool _dirty = true;

		private static bool _subscribed;

		private static Sprite _icon;

		private static TeleportWorld _pickFrom;

		private static bool _pickSawMap;

		private static GUIStyle _hint;

		public static bool Picking => (Object)(object)_pickFrom != (Object)null;

		public static void BeginPick(TeleportWorld from)
		{
			if (!((Object)(object)from == (Object)null) && !((Object)(object)Minimap.instance == (Object)null))
			{
				_pickFrom = from;
				_pickSawMap = false;
				Minimap.instance.SetMapMode((MapMode)2);
			}
		}

		private static void UpdatePick()
		{
			//IL_0023: 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)
			if (!((Object)(object)_pickFrom == (Object)null))
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_pickFrom).transform.position) > 20f)
				{
					_pickFrom = null;
				}
				else if (Minimap.IsOpen())
				{
					_pickSawMap = true;
				}
				else if (_pickSawMap)
				{
					_pickFrom = null;
				}
			}
		}

		public static void DrawHint()
		{
			//IL_007b: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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)
			//IL_005a: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_pickFrom == (Object)null || !Minimap.IsOpen())
			{
				return;
			}
			float num = Mathf.Clamp((float)Screen.height / 1080f, 0.8f, 2.5f);
			if (_hint == null)
			{
				_hint = new GUIStyle(GUI.skin.box)
				{
					alignment = (TextAnchor)4,
					fontStyle = (FontStyle)1
				};
			}
			_hint.fontSize = Mathf.RoundToInt(22f * num);
			string text = "this gate";
			ZDOID val = GateRegistry.IdOf(_pickFrom);
			foreach (GateInfo gate in GateClient.Gates)
			{
				if (gate.Id == val && !string.IsNullOrWhiteSpace(gate.Name))
				{
					text = gate.Name;
				}
			}
			float num2 = 640f * num;
			float num3 = 46f * num;
			GUI.Box(new Rect(((float)Screen.width - num2) / 2f, 14f * num, num2, num3), "Click a gate to dial it from " + text + "   (Esc to cancel)", _hint);
		}

		private static Sprite GateIcon()
		{
			//IL_0027: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_icon != (Object)null)
			{
				return _icon;
			}
			Pixels pixels = MapIcon.Draw();
			Texture2D val = new Texture2D(pixels.Width, pixels.Height, (TextureFormat)4, false)
			{
				name = "SG1MapIcon"
			};
			val.SetPixelData<byte>(pixels.Rgba, 0, 0);
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			val.Apply(false, false);
			((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
			_icon = Sprite.Create(val, new Rect(0f, 0f, (float)pixels.Width, (float)pixels.Height), new Vector2(0.5f, 0.5f), 100f);
			Sprite icon = _icon;
			((Object)icon).hideFlags = (HideFlags)(((Object)icon).hideFlags | 0x20);
			return _icon;
		}

		public static void Tick()
		{
			if (!_subscribed)
			{
				_subscribed = true;
				GateClient.GatesChanged += delegate
				{
					_dirty = true;
				};
			}
			UpdatePick();
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance != (Object)(object)_forMap)
			{
				Pins.Clear();
				_forMap = instance;
				_dirty = true;
			}
			if (!((Object)(object)instance == (Object)null) && _dirty)
			{
				_dirty = false;
				Rebuild(instance);
			}
		}

		private static void Rebuild(Minimap map)
		{
			//IL_003e: 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_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			bool num = PortalHeimSG1Plugin.DialingEnabled.Value && PortalHeimSG1Plugin.GatePins.Value && GateClient.ServerHasMod;
			Dictionary<string, GateInfo> dictionary = new Dictionary<string, GateInfo>();
			if (num)
			{
				foreach (GateInfo gate in GateClient.Gates)
				{
					if (GateClient.IsVisible(gate.Id))
					{
						dictionary[GateClient.Key(gate.Id)] = gate;
					}
				}
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, PinData> pin in Pins)
			{
				if (!dictionary.ContainsKey(pin.Key))
				{
					list.Add(pin.Key);
				}
			}
			foreach (string item in list)
			{
				map.RemovePin(Pins[item]);
				Pins.Remove(item);
			}
			foreach (KeyValuePair<string, GateInfo> item2 in dictionary)
			{
				string text = DialMenu.DisplayName(item2.Value);
				if (Pins.TryGetValue(item2.Key, out var value))
				{
					value.m_name = text;
					value.m_pos = item2.Value.Position;
					if (PortalHeimSG1Plugin.GateIconOnMap.Value)
					{
						value.m_icon = GateIcon();
					}
				}
				else
				{
					PinData val = map.AddPin(item2.Value.Position, PortalHeimSG1Plugin.PinIcon.Value, text, false, false, 0L, default(PlatformUserID));
					if (PortalHeimSG1Plugin.GateIconOnMap.Value)
					{
						val.m_icon = GateIcon();
					}
					Pins[item2.Key] = val;
				}
			}
			map.m_pinUpdateRequired = true;
		}

		public static bool TryDialFromClick(Minimap map)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			if (!PortalHeimSG1Plugin.DialingEnabled.Value || !GateClient.ServerHasMod)
			{
				return false;
			}
			bool flag = (Object)(object)_pickFrom != (Object)null;
			if (!flag && !Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303))
			{
				return false;
			}
			PinData closestPin = map.GetClosestPin(map.ScreenToWorldPoint(ZInput.pointerPosition), map.PinInteractRadius, true);
			if (closestPin == null)
			{
				return false;
			}
			string text = null;
			foreach (KeyValuePair<string, PinData> pin in Pins)
			{
				if (pin.Value == closestPin)
				{
					text = pin.Key;
				}
			}
			if (text == null)
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return true;
			}
			GateInfo target = default(GateInfo);
			bool flag2 = false;
			foreach (GateInfo gate in GateClient.Gates)
			{
				if (GateClient.Key(gate.Id) == text)
				{
					target = gate;
					flag2 = true;
				}
			}
			TeleportWorld val = (flag ? _pickFrom : GateRegistry.Nearest(((Component)localPlayer).transform.position, 8f));
			if (!flag2)
			{
				return true;
			}
			if ((Object)(object)val == (Object)null)
			{
				((Character)localPlayer).Message((MessageType)2, "Stand at a gate to dial from the map.", 0, (Sprite)null, false);
				return true;
			}
			DialMenu.DialFrom(val, target);
			if (flag)
			{
				_pickFrom = null;
				map.SetMapMode((MapMode)0);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
	internal static class MapClickPatch
	{
		private static bool Prefix(Minimap __instance)
		{
			return !DialMap.TryDialFromClick(__instance);
		}
	}
	internal static class GateClient
	{
		private const string SeenKey = "PortalHeimSG1.Seen";

		private const string HomeKey = "PortalHeimSG1.Home";

		private const float VisitRange = 30f;

		public static bool ServerHasMod;

		public static string ServerVersion = "";

		public static float HelloSentAt = -1f;

		private static Player _forPlayer;

		private static readonly HashSet<string> Seen = new HashSet<string>();

		private static string _home = "";

		private static float _nextVisitCheck;

		private static float _nextHello;

		private static bool _gaveUpLogged;

		public static List<GateInfo> Gates { get; private set; } = new List<GateInfo>();

		public static event Action GatesChanged;

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

		public static bool TryParse(string text, out ZDOID id)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			id = ZDOID.None;
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			int num = text.IndexOf(':');
			if (num <= 0)
			{
				return false;
			}
			if (!long.TryParse(text.Substring(0, num), out var result) || !uint.TryParse(text.Substring(num + 1), out var result2))
			{
				return false;
			}
			id = new ZDOID(result, result2);
			return true;
		}

		public static void SetGates(List<GateInfo> gates)
		{
			Gates = gates;
			GateClient.GatesChanged?.Invoke();
		}

		public static void Tick()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				_forPlayer = null;
				ServerHasMod = false;
				HelloSentAt = -1f;
				_gaveUpLogged = false;
				return;
			}
			if ((Object)(object)_forPlayer != (Object)(object)localPlayer)
			{
				LoadFor(localPlayer);
			}
			if (!PortalHeimSG1Plugin.DialingEnabled.Value && !PortalHeimSG1Plugin.CartsFollow.Value)
			{
				return;
			}
			if (!ServerHasMod && Time.time >= _nextHello)
			{
				_nextHello = Time.time + 5f;
				if (HelloSentAt < 0f || Time.time - HelloSentAt < 40f)
				{
					GateNet.SendHello();
				}
				else if (!_gaveUpLogged)
				{
					_gaveUpLogged = true;
					PortalHeimSG1Plugin.Log.LogInfo((object)"The server didn't answer: it doesn't have PortalHeim SG1, so dialing and gate pins are off here.");
				}
			}
			if (Time.time >= _nextVisitCheck)
			{
				_nextVisitCheck = Time.time + 1f;
				NoteNearbyGates(localPlayer);
			}
		}

		private static void LoadFor(Player player)
		{
			_forPlayer = player;
			Seen.Clear();
			player.m_customData.TryGetValue("PortalHeimSG1.Seen", out var value);
			if (!string.IsNullOrEmpty(value))
			{
				string[] array = value.Split(';');
				foreach (string text in array)
				{
					if (text.Length > 0)
					{
						Seen.Add(text);
					}
				}
			}
			player.m_customData.TryGetValue("PortalHeimSG1.Home", out var value2);
			_home = value2 ?? "";
			ServerHasMod = false;
			HelloSentAt = -1f;
			_nextHello = 0f;
			_gaveUpLogged = false;
		}

		private static void NoteNearbyGates(Player player)
		{
			//IL_003b: 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)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			foreach (TeleportWorld item in GateRegistry.Loaded())
			{
				if (!((Object)(object)item.m_nview == (Object)null) && item.m_nview.IsValid())
				{
					bool num = Vector3.Distance(((Component)item).transform.position, ((Component)player).transform.position) <= 30f;
					bool flag2 = false;
					Piece component = ((Component)item).GetComponent<Piece>();
					if ((Object)(object)component != (Object)null)
					{
						flag2 = component.GetCreator() == player.GetPlayerID();
					}
					if (num || flag2)
					{
						flag |= Seen.Add(Key(item.m_nview.GetZDO().m_uid));
					}
				}
			}
			if (flag)
			{
				Save(player);
			}
		}

		private static void Save(Player player)
		{
			player.m_customData["PortalHeimSG1.Seen"] = string.Join(";", Seen);
			GateClient.GatesChanged?.Invoke();
		}

		public static bool IsVisited(ZDOID id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Seen.Contains(Key(id));
		}

		public static bool IsVisible(ZDOID id)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (PortalHeimSG1Plugin.OnlyVisited.Value)
			{
				return IsVisited(id);
			}
			return true;
		}

		public static bool Dialable(GateState state)
		{
			return state switch
			{
				GateState.Linked => PortalHeimSG1Plugin.AllowDialingLinkedGates.Value, 
				GateState.Idle => true, 
				_ => false, 
			};
		}

		public static bool IsHome(ZDOID id)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (_home.Length > 0)
			{
				return _home == Key(id);
			}
			return false;
		}

		public static bool TryGetHome(out GateInfo home)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			foreach (GateInfo gate in Gates)
			{
				if (IsHome(gate.Id))
				{
					home = gate;
					return true;
				}
			}
			home = default(GateInfo);
			return false;
		}

		public static void SetHome(ZDOID id, bool on)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				_home = (on ? Key(id) : "");
				localPlayer.m_customData["PortalHeimSG1.Home"] = _home;
				GateClient.GatesChanged?.Invoke();
			}
		}
	}
	internal static class GateRegistry
	{
		private static readonly List<TeleportWorld> All = new List<TeleportWorld>();

		public static void Add(TeleportWorld portal)
		{
			if ((Object)(object)portal != (Object)null && !All.Contains(portal))
			{
				All.Add(portal);
			}
		}

		public static List<TeleportWorld> Loaded()
		{
			All.RemoveAll((TeleportWorld p) => (Object)(object)p == (Object)null);
			return All;
		}

		public static ZDOID IdOf(TeleportWorld portal)
		{
			//IL_0024: 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 (!((Object)(object)portal != (Object)null) || !((Object)(object)portal.m_nview != (Object)null) || !portal.m_nview.IsValid())
			{
				return ZDOID.None;
			}
			return portal.m_nview.GetZDO().m_uid;
		}

		public static TeleportWorld Nearest(Vector3 from, float range)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			TeleportWorld result = null;
			float num = range;
			foreach (TeleportWorld item in Loaded())
			{
				if (!((Object)(object)item.m_nview == (Object)null) && item.m_nview.IsValid())
				{
					float num2 = Vector3.Distance(((Component)item).transform.position, from);
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}
	}
	internal static class GateNet
	{
		private const string Hello = "SG1_Hello";

		private const string HelloAck = "SG1_HelloAck";

		private const string ListRequest = "SG1_ListRequest";

		private const string Gates = "SG1_Gates";

		private const string DialRpc = "SG1_Dial";

		private const string HangUpRpc = "SG1_HangUp";

		private const string Result = "SG1_Result";

		private const string MoveCart = "SG1_MoveCart";

		private static ZRoutedRpc _registeredOn;

		public static void Register()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null && instance != _registeredOn)
			{
				_registeredOn = instance;
				instance.Register<string>("SG1_Hello", (Action<long, string>)RpcHello);
				instance.Register<string>("SG1_HelloAck", (Action<long, string>)RpcHelloAck);
				instance.Register("SG1_ListRequest", (Action<long>)RpcListRequest);
				instance.Register<ZPackage>("SG1_Gates", (Action<long, ZPackage>)RpcGates);
				instance.Register<ZDOID, ZDOID>("SG1_Dial", (Action<long, ZDOID, ZDOID>)RpcDial);
				instance.Register<ZDOID>("SG1_HangUp", (Action<long, ZDOID>)RpcHangUp);
				instance.Register<string>("SG1_Result", (Action<long, string>)RpcResult);
				instance.Register<ZDOID, Vector3, Quaternion>("SG1_MoveCart", (Action<long, ZDOID, Vector3, Quaternion>)RpcMoveCart);
			}
		}

		public static void SendHello()
		{
			if (ZRoutedRpc.instance != null)
			{
				GateClient.HelloSentAt = Time.time;
				ZRoutedRpc.instance.InvokeRoutedRPC("SG1_Hello", new object[1] { "0.5.13" });
			}
		}

		public static void RequestGates()
		{
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("SG1_ListRequest", Array.Empty<object>());
			}
		}

		public static void RequestDial(ZDOID from, ZDOID to)
		{
			//IL_0019: 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)
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("SG1_Dial", new object[2] { from, to });
			}
		}

		public static void RequestHangUp(ZDOID gate)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("SG1_HangUp", new object[1] { gate });
			}
		}

		public static void RequestMoveCart(ZDOID cart, Vector3 position, Quaternion rotation)
		{
			//IL_0019: 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)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("SG1_MoveCart", new object[3] { cart, position, rotation });
			}
		}

		private static void RpcMoveCart(long sender, ZDOID cart, Vector3 position, Quaternion rotation)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (GateServer.IsServer)
			{
				CartFollow.ServerMove(sender, cart, position, rotation);
			}
		}

		private static void RpcHello(long sender, string version)
		{
			if (GateServer.IsServer)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "SG1_HelloAck", new object[1] { "0.5.13" });
				SendGates(sender);
			}
		}

		private static void RpcListRequest(long sender)
		{
			if (GateServer.IsServer)
			{
				SendGates(sender);
			}
		}

		private static void RpcDial(long sender, ZDOID from, ZDOID to)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (GateServer.IsServer)
			{
				string text = GateServer.TryDial(sender, from, to);
				if (text != null)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(sender, "SG1_Result", new object[1] { text });
				}
			}
		}

		private static void RpcHangUp(long sender, ZDOID gate)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (GateServer.IsServer)
			{
				string text = GateServer.TryHangUp(gate);
				if (text != null)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(sender, "SG1_Result", new object[1] { text });
				}
			}
		}

		private static void SendGates(long target)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(target, "SG1_Gates", new object[1] { Pack(GateServer.Snapshot()) });
		}

		public static void BroadcastGates()
		{
			if (ZRoutedRpc.instance != null && GateServer.IsServer)
			{
				SendGates(0L);
			}
		}

		private static ZPackage Pack(List<GateInfo> gates)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0025: 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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(gates.Count);
			foreach (GateInfo gate in gates)
			{
				val.Write(gate.Id);
				val.Write(gate.Name ?? "");
				val.Write(gate.Position);
				val.Write((int)gate.State);
				val.Write(gate.Partner);
			}
			return val;
		}

		private static void RpcHelloAck(long sender, string version)
		{
			GateClient.ServerHasMod = true;
			GateClient.ServerVersion = version;
			PortalHeimSG1Plugin.Log.LogInfo((object)("The server has PortalHeim SG1 " + version + ": dialing is on."));
		}

		private static void RpcGates(long sender, ZPackage pkg)
		{
			//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_0036: 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_0050: 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)
			try
			{
				List<GateInfo> list = new List<GateInfo>();
				int num = pkg.ReadInt();
				for (int i = 0; i < num; i++)
				{
					GateInfo item = new GateInfo
					{
						Id = pkg.ReadZDOID(),
						Name = pkg.ReadString(),
						Position = pkg.ReadVector3(),
						State = (GateState)pkg.ReadInt(),
						Partner = pkg.ReadZDOID()
					};
					list.Add(item);
				}
				GateClient.SetGates(list);
			}
			catch (Exception arg)
			{
				PortalHeimSG1Plugin.Log.LogError((object)$"Couldn't read the gate list from the server. {arg}");
			}
		}

		private static void RpcResult(long sender, string message)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null && !string.IsNullOrEmpty(message))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	internal static class GameStartPatch
	{
		private static void Postfix()
		{
			GateNet.Register();
		}
	}
	internal enum GateState
	{
		Idle,
		Linked,
		Dialing
	}
	internal static class GateServer
	{
		private class Dial
		{
			public ZDOID A;

			public ZDOID B;

			public List<ZDOID> Parked = new List<ZDOID>();

			public float Start;

			public float LastNear;

			public bool Has(ZDOID id)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: 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)
				if (!(A == id) && !(B == id))
				{
					return Parked.Contains(id);
				}
				return true;
			}
		}

		private static readonly int KeyOriginalName = StringExtensionMethods.GetStableHashCode("sg1_orig");

		private static readonly int KeyOldPartner = StringExtensionMethods.GetStableHashCode("sg1_partner");

		private static readonly List<Dial> Dials = new List<Dial>();

		private static float _nextTick;

		private static float _serverUpSince = -1f;

		private static bool _repaired;

		private static int _counter;

		private static int _lastSignature;

		private static bool _sentList;

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

		public static void Tick()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			if (!IsServer || ZDOMan.instance == null || (Object)(object)Game.instance == (Object)null)
			{
				_serverUpSince = -1f;
				_repaired = false;
				_sentList = false;
				Dials.Clear();
			}
			else
			{
				if (Time.time < _nextTick)
				{
					return;
				}
				_nextTick = Time.time + 1f;
				if (_serverUpSince < 0f)
				{
					_serverUpSince = Time.time;
				}
				if (Time.time - _serverUpSince < 5f)
				{
					return;
				}
				if (!_repaired)
				{
					_repaired = true;
					RepairLeftovers();
				}
				int num = Signature(Snapshot());
				if (!_sentList || num != _lastSignature)
				{
					_sentList = true;
					_lastSignature = num;
					GateNet.BroadcastGates();
				}
				if (Dials.Count == 0)
				{
					return;
				}
				List<Vector3> positions = PlayerPositions();
				bool flag = false;
				for (int num2 = Dials.Count - 1; num2 >= 0; num2--)
				{
					Dial dial = Dials[num2];
					ZDO zDO = ZDOMan.instance.GetZDO(dial.A);
					ZDO zDO2 = ZDOMan.instance.GetZDO(dial.B);
					int num3;
					if (zDO != null)
					{
						num3 = ((zDO2 == null) ? 1 : 0);
						if (num3 == 0 && AnyoneNear(positions, zDO.GetPosition(), zDO2.GetPosition()))
						{
							dial.LastNear = Time.time;
						}
					}
					else
					{
						num3 = 1;
					}
					bool flag2 = Time.time - dial.LastNear > PortalHeimSG1Plugin.DialIdleSeconds.Value;
					bool flag3 = Time.time - dial.Start > PortalHeimSG1Plugin.DialMaxSeconds.Value;
					if (((uint)num3 | (flag2 ? 1u : 0u) | (flag3 ? 1u : 0u)) != 0)
					{
						Close(dial);
						Dials.RemoveAt(num2);
						flag = true;
					}
				}
				if (flag)
				{
					Game.instance.ConnectPortals();
					GateNet.BroadcastGates();
				}
			}
		}

		private static void RepairLeftovers()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			List<ZDO> list = new List<ZDO>();
			foreach (ZDO portal in ZDOMan.instance.GetPortalList())
			{
				if (HasStoredName(portal) && !IsInDial(portal.m_uid))
				{
					list.Add(portal);
				}
			}
			int count = list.Count;
			RestoreAll(list);
			if (count > 0)
			{
				PortalHeimSG1Plugin.Log.LogInfo((object)$"Put the names back on {count} gate(s) left mid-dial.");
				Game.instance.ConnectPortals();
			}
		}

		private static bool IsInDial(ZDOID id)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return Dials.Exists((Dial d) => d.Has(id));
		}

		private static bool HasStoredName(ZDO zdo)
		{
			return zdo.GetString(KeyOriginalName, "").Length > 0;
		}

		public static string NameOf(ZDO zdo)
		{
			string text = zdo.GetString(KeyOriginalName, "");
			if (text.Length <= 0)
			{
				return zdo.GetString(ZDOVars.s_tag, "");
			}
			return text.Substring(2);
		}

		public static GateState StateOf(ZDO zdo)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (HasStoredName(zdo))
			{
				return GateState.Dialing;
			}
			if (!(zdo.GetConnectionZDOID((ConnectionType)1) == ZDOID.None))
			{
				return GateState.Linked;
			}
			return GateState.Idle;
		}

		public static ZDOID PartnerOf(ZDO zdo)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return zdo.GetConnectionZDOID((ConnectionType)1);
		}

		public static string TryDial(long sender, ZDOID srcId, ZDOID dstId)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			//IL_0032: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_0100: 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_0107: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			if (!PortalHeimSG1Plugin.DialingEnabled.Value)
			{
				return "Dialing is switched off on this server.";
			}
			if (srcId == dstId)
			{
				return "That is this gate.";
			}
			ZDO zDO = ZDOMan.instance.GetZDO(srcId);
			ZDO zDO2 = ZDOMan.instance.GetZDO(dstId);
			if (zDO == null || zDO2 == null || !IsPortal(zDO) || !IsPortal(zDO2))
			{
				return "That gate is gone.";
			}
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)32))
			{
				return "Portals are blocked in this world.";
			}
			if (TryGetPlayerPosition(sender, out var position))
			{
				float value = PortalHeimSG1Plugin.DialRange.Value;
				if (Vector3.Distance(position, zDO.GetPosition()) > value)
				{
					return "You are too far from the gate.";
				}
			}
			GateState gateState = StateOf(zDO);
			GateState gateState2 = StateOf(zDO2);
			bool value2 = PortalHeimSG1Plugin.AllowDialingLinkedGates.Value;
			if (gateState == GateState.Dialing)
			{
				return "This gate is already connected.";
			}
			if (gateState2 == GateState.Dialing)
			{
				return "That gate is busy.";
			}
			if (!value2 && gateState == GateState.Linked)
			{
				return "This gate is already connected.";
			}
			if (!value2 && gateState2 == GateState.Linked)
			{
				return "That gate is busy.";
			}
			ZDOID val = ((gateState == GateState.Linked) ? PartnerOf(zDO) : ZDOID.None);
			ZDOID val2 = ((gateState2 == GateState.Linked) ? PartnerOf(zDO2) : ZDOID.None);
			if (val == dstId || val2 == srcId)
			{
				return "These two gates are already connected.";
			}
			Dial dial = new Dial
			{
				A = srcId,
				B = dstId,
				Start = Time.time,
				LastNear = Time.time
			};
			string sessionTag = "~sg1:" + ++_counter + ":" + Random.Range(1000, 9999);
			Begin(zDO, sessionTag, val);
			Begin(zDO2, sessionTag, val2);
			Park(dial, val, srcId);
			Park(dial, val2, dstId);
			zDO.SetConnection((ConnectionType)1, zDO2.m_uid);
			zDO2.SetConnection((ConnectionType)1, zDO.m_uid);
			ZDOMan.instance.ForceSendZDO(zDO.m_uid);
			ZDOMan.instance.ForceSendZDO(zDO2.m_uid);
			Dials.Add(dial);
			PortalHeimSG1Plugin.Log.LogInfo((object)("Dialed '" + NameOf(zDO) + "' -> '" + NameOf(zDO2) + "'."));
			GateNet.BroadcastGates();
			return null;
		}

		public static string TryHangUp(ZDOID gateId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Dial dial = Dials.Find((Dial d) => d.Has(gateId));
			if (dial == null)
			{
				return "This gate isn't dialed.";
			}
			Close(dial);
			Dials.Remove(dial);
			Game.instance.ConnectPortals();
			GateNet.BroadcastGates();
			return null;
		}

		private static void Begin(ZDO zdo, string sessionTag, ZDOID oldPartner)
		{
			//IL_0036: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			zdo.SetOwner(ZDOMan.GetSessionID());
			zdo.Set(KeyOriginalName, "o:" + zdo.GetString(ZDOVars.s_tag, ""));
			zdo.Set(KeyOldPartner, (oldPartner == ZDOID.None) ? "" : GateClient.Key(oldPartner));
			zdo.Set(ZDOVars.s_tag, sessionTag);
		}

		private static void Park(Dial dial, ZDOID partnerId, ZDOID pairedWith)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (!(partnerId == ZDOID.None))
			{
				ZDO zDO = ZDOMan.instance.GetZDO(partnerId);
				if (zDO != null && StateOf(zDO) != GateState.Dialing)
				{
					int num = ++_counter;
					Begin(zDO, "~sg1park:" + num + ":" + Random.Range(1000, 9999), pairedWith);
					zDO.SetConnection((ConnectionType)1, ZDOID.None);
					ZDOMan.instance.ForceSendZDO(zDO.m_uid);
					dial.Parked.Add(partnerId);
				}
			}
		}

		private static void Close(Dial dial)
		{
			//IL_000c: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			List<ZDO> list = new List<ZDO>();
			ZDO zDO = ZDOMan.instance.GetZDO(dial.A);
			ZDO zDO2 = ZDOMan.instance.GetZDO(dial.B);
			if (zDO != null)
			{
				list.Add(zDO);
			}
			if (zDO2 != null)
			{
				list.Add(zDO2);
			}
			foreach (ZDOID item in dial.Parked)
			{
				ZDO zDO3 = ZDOMan.instance.GetZDO(item);
				if (zDO3 != null)
				{
					list.Add(zDO3);
				}
			}
			RestoreAll(list);
		}

		private static void RestoreAll(List<ZDO> gates)
		{
			//IL_0032: 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)
			List<KeyValuePair<ZDO, ZDOID>> list = new List<KeyValuePair<ZDO, ZDOID>>();
			foreach (ZDO gate in gates)
			{
				if (GateClient.TryParse(gate.GetString(KeyOldPartner, ""), out var id))
				{
					list.Add(new KeyValuePair<ZDO, ZDOID>(gate, id));
				}
			}
			foreach (ZDO gate2 in gates)
			{
				Restore(gate2);
			}
			foreach (KeyValuePair<ZDO, ZDOID> item in list)
			{
				Reconnect(item.Key, ZDOMan.instance.GetZDO(item.Value));
			}
		}

		private static void Restore(ZDO zdo)
		{
			//IL_0059: 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)
			string text = zdo.GetString(KeyOriginalName, "");
			if (text.Length != 0)
			{
				zdo.SetOwner(ZDOMan.GetSessionID());
				zdo.Set(ZDOVars.s_tag, text.Substring(2));
				zdo.Set(KeyOriginalName, "");
				zdo.Set(KeyOldPartner, "");
				zdo.SetConnection((ConnectionType)1, ZDOID.None);
				ZDOMan.instance.ForceSendZDO(zdo.m_uid);
			}
		}

		private static void Reconnect(ZDO a, ZDO b)
		{
			//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)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (a != null && b != null && !(a.GetString(ZDOVars.s_tag, "") != b.GetString(ZDOVars.s_tag, "")) && !(a.GetConnectionZDOID((ConnectionType)1) != ZDOID.None) && !(b.GetConnectionZDOID((ConnectionType)1) != ZDOID.None))
			{
				a.SetOwner(ZDOMan.GetSessionID());
				b.SetOwner(ZDOMan.GetSessionID());
				a.SetConnection((ConnectionType)1, b.m_uid);
				b.SetConnection((ConnectionType)1, a.m_uid);
				ZDOMan.instance.ForceSendZDO(a.m_uid);
				ZDOMan.instance.ForceSendZDO(b.m_uid);
			}
		}

		private static bool IsPortal(ZDO zdo)
		{
			foreach (ZDO portal in ZDOMan.instance.GetPortalList())
			{
				if (portal == zdo)
				{
					return true;
				}
			}
			return false;
		}

		public static List<GateInfo> Snapshot()
		{
			//IL_003c: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			List<GateInfo> list = new List<GateInfo>();
			if (!IsServer || ZDOMan.instance == null)
			{
				return list;
			}
			foreach (ZDO portal in ZDOMan.instance.GetPortalList())
			{
				list.Add(new GateInfo
				{
					Id = portal.m_uid,
					Name = NameOf(portal),
					Position = portal.GetPosition(),
					State = StateOf(portal),
					Partner = PartnerOf(portal)
				});
			}
			return list;
		}

		private unsafe static int Signature(List<GateInfo> gates)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			int num = gates.Count * 7919;
			foreach (GateInfo gate in gates)
			{
				int num2 = 17;
				int num3 = num2 * 31;
				ZDOID id = gate.Id;
				num2 = num3 + ((object)(*(ZDOID*)(&id))/*cast due to .constrained prefix*/).GetHashCode();
				num2 = num2 * 31 + (gate.Name ?? "").GetHashCode();
				num2 = (int)(num2 * 31 + gate.State);
				int num4 = num2 * 31;
				id = gate.Partner;
				num2 = num4 + ((object)(*(ZDOID*)(&id))/*cast due to .constrained prefix*/).GetHashCode();
				num2 = num2 * 31 + Mathf.RoundToInt(gate.Position.x) * 73 + Mathf.RoundToInt(gate.Position.z);
				num += num2;
			}
			return num;
		}

		private static List<Vector3> PlayerPositions()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				list.Add(peer.m_refPos);
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				list.Add(((Component)Player.m_localPlayer).transform.position);
			}
			return list;
		}

		internal static bool TryGetPlayerPosition(long sender, out Vector3 position)
		{
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			ZNetPeer peer = ZNet.instance.GetPeer(sender);
			if (peer != null)
			{
				position = peer.m_refPos;
				return true;
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				position = ((Component)Player.m_localPlayer).transform.position;
				return true;
			}
			position = Vector3.zero;
			return false;
		}

		private static bool AnyoneNear(List<Vector3> positions, Vector3 a, Vector3 b)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0026: 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)
			float value = PortalHeimSG1Plugin.DialKeepOpenRange.Value;
			foreach (Vector3 position in positions)
			{
				if (Vector3.Distance(position, a) <= value || Vector3.Distance(position, b) <= value)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal struct GateInfo
	{
		public ZDOID Id;

		public string Name;

		public Vector3 Position;

		public GateState State;

		public ZDOID Partner;
	}
	internal static class GateBuilder
	{
		private const float SlabHalfDepth = 0.395f;

		private const float SlabTop = 0.1f;

		private const float RampHalfWidth = 1.45f;

		private const float RampSlope = 0.32f;

		private static Mesh _ramp;

		private const int MaxBuildAttempts = 3;

		private static Mesh _outerRing;

		private static Mesh _innerRing;

		private static Mesh _chevrune;

		private static Mesh _waterDisc;

		private static Mesh[] _runes;

		private static readonly int[] RuneAt = new int[9] { 23, 7, 3, 20, 8, 18, 10, 19, 22 };

		private static Material _outerMaterial;

		private static Material _innerMaterial;

		private static bool _built;

		private static int _failures;

		private static int _attached;

		private static readonly string[] ExtraTextures = new string[8] { "_BumpMap", "_MetallicGlossMap", "_EmissiveTex", "_EmissionMap", "_OcclusionMap", "_ParallaxMap", "_DetailAlbedoMap", "_DetailNormalMap" };

		private static Vector3 GateCenter => new Vector3(0f, PortalHeimSG1Plugin.SinkRing.Value ? 1.16f : 1.5f, 0f);

		public static Material ChevruneOff { get; private set; }

		public static Material ChevruneOn { get; private set; }

		public static Material ChevruneDim { get; private set; }

		public static void Attach(TeleportWorld portal)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portal == (Object)null || (Object)(object)((Component)portal).GetComponentInChildren<GateRing>(true) != (Object)null)
			{
				return;
			}
			EnsureAssets(portal);
			if (!_built)
			{
				return;
			}
			Transform transform = new GameObject("SG1Gate").transform;
			transform.SetParent(((Component)portal).transform, false);
			transform.localPosition = GateCenter;
			Add(transform, "OuterRing", _outerRing, _outerMaterial);
			GameObject val = Add(transform, "InnerRing", _innerRing, _innerMaterial);
			if (PortalHeimSG1Plugin.Ramps.Value)
			{
				AddRamps(portal, transform);
			}
			List<ChevruneParts> list = new List<ChevruneParts>();
			float num = 1.56f;
			for (int i = 0; i < 9; i++)
			{
				float num2 = 90f + 360f * (float)i / 9f;
				Transform transform2 = new GameObject($"Chevrune{i}").transform;
				transform2.SetParent(transform, false);
				transform2.localPosition = Quaternion.Euler(0f, 0f, num2) * new Vector3(num, 0f, 0f);
				transform2.localRotation = Quaternion.Euler(0f, 0f, num2);
				MeshRenderer component = Add(transform2, "Arrow", _chevrune, ChevruneOff).GetComponent<MeshRenderer>();
				MeshRenderer component2 = Add(transform2, "Rune", _runes[i], ChevruneOff).GetComponent<MeshRenderer>();
				MeshRenderer[] array = (MeshRenderer[])(object)new MeshRenderer[2] { component, component2 };
				foreach (MeshRenderer obj in array)
				{
					((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)obj).receiveShadows = false;
				}
				((Renderer)component2).enabled = false;
				((Component)component2).transform.localScale = Vector3.zero;
				list.Add(new ChevruneParts
				{
					Arrow = component,
					Rune = component2
				});
			}
			int num3 = HideWoodenFrame(portal, transform);
			MeshRenderer val2 = null;
			if (PortalHeimSG1Plugin.Interior.Value == InteriorMode.Water && (Object)(object)WaterSurface.Material != (Object)null)
			{
				GameObject obj2 = Add(transform, "Water", _waterDisc, WaterSurface.Material);
				obj2.transform.localPosition = new Vector3(0f, 0f, 0f);
				val2 = obj2.GetComponent<MeshRenderer>();
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				((Renderer)val2).enabled = false;
			}
			ParticleSystemRenderer[] swirl = (ParticleSystemRenderer[])(((Object)(object)portal.m_target_found != (Object)null) ? ((Array)((Component)portal.m_target_found).GetComponentsInChildren<ParticleSystemRenderer>(true)) : ((Array)new ParticleSystemRenderer[0]));
			((Component)transform).gameObject.AddComponent<GateRing>().Setup(portal, val.transform, list.ToArray(), val2, swirl);
			_attached++;
			Diagnostics.Attached++;
			if (_attached <= 3)
			{
				PortalHeimSG1Plugin.Log.LogInfo((object)($"Gate #{_attached} attached to '{((Object)portal).name}': hid {num3} frame renderer(s), " + $"ring at {transform.position}, stone shader '{((Object)_outerMaterial.shader).name}', " + $"portal enabled={((Behaviour)portal).enabled}."));
			}
		}

		private static void AddRamps(TeleportWorld portal, Transform gateRoot)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			int layer = 0;
			Collider[] componentsInChildren = ((Component)portal).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!val.isTrigger && !((Component)val).transform.IsChildOf(gateRoot))
				{
					layer = ((Component)val).gameObject.layer;
					break;
				}
			}
			float[] array = ((!PortalHeimSG1Plugin.BackRamp.Value) ? new float[1] { 1f } : new float[2] { 1f, -1f });
			foreach (float num in array)
			{
				GameObject val2 = new GameObject((num > 0f) ? "RampFront" : "RampBack");
				val2.transform.SetParent(gateRoot, false);
				val2.transform.localPosition = -gateRoot.localPosition;
				val2.transform.localRotation = Quaternion.Euler(0f, (num > 0f) ? 0f : 180f, 0f);
				val2.layer = layer;
				val2.AddComponent<MeshFilter>().sharedMesh = _ramp;
				MeshRenderer obj = val2.AddComponent<MeshRenderer>();
				((Renderer)obj).sharedMaterial = _outerMaterial;
				((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
				MeshCollider obj2 = val2.AddComponent<MeshCollider>();
				obj2.sharedMesh = _ramp;
				obj2.convex = true;
			}
		}

		private static GameObject Add(Transform parent, string name, Mesh mesh, Material material)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			//IL_002c: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material;
			return val;
		}

		private static int HideWoodenFrame(TeleportWorld portal, Transform ourGate)
		{
			int num = 0;
			LODGroup[] componentsInChildren = ((Component)portal).GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			Renderer[] componentsInChildren2 = ((Component)portal).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren2)
			{
				if (!(val is ParticleSystemRenderer) && !(val is TrailRenderer) && !(val is LineRenderer) && !((Component)val).transform.IsChildOf(ourGate) && (!IsEffectOrDebris(((Component)val).transform, ((Component)portal).transform) || !((Object)(object)val != (Object)(object)portal.m_model)))
				{
					val.forceRenderingOff = true;
					num++;
				}
			}
			if ((Object)(object)portal.m_model != (Object)null && !((Renderer)portal.m_model).forceRenderingOff)
			{
				((Renderer)portal.m_model).forceRenderingOff = true;
				num++;
			}
			return num;
		}

		private static bool IsEffectOrDebris(Transform t, Transform portalRoot)
		{
			while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)portalRoot)
			{
				string text = ((Object)t).name.ToLowerInvariant();
				if (text.Contains("destruction") || text.Contains("target_found") || text.Contains("particle"))
				{
					return true;
				}
				t = t.parent;
			}
			return false;
		}

		private static void EnsureAssets(TeleportWorld portal)
		{
			//IL_0190: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			if (_built || _failures >= 3)
			{
				return;
			}
			string text = "start";
			try
			{
				text = "meshes";
				_outerRing = GateMeshes.Annulus("SG1OuterRing", 1.42f, 1.7f, 0.16f);
				_innerRing = GateMeshes.Annulus("SG1InnerRing", 1.14f, 1.42f, 0.11f);
				_chevrune = GateMeshes.Chevrune();
				_runes = Array.ConvertAll(RuneAt, GateMeshes.Rune);
				float value = PortalHeimSG1Plugin.RampDepth.Value;
				float num = (0.1f + value) / 0.32f;
				_ramp = GateMeshes.Ramp(1.45f, 0.395f, 0.395f + num, 0.1f, 0f - value);
				_waterDisc = GateMeshes.Disc(1.17f, 64);
				text = "stone textures";
				Pixels canvas = Textures.OuterRing(1.7f, 1.42f, 1.7f);
				Pixels canvas2 = Textures.InnerRing(1.7f, 1.14f, 1.42f, 36);
				text = "stone materials";
				Material template = ((PortalHeimSG1Plugin.Shading.Value == ShadingMode.PortalShader && (Object)(object)portal.m_model != (Object)null) ? ((Renderer)portal.m_model).sharedMaterial : null);
				_outerMaterial = StoneMaterial(template, canvas, "SG1OuterStone");
				_innerMaterial = StoneMaterial(template, canvas2, "SG1InnerStone");
				text = "chevrune materials";
				Shader val = Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default") ?? _outerMaterial.shader;
				ChevruneOff = Flat(val, "SG1ChevruneOff", GateRing.Dark);
				ChevruneOn = Flat(val, "SG1ChevruneOn", PortalHeimSG1Plugin.ChevruneColor.Value);
				ChevruneDim = Flat(val, "SG1ChevruneDim", DimColor());
				PortalHeimSG1Plugin.ChevruneColor.SettingChanged += delegate
				{
					//IL_000a: 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)
					Tint(ChevruneOn, PortalHeimSG1Plugin.ChevruneColor.Value);
					Tint(ChevruneDim, DimColor());
				};
				PortalHeimSG1Plugin.DormantGlow.SettingChanged += delegate
				{
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					Tint(ChevruneDim, DimColor());
				};
				Object[] array = (Object[])(object)new Object[10]
				{
					(Object)_outerRing,
					(Object)_innerRing,
					(Object)_chevrune,
					(Object)_waterDisc,
					(Object)_ramp,
					(Object)_outerMaterial,
					(Object)_innerMaterial,
					(Object)ChevruneOff,
					(Object)ChevruneOn,
					(Object)ChevruneDim
				};
				foreach (Object val2 in array)
				{
					if (val2 != (Object)null)
					{
						val2.hideFlags = (HideFlags)(val2.hideFlags | 0x20);
					}
				}
				_built = true;
				PortalHeimSG1Plugin.Log.LogInfo((object)("Gate art built. Stone shader '" + ((Object)_outerMaterial.shader).name + "', chevrune shader '" + ((Object)val).name + "', " + $"shading mode {PortalHeimSG1Plugin.Shading.Value}."));
			}
			catch (Exception ex)
			{
				_failures++;
				_built = false;
				Diagnostics.RecordFailure(text, ex);
				PortalHeimSG1Plugin.Log.LogError((object)($"Couldn't build the gate art (failed at: {text}, attempt {_failures} of {3}); " + $"portals stay as they are for now. {ex}"));
			}
		}

		private static Color DimColor()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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)
			return Color.Lerp(GateRing.Dark, PortalHeimSG1Plugin.ChevruneColor.Value, Mathf.Clamp01(PortalHeimSG1Plugin.DormantGlow.Value));
		}

		private static Material Flat(Shader shader, string name, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0015: Expected O, but got Unknown
			Material val = new Material(shader)
			{
				name = name
			};
			Tint(val, color);
			return val;
		}

		private static void Tint(Material material, Color color)
		{
			//IL_000b: 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)
			if (!((Object)(object)material == (Object)null))
			{
				material.color = color;
				if (material.HasProperty("_EmissionColor"))
				{
					material.SetColor("_EmissionColor", color);
				}
			}
		}

		private static Material StoneMaterial(Material template, Pixels canvas, string name)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0052: 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)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_00b5: 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)
			Texture2D val = new Texture2D(canvas.Width, canvas.Height, (TextureFormat)4, true)
			{
				name = name + "Tex"
			};
			val.SetPixelData<byte>(canvas.Rgba, 0, 0);
			((Texture)val).filterMode = (FilterMode)2;
			((Texture)val).anisoLevel = 4;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			val.Apply(true, true);
			((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
			Material val2;
			if ((Object)(object)template != (Object)null)
			{
				val2 = new Material(template)
				{
					name = name
				};
				string[] extraTextures = ExtraTextures;
				foreach (string text in extraTextures)
				{
					if (val2.HasProperty(text))
					{
						val2.SetTexture(text, (Texture)null);
					}
				}
				if (val2.HasProperty("_EmissionColor"))
				{
					val2.SetColor("_EmissionColor", Color.black);
				}
				if (val2.HasProperty("_Color"))
				{
					val2.SetColor("_Color", Color.white);
				}
			}
			else
			{
				val2 = new Material(Shader.Find("Standard") ?? Shader.Find("Sprites/Default"))
				{
					name = name
				};
			}
			val2.mainTexture = (Texture)(object)val;
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", 0.12f);
			}
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", 0f);
			}
			return val2;
		}
	}
	internal static class GateMeshes
	{
		private sealed class Builder
		{
			private readonly List<Vector3> _vertices = new List<Vector3>();

			private readonly List<Vector3> _normals = new List<Vector3>();

			private readonly List<Vector2> _uvs = new List<Vector2>();

			private readonly List<int> _triangles = new List<int>();

			public void Quad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, Vector3 normal, Vector2 uvA, Vector2 uvB, Vector2 uvC, Vector2 uvD)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: 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_000e: 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)
				Quad(a, b, c, d, normal, normal, uvA, uvB, uvC, uvD);
			}

			public void Quad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, Vector3 normalStart, Vector3 normalEnd, Vector2 uvA, Vector2 uvB, Vector2 uvC, Vector2 uvD)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: 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_002b: 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_0034: 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_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)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: 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_0069: 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_0083: 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_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: 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_00a8: 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_00ac: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				int count = _vertices.Count;
				_vertices.AddRange((IEnumerable<Vector3>)(object)new Vector3[4] { a, b, c, d });
				_normals.AddRange((IEnumerable<Vector3>)(object)new Vector3[4] { normalStart, normalStart, normalEnd, normalEnd });
				_uvs.AddRange((IEnumerable<Vector2>)(object)new Vector2[4] { uvA, uvB, uvC, uvD });
				Vector3 val = normalStart + normalEnd;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				Tri(count, count + 1, count + 2, normalized);
				Tri(count, count + 2, count + 3, normalized);
			}

			private void Tri(int i0, int i1, int i2, Vector3 facing)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				if (Vector3.Dot(Vector3.Cross(_vertices[i1] - _vertices[i0], _vertices[i2] - _vertices[i0]), facing) < 0f)
				{
					int num = i1;
					i1 = i2;
					i2 = num;
				}
				_triangles.Add(i0);
				_triangles.Add(i1);
				_triangles.Add(i2);
			}

			public Mesh ToMesh(string name)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Expected O, but got Unknown
				Mesh val = new Mesh
				{
					name = name
				};
				val.SetVertices(_vertices);
				val.SetNormals(_normals);
				val.SetUVs(0, _uvs);
				val.SetTriangles(_triangles, 0);
				val.RecalculateBounds();
				val.RecalculateTangents();
				return val;
			}
		}

		public const float OuterRadius = 1.7f;

		public const float OuterRingIn = 1.42f;

		public const float InnerRingIn = 1.14f;

		public const float InnerRingOut = 1.42f;

		public const float OuterHalfDepth = 0.16f;

		public const float InnerHalfDepth = 0.11f;

		public const float ChevruneProtrusion = 0.05f;

		public const int ChevruneCount = 9;

		private const int Segments = 96;

		private const float RuneScale = 0.125f;

		private const float RuneStroke = 0.034f;

		private const float RunePlate = 0.035f;

		public static Mesh Annulus(string name, float radiusIn, float radiusOut, float halfDepth)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00b9: 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_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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result t