Decompiled source of RemoteChunk v1.0.2

RemoteChunk.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 RemoteChunk
{
	internal enum ZoneState
	{
		Sleeping,
		Waking,
		NeedsVisit,
		Loading,
		NearYou,
		TooClose,
		NearRunning,
		PlayerThere,
		Simulating,
		Starting,
		NotClaiming
	}
	internal struct ZoneStatus
	{
		public Vector2s Zone;

		public string Name;

		public Vector3 Centre;

		public float Distance;

		public bool TerrainLoaded;

		public bool Spawns;

		public bool Sleeping;

		public int EnemiesSpawned;

		public int AnimalsBorn;

		public List<Herd> Animals;

		public int Cached;

		public int Instantiated;

		public int Mine;

		public int Players;

		public int Unowned;

		public ZoneState State;
	}
	internal static class AnchorManager
	{
		private struct Probe
		{
			public ZDOID Id;

			public long Owner;

			public float Started;
		}

		private enum RunKind
		{
			None,
			Simulated,
			Spawner
		}

		private const float ClaimInterval = 2f;

		internal const float ZoneSize = 64f;

		private static readonly Func<ZoneSystem, Vector2s, bool> PokeLocalZone = AccessTools.MethodDelegate<Func<ZoneSystem, Vector2s, bool>>(AccessTools.Method(typeof(ZoneSystem), "PokeLocalZone", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Action<ZDOMan, Vector2s, List<ZDO>, HashSet<SectorIndex>> FindObjects = AccessTools.MethodDelegate<Action<ZDOMan, Vector2s, List<ZDO>, HashSet<SectorIndex>>>(AccessTools.Method(typeof(ZDOMan), "FindObjects", (Type[])null, (Type[])null), (object)null, true);

		private static readonly List<Vector2s> NoAnchors = new List<Vector2s>();

		private static readonly Dictionary<long, List<Vector2s>> Anchors = new Dictionary<long, List<Vector2s>>();

		private static readonly Dictionary<long, HashSet<Vector2s>> SpawnZones = new Dictionary<long, HashSet<Vector2s>>();

		private static readonly Dictionary<long, Dictionary<Vector2s, string>> Names = new Dictionary<long, Dictionary<Vector2s, string>>();

		private static readonly Dictionary<long, HashSet<Vector2s>> SleepZones = new Dictionary<long, HashSet<Vector2s>>();

		internal const int MaxNameLength = 32;

		private static readonly HashSet<long> ConnectedOwners = new HashSet<long>();

		private static readonly List<ZDO> TempZdos = new List<ZDO>();

		private static readonly HashSet<SectorIndex> TempVisited = new HashSet<SectorIndex>();

		private static readonly HashSet<Vector2s> TempCovered = new HashSet<Vector2s>();

		private static readonly List<Vector2s> TempSingle = new List<Vector2s>();

		private static readonly HashSet<Vector2s> TakenOver = new HashSet<Vector2s>();

		private static readonly Dictionary<Vector2s, HashSet<ZDOID>> LastClaims = new Dictionary<Vector2s, HashSet<ZDOID>>();

		private static readonly HashSet<Vector2s> Flipping = new HashSet<Vector2s>();

		private static Vector2s _flipPlayerZone;

		private static float _claimTimer;

		private const float FirstProbeDelay = 10f;

		private const float ProbeInterval = 30f;

		private const float ProbeSeconds = 6f;

		private static readonly Dictionary<Vector2s, Probe> Probes = new Dictionary<Vector2s, Probe>();

		private static readonly Dictionary<Vector2s, float> NextProbe = new Dictionary<Vector2s, float>();

		private const float NearClaimInterval = 0.2f;

		private static float _nearClaimTimer;

		private static readonly Dictionary<int, RunKind> RunPrefabs = new Dictionary<int, RunKind>();

		private const float SummaryInterval = 60f;

		private static float _summaryTimer;

		private static readonly Dictionary<Vector2s, int> SummarySpawned = new Dictionary<Vector2s, int>();

		private static readonly Dictionary<Vector2s, int> SummaryBorn = new Dictionary<Vector2s, int>();

		internal static int Version { get; private set; }

		internal static bool InWorld
		{
			get
			{
				long worldUid;
				return TryGetWorld(out worldUid);
			}
		}

		internal static void Load(string saved)
		{
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
			Anchors.Clear();
			SpawnZones.Clear();
			Names.Clear();
			SleepZones.Clear();
			string[] array = saved.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			Vector2s val = default(Vector2s);
			foreach (string text in array)
			{
				int num = text.IndexOf(':');
				if (num < 0 || !long.TryParse(text.Substring(0, num), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
				{
					Plugin.Log.LogWarning((object)("Ignoring malformed anchor entry '" + text + "'"));
					continue;
				}
				List<Vector2s> list = new List<Vector2s>();
				HashSet<Vector2s> hashSet = new HashSet<Vector2s>();
				Dictionary<Vector2s, string> dictionary = new Dictionary<Vector2s, string>();
				HashSet<Vector2s> hashSet2 = new HashSet<Vector2s>();
				string[] array2 = text.Substring(num + 1).Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries);
				foreach (string text2 in array2)
				{
					string[] array3 = text2.Split(new char[1] { ',' });
					if (array3.Length < 2 || !int.TryParse(array3[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) || !int.TryParse(array3[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3))
					{
						Plugin.Log.LogWarning((object)("Ignoring malformed anchor zone '" + text2 + "'"));
						continue;
					}
					((Vector2s)(ref val))..ctor(result2, result3);
					if (!list.Contains(val))
					{
						list.Add(val);
					}
					for (int k = 2; k < array3.Length; k++)
					{
						if (array3[k] == "s")
						{
							hashSet.Add(val);
						}
						else if (array3[k] == "z")
						{
							hashSet2.Add(val);
						}
						else if (array3[k].StartsWith("n="))
						{
							dictionary[val] = Uri.UnescapeDataString(array3[k].Substring(2));
						}
						else
						{
							Plugin.Log.LogWarning((object)("Ignoring unknown anchor flag '" + array3[k] + "' for zone " + Format(val)));
						}
					}
				}
				if (list.Count > 0)
				{
					Anchors[result] = list;
				}
				if (hashSet.Count > 0)
				{
					SpawnZones[result] = hashSet;
				}
				if (dictionary.Count > 0)
				{
					Names[result] = dictionary;
				}
				if (hashSet2.Count > 0)
				{
					SleepZones[result] = hashSet2;
				}
			}
		}

		private static void Save()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<long, List<Vector2s>> anchor in Anchors)
			{
				if (anchor.Value.Count == 0)
				{
					continue;
				}
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(';');
				}
				stringBuilder.Append(anchor.Key.ToString(CultureInfo.InvariantCulture)).Append(':');
				SpawnZones.TryGetValue(anchor.Key, out var value);
				Names.TryGetValue(anchor.Key, out var value2);
				SleepZones.TryGetValue(anchor.Key, out var value3);
				for (int i = 0; i < anchor.Value.Count; i++)
				{
					Vector2s val = anchor.Value[i];
					if (i > 0)
					{
						stringBuilder.Append('|');
					}
					stringBuilder.Append(val.x.ToString(CultureInfo.InvariantCulture)).Append(',').Append(val.y.ToString(CultureInfo.InvariantCulture));
					if (value != null && value.Contains(val))
					{
						stringBuilder.Append(",s");
					}
					if (value3 != null && value3.Contains(val))
					{
						stringBuilder.Append(",z");
					}
					if (value2 != null && value2.TryGetValue(val, out var value4))
					{
						stringBuilder.Append(",n=").Append(Uri.EscapeDataString(value4));
					}
				}
			}
			Plugin.SavedAnchors.Value = stringBuilder.ToString();
		}

		internal static string Format(Vector2s zone)
		{
			//IL_0005: 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)
			return $"({zone.x}, {zone.y})";
		}

		internal static string GetName(Vector2s zone)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetWorld(out var worldUid) || !Names.TryGetValue(worldUid, out var value) || !value.TryGetValue(zone, out var value2))
			{
				return null;
			}
			return value2;
		}

		internal static string Title(Vector2s zone)
		{
			//IL_0000: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			string name = GetName(zone);
			if (name == null)
			{
				return "Zone " + Format(zone);
			}
			return name + " " + Format(zone);
		}

		internal static string SetName(Vector2s zone, string name)
		{
			//IL_002c: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_00ab: 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)
			if (!TryGetWorld(out var worldUid))
			{
				return "Join a world first.";
			}
			if (!Anchors.TryGetValue(worldUid, out var value) || !value.Contains(zone))
			{
				return "Zone " + Format(zone) + " is not anchored; anchor it first.";
			}
			if (!Names.TryGetValue(worldUid, out var value2))
			{
				value2 = (Names[worldUid] = new Dictionary<Vector2s, string>());
			}
			name = (name ?? "").Replace("<", "").Replace(">", "").Trim();
			if (name.Length > 32)
			{
				name = name.Substring(0, 32);
			}
			if (name.Length == 0)
			{
				value2.Remove(zone);
				Save();
				return "Zone " + Format(zone) + ": name cleared";
			}
			value2[zone] = name;
			Save();
			Plugin.Log.LogInfo((object)$"Named zone {Format(zone)} '{name}' in world {worldUid}");
			return "Zone " + Format(zone) + " is now called " + name;
		}

		internal static string CapCount(int count)
		{
			if (count < 100)
			{
				return count.ToString();
			}
			return "100+";
		}

		internal static string DescribePosition(Vector3 pos)
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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)
			Vector3 zonePos = ZoneSystem.GetZonePos(ZoneSystem.GetZone(pos));
			float num = 32f;
			float num2 = Mathf.Min(num - Mathf.Abs(pos.x - zonePos.x), num - Mathf.Abs(pos.z - zonePos.z));
			return $"Position ({pos.x:0.0}, {pos.z:0.0}), {num2:0.0} m from the zone edge";
		}

		internal static bool IsAnchored(Vector2s zone)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return ActiveAnchors().Contains(zone);
		}

		internal static bool SpawnsEnabled(Vector2s zone)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetWorld(out var worldUid) && SpawnZones.TryGetValue(worldUid, out var value))
			{
				return value.Contains(zone);
			}
			return false;
		}

		internal static bool SpawnsEnabledAt(Vector3 point)
		{
			//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_002a: 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)
			if (!TryGetWorld(out var worldUid) || !SpawnZones.TryGetValue(worldUid, out var value) || value.Count == 0)
			{
				return false;
			}
			Vector2s zone = ZoneSystem.GetZone(point);
			if (value.Contains(zone))
			{
				if (SleepZones.TryGetValue(worldUid, out var value2))
				{
					return !value2.Contains(zone);
				}
				return true;
			}
			return false;
		}

		internal static bool IsSleeping(Vector2s zone)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetWorld(out var worldUid) && SleepZones.TryGetValue(worldUid, out var value))
			{
				return value.Contains(zone);
			}
			return false;
		}

		private static HashSet<Vector2s> SleepingInWorld()
		{
			if (!TryGetWorld(out var worldUid) || !SleepZones.TryGetValue(worldUid, out var value) || value.Count <= 0)
			{
				return null;
			}
			return value;
		}

		internal static string Sleep(Vector2s zone)
		{
			//IL_002c: 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_005f: 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_0089: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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)
			//IL_00eb: 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)
			if (!TryGetWorld(out var worldUid))
			{
				return "Join a world first.";
			}
			if (!Anchors.TryGetValue(worldUid, out var value) || !value.Contains(zone))
			{
				return "Zone " + Format(zone) + " is not anchored; anchor it first.";
			}
			if (!SleepZones.TryGetValue(worldUid, out var value2))
			{
				value2 = (SleepZones[worldUid] = new HashSet<Vector2s>());
			}
			if (!value2.Add(zone))
			{
				return Title(zone) + " is already sleeping; press Wake to start it.";
			}
			TakenOver.Remove(zone);
			LastClaims.Remove(zone);
			Probes.Remove(zone);
			NextProbe.Remove(zone);
			ZoneRefresher.Reset();
			ReleaseOwnership(zone, Running(worldUid, value));
			Version++;
			Save();
			Plugin.Log.LogInfo((object)$"Zone {Format(zone)} put to sleep in world {worldUid}");
			return Title(zone) + ": sleeping";
		}

		private static List<Vector2s> Running(long world, List<Vector2s> zones)
		{
			//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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (!SleepZones.TryGetValue(world, out var value) || value.Count == 0)
			{
				return zones;
			}
			List<Vector2s> list = new List<Vector2s>();
			foreach (Vector2s zone in zones)
			{
				if (!value.Contains(zone))
				{
					list.Add(zone);
				}
			}
			return list;
		}

		internal static bool Awaken(Vector2s zone)
		{
			//IL_0019: 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)
			if (!TryGetWorld(out var worldUid) || !SleepZones.TryGetValue(worldUid, out var value) || !value.Remove(zone))
			{
				return false;
			}
			Version++;
			Save();
			Plugin.Log.LogInfo((object)$"Zone {Format(zone)} woken up in world {worldUid}");
			return true;
		}

		internal static string ToggleSpawns(Vector2s zone)
		{
			//IL_002c: 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_005f: 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_009b: 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)
			if (!TryGetWorld(out var worldUid))
			{
				return "Join a world first.";
			}
			if (!Anchors.TryGetValue(worldUid, out var value) || !value.Contains(zone))
			{
				return "Zone " + Format(zone) + " is not anchored; anchor it first.";
			}
			if (!SpawnZones.TryGetValue(worldUid, out var value2))
			{
				value2 = (SpawnZones[worldUid] = new HashSet<Vector2s>());
			}
			bool flag = value2.Add(zone);
			if (!flag)
			{
				value2.Remove(zone);
			}
			Version++;
			Save();
			Plugin.Log.LogInfo((object)string.Format("Enemy spawns {0} for zone {1} in world {2}", flag ? "on" : "off", Format(zone), worldUid));
			return Title(zone) + ": enemy spawns " + (flag ? "on" : "off");
		}

		internal static string StateLabel(ZoneState state)
		{
			return state switch
			{
				ZoneState.Sleeping => "Sleeping", 
				ZoneState.Waking => "Waking", 
				ZoneState.NeedsVisit => "Needs visit", 
				ZoneState.Loading => "Loading", 
				ZoneState.NearYou => "Near you", 
				ZoneState.TooClose => "Too close", 
				ZoneState.NearRunning => "Running (near)", 
				ZoneState.PlayerThere => "Player there", 
				ZoneState.Simulating => "Simulating", 
				ZoneState.Starting => "Starting", 
				_ => "Loaded only", 
			};
		}

		internal static string StateHint(ZoneState state)
		{
			return state switch
			{
				ZoneState.Sleeping => "paused by you: not loaded, not run, no network use - press Wake to start it again", 
				ZoneState.Waking => "fetching its objects from the server (a few seconds; your map marker jumps there meanwhile)", 
				ZoneState.NeedsVisit => "no objects received this session - press Wake or walk through it once", 
				ZoneState.Loading => "terrain or objects are still being created", 
				ZoneState.NearYou => "inside your own area - the game runs it normally", 
				ZoneState.TooClose => "about 2 zones from you: the server takes it back every 2 s, so it stays frozen like in the normal game - go 3+ zones away (or into it), or turn on 'Run zones next to you'", 
				ZoneState.NearRunning => "about 2 zones from you: the server takes it back every 2 s and the mod takes its animals and food back right away ('Run zones next to you' is on)", 
				ZoneState.PlayerThere => "another player (or the server) runs it - paused; checked every 30 s, resumes when they've left", 
				ZoneState.Simulating => "your game runs it", 
				ZoneState.Starting => "taking control of objects (every 2 s)", 
				_ => "ClaimOwnership is off - loaded but not run", 
			};
		}

		internal static List<ZoneStatus> GetStatuses()
		{
			//IL_0033: 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_0038: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_009b: 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)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			List<ZoneStatus> list = new List<ZoneStatus>();
			if (!TryGetWorld(out var _))
			{
				return list;
			}
			Vector3 val = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.position : ZNet.instance.GetReferencePosition());
			RefreshConnectedOwners();
			long sessionID = ZDOMan.GetSessionID();
			List<Vector2s> list2 = new List<Vector2s>(1);
			foreach (Vector2s item in ActiveAnchors())
			{
				list2.Clear();
				list2.Add(item);
				CollectObjects(list2, 0);
				ZoneStatus zoneStatus = new ZoneStatus
				{
					Zone = item,
					Name = GetName(item),
					Centre = ZoneSystem.GetZonePos(item),
					TerrainLoaded = ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.IsZoneLoaded(item)),
					Spawns = SpawnsEnabled(item),
					Sleeping = IsSleeping(item),
					EnemiesSpawned = ZoneStats.SpawnedIn(item),
					AnimalsBorn = ZoneStats.BornIn(item),
					Cached = TempZdos.Count
				};
				zoneStatus.Distance = Vector2.Distance(new Vector2(val.x, val.z), new Vector2(zoneStatus.Centre.x, zoneStatus.Centre.z));
				zoneStatus.Animals = Breeding.Inspect(TempZdos);
				foreach (ZDO tempZdo in TempZdos)
				{
					if ((Object)(object)ZNetScene.instance != (Object)null && (Object)(object)ZNetScene.instance.FindInstance(tempZdo) != (Object)null)
					{
						zoneStatus.Instantiated++;
					}
					if (tempZdo.Persistent)
					{
						long owner = tempZdo.GetOwner();
						if (owner == sessionID)
						{
							zoneStatus.Mine++;
						}
						else if (ConnectedOwners.Contains(owner))
						{
							zoneStatus.Players++;
						}
						else
						{
							zoneStatus.Unowned++;
						}
					}
				}
				zoneStatus.State = Classify(zoneStatus, val);
				list.Add(zoneStatus);
			}
			return list;
		}

		private static ZoneState Classify(ZoneStatus status, Vector3 playerPos)
		{
			//IL_000b: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			if (status.Sleeping)
			{
				return ZoneState.Sleeping;
			}
			if (ZoneWaker.IsPending(status.Zone))
			{
				return ZoneState.Waking;
			}
			if (status.Cached == 0)
			{
				return ZoneState.NeedsVisit;
			}
			if (!status.TerrainLoaded || status.Instantiated == 0)
			{
				return ZoneState.Loading;
			}
			if (ZNetScene.InActiveArea(status.Centre, playerPos))
			{
				return ZoneState.NearYou;
			}
			if (IsNearPlayer(status.Zone))
			{
				if (!Plugin.RunNearZones.Value || !Plugin.ClaimOwnership.Value)
				{
					return ZoneState.TooClose;
				}
				if (status.Players <= 0)
				{
					return ZoneState.NearRunning;
				}
				return ZoneState.PlayerThere;
			}
			if (status.Players > 0)
			{
				return ZoneState.PlayerThere;
			}
			if (!Plugin.ClaimOwnership.Value)
			{
				return ZoneState.NotClaiming;
			}
			if (status.Mine <= 0)
			{
				return ZoneState.Starting;
			}
			return ZoneState.Simulating;
		}

		internal static bool TryGetWorld(out long worldUid)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			worldUid = 0L;
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || instance.IsDedicated() || (int)ZNet.GetConnectionStatus() != 2 || instance.GetWorld() == null)
			{
				return false;
			}
			worldUid = instance.GetWorldUID();
			return true;
		}

		private static List<Vector2s> ActiveAnchors()
		{
			if (!TryGetWorld(out var worldUid) || !Anchors.TryGetValue(worldUid, out var value))
			{
				return NoAnchors;
			}
			return value;
		}

		internal static List<Vector2s> AnchorsInWorld()
		{
			return new List<Vector2s>(ActiveAnchors());
		}

		internal static bool IsNearPlayer(Vector2s zone)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_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)
			//IL_0064: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			Vector2s zone2 = ZoneSystem.GetZone(((Component)localPlayer).transform.position);
			if (Flipping.Contains(zone) && zone2 == _flipPlayerZone)
			{
				return true;
			}
			SimulationDistance syncedSimulationDistance = ZNet.instance.GetSyncedSimulationDistance();
			int num = Mathf.Max(((SimulationDistance)(ref syncedSimulationDistance)).NearSimulationDistance, 2);
			if (Math.Abs(zone.x - zone2.x) <= num)
			{
				return Math.Abs(zone.y - zone2.y) <= num;
			}
			return false;
		}

		internal static string Toggle(Vector2s zone)
		{
			//IL_0042: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0061: 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_0079: 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_00a9: 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_00e4: 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)
			if (!TryGetWorld(out var worldUid))
			{
				return "Join a world first.";
			}
			if (!Anchors.TryGetValue(worldUid, out var value))
			{
				value = (Anchors[worldUid] = new List<Vector2s>());
			}
			ZoneRefresher.Reset();
			Version++;
			if (value.Contains(zone))
			{
				string arg = Title(zone);
				value.Remove(zone);
				TakenOver.Remove(zone);
				Probes.Remove(zone);
				NextProbe.Remove(zone);
				if (SpawnZones.TryGetValue(worldUid, out var value2))
				{
					value2.Remove(zone);
				}
				if (Names.TryGetValue(worldUid, out var value3))
				{
					value3.Remove(zone);
				}
				if (SleepZones.TryGetValue(worldUid, out var value4))
				{
					value4.Remove(zone);
				}
				ReleaseOwnership(zone, Running(worldUid, value));
				Save();
				Plugin.Log.LogInfo((object)$"Released zone {Format(zone)} in world {worldUid}");
				return $"{arg} released ({value.Count} loaded)";
			}
			value.Add(zone);
			Save();
			Plugin.Log.LogInfo((object)$"Anchored zone {Format(zone)} in world {worldUid}");
			string text = $"Zone {Format(zone)} anchored ({value.Count} loaded)";
			if (CountCached(zone) == 0)
			{
				text += "\nNo objects cached yet: press Wake in F1 or visit it once";
			}
			return text;
		}

		internal static string ClearAll()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetWorld(out var worldUid) || !Anchors.TryGetValue(worldUid, out var value) || value.Count == 0)
			{
				return "No anchors in this world.";
			}
			int count = value.Count;
			List<Vector2s> list = new List<Vector2s>(value);
			value.Clear();
			SpawnZones.Remove(worldUid);
			Names.Remove(worldUid);
			SleepZones.Remove(worldUid);
			TakenOver.Clear();
			Probes.Clear();
			NextProbe.Clear();
			ZoneRefresher.Reset();
			Version++;
			foreach (Vector2s item in list)
			{
				ReleaseOwnership(item, value);
			}
			Save();
			Plugin.Log.LogInfo((object)$"Cleared {count} anchors in world {worldUid}");
			return $"Released all {count} anchored zones.";
		}

		internal static void KeepTerrainLoaded(ZoneSystem zoneSystem)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			int value = Plugin.NeighbourRadius.Value;
			HashSet<Vector2s> hashSet = SleepingInWorld();
			Vector2s val = default(Vector2s);
			foreach (Vector2s item in ActiveAnchors())
			{
				if (hashSet != null && hashSet.Contains(item))
				{
					continue;
				}
				for (int i = -value; i <= value; i++)
				{
					for (int j = -value; j <= value; j++)
					{
						((Vector2s)(ref val))..ctor(item.x + j, item.y + i);
						if ((hashSet == null || !hashSet.Contains(val)) && PokeLocalZone(zoneSystem, val))
						{
							return;
						}
					}
				}
			}
		}

		internal static void AppendAnchorObjects(ZDOMan zdoMan, List<ZDO> objects, HashSet<SectorIndex> visited)
		{
			//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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			int value = Plugin.NeighbourRadius.Value;
			HashSet<Vector2s> hashSet = SleepingInWorld();
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Vector2s val = default(Vector2s);
			foreach (Vector2s item in ActiveAnchors())
			{
				if (hashSet != null && hashSet.Contains(item))
				{
					continue;
				}
				for (int i = -value; i <= value; i++)
				{
					for (int j = -value; j <= value; j++)
					{
						((Vector2s)(ref val))..ctor(item.x + j, item.y + i);
						if ((hashSet == null || !hashSet.Contains(val)) && instance.IsZoneLoaded(val))
						{
							FindObjects(zdoMan, val, objects, visited);
						}
					}
				}
			}
		}

		internal static void Update(float dt)
		{
			//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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			ZoneRefresher.Update(dt);
			ZoneWaker.Update(dt);
			_nearClaimTimer += dt;
			if (_nearClaimTimer >= 0.2f)
			{
				_nearClaimTimer = 0f;
				ClaimNearZones();
			}
			_summaryTimer += dt;
			if (_summaryTimer >= 60f)
			{
				_summaryTimer = 0f;
				LogSummary();
			}
			_claimTimer += dt;
			if (_claimTimer < 2f)
			{
				return;
			}
			_claimTimer = 0f;
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			List<Vector2s> list = ActiveAnchors();
			if (list.Count == 0)
			{
				return;
			}
			RefreshConnectedOwners();
			long sessionID = ZDOMan.GetSessionID();
			Vector2s zone = ZoneSystem.GetZone(((Component)Player.m_localPlayer).transform.position);
			if (zone != _flipPlayerZone)
			{
				_flipPlayerZone = zone;
				Flipping.Clear();
				LastClaims.Clear();
			}
			int num = 0;
			HashSet<Vector2s> hashSet = SleepingInWorld();
			foreach (Vector2s item in list)
			{
				if (hashSet != null && hashSet.Contains(item))
				{
					continue;
				}
				if (IsNearPlayer(item))
				{
					TakenOver.Remove(item);
					LastClaims.Remove(item);
					Probes.Remove(item);
					NextProbe.Remove(item);
					continue;
				}
				TempSingle.Clear();
				TempSingle.Add(item);
				CollectObjects(TempSingle, 0);
				if (UpdateTakeover(item, sessionID))
				{
					if (Plugin.ClaimOwnership.Value)
					{
						ProbeTakenZone(item, sessionID);
					}
				}
				else
				{
					if (!Plugin.ClaimOwnership.Value || ServerKeepsReleasing(item, sessionID))
					{
						continue;
					}
					HashSet<ZDOID> hashSet2 = new HashSet<ZDOID>();
					foreach (ZDO tempZdo in TempZdos)
					{
						if (tempZdo.Persistent)
						{
							long owner = tempZdo.GetOwner();
							if (owner != sessionID && !ConnectedOwners.Contains(owner) && !((Object)(object)ZNetScene.instance.FindInstance(tempZdo) == (Object)null))
							{
								tempZdo.SetOwner(sessionID);
								hashSet2.Add(tempZdo.m_uid);
							}
						}
					}
					LastClaims[item] = hashSet2;
					num += hashSet2.Count;
				}
			}
			if (num > 0)
			{
				Plugin.Log.LogDebug((object)$"Claimed {num} objects in {list.Count} anchored zones");
			}
		}

		private static bool ServerKeepsReleasing(Vector2s zone, long me)
		{
			//IL_0005: 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)
			//IL_002c: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (!LastClaims.TryGetValue(zone, out var value) || value.Count < 5)
			{
				return false;
			}
			int num = 0;
			foreach (ZDOID item in value)
			{
				ZDO zDO = ZDOMan.instance.GetZDO(item);
				if (zDO != null && zDO.GetOwner() != me && !ConnectedOwners.Contains(zDO.GetOwner()))
				{
					num++;
				}
			}
			if (num * 2 < value.Count)
			{
				return false;
			}
			Flipping.Add(zone);
			LastClaims.Remove(zone);
			Plugin.Log.LogInfo((object)$"Server keeps releasing zone {Format(zone)} ({num}/{value.Count}); leaving it to the game while you stay in zone {Format(_flipPlayerZone)}");
			return true;
		}

		private static bool UpdateTakeover(Vector2s zone, long me)
		{
			//IL_005a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			foreach (ZDO tempZdo in TempZdos)
			{
				long owner = tempZdo.GetOwner();
				if (tempZdo.Persistent && owner != me && ConnectedOwners.Contains(owner))
				{
					flag = true;
					break;
				}
			}
			if (flag && TakenOver.Add(zone))
			{
				ZoneRefresher.Prioritize(TempZdos);
				NextProbe[zone] = Time.time + 10f;
				LastClaims.Remove(zone);
				Plugin.Log.LogInfo((object)("Zone " + Format(zone) + " is being run by another player; paused"));
				Plugin.Notify(Title(zone) + ": another player is there, paused", (MessageType)1);
			}
			else if (!flag && TakenOver.Remove(zone))
			{
				Probes.Remove(zone);
				NextProbe.Remove(zone);
				Plugin.Log.LogInfo((object)("Zone " + Format(zone) + " is free again; resumed"));
				Plugin.Notify(Title(zone) + ": resumed", (MessageType)1);
			}
			return flag;
		}

		private static bool IsTooClose(Vector2s zone, Vector3 playerPos)
		{
			//IL_0000: 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_0009: 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)
			if (IsNearPlayer(zone))
			{
				return !ZNetScene.InActiveArea(ZoneSystem.GetZonePos(zone), playerPos);
			}
			return false;
		}

		private static void ClaimNearZones()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_008f: 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_0083: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.RunNearZones.Value || !Plugin.ClaimOwnership.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || ZDOMan.instance == null)
			{
				return;
			}
			List<Vector2s> list = ActiveAnchors();
			if (list.Count == 0)
			{
				return;
			}
			HashSet<Vector2s> hashSet = SleepingInWorld();
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			long sessionID = ZDOMan.GetSessionID();
			bool flag = false;
			foreach (Vector2s item in list)
			{
				if ((hashSet != null && hashSet.Contains(item)) || !IsTooClose(item, position))
				{
					continue;
				}
				if (!flag)
				{
					RefreshConnectedOwners();
					flag = true;
				}
				TempSingle.Clear();
				TempSingle.Add(item);
				CollectObjects(TempSingle, 0);
				if (OwnedByAnotherPlayer(sessionID))
				{
					continue;
				}
				bool flag2 = SpawnsEnabled(item);
				foreach (ZDO tempZdo in TempZdos)
				{
					if (!tempZdo.Persistent)
					{
						continue;
					}
					long owner = tempZdo.GetOwner();
					if (owner != sessionID && !ConnectedOwners.Contains(owner))
					{
						RunKind runKind = GetRunKind(tempZdo);
						if (runKind != RunKind.None && (runKind != RunKind.Spawner || flag2) && !((Object)(object)ZNetScene.instance.FindInstance(tempZdo) == (Object)null))
						{
							tempZdo.SetOwner(sessionID);
						}
					}
				}
			}
		}

		private static bool OwnedByAnotherPlayer(long me)
		{
			foreach (ZDO tempZdo in TempZdos)
			{
				long owner = tempZdo.GetOwner();
				if (tempZdo.Persistent && owner != me && ConnectedOwners.Contains(owner))
				{
					return true;
				}
			}
			return false;
		}

		private static RunKind GetRunKind(ZDO zdo)
		{
			int prefab = zdo.GetPrefab();
			if (!RunPrefabs.TryGetValue(prefab, out var value))
			{
				GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab);
				value = ((!((Object)(object)prefab2 == (Object)null)) ? (((Object)(object)prefab2.GetComponent<Character>() != (Object)null || (Object)(object)prefab2.GetComponent<ItemDrop>() != (Object)null) ? RunKind.Simulated : (((Object)(object)prefab2.GetComponent<CreatureSpawner>() != (Object)null || (Object)(object)prefab2.GetComponent<SpawnArea>() != (Object)null) ? RunKind.Spawner : RunKind.None)) : RunKind.None);
				RunPrefabs[prefab] = value;
			}
			return value;
		}

		private static void ProbeTakenZone(Vector2s zone, long me)
		{
			//IL_0019: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.RefreshRate.Value <= 0)
			{
				return;
			}
			float time = Time.time;
			if (Probes.TryGetValue(zone, out var value))
			{
				ZDO zDO = ZDOMan.instance.GetZDO(value.Id);
				if (zDO == null)
				{
					Probes.Remove(zone);
					return;
				}
				if (time - value.Started < 6f)
				{
					ZoneRefresher.RequestNow(value.Id);
					return;
				}
				Probes.Remove(zone);
				if (zDO.GetOwner() != me)
				{
					NextProbe[zone] = time + 30f;
					return;
				}
				int num = 0;
				foreach (ZDO tempZdo in TempZdos)
				{
					if (tempZdo.Persistent && tempZdo.GetOwner() == value.Owner && (Object)(object)ZNetScene.instance.FindInstance(tempZdo) != (Object)null)
					{
						tempZdo.SetOwner(me);
						num++;
					}
				}
				Plugin.Log.LogInfo((object)$"Zone {Format(zone)}: its last owner left; took over {num + 1} objects");
			}
			else
			{
				if (NextProbe.TryGetValue(zone, out var value2) && time < value2)
				{
					return;
				}
				foreach (ZDO tempZdo2 in TempZdos)
				{
					long owner = tempZdo2.GetOwner();
					if (tempZdo2.Persistent && owner != me && ConnectedOwners.Contains(owner))
					{
						Probes[zone] = new Probe
						{
							Id = tempZdo2.m_uid,
							Owner = owner,
							Started = time
						};
						tempZdo2.SetOwner(me);
						Plugin.Log.LogDebug((object)$"Probing zone {Format(zone)} with one object owned by {owner}");
						break;
					}
				}
			}
		}

		internal static void CollectRefreshTargets(List<ZDO> creatures, List<ZDO> others, Func<ZDO, bool> isCreature)
		{
			//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)
			//IL_0057: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2s> list = ActiveAnchors();
			if (list.Count == 0 || ZDOMan.instance == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			long sessionID = ZDOMan.GetSessionID();
			int value = Plugin.NeighbourRadius.Value;
			HashSet<Vector2s> hashSet = SleepingInWorld();
			TempSingle.Clear();
			foreach (Vector2s item in list)
			{
				if (!IsNearPlayer(item) && (hashSet == null || !hashSet.Contains(item)))
				{
					TempSingle.Add(item);
				}
			}
			CollectObjects(TempSingle, value);
			foreach (ZDO tempZdo in TempZdos)
			{
				if (tempZdo.Persistent && (TempSingle.Contains(tempZdo.GetSector()) || tempZdo.GetOwner() == sessionID))
				{
					(isCreature(tempZdo) ? creatures : others).Add(tempZdo);
				}
			}
		}

		internal static IEnumerable<string> Describe()
		{
			if (!TryGetWorld(out var _))
			{
				yield return "Join a world first.";
				yield break;
			}
			Vector3 position = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.position : ZNet.instance.GetReferencePosition());
			List<ZoneStatus> statuses = GetStatuses();
			yield return $"Anchored zones in this world: {statuses.Count}";
			yield return "You are in zone " + Format(ZoneSystem.GetZone(position)) + ": " + DescribePosition(position);
			for (int i = 0; i < statuses.Count; i++)
			{
				ZoneStatus s = statuses[i];
				yield return $"{i + 1}. {Title(s.Zone)} {StateLabel(s.State)} ({StateHint(s.State)})";
				yield return $"   centre ({s.Centre.x:0}, {s.Centre.z:0}), {s.Distance:0} m away, " + $"objects {s.Instantiated}/{s.Cached} loaded, owned by you {s.Mine} / players {s.Players} / nobody {s.Unowned}, " + "enemy spawns " + (s.Spawns ? "on" : "off");
				yield return $"   this session: enemies spawned {CapCount(s.EnemiesSpawned)}, animals born {s.AnimalsBorn}";
				foreach (Herd herd in s.Animals)
				{
					yield return "   " + Breeding.Describe(herd);
					string text = Breeding.DescribeYoung(herd, position);
					if (text != null)
					{
						yield return "   " + text;
					}
					string text2 = Breeding.Rule(herd);
					if (text2 != null)
					{
						yield return "   Pen limit (game rule, young count too) - " + text2;
					}
				}
			}
		}

		private static void LogSummary()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || ActiveAnchors().Count == 0)
			{
				return;
			}
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			List<string> list = new List<string> { $"Zone summary at {DateTime.Now:HH:mm:ss}, you are in zone {Format(ZoneSystem.GetZone(position))}, " + "Run zones next to you: " + (Plugin.RunNearZones.Value ? "on" : "off") };
			List<string> list2 = new List<string>();
			foreach (ZoneStatus status in GetStatuses())
			{
				string text = Since(SummarySpawned, status.Zone, status.EnemiesSpawned);
				string text2 = Since(SummaryBorn, status.Zone, status.AnimalsBorn);
				if (status.State == ZoneState.Sleeping)
				{
					list2.Add(Title(status.Zone));
					continue;
				}
				list.Add($"  {Title(status.Zone)}: {StateLabel(status.State)}, {status.Distance:0} m, objects {status.Instantiated}/{status.Cached} " + string.Format("(yours {0}, players {1}, nobody {2}), spawns {3}, ", status.Mine, status.Players, status.Unowned, status.Spawns ? "on" : "off") + $"enemies {status.EnemiesSpawned}{text}, born {status.AnimalsBorn}{text2}");
				foreach (Herd animal in status.Animals)
				{
					list.Add("    " + Breeding.Describe(animal));
					string text3 = Breeding.DescribeYoung(animal, position);
					if (text3 != null)
					{
						list.Add("    " + text3);
					}
				}
			}
			if (list2.Count > 0)
			{
				list.Add("  Sleeping: " + string.Join(", ", list2));
			}
			Plugin.Log.LogInfo((object)string.Join(Environment.NewLine, list));
		}

		private static string Since(Dictionary<Vector2s, int> last, Vector2s zone, int now)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			last.TryGetValue(zone, out var value);
			last[zone] = now;
			if (now <= value)
			{
				return "";
			}
			return $" (+{now - value})";
		}

		internal static int CountCached(Vector2s zone)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			CollectObjects(new List<Vector2s> { zone }, 0);
			return TempZdos.Count;
		}

		private static void CollectObjects(List<Vector2s> anchors, int radius)
		{
			//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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			TempZdos.Clear();
			TempVisited.Clear();
			if (ZDOMan.instance == null)
			{
				return;
			}
			foreach (Vector2s anchor in anchors)
			{
				for (int i = -radius; i <= radius; i++)
				{
					for (int j = -radius; j <= radius; j++)
					{
						FindObjects(ZDOMan.instance, new Vector2s(anchor.x + j, anchor.y + i), TempZdos, TempVisited);
					}
				}
			}
		}

		private static void ReleaseOwnership(Vector2s released, List<Vector2s> remaining)
		{
			//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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_005a: 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)
			//IL_00d5: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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)ZNet.instance == (Object)null)
			{
				return;
			}
			int value = Plugin.NeighbourRadius.Value;
			TempCovered.Clear();
			foreach (Vector2s item in remaining)
			{
				for (int i = -value; i <= value; i++)
				{
					for (int j = -value; j <= value; j++)
					{
						TempCovered.Add(new Vector2s(item.x + j, item.y + i));
					}
				}
			}
			long sessionID = ZDOMan.GetSessionID();
			Vector3 referencePosition = ZNet.instance.GetReferencePosition();
			CollectObjects(new List<Vector2s> { released }, value);
			foreach (ZDO tempZdo in TempZdos)
			{
				Vector2s sector = tempZdo.GetSector();
				if (tempZdo.GetOwner() == sessionID && !ZNetScene.InActiveArea(tempZdo.GetPosition(), referencePosition) && (!(sector != released) || !TempCovered.Contains(sector)))
				{
					tempZdo.SetOwner(0L);
				}
			}
		}

		private static void RefreshConnectedOwners()
		{
			//IL_001e: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			ConnectedOwners.Clear();
			foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
			{
				ZDOID characterID = player.m_characterID;
				if (!((ZDOID)(ref characterID)).IsNone())
				{
					HashSet<long> connectedOwners = ConnectedOwners;
					characterID = player.m_characterID;
					connectedOwners.Add(((ZDOID)(ref characterID)).UserID);
				}
			}
			ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
			if (serverPeer != null)
			{
				ConnectedOwners.Add(serverPeer.m_uid);
			}
		}
	}
	internal class Herd
	{
		public string Species;

		public int Adults;

		public int Young;

		public int Ready;

		public int Pregnant;

		public int Alarmed;

		public int Hungry;

		public int Crowded;

		public int NoPartner;

		public int Around;

		public int MaxCreatures;

		public float CheckRange;

		public float PartnerRange;

		public readonly List<Vector3> YoungAt = new List<Vector3>();
	}
	internal enum Verdict
	{
		Breeding,
		OnlyYoung,
		PenFull,
		Hungry,
		Alarmed,
		NoPartner
	}
	internal static class Breeding
	{
		private static readonly Func<Procreation, bool> IsPregnant = AccessTools.MethodDelegate<Func<Procreation, bool>>(AccessTools.Method(typeof(Procreation), "IsPregnant", (Type[])null, (Type[])null), (object)null, true);

		private static readonly string[] Compass = new string[8] { "north", "north-east", "east", "south-east", "south", "south-west", "west", "north-west" };

		internal static List<Herd> Inspect(List<ZDO> zdos)
		{
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			List<Herd> list = new List<Herd>();
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return list;
			}
			foreach (ZDO zdo in zdos)
			{
				ZNetView val = instance.FindInstance(zdo);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Character component = ((Component)val).GetComponent<Character>();
				if ((Object)(object)component == (Object)null || !component.IsTamed())
				{
					continue;
				}
				Procreation component2 = ((Component)val).GetComponent<Procreation>();
				if ((Object)(object)component2 == (Object)null)
				{
					Growup component3 = ((Component)val).GetComponent<Growup>();
					if (!((Object)(object)component3 == (Object)null))
					{
						string species = (((Object)(object)component3.m_grownPrefab != (Object)null) ? ((Object)component3.m_grownPrefab).name : Utils.GetPrefabName(((Component)val).gameObject));
						Herd herd = Find(list, species);
						herd.Young++;
						herd.YoungAt.Add(((Component)val).transform.position);
					}
					continue;
				}
				Herd herd2 = Find(list, Utils.GetPrefabName(((Component)val).gameObject));
				herd2.Adults++;
				herd2.MaxCreatures = component2.m_maxCreatures;
				herd2.CheckRange = component2.m_totalCheckRange;
				herd2.PartnerRange = component2.m_partnerCheckRange;
				Vector3 position = ((Component)val).transform.position;
				GameObject prefab = instance.GetPrefab(zdo.GetPrefab());
				GameObject prefab2 = (((Object)(object)component2.m_offspring != (Object)null) ? instance.GetPrefab(((Object)component2.m_offspring).name) : null);
				int num = Count(prefab, position, component2.m_totalCheckRange, readyOnly: false) + Count(prefab2, position, component2.m_totalCheckRange, readyOnly: false);
				herd2.Around = Mathf.Max(herd2.Around, num);
				if (IsPregnant(component2))
				{
					herd2.Pregnant++;
					continue;
				}
				BaseAI component4 = ((Component)val).GetComponent<BaseAI>();
				if ((Object)(object)component4 != (Object)null && component4.IsAlerted())
				{
					herd2.Alarmed++;
					continue;
				}
				Tameable component5 = ((Component)val).GetComponent<Tameable>();
				if ((Object)(object)component5 != (Object)null && component5.IsHungry())
				{
					herd2.Hungry++;
					continue;
				}
				if (num >= component2.m_maxCreatures)
				{
					herd2.Crowded++;
					continue;
				}
				bool flag = (Object)(object)component2.m_seperatePartner != (Object)null;
				if (Count(flag ? component2.m_seperatePartner : prefab, position, component2.m_partnerCheckRange, readyOnly: true) < (flag ? 1 : 2))
				{
					herd2.NoPartner++;
				}
				else
				{
					herd2.Ready++;
				}
			}
			list.Sort((Herd a, Herd b) => (b.Adults + b.Young).CompareTo(a.Adults + a.Young));
			return list;
		}

		private static Herd Find(List<Herd> herds, string species)
		{
			foreach (Herd herd2 in herds)
			{
				if (herd2.Species == species)
				{
					return herd2;
				}
			}
			Herd herd = new Herd
			{
				Species = species
			};
			herds.Add(herd);
			return herd;
		}

		internal static Verdict GetVerdict(Herd herd)
		{
			if (herd.Adults == 0)
			{
				return Verdict.OnlyYoung;
			}
			if (herd.Ready + herd.Pregnant > 0)
			{
				return Verdict.Breeding;
			}
			Verdict result = Verdict.PenFull;
			int num = herd.Crowded;
			if (herd.Hungry > num)
			{
				result = Verdict.Hungry;
				num = herd.Hungry;
			}
			if (herd.Alarmed > num)
			{
				result = Verdict.Alarmed;
				num = herd.Alarmed;
			}
			if (herd.NoPartner > num)
			{
				result = Verdict.NoPartner;
			}
			return result;
		}

		internal static string Label(Verdict verdict)
		{
			return verdict switch
			{
				Verdict.Breeding => "Breeding", 
				Verdict.OnlyYoung => "Only young", 
				Verdict.PenFull => "Pen full", 
				Verdict.Hungry => "Hungry", 
				Verdict.Alarmed => "Alarmed", 
				_ => "No partner", 
			};
		}

		internal static string Hint(Verdict verdict, Herd herd)
		{
			return verdict switch
			{
				Verdict.Breeding => "'ready' adults get pregnant by chance over the next minutes", 
				Verdict.OnlyYoung => "no adults of this kind here; the young grow up by themselves", 
				Verdict.PenFull => $"{herd.MaxCreatures} or more of this kind within {herd.CheckRange:0} m, young included: " + $"move some to a pen at least {herd.CheckRange:0} m away", 
				Verdict.Hungry => "they only breed when fed: put their food on the ground near them", 
				Verdict.Alarmed => "enemies nearby scare them; they calm down once it's quiet", 
				_ => $"each needs another adult of its kind within {herd.PartnerRange:0} m", 
			};
		}

		internal static string AdultsText(Herd herd)
		{
			if (herd.Adults == 0)
			{
				return "no adults";
			}
			List<string> list = new List<string>();
			Add(list, herd.Ready, "ready");
			Add(list, herd.Pregnant, "pregnant");
			Add(list, herd.Hungry, "hungry");
			Add(list, herd.Alarmed, "alarmed");
			Add(list, herd.Crowded, "pen full");
			Add(list, herd.NoPartner, "no partner");
			return string.Format("{0} adult{1}: {2}", herd.Adults, (herd.Adults == 1) ? "" : "s", string.Join(", ", list));
		}

		internal static string YoungText(Herd herd)
		{
			if (herd.Young != 0)
			{
				return $"{herd.Young} young";
			}
			return "no young";
		}

		internal static string PenText(Herd herd)
		{
			if (herd.Adults != 0)
			{
				return $"{herd.Around}/{herd.MaxCreatures} in {herd.CheckRange:0} m";
			}
			return null;
		}

		internal static string Rule(Herd herd)
		{
			if (herd.Adults != 0)
			{
				return $"{herd.Species}: {herd.MaxCreatures} within {herd.CheckRange:0} m, partner within {herd.PartnerRange:0} m";
			}
			return null;
		}

		internal static bool PenFull(Herd herd)
		{
			if (herd.Adults > 0)
			{
				return herd.Around >= herd.MaxCreatures;
			}
			return false;
		}

		internal static string Describe(Herd herd)
		{
			Verdict verdict = GetVerdict(herd);
			string text = herd.Species + ": " + Label(verdict) + " · " + AdultsText(herd) + " · " + YoungText(herd);
			string text2 = PenText(herd);
			if (text2 != null)
			{
				text = text + " · pen " + text2;
			}
			if (verdict != Verdict.Breeding)
			{
				text = text + " (" + Hint(verdict, herd) + ")";
			}
			return text;
		}

		internal static string DescribeYoung(Herd herd, Vector3 from)
		{
			//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_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_002f: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (herd.YoungAt.Count == 0)
			{
				return null;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < herd.YoungAt.Count && i < 6; i++)
			{
				Vector3 val = herd.YoungAt[i] - from;
				Vector2 val2 = new Vector2(val.x, val.z);
				float magnitude = ((Vector2)(ref val2)).magnitude;
				string text = ((magnitude < 1f) ? "where you stand" : $"{magnitude:0} m {Direction(val)} of you");
				if (Mathf.Abs(val.y) >= 2f)
				{
					text += string.Format(", {0:0} m {1}", Mathf.Abs(val.y), (val.y < 0f) ? "below" : "above");
				}
				list.Add(text);
			}
			if (herd.YoungAt.Count > 6)
			{
				list.Add($"{herd.YoungAt.Count - 6} more");
			}
			return herd.Species + " young: " + string.Join(" · ", list);
		}

		private static string Direction(Vector3 offset)
		{
			//IL_0000: 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)
			float num = Mathf.Atan2(offset.x, offset.z) * 57.29578f;
			return Compass[Mathf.RoundToInt((num + 360f) % 360f / 45f) % 8];
		}

		private static void Add(List<string> parts, int count, string what)
		{
			if (count > 0)
			{
				parts.Add($"{count} {what}");
			}
		}

		private static int Count(GameObject prefab, Vector3 position, float range, bool readyOnly)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)prefab == (Object)null))
			{
				return SpawnSystem.GetNrOfInstances(prefab, position, range, false, readyOnly);
			}
			return 0;
		}
	}
	internal static class Commands
	{
		internal static void Anchor(ConsoleEventArgs args)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: 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_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			string text = ((args.Length > 1) ? args[1].ToLowerInvariant() : "");
			switch (text)
			{
			case "clear":
				args.Context.AddString(AnchorManager.ClearAll());
				return;
			case "spawns":
			{
				if (args.Length >= 4 && int.TryParse(args[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result3) && int.TryParse(args[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result4))
				{
					args.Context.AddString(AnchorManager.ToggleSpawns(new Vector2s(result3, result4)));
				}
				else if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					args.Context.AddString(AnchorManager.ToggleSpawns(ZoneSystem.GetZone(((Component)Player.m_localPlayer).transform.position)));
				}
				else
				{
					args.Context.AddString("No local player.");
				}
				return;
			}
			case "wake":
			{
				if (args.Length >= 4 && int.TryParse(args[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(args[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
				{
					args.Context.AddString(ZoneWaker.Wake(new Vector2s(result, result2)));
					return;
				}
				int num = ZoneWaker.WakeAllNeeded();
				args.Context.AddString((num > 0) ? string.Format("Waking {0} anchored zone{1} with no objects yet.", num, (num == 1) ? "" : "s") : "No far anchored zone needs waking. Use 'anchor wake <x> <y>' to refresh one anyway.");
				return;
			}
			case "sleep":
			{
				if (args.Length >= 4 && int.TryParse(args[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result5) && int.TryParse(args[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result6))
				{
					args.Context.AddString(AnchorManager.Sleep(new Vector2s(result5, result6)));
				}
				else if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					args.Context.AddString(AnchorManager.Sleep(ZoneSystem.GetZone(((Component)Player.m_localPlayer).transform.position)));
				}
				else
				{
					args.Context.AddString("No local player.");
				}
				return;
			}
			case "name":
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					args.Context.AddString("No local player.");
					return;
				}
				string name = ((args.Length > 2) ? string.Join(" ", args.Args, 2, args.Length - 2) : "");
				args.Context.AddString(AnchorManager.SetName(ZoneSystem.GetZone(((Component)Player.m_localPlayer).transform.position), name));
				return;
			}
			case "show":
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					args.Context.AddString("No local player.");
					return;
				}
				Vector3 position = ((Component)Player.m_localPlayer).transform.position;
				args.Context.AddString(AnchorManager.DescribePosition(position));
				ZoneBorders.Show(position, Mathf.Max(Plugin.BorderSeconds.Value, 5f));
				return;
			}
			case "list":
			case "info":
			{
				foreach (string item in AnchorManager.Describe())
				{
					args.Context.AddString(item);
				}
				return;
			}
			}
			if (args.Length >= 3 && int.TryParse(args[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result7) && int.TryParse(args[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result8))
			{
				args.Context.AddString(AnchorManager.Toggle(new Vector2s(result7, result8)));
			}
			else if (text == "")
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					args.Context.AddString("No local player.");
					return;
				}
				Vector3 position2 = ((Component)Player.m_localPlayer).transform.position;
				args.Context.AddString(AnchorManager.Toggle(ZoneSystem.GetZone(position2)));
				args.Context.AddString(AnchorManager.DescribePosition(position2));
				ZoneBorders.Show(position2, Plugin.BorderSeconds.Value);
			}
			else
			{
				args.Context.AddString("Usage: anchor [list|show|clear|wake [x y]|sleep [x y]|spawns [x y]|name [text]|<zoneX> <zoneY>]");
			}
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public Action<ConfigEntryBase> CustomDrawer;

		public bool? HideSettingName;

		public bool? HideDefaultButton;

		public string Category;

		public string DispName;

		public int? Order;
	}
	[HarmonyPatch(typeof(ZoneSystem), "Update")]
	internal static class ZoneSystemUpdatePatch
	{
		private static void Postfix(ZoneSystem __instance)
		{
			AnchorManager.KeepTerrainLoaded(__instance);
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "CreateDestroyObjects")]
	internal static class CreateDestroyObjectsPatch
	{
		internal static bool Active;

		private static void Prefix()
		{
			Active = true;
		}

		private static void Finalizer()
		{
			Active = false;
		}
	}
	[HarmonyPatch(typeof(ZDOMan), "FindSectorObjects")]
	internal static class FindSectorObjectsPatch
	{
		private static void Postfix(ZDOMan __instance, List<ZDO> sectorObjects, HashSet<SectorIndex> ___m_visitedSectorIndices)
		{
			if (CreateDestroyObjectsPatch.Active)
			{
				AnchorManager.AppendAnchorObjects(__instance, sectorObjects, ___m_visitedSectorIndices);
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	internal static class TerminalPatch
	{
		private static void Postfix()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("anchor", "[list|show|clear|wake [x y]|sleep [x y]|spawns [x y]|name [text]|<zoneX> <zoneY>] - toggle keeping a zone loaded and simulated (RemoteChunk)", new ConsoleEvent(Commands.Anchor), false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	[BepInPlugin("vh.remotechunk", "RemoteChunk", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "vh.remotechunk";

		public const string Name = "RemoteChunk";

		public const string Version = "1.0.2";

		private static readonly Func<Player, bool> TakeInput = AccessTools.MethodDelegate<Func<Player, bool>>(AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null), (object)null, true);

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<KeyboardShortcut> BordersKey;

		internal static ConfigEntry<float> BorderSeconds;

		internal static ConfigEntry<int> NeighbourRadius;

		internal static ConfigEntry<bool> ClaimOwnership;

		internal static ConfigEntry<int> RefreshRate;

		internal static ConfigEntry<bool> AutoWake;

		internal static ConfigEntry<bool> RunNearZones;

		internal static ConfigEntry<string> SavedAnchors;

		private const string Hotkeys = "1. Hotkeys";

		private const string Zones = "2. Anchored zones";

		private const string Network = "3. Network";

		private const string ZoneList = "4. Zones";

		private Harmony _harmony;

		private static ConfigurationManagerAttributes Display(string category, string name, int order)
		{
			return new ConfigurationManagerAttributes
			{
				Category = category,
				DispName = name,
				Order = order
			};
		}

		private void Awake()
		{
			//IL_0022: 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_0050: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Expected O, but got Unknown
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)110, Array.Empty<KeyCode>()), new ConfigDescription("Press in a zone to anchor it: keep it loaded and running while you are away. Press again in the same zone to release it. Default N. Each press shows a message with the zone and your distance to its edge, and draws the zone borders for 'Border lines after anchor key'.", (AcceptableValueBase)null, new object[1] { Display("1. Hotkeys", "Anchor / release key", 3) }));
			BorderSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BorderSeconds", 5f, new ConfigDescription("How many seconds the zone border lines stay on the ground after you press the anchor key (N). 0 = don't draw them. Doesn't affect the borders key (K), which keeps them on until pressed again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), new object[1] { Display("1. Hotkeys", "Border lines after anchor key (seconds)", 2) }));
			BordersKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "BordersKey", new KeyboardShortcut((KeyCode)107, Array.Empty<KeyCode>()), new ConfigDescription("Press to show the zone border lines around you until you press it again. Default K. They follow you into other zones. Green = anchored, orange = anchored with enemy spawns, yellow = the zone you are in, white = other zones.", (AcceptableValueBase)null, new object[1] { Display("1. Hotkeys", "Zone borders on/off key", 1) }));
			ClaimOwnership = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ClaimOwnership", true, new ConfigDescription("On: your game takes control of the objects in far anchored zones and runs them, so animals keep breeding and being tamed. It never takes objects from a player who is online. Off: anchored zones stay loaded but frozen, like vanilla when nobody is there.", (AcceptableValueBase)null, new object[1] { Display("2. Anchored zones", "Run anchored zones", 3) }));
			NeighbourRadius = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NeighbourRadius", 1, new ConfigDescription("How many rings of zones around each anchored zone are also loaded. 0 = only the anchored zone, 1 = 3×3 zones (default), 2 = 5×5. Keeps ground and walls loaded for animals near a zone edge; neighbour zones are loaded but not run. More rings = lower FPS. Applies immediately.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), new object[1] { Display("2. Anchored zones", "Neighbour zones kept loaded (rings)", 2) }));
			AutoWake = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoWake", true, new ConfigDescription("About 5 seconds after you join, fetch every far anchored zone that has no objects yet ('Needs visit') from the server, a few seconds each, so you don't have to walk there. While a zone is fetched the server thinks you are there: your map marker jumps and other players' things right around you pause briefly. Off: use the Wake button in the zone list, or walk there.", (AcceptableValueBase)null, new object[1] { Display("2. Anchored zones", "Wake zones after joining", 1) }));
			RunNearZones = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RunNearZones", false, new ConfigDescription("Anchored zones about 2 zones from you ('Too close') are frozen in the normal game: every 2 s the server takes control of them away from you. On: the mod takes back the animals and the items on the ground there (their food) right after each time, so breeding and feeding go on. Buildings are left alone. Animals may twitch briefly every 2 s; uses a little extra network. Off by default.", (AcceptableValueBase)null, new object[1] { Display("2. Anchored zones", "Run zones next to you (Too close)", 0) }));
			RefreshRate = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RefreshRate", 100, new ConfigDescription("Not milliseconds: how many objects per second your game asks the server about, to keep far anchored zones up to date and notice when another player is there. Higher = notices sooner but uses more upload (about 6 KB/s at 100). 0 = off: another player in your zone is not noticed and both games would run it. Default 100.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 500), new object[1] { Display("3. Network", "Refresh rate (objects per second)", 1) }));
			SavedAnchors = ((BaseUnityPlugin)this).Config.Bind<string>("Data", "Anchors", "", new ConfigDescription("Anchored zones per world as worldUid:x,y|x,y entries separated by ';'. Managed by the hotkey, the 'anchor' command and the zone table.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					CustomDrawer = ZoneTable.Draw,
					HideSettingName = true,
					HideDefaultButton = true,
					Category = "4. Zones",
					DispName = "Anchored zones"
				}
			}));
			AnchorManager.Load(SavedAnchors.Value);
			_harmony = new Harmony("vh.remotechunk");
			_harmony.PatchAll();
		}

		private void Update()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0043: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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)
			Player localPlayer = Player.m_localPlayer;
			int num;
			if ((Object)(object)localPlayer != (Object)null && !TypingInWindow())
			{
				num = (TakeInput(localPlayer) ? 1 : 0);
				if (num != 0 && IsDown(ToggleKey.Value))
				{
					Vector3 position = ((Component)localPlayer).transform.position;
					Notify(AnchorManager.Toggle(ZoneSystem.GetZone(position)) + "\n" + AnchorManager.DescribePosition(position), (MessageType)2);
					ZoneBorders.Show(position, BorderSeconds.Value);
				}
			}
			else
			{
				num = 0;
			}
			if (num != 0 && IsDown(BordersKey.Value))
			{
				Notify(ZoneBorders.ToggleAlwaysOn(((Component)localPlayer).transform.position), (MessageType)1);
			}
			AnchorManager.Update(Time.deltaTime);
		}

		private static bool TypingInWindow()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if (GUIUtility.keyboardControl != 0)
			{
				return (int)Cursor.lockState != 1;
			}
			return false;
		}

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

		private static bool IsDown(KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, false))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}

		internal static void Notify(string message, MessageType type = (MessageType)2)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage(type, message, 0, (Sprite)null, false, true);
			}
		}
	}
	public static class SpawnGates
	{
		private static readonly MethodInfo PlayerInRange2 = AccessTools.Method(typeof(Player), "IsPlayerInRange", new Type[2]
		{
			typeof(Vector3),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo PlayerInRange3 = AccessTools.Method(typeof(Player), "IsPlayerInRange", new Type[3]
		{
			typeof(Vector3),
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo OutsideArea = AccessTools.Method(typeof(ZNetScene), "OutsideActiveArea", new Type[1] { typeof(Vector3) }, (Type[])null);

		internal static IEnumerable<CodeInstruction> Redirect(IEnumerable<CodeInstruction> instructions, MethodBase original)
		{
			int replaced = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				MethodInfo methodInfo = null;
				if (CodeInstructionExtensions.Calls(instruction, PlayerInRange2))
				{
					methodInfo = AccessTools.Method(typeof(SpawnGates), "IsPlayerInRange", new Type[2]
					{
						typeof(Vector3),
						typeof(float)
					}, (Type[])null);
				}
				else if (CodeInstructionExtensions.Calls(instruction, PlayerInRange3))
				{
					methodInfo = AccessTools.Method(typeof(SpawnGates), "IsPlayerInRange", new Type[3]
					{
						typeof(Vector3),
						typeof(float),
						typeof(float)
					}, (Type[])null);
				}
				else if (CodeInstructionExtensions.Calls(instruction, OutsideArea))
				{
					methodInfo = AccessTools.Method(typeof(SpawnGates), "OutsideActiveArea", (Type[])null, (Type[])null);
				}
				if (methodInfo != null)
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = methodInfo;
					replaced++;
				}
				yield return instruction;
			}
			if (replaced == 0)
			{
				Plugin.Log.LogWarning((object)("No player checks found in " + original.DeclaringType?.Name + "." + original.Name + "; enemy spawn switch won't affect it."));
			}
		}

		public static bool IsPlayerInRange(Vector3 point, float range)
		{
			//IL_0000: 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)
			if (!AnchorManager.SpawnsEnabledAt(point))
			{
				return Player.IsPlayerInRange(point, range);
			}
			return true;
		}

		public static bool IsPlayerInRange(Vector3 point, float range, float minNoise)
		{
			//IL_0000: 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)
			if (!AnchorManager.SpawnsEnabledAt(point))
			{
				return Player.IsPlayerInRange(point, range, minNoise);
			}
			return true;
		}

		public static bool OutsideActiveArea(ZNetScene scene, Vector3 point)
		{
			//IL_0000: 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)
			if (!AnchorManager.SpawnsEnabledAt(point))
			{
				return scene.OutsideActiveArea(point);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(CreatureSpawner), "UpdateSpawner")]
	internal static class CreatureSpawnerPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
		{
			return SpawnGates.Redirect(instructions, original);
		}
	}
	[HarmonyPatch(typeof(SpawnArea), "UpdateSpawn")]
	internal static class SpawnAreaPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
		{
			return SpawnGates.Redirect(instructions, original);
		}
	}
	internal class ZoneBorders : MonoBehaviour
	{
		private const float PointSpacing = 2f;

		private const float Lift = 0.4f;

		private const float Inset = 0.4f;

		private const float FadeSeconds = 1f;

		private static readonly Color AnchoredColor = new Color(0.3f, 1f, 0.35f);

		private static readonly Color SpawnsColor = new Color(1f, 0.45f, 0.2f);

		private static readonly Color SleepingColor = new Color(0.56f, 0.64f, 0.68f);

		private static readonly Color CurrentColor = new Color(1f, 0.85f, 0.2f);

		private static readonly Color OtherColor = new Color(1f, 1f, 1f, 0.7f);

		private static ZoneBorders _instance;

		private static Material _material;

		private static bool _warnedNoShader;

		private readonly List<LineRenderer> _lines = new List<LineRenderer>();

		private readonly List<Color> _colors = new List<Color>();

		private float _remaining;

		private float _fallbackHeight;

		private bool _alwaysOn;

		private Vector2s _builtZone;

		private int _builtVersion;

		internal static void Show(Vector3 position, float seconds)
		{
			//IL_0052: 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)
			if (!((Object)(object)ZoneSystem.instance == (Object)null) && !((Object)(object)GetMaterial() == (Object)null))
			{
				if (Object.op_Implicit((Object)(object)_instance) && _instance._alwaysOn)
				{
					_instance.Build(position);
				}
				else if (!(seconds <= 0f))
				{
					EnsureInstance();
					_instance.Build(position);
					_instance._remaining = seconds;
					((Behaviour)_instance).enabled = true;
				}
			}
		}

		internal static string ToggleAlwaysOn(Vector3 position)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return "Join a world first.";
			}
			if ((Object)(object)GetMaterial() == (Object)null)
			{
				return "Zone borders are unavailable (no line shader).";
			}
			EnsureInstance();
			_instance._alwaysOn = !_instance._alwaysOn;
			if (_instance._alwaysOn)
			{
				_instance.Build(position);
				((Behaviour)_instance).enabled = true;
				return "Zone borders: on";
			}
			_instance.Clear();
			((Behaviour)_instance).enabled = false;
			return "Zone borders: off";
		}

		private static void EnsureInstance()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_instance))
			{
				_instance = new GameObject("RemoteChunk_ZoneBorders").AddComponent<ZoneBorders>();
			}
		}

		private void Build(Vector3 position)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0068: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Clear();
			_fallbackHeight = position.y;
			Vector2s val = (_builtZone = ZoneSystem.GetZone(position));
			_builtVersion = AnchorManager.Version;
			Vector2s zone = default(Vector2s);
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					((Vector2s)(ref zone))..ctor(val.x + j, val.y + i);
					bool flag = j == 0 && i == 0;
					bool flag2 = AnchorManager.IsAnchored(zone);
					Color color = ((flag2 && AnchorManager.IsSleeping(zone)) ? SleepingColor : (AnchorManager.SpawnsEnabled(zone) ? SpawnsColor : (flag2 ? AnchoredColor : (flag ? CurrentColor : OtherColor))));
					AddOutline(zone, color, flag ? 0.35f : 0.2f);
				}
			}
		}

		private void AddOutline(Vector2s zone, Color color, float width)
		{
			//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_0006: 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_0022: 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)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0057: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			Vector3 zonePos = ZoneSystem.GetZonePos(zone);
			float num = 31.6f;
			Vector3[] array = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(zonePos.x - num, 0f, zonePos.z - num),
				new Vector3(zonePos.x + num, 0f, zonePos.z - num),
				new Vector3(zonePos.x + num, 0f, zonePos.z + num),
				new Vector3(zonePos.x - num, 0f, zonePos.z + num)
			};
			List<Vector3> list = new List<Vector3>();
			for (int i = 0; i < array.Length; i++)
			{
				Vector3 val = array[i];
				Vector3 val2 = array[(i + 1) % array.Length];
				int num2 = Mathf.CeilToInt(Vector3.Distance(val, val2) / 2f);
				for (int j = 0; j < num2; j++)
				{
					list.Add(OnGround(Vector3.Lerp(val, val2, (float)j / (float)num2)));
				}
			}
			LineRenderer val3 = new GameObject("ZoneOutline").AddComponent<LineRenderer>();
			((Component)val3).transform.SetParent(((Component)this).transform, false);
			val3.useWorldSpace = true;
			val3.loop = true;
			((Renderer)val3).sharedMaterial = _material;
			val3.widthMultiplier = width;
			val3.numCornerVertices = 2;
			((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)val3).receiveShadows = false;
			val3.positionCount = list.Count;
			val3.SetPositions(list.ToArray());
			Color startColor = (val3.endColor = color);
			val3.startColor = startColor;
			_lines.Add(val3);
			_colors.Add(color);
		}

		private Vector3 OnGround(Vector3 point)
		{
			//IL_0007: 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)
			ZoneSystem instance = ZoneSystem.instance;
			float fallbackHeight = default(float);
			if (!instance.GetGroundHeight(point, ref fallbackHeight))
			{
				fallbackHeight = _fallbackHeight;
			}
			point.y = Mathf.Max(fallbackHeight, instance.m_waterLevel) + 0.4f;
			return point;
		}

		private void Update()
		{
			//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_0024: 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_0044: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00c3: 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)
			if (_alwaysOn)
			{
				Player localPlayer = Player.m_localPlayer;
				if (Object.op_Implicit((Object)(object)localPlayer))
				{
					Vector3 position = ((Component)localPlayer).transform.position;
					if (ZoneSystem.GetZone(position) != _builtZone || AnchorManager.Version != _builtVersion)
					{
						Build(position);
					}
				}
				return;
			}
			_remaining -= Time.deltaTime;
			if (_remaining <= 0f)
			{
				Clear();
				((Behaviour)this).enabled = false;
				return;
			}
			float num = Mathf.Clamp01(_remaining / 1f);
			for (int i = 0; i < _lines.Count; i++)
			{
				Color val = _colors[i];
				val.a *= num;
				LineRenderer obj = _lines[i];
				Color startColor =