Decompiled source of ProtectiveWards v2.0.11

ProtectiveWards.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn.GUI;
using Jotunn.Managers;
using Jotunn.Utils;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ProtectiveWards;
using ProtectiveWards.Compatibility;
using SoftReferenceableAssets;
using Splatform;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Protective Wards")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Protective Wards")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f71912b8-9b1c-4181-911a-1550f4ec2889")]
[assembly: AssemblyFileVersion("2.0.11")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.11.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private const string defaultLanguage = "English";

		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin Plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static IEnumerator Load()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized));
			if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", "")))
			{
				PlatformPrefs.SetString("language", "English");
			}
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Expected O, but got Unknown
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> localizationFiles = new Dictionary<string, string>();
			string[] prefixes = new string[2]
			{
				Plugin.Info.Metadata.Name + ".",
				Plugin.Info.Metadata.Name.Replace(" ", "") + "."
			};
			Scan(Paths.ConfigPath, warn: true);
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml.");
			}
			Dictionary<string, string> dictionary = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary == null)
			{
				throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text = null;
			if (language != "English")
			{
				if (localizationFiles.ContainsKey(language))
				{
					text = File.ReadAllText(localizationFiles[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text == null && localizationFiles.ContainsKey("English"))
			{
				text = File.ReadAllText(localizationFiles["English"]);
			}
			if (text != null)
			{
				Dictionary<string, string> dictionary2;
				try
				{
					dictionary2 = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>();
				}
				catch (Exception arg)
				{
					global::ProtectiveWards.ProtectiveWards.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}");
					dictionary2 = new Dictionary<string, string>();
				}
				foreach (KeyValuePair<string, string> item in dictionary2)
				{
					dictionary[item.Key] = item.Value;
				}
			}
			loadedTexts[language] = dictionary;
			foreach (KeyValuePair<string, string> item2 in dictionary)
			{
				UpdatePlaceholderText(__instance, item2.Key);
			}
			void Scan(string root, bool warn)
			{
				foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories)
					where fileExtensions.Contains(Path.GetExtension(f))
					select f)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3);
					string[] array3 = prefixes;
					foreach (string text2 in array3)
					{
						if (fileNameWithoutExtension.StartsWith(text2))
						{
							string text3 = fileNameWithoutExtension.Substring(text2.Length);
							if (!string.IsNullOrWhiteSpace(text3))
							{
								if (localizationFiles.ContainsKey(text3))
								{
									if (warn)
									{
										global::ProtectiveWards.ProtectiveWards.LogInfo("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3);
									}
								}
								else
								{
									localizationFiles[text3] = item3;
								}
							}
							break;
						}
					}
				}
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace ProtectiveWards
{
	internal static class AdminServerFeatures
	{
		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		private static class Terminal_InitTerminal_RegisterCommands
		{
			private static void Postfix()
			{
				RegisterCommands();
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "Start")]
		private static class ZoneSystem_Start_RegisterAdminRPCs
		{
			private static void Postfix()
			{
				RegisterRPCs();
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "OnDestroy")]
		private static class ZoneSystem_OnDestroy_ResetAdminRPCs
		{
			private static void Postfix()
			{
				ResetRPCRegistration();
			}
		}

		[HarmonyPatch(typeof(Piece), "SetCreator")]
		private static class Piece_SetCreator_CheckWardBuildLimit
		{
			private static void Postfix(Piece __instance, long uid)
			{
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
				if (ProtectiveWards.wardBuildLimitPerPlayer.Value <= 0 || (Object)(object)__instance == (Object)null || uid == 0L || (Object)(object)((Component)__instance).GetComponent<PrivateArea>() == (Object)null || !WardZdoUtils.IsWardPrefab(((Component)__instance).gameObject))
				{
					return;
				}
				ZNetView componentZNetView = ((Component)(object)__instance).GetComponentZNetView();
				if ((Object)(object)componentZNetView == (Object)null || !componentZNetView.IsValid())
				{
					return;
				}
				ZDO zDO = componentZNetView.GetZDO();
				if (zDO != null)
				{
					ZDOID uid2 = zDO.m_uid;
					if (!s_requestedWardLimitChecks.Contains(uid2))
					{
						s_requestedWardLimitChecks.Add(uid2);
						RequestWardBuildLimitCheck(uid, uid2);
					}
				}
			}
		}

		private const string RPC_PermitPlayer = "PW_PermitPlayer";

		private const string RPC_UnpermitPlayer = "PW_UnpermitPlayer";

		private const string RPC_SetWardEnabled = "PW_SetWardEnabled";

		private const string RPC_ToggleWardPermitted = "PW_ToggleWardPermitted";

		private const string RPC_SetWardExpired = "PW_SetWardExpired";

		private const string RPC_CheckWardBuildLimit = "PW_CheckWardBuildLimit";

		private const string RPC_DestroyWardForBuildLimit = "PW_DestroyWardForBuildLimit";

		private static readonly HashSet<ZDOID> s_requestedWardLimitChecks = new HashSet<ZDOID>();

		private static bool s_rpcRegistered;

		private static bool s_commandRegistered;

		internal static void RegisterRPCs()
		{
			if (!s_rpcRegistered && ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<ZPackage>("PW_DestroyWardForBuildLimit", (Action<long, ZPackage>)RPC_DestroyWardForBuildLimitClient);
				ZNet instance = ZNet.instance;
				if (instance != null && instance.IsServer())
				{
					ZRoutedRpc.instance.Register<ZPackage>("PW_PermitPlayer", (Action<long, ZPackage>)RPC_PermitPlayerServer);
					ZRoutedRpc.instance.Register<ZPackage>("PW_UnpermitPlayer", (Action<long, ZPackage>)RPC_UnpermitPlayerServer);
					ZRoutedRpc.instance.Register<ZPackage>("PW_SetWardEnabled", (Action<long, ZPackage>)RPC_SetWardEnabledServer);
					ZRoutedRpc.instance.Register<ZPackage>("PW_ToggleWardPermitted", (Action<long, ZPackage>)RPC_ToggleWardPermittedServer);
					ZRoutedRpc.instance.Register<ZPackage>("PW_SetWardExpired", (Action<long, ZPackage>)RPC_SetWardExpiredServer);
					ZRoutedRpc.instance.Register<ZPackage>("PW_CheckWardBuildLimit", (Action<long, ZPackage>)RPC_CheckWardBuildLimitServer);
				}
				s_rpcRegistered = true;
			}
		}

		internal static void ResetRPCRegistration()
		{
			s_rpcRegistered = false;
			s_requestedWardLimitChecks.Clear();
		}

		private static void RegisterCommands()
		{
			if (!s_commandRegistered)
			{
				RegisterPlayerListCommand("pw_permit", "<player name> - add an online player to the nearest ward within configured range", RequestPermit);
				RegisterPlayerListCommand("ward_permit", "<player name> - add an online player to the nearest ward within configured range", RequestPermit);
				RegisterPlayerListCommand("pw_unpermit", "<player name> - remove a player from the nearest ward permitted list", RequestUnpermit);
				RegisterPlayerListCommand("ward_unpermit", "<player name> - remove a player from the nearest ward permitted list", RequestUnpermit);
				RegisterWardStateCommand("pw_enable", "enable the nearest ward within configured range", enabled: true);
				RegisterWardStateCommand("ward_enable", "enable the nearest ward within configured range", enabled: true);
				RegisterWardStateCommand("pw_disable", "disable the nearest ward within configured range", enabled: false);
				RegisterWardStateCommand("ward_disable", "disable the nearest ward within configured range", enabled: false);
				RegisterWardExpirationStateCommand("pw_set_expired", "mark the nearest ward as expired", expired: true);
				RegisterWardExpirationStateCommand("ward_set_expired", "mark the nearest ward as expired", expired: true);
				RegisterWardExpirationStateCommand("pw_set_unexpired", "clear expired state from the nearest ward", expired: false);
				RegisterWardExpirationStateCommand("ward_set_unexpired", "clear expired state from the nearest ward", expired: false);
				s_commandRegistered = true;
			}
		}

		private static void RegisterPlayerListCommand(string command, string description, Action<string, Terminal> action)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				if (ValidateWardControlCommand(args.Context))
				{
					if (args.Length < 2)
					{
						args.Context.AddString("Usage: <player name>");
					}
					else
					{
						action(GetCommandQuery(args), args.Context);
					}
				}
			}, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		private static void RegisterWardStateCommand(string command, string description, bool enabled)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				if (ValidateWardControlCommand(args.Context))
				{
					RequestSetWardEnabled(enabled, args.Context);
				}
			}, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		private static void RegisterWardExpirationStateCommand(string command, string description, bool expired)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				if (ValidateWardControlCommand(args.Context))
				{
					RequestSetWardExpired(expired, args.Context);
				}
			}, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		private static string GetCommandQuery(ConsoleEventArgs args)
		{
			return string.Join(" ", args.Args.Skip(1).ToArray()).Trim();
		}

		private static bool ValidateWardControlCommand(Terminal context)
		{
			if (AreWardControlCommandsEnabled())
			{
				return true;
			}
			context.AddString("Ward control commands are disabled.");
			return false;
		}

		private static bool AreWardControlCommandsEnabled()
		{
			return ProtectiveWards.wardExternalControlCommandsEnabled.Value;
		}

		private static float GetWardControlCommandRange()
		{
			return Math.Max(ProtectiveWards.wardExternalControlCommandRange.Value, 0f);
		}

		private static void RequestPermit(string query, Terminal context)
		{
			//IL_002c: 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_017a: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				context.AddString("Player is not available.");
				return;
			}
			PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange());
			if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid())
			{
				context.AddString("$pw_permit_no_ward".Localize());
				return;
			}
			if (!ProtectiveWards.HasAccessToWardOrConnectedWard(val, localPlayer))
			{
				context.AddString("$pw_permit_no_access".Localize());
				return;
			}
			List<Player> list = FindOnlinePlayers(query);
			if (list.Count == 0)
			{
				context.AddString("$pw_permit_no_match".Localize(query));
				return;
			}
			if (list.Count > 1)
			{
				context.AddString("$pw_permit_multiple".Localize(string.Join(", ", list.Select((Player p) => p.GetPlayerName()).ToArray())));
				return;
			}
			Player val2 = list[0];
			if (IsPlayerInPermittedList(val, val2.GetPlayerID()))
			{
				context.AddString("$pw_permit_already".Localize());
				return;
			}
			ZPackage val3 = new ZPackage();
			val3.Write(val.m_nview.GetZDO().m_uid);
			val3.Write(localPlayer.GetPlayerID());
			val3.Write(val2.GetPlayerID());
			val3.Write(val2.GetPlayerName());
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				RPC_PermitPlayerServer(0L, new ZPackage(val3.GetArray()));
			}
			else
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("PW_PermitPlayer", new object[1] { val3 });
			}
			context.AddString("Permit for " + val2.GetPlayerName() + " requested.");
		}

		private static void RequestUnpermit(string query, Terminal context)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				context.AddString("Player is not available.");
				return;
			}
			PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange());
			if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid())
			{
				context.AddString("$pw_permit_no_ward".Localize());
				return;
			}
			if (!ProtectiveWards.HasAccessToWardOrConnectedWard(val, localPlayer))
			{
				context.AddString("$pw_permit_no_access".Localize());
				return;
			}
			List<KeyValuePair<long, string>> list = FindPermittedPlayers(val, query);
			if (list.Count == 0)
			{
				context.AddString("No permitted player matched: " + query);
				return;
			}
			if (list.Count > 1)
			{
				context.AddString("Multiple permitted players matched: " + string.Join(", ", list.Select((KeyValuePair<long, string> p) => p.Value).ToArray()));
				return;
			}
			KeyValuePair<long, string> keyValuePair = list[0];
			ZPackage val2 = new ZPackage();
			val2.Write(val.m_nview.GetZDO().m_uid);
			val2.Write(localPlayer.GetPlayerID());
			val2.Write(keyValuePair.Key);
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				RPC_UnpermitPlayerServer(0L, new ZPackage(val2.GetArray()));
			}
			else
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("PW_UnpermitPlayer", new object[1] { val2 });
			}
			context.AddString("Unpermit for " + keyValuePair.Value + " requested.");
		}

		internal static void RequestPermittedWardToggle(PrivateArea ward, long playerID)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0053: 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_008d: Expected O, but got Unknown
			if (ward == null)
			{
				return;
			}
			ZNetView nview = ward.m_nview;
			if (((nview != null) ? new bool?(nview.IsValid()) : ((bool?)null)) == true && playerID != 0)
			{
				ZPackage val = new ZPackage();
				val.Write(ward.m_nview.GetZDO().m_uid);
				val.Write(playerID);
				ZNet instance = ZNet.instance;
				if (instance != null && instance.IsServer())
				{
					RPC_ToggleWardPermittedServer(0L, new ZPackage(val.GetArray()));
				}
				else if (ZRoutedRpc.instance != null)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC("PW_ToggleWardPermitted", new object[1] { val });
				}
			}
		}

		private static void RequestSetWardEnabled(bool enabled, Terminal context)
		{
			//IL_002a: 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_00ab: Expected O, but got Unknown
			//IL_00b7: 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_0100: Expected O, but got Unknown
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				context.AddString("Player is not available.");
				return;
			}
			PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange());
			if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid())
			{
				context.AddString("$pw_permit_no_ward".Localize());
				return;
			}
			if (!CanLocalToggleWard(val))
			{
				context.AddString("$pw_permit_no_access".Localize());
				return;
			}
			ZPackage val2 = new ZPackage();
			val2.Write(val.m_nview.GetZDO().m_uid);
			val2.Write(localPlayer.GetPlayerID());
			val2.Write(enabled);
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				RPC_SetWardEnabledServer(0L, new ZPackage(val2.GetArray()));
			}
			else
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("PW_SetWardEnabled", new object[1] { val2 });
			}
			context.AddString(enabled ? "Ward enable requested." : "Ward disable requested.");
		}

		private static void RequestSetWardExpired(bool expired, Terminal context)
		{
			//IL_004f: 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_00aa: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				context.AddString("Player is not available.");
				return;
			}
			if (!ProtectiveWards.HasLocalWardAdminAccess())
			{
				context.AddString("$pw_permit_no_access".Localize());
				return;
			}
			PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange());
			if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid())
			{
				context.AddString("$pw_permit_no_ward".Localize());
				return;
			}
			ZPackage val2 = new ZPackage();
			val2.Write(val.m_nview.GetZDO().m_uid);
			val2.Write(localPlayer.GetPlayerID());
			val2.Write(localPlayer.GetPlayerName());
			val2.Write(expired);
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				RPC_SetWardExpiredServer(0L, new ZPackage(val2.GetArray()));
			}
			else
			{
				ZRoutedRpc.instance.InvokeRoutedRPC("PW_SetWardExpired", new object[1] { val2 });
			}
			context.AddString(expired ? "Ward expired state requested." : "Ward unexpired state requested.");
		}

		private static void RPC_PermitPlayerServer(long sender, ZPackage package)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			ZDOID val = package.ReadZDOID();
			long claimedPlayerID = package.ReadLong();
			long num = package.ReadLong();
			string text = package.ReadString();
			if (!AreWardControlCommandsEnabled() || !ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player))
			{
				return;
			}
			ZDO ward = WardZdoUtils.GetWard(val);
			if (ward != null && CanRequesterPermit(ward, player.PlayerID))
			{
				Player player2 = Player.GetPlayer(num);
				if (!((Object)(object)player2 == (Object)null) && !(player2.GetPlayerName() != text) && !WardZdoUtils.IsExplicitlyPermitted(ward, num))
				{
					WardZdoUtils.AddPermitted(ward, num, text);
					ProtectiveWards.LogInfo($"Added {text} to ward {val} permitted list by command");
				}
			}
		}

		private static void RPC_UnpermitPlayerServer(long sender, ZPackage package)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			ZDOID val = package.ReadZDOID();
			long claimedPlayerID = package.ReadLong();
			long playerID = package.ReadLong();
			if (AreWardControlCommandsEnabled() && ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player))
			{
				ZDO ward = WardZdoUtils.GetWard(val);
				if (ward != null && CanRequesterPermit(ward, player.PlayerID) && WardZdoUtils.RemovePermitted(ward, playerID, out var playerName))
				{
					ProtectiveWards.LogInfo($"Removed {playerName} from ward {val} permitted list by command");
				}
			}
		}

		private static void RPC_ToggleWardPermittedServer(long sender, ZPackage package)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			ZDOID val = package.ReadZDOID();
			long claimedPlayerID = package.ReadLong();
			if (ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player))
			{
				ZDO ward = WardZdoUtils.GetWard(val);
				if (ward != null && ProtectiveWards.CanPermittedPlayersToggleWard(ward, player.PlayerID))
				{
					bool flag = !ward.GetBool(ZDOVars.s_enabled, false);
					ward.Set(ZDOVars.s_enabled, flag);
					ProtectiveWards.LogInfo(string.Format("{0} ward {1} by permitted player", flag ? "Enabled" : "Disabled", val));
				}
			}
		}

		private static void RPC_SetWardEnabledServer(long sender, ZPackage package)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			ZDOID val = package.ReadZDOID();
			long claimedPlayerID = package.ReadLong();
			bool flag = package.ReadBool();
			if (!AreWardControlCommandsEnabled() || !ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player))
			{
				return;
			}
			ZDO ward = WardZdoUtils.GetWard(val);
			if (ward != null && CanRequesterToggleWard(ward, player.PlayerID) && ward.GetBool(ZDOVars.s_enabled, false) != flag)
			{
				ward.Set(ZDOVars.s_enabled, flag);
				if (flag)
				{
					ProtectiveWards.ActivateConnectedWardZdos(ward, player.PlayerID, player.PlayerName);
				}
				ProtectiveWards.LogInfo(string.Format("{0} ward {1} by command", flag ? "Enabled" : "Disabled", val));
			}
		}

		private static void RPC_SetWardExpiredServer(long sender, ZPackage package)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			ZDOID val = package.ReadZDOID();
			long claimedPlayerID = package.ReadLong();
			package.ReadString();
			bool flag = package.ReadBool();
			if (AreWardControlCommandsEnabled() && ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player))
			{
				ZDO ward = WardZdoUtils.GetWard(val);
				if (ward != null && ProtectiveWards.HasWardManagementAccess(ward, player.PlayerID))
				{
					WardExpiration.SetExpired(ward, flag, player.PlayerID, player.PlayerName);
					ProtectiveWards.LogInfo(string.Format("{0} ward {1} expired state by admin command", flag ? "Marked" : "Cleared", val));
				}
			}
		}

		private static bool CanRequesterPermit(ZDO zdo, long requesterID)
		{
			if (!WardZdoUtils.IsWard(zdo) || requesterID == 0)
			{
				return false;
			}
			if (WardZdoUtils.HasDirectAccessToWardZdo(zdo, requesterID))
			{
				return true;
			}
			if (!IsActiveWardZdoForCommandAccess(zdo))
			{
				return false;
			}
			ProtectiveWards.WardConnectedAccessMode mode = ProtectiveWards.wardAccessConnectedAccessMode?.Value ?? ProtectiveWards.WardConnectedAccessMode.Off;
			return zdo.HasConnectedWardAccess(requesterID, mode, IsActiveWardZdoForCommandAccess);
		}

		private static bool CanLocalToggleWard(PrivateArea ward)
		{
			int result;
			if ((Object)(object)ward != (Object)null)
			{
				if (!((Object)(object)ward.m_piece != (Object)null) || !ward.m_piece.IsCreator())
				{
					Player localPlayer = Player.m_localPlayer;
					result = (ProtectiveWards.HasWardManagementAccess(ward, (localPlayer != null) ? localPlayer.GetPlayerID() : 0) ? 1 : 0);
				}
				else
				{
					result = 1;
				}
			}
			else
			{
				result = 0;
			}
			return (byte)result != 0;
		}

		private static bool CanRequesterToggleWard(ZDO zdo, long requesterID)
		{
			if (!WardZdoUtils.IsWard(zdo) || requesterID == 0)
			{
				return false;
			}
			return ProtectiveWards.HasWardManagementAccess(zdo, requesterID) || zdo.IsCreator(requesterID);
		}

		private static bool IsActiveWardZdoForCommandAccess(ZDO zdo)
		{
			return WardZdoUtils.IsWard(zdo) && zdo.GetBool(ZDOVars.s_enabled, false) && !WardExpiration.IsExpired(zdo);
		}

		private static bool IsPlayerInPermittedList(PrivateArea ward, long playerID)
		{
			return (Object)(object)ward != (Object)null && ward.GetPermittedPlayers().Any((KeyValuePair<long, string> player) => player.Key == playerID);
		}

		private static List<KeyValuePair<long, string>> FindPermittedPlayers(PrivateArea ward, string query)
		{
			string normalized = query.Trim();
			if (normalized.Length == 0)
			{
				return new List<KeyValuePair<long, string>>();
			}
			List<KeyValuePair<long, string>> permittedPlayers = ward.GetPermittedPlayers();
			List<KeyValuePair<long, string>> list = permittedPlayers.Where((KeyValuePair<long, string> player) => string.Equals(player.Value, normalized, StringComparison.OrdinalIgnoreCase)).ToList();
			if (list.Count > 0)
			{
				return list;
			}
			return permittedPlayers.Where((KeyValuePair<long, string> player) => player.Value.IndexOf(normalized, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
		}

		private static PrivateArea FindNearestWard(Vector3 point, float range)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			PrivateArea result = null;
			float num = Math.Max(range, 0f);
			foreach (PrivateArea allArea in PrivateArea.m_allAreas)
			{
				if (!((Object)(object)allArea == (Object)null) && (int)allArea.m_ownerFaction <= 0)
				{
					float num2 = Utils.DistanceXZ(((Component)allArea).transform.position, point);
					if (num2 <= num)
					{
						num = num2;
						result = allArea;
					}
				}
			}
			return result;
		}

		private static List<Player> FindOnlinePlayers(string query)
		{
			string normalized = query.Trim();
			if (normalized.Length == 0)
			{
				return new List<Player>();
			}
			List<Player> allPlayers = Player.GetAllPlayers();
			List<Player> list = allPlayers.Where((Player player) => string.Equals(player.GetPlayerName(), normalized, StringComparison.OrdinalIgnoreCase)).ToList();
			if (list.Count > 0)
			{
				return list;
			}
			return allPlayers.Where((Player player) => player.GetPlayerName().IndexOf(normalized, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
		}

		private static void RequestWardBuildLimitCheck(long creatorID, ZDOID newWardID)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0010: 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_003e: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(creatorID);
			val.Write(newWardID);
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				RPC_CheckWardBuildLimitServer(0L, new ZPackage(val.GetArray()));
				return;
			}
			ZRoutedRpc instance2 = ZRoutedRpc.instance;
			if (instance2 != null)
			{
				instance2.InvokeRoutedRPC("PW_CheckWardBuildLimit", new object[1] { val });
			}
		}

		private static void RPC_CheckWardBuildLimitServer(long sender, ZPackage package)
		{
			//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)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			long num = package.ReadLong();
			ZDOID val = package.ReadZDOID();
			try
			{
				if (ProtectiveWards.wardBuildLimitPerPlayer.Value <= 0 || num == 0L || ((ZDOID)(ref val)).Equals(ZDOID.None) || !ProtectiveWards.TryGetRoutedPlayer(sender, num, out var player))
				{
					return;
				}
				ZDOMan instance = ZDOMan.instance;
				ZDO val2 = ((instance != null) ? instance.GetZDO(val) : null);
				if (val2.IsWard() && val2.IsCreator(player.PlayerID) && (sender == 0L || val2.GetOwner() == sender))
				{
					int value = ProtectiveWards.wardBuildLimitPerPlayer.Value;
					int num2 = WardZdoUtils.CountWardsByCreator(player.PlayerID);
					if (num2 > value)
					{
						int current = Math.Max(num2 - 1, 0);
						SendDestroyWardForBuildLimit(val2, current, value);
					}
				}
			}
			finally
			{
				s_requestedWardLimitChecks.Remove(val);
			}
		}

		private static void SendDestroyWardForBuildLimit(ZDO zdo, int current, int limit)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			if (zdo != null)
			{
				ZDOID uid = zdo.m_uid;
				long owner = zdo.GetOwner();
				DestroyWardForBuildLimitServer(zdo);
				ZPackage val = new ZPackage();
				val.Write(uid);
				val.Write(current);
				val.Write(limit);
				if (owner != 0L && ZRoutedRpc.instance != null)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(owner, "PW_DestroyWardForBuildLimit", new object[1] { val });
				}
				else if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					RPC_DestroyWardForBuildLimitClient(0L, new ZPackage(val.GetArray()));
				}
			}
		}

		private static void DestroyWardForBuildLimitServer(ZDO zdo)
		{
			if (zdo != null && ZDOMan.instance != null)
			{
				zdo.SetOwner(ZDOMan.instance.m_sessionID);
				ZDOMan.instance.DestroyZDO(zdo);
			}
		}

		private static void RPC_DestroyWardForBuildLimitClient(long sender, ZPackage package)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (ProtectiveWards.IsServerRpcSender(sender))
			{
				ZDOID wardID = package.ReadZDOID();
				int num = package.ReadInt();
				int num2 = package.ReadInt();
				DestroyLocalWard(wardID);
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "$pw_ward_limit_reached".Localize(num.ToString(), num2.ToString()), 0, (Sprite)null, false);
				}
			}
		}

		private static void DestroyLocalWard(ZDOID wardID)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ZNetScene.instance == (Object)null))
			{
				GameObject val = ZNetScene.instance.FindInstance(wardID);
				if ((Object)(object)val != (Object)null)
				{
					ZNetScene.instance.Destroy(val);
				}
			}
		}
	}
	internal static class ItemNameTokens
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class ObjectDB_Awake_UpdateItemNameTokens
		{
			private static void Postfix()
			{
				UpdateRegisters();
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		private static class ObjectDB_CopyOtherDB_UpdateItemNameTokens
		{
			private static void Postfix()
			{
				UpdateRegisters();
			}
		}

		[HarmonyPatch(typeof(Player), "Load")]
		private static class Player_Load_UpdateItemNameTokens
		{
			private static void Prefix()
			{
				UpdateRegisters();
			}
		}

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

		internal static void UpdateRegisters()
		{
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return;
			}
			s_itemNames.Clear();
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if (component != null)
				{
					SharedData val = component.m_itemData?.m_shared;
					if (val != null && !string.IsNullOrWhiteSpace(val.m_name) && val.m_name.StartsWith("$"))
					{
						Register(((Object)item).name, val.m_name);
						Register(val.m_name, val.m_name);
						Localization instance = Localization.instance;
						Register((instance != null) ? instance.Localize(val.m_name) : null, val.m_name);
					}
				}
			}
		}

		internal static string GetItemName(this string input)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				return "";
			}
			string text = input.Trim();
			string value;
			return s_itemNames.TryGetValue(text, out value) ? value : text;
		}

		private static void Register(string key, string token)
		{
			if (!string.IsNullOrWhiteSpace(key))
			{
				s_itemNames[key.Trim()] = token;
			}
		}
	}
	public static class StringExtensions
	{
		public static string Localize(this string text)
		{
			return (Localization.instance != null) ? Localization.instance.Localize(text) : text;
		}

		public static string Localize(this string text, params string[] words)
		{
			return (Localization.instance != null) ? Localization.instance.Localize(text, words) : text;
		}
	}
	internal static class ComponentExtensions
	{
		internal static bool IsVehicle(this Component component)
		{
			return (Object)(object)component != (Object)null && ((Object)(object)component.GetComponentInParent<Ship>() != (Object)null || (Object)(object)component.GetComponentInParent<Vagon>() != (Object)null);
		}

		internal static ZNetView GetComponentZNetView(this Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			PrivateArea val = (PrivateArea)(object)((component is PrivateArea) ? component : null);
			if (val != null)
			{
				return val.m_nview;
			}
			Ship val2 = (Ship)(object)((component is Ship) ? component : null);
			if (val2 != null)
			{
				return val2.m_nview;
			}
			ShipControlls val3 = (ShipControlls)(object)((component is ShipControlls) ? component : null);
			if (val3 != null)
			{
				return val3.m_nview;
			}
			Vagon val4 = (Vagon)(object)((component is Vagon) ? component : null);
			if (val4 != null)
			{
				return val4.m_nview;
			}
			Catapult val5 = (Catapult)(object)((component is Catapult) ? component : null);
			if (val5 != null)
			{
				return val5.m_nview;
			}
			MapTable val6 = (MapTable)(object)((component is MapTable) ? component : null);
			if (val6 != null)
			{
				return val6.m_nview;
			}
			Turret val7 = (Turret)(object)((component is Turret) ? component : null);
			if (val7 != null)
			{
				return val7.m_nview;
			}
			Fireplace val8 = (Fireplace)(object)((component is Fireplace) ? component : null);
			if (val8 != null)
			{
				return val8.m_nview;
			}
			Tameable val9 = (Tameable)(object)((component is Tameable) ? component : null);
			if (val9 != null)
			{
				return val9.m_nview;
			}
			Sadle val10 = (Sadle)(object)((component is Sadle) ? component : null);
			if (val10 != null)
			{
				return val10.m_nview;
			}
			TeleportWorld val11 = (TeleportWorld)(object)((component is TeleportWorld) ? component : null);
			if (val11 != null)
			{
				return val11.m_nview;
			}
			return component.GetComponent<ZNetView>() ?? component.GetComponentInParent<ZNetView>();
		}

		internal static ZDO GetWardZDO(this Component component)
		{
			ZNetView componentZNetView = component.GetComponentZNetView();
			return ((Object)(object)componentZNetView != (Object)null && componentZNetView.IsValid()) ? componentZNetView.GetZDO() : null;
		}
	}
	internal static class UIExtensions
	{
		internal static void KeepClickSfxOnly(this GameObject button)
		{
			ButtonSfx val = default(ButtonSfx);
			if ((Object)(object)button != (Object)null && button.TryGetComponent<ButtonSfx>(ref val))
			{
				val.m_selectSfxPrefab = null;
				val.m_selectSfxPrefabVibrationOnly = null;
			}
		}
	}
	internal static class PrivateAreaExtensions
	{
		internal static ZDO GetWardZDO(this PrivateArea ward)
		{
			ZNetView componentZNetView = ((Component)(object)ward).GetComponentZNetView();
			return ((Object)(object)componentZNetView != (Object)null && componentZNetView.IsValid()) ? componentZNetView.GetZDO() : null;
		}

		internal static bool HasDirectWardAccess(this PrivateArea ward, long playerID)
		{
			return ProtectiveWards.HasDirectAccessToWard(ward, playerID);
		}

		internal static bool HasConnectedWardAccess(this PrivateArea ward, long playerID, ProtectiveWards.WardConnectedAccessMode mode)
		{
			return ProtectiveWards.HasAccessToWardOrConnectedWard(ward, playerID, mode);
		}
	}
	internal static class WardZdoExtensions
	{
		internal static bool IsWard(this ZDO zdo)
		{
			return WardZdoUtils.IsWard(zdo);
		}

		internal static long GetCreatorId(this ZDO zdo)
		{
			return (zdo != null) ? zdo.GetLong(ZDOVars.s_creator, 0L) : 0;
		}

		internal static bool IsCreator(this ZDO zdo, long creatorID)
		{
			return zdo.GetCreatorId() == creatorID;
		}

		internal static bool HasDirectWardAccess(this ZDO zdo, long playerID)
		{
			return WardZdoUtils.HasDirectAccessToWardZdo(zdo, playerID);
		}

		internal static bool HasConnectedWardAccess(this ZDO zdo, long playerID, ProtectiveWards.WardConnectedAccessMode mode, Func<ZDO, bool> isActiveCandidate)
		{
			return WardZdoUtils.HasAccessToWardOrConnectedWardZdo(zdo, playerID, mode, isActiveCandidate);
		}

		internal static float GetWardRadius(this ZDO zdo)
		{
			return WardZdoUtils.GetWardRadius(zdo);
		}

		internal static bool IsWardPermitted(this ZDO zdo, long playerID)
		{
			return WardZdoUtils.IsPermitted(zdo, playerID);
		}
	}
	internal static class WardZdoUtils
	{
		private sealed class WardTraversal
		{
			internal readonly HashSet<ZDOID> Visited = new HashSet<ZDOID>();

			internal readonly List<ZDO> Queue = new List<ZDO>();

			internal readonly List<ZDO> Candidates = new List<ZDO>();
		}

		[HarmonyPatch]
		private static class ZDOMan_Load_WardListInit
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				yield return AccessTools.Method(typeof(ZDOMan), "Load", (Type[])null, (Type[])null);
				yield return AccessTools.Method(typeof(ZDOMan), "LoadChunks", (Type[])null, (Type[])null);
			}

			private static void Postfix(ZDOMan __instance)
			{
				RebuildWardObjects(__instance);
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "Start")]
		private static class ZoneSystem_Start_WardListInit
		{
			private static void Postfix()
			{
				EnsureWardObjectsInitialized();
				UpdateAllWardRuntimeFields();
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[]
		{
			typeof(ZDOID),
			typeof(Vector3),
			typeof(int)
		})]
		private static class ZDOMan_CreateNewZDO_WardListAddNew
		{
			private static void Postfix(int prefabHashIn, ZDO __result)
			{
				if (ShouldTrackServerWards() && (prefabHashIn == 0 || prefabHashIn == s_wardPrefabHash))
				{
					AddIfWard(__result);
				}
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")]
		private static class ZDOMan_HandleDestroyedZDO_WardListRemove
		{
			private static void Prefix(ZDOMan __instance, ZDOID uid)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				if (__instance != null)
				{
					RemoveIfWard(__instance.GetZDO(uid));
				}
			}
		}

		[HarmonyPatch(typeof(ZDO), "SetPrefab")]
		private static class ZDO_SetPrefab_WardListUpdate
		{
			private static void Postfix(ZDO __instance)
			{
				if (ShouldTrackServerWards())
				{
					if (IsWard(__instance))
					{
						s_wardObjects.Add(__instance);
						EnsureWardSettingsInitialized(__instance);
					}
					else
					{
						s_wardObjects.Remove(__instance);
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZDO), "Deserialize")]
		private static class ZDO_Deserialize_WardListAdd
		{
			private static void Postfix(ZDO __instance)
			{
				AddIfWard(__instance);
				ProtectiveWards.NotifyWardZdoSynchronized(__instance);
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "OnDestroy")]
		private static class ZoneSystem_OnDestroy_WardListClear
		{
			private static void Postfix()
			{
				s_wardObjects.Clear();
				s_wardObjectsInitialized = false;
				s_wardDefaultRadius = 32f;
				s_wardDefaultRadiusCached = false;
			}
		}

		[CompilerGenerated]
		private sealed class <ConnectedAccessWardZdos>d__45 : IEnumerable<ZDO>, IEnumerable, IEnumerator<ZDO>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private ZDO <>2__current;

			private int <>l__initialThreadId;

			private ZDO rootWard;

			public ZDO <>3__rootWard;

			private ProtectiveWards.WardConnectedAccessMode mode;

			public ProtectiveWards.WardConnectedAccessMode <>3__mode;

			private Func<ZDO, bool> isActiveCandidate;

			public Func<ZDO, bool> <>3__isActiveCandidate;

			private WardTraversal <traversal>5__1;

			private int <queueIndex>5__2;

			private IEnumerator<ZDO> <>s__3;

			private ZDO <candidate>5__4;

			private ZDO <current>5__5;

			private List<ZDO>.Enumerator <>s__6;

			private ZDO <candidate>5__7;

			private bool <retain>5__8;

			ZDO IEnumerator<ZDO>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ConnectedAccessWardZdos>d__45(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 2)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<traversal>5__1 = null;
				<>s__3 = null;
				<candidate>5__4 = null;
				<current>5__5 = null;
				<>s__6 = default(List<ZDO>.Enumerator);
				<candidate>5__7 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_0202: Unknown result type (might be due to invalid IL or missing references)
				//IL_0290: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						if (!IsWard(rootWard))
						{
							return false;
						}
						<>2__current = rootWard;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						if (mode == ProtectiveWards.WardConnectedAccessMode.Off)
						{
							return false;
						}
						<traversal>5__1 = ((s_traversalPool.Count > 0) ? s_traversalPool.Pop() : new WardTraversal());
						<>1__state = -3;
						<traversal>5__1.Visited.Add(rootWard.m_uid);
						<traversal>5__1.Queue.Add(rootWard);
						<>s__3 = GetAllWards().GetEnumerator();
						try
						{
							while (<>s__3.MoveNext())
							{
								<candidate>5__4 = <>s__3.Current;
								<traversal>5__1.Candidates.Add(<candidate>5__4);
								<candidate>5__4 = null;
							}
						}
						finally
						{
							if (<>s__3 != null)
							{
								<>s__3.Dispose();
							}
						}
						<>s__3 = null;
						<queueIndex>5__2 = 0;
						goto IL_02f3;
					case 2:
						{
							<>1__state = -3;
							goto IL_01b6;
						}
						IL_02f3:
						if (<queueIndex>5__2 < <traversal>5__1.Queue.Count)
						{
							<current>5__5 = <traversal>5__1.Queue[<queueIndex>5__2++];
							if (<queueIndex>5__2 > 1)
							{
								<>2__current = <current>5__5;
								<>1__state = 2;
								return true;
							}
							goto IL_01b6;
						}
						<>m__Finally1();
						return false;
						IL_01b6:
						<>s__6 = <traversal>5__1.Candidates.GetEnumerator();
						try
						{
							while (<>s__6.MoveNext())
							{
								<candidate>5__7 = <>s__6.Current;
								if (IsWard(<candidate>5__7) && !<traversal>5__1.Visited.Contains(<candidate>5__7.m_uid) && (isActiveCandidate == null || isActiveCandidate(<candidate>5__7)) && AreWardZdosOverlapping(<current>5__5, <candidate>5__7) && CanShareConnectedWardAccess(rootWard, <candidate>5__7, mode))
								{
									<traversal>5__1.Visited.Add(<candidate>5__7.m_uid);
									<traversal>5__1.Queue.Add(<candidate>5__7);
									<candidate>5__7 = null;
								}
							}
						}
						finally
						{
							((IDisposable)<>s__6/*cast due to .constrained prefix*/).Dispose();
						}
						<>s__6 = default(List<ZDO>.Enumerator);
						<current>5__5 = null;
						goto IL_02f3;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				<retain>5__8 = <traversal>5__1.Candidates.Count <= 4096 && <traversal>5__1.Queue.Count <= 4096;
				<traversal>5__1.Visited.Clear();
				<traversal>5__1.Queue.Clear();
				<traversal>5__1.Candidates.Clear();
				if (<retain>5__8 && s_traversalPool.Count < 4)
				{
					s_traversalPool.Push(<traversal>5__1);
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<ZDO> IEnumerable<ZDO>.GetEnumerator()
			{
				<ConnectedAccessWardZdos>d__45 <ConnectedAccessWardZdos>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<ConnectedAccessWardZdos>d__ = this;
				}
				else
				{
					<ConnectedAccessWardZdos>d__ = new <ConnectedAccessWardZdos>d__45(0);
				}
				<ConnectedAccessWardZdos>d__.rootWard = <>3__rootWard;
				<ConnectedAccessWardZdos>d__.mode = <>3__mode;
				<ConnectedAccessWardZdos>d__.isActiveCandidate = <>3__isActiveCandidate;
				return <ConnectedAccessWardZdos>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<ZDO>)this).GetEnumerator();
			}
		}

		internal const string WardPrefabName = "guard_stone";

		internal static readonly int s_wardPrefabHash = StringExtensionMethods.GetStableHashCode("guard_stone");

		private static readonly HashSet<ZDO> s_wardObjects = new HashSet<ZDO>();

		private static bool s_wardObjectsInitialized;

		private static bool s_wardDefaultRadiusCached;

		private static float s_wardDefaultRadius = 32f;

		private const int MaximumPooledBuffers = 4;

		private const int MaximumRetainedEntries = 4096;

		private static readonly Stack<HashSet<ZDOID>> s_visitedPool = new Stack<HashSet<ZDOID>>();

		private static readonly Stack<WardTraversal> s_traversalPool = new Stack<WardTraversal>();

		private static readonly int[] s_permittedPlayerIdHashes = CreatePermittedPlayerIdHashes();

		private const string HasFieldsKey = "HasFields";

		private const string HasPrivateAreaFieldsKey = "HasFieldsPrivateArea";

		internal const string PrivateAreaRadiusField = "PrivateArea.m_radius";

		private const string PrivateAreaFlashAvailableField = "PrivateArea.m_flashAvailable";

		private static int[] CreatePermittedPlayerIdHashes()
		{
			int[] array = new int[64];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = StringExtensionMethods.GetStableHashCode("pu_id" + i);
			}
			return array;
		}

		internal static bool IsWardPrefab(GameObject gameObject)
		{
			return (Object)(object)gameObject != (Object)null && Utils.GetPrefabName(gameObject) == "guard_stone";
		}

		internal static bool IsWard(ZDO zdo)
		{
			return zdo != null && zdo.GetPrefab() == s_wardPrefabHash;
		}

		internal static bool HasStoredWardSettings(ZDO zdo)
		{
			return IsWard(zdo) && zdo.GetInt(ProtectiveWards.s_wardSettingsVersion, 0) >= 1;
		}

		private static bool CanWriteWardZdo(ZDO zdo)
		{
			int result;
			if (IsWard(zdo))
			{
				ZNet instance = ZNet.instance;
				result = ((instance != null && instance.IsServer()) ? 1 : 0);
			}
			else
			{
				result = 0;
			}
			return (byte)result != 0;
		}

		internal static void EnsureWardSettingsInitialized(ZDO zdo)
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: 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_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			if (!CanWriteWardZdo(zdo))
			{
				return;
			}
			if (!HasStoredWardSettings(zdo))
			{
				bool flag = ProtectiveWards.HasZdoVec3(zdo, ProtectiveWards.s_color);
				if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_customRange))
				{
					zdo.Set(ProtectiveWards.s_customRange, ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range) || ProtectiveWards.setWardRange.Value);
				}
				if (!ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range))
				{
					zdo.Set(ProtectiveWards.s_range, ProtectiveWards.ClampWardRange(ProtectiveWards.wardRange.Value));
				}
				if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_customColor))
				{
					zdo.Set(ProtectiveWards.s_customColor, flag || ProtectiveWards.wardEmissionColorEnabled.Value);
				}
				if (!ProtectiveWards.HasZdoVec3(zdo, ProtectiveWards.s_color))
				{
					zdo.Set(ProtectiveWards.s_color, new Vector3(ProtectiveWards.wardEmissionColor.Value.r, ProtectiveWards.wardEmissionColor.Value.g, ProtectiveWards.wardEmissionColor.Value.b));
				}
				if (!ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_colorMultiplier))
				{
					zdo.Set(ProtectiveWards.s_colorMultiplier, flag ? 1f : ProtectiveWards.wardEmissionColorMultiplier.Value);
				}
				if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_bubbleEnabled))
				{
					zdo.Set(ProtectiveWards.s_bubbleEnabled, ProtectiveWards.wardBubbleShow.Value);
				}
				if (!ProtectiveWards.HasZdoVec3(zdo, ProtectiveWards.s_bubbleColor))
				{
					zdo.Set(ProtectiveWards.s_bubbleColor, new Vector3(ProtectiveWards.wardBubbleColor.Value.r, ProtectiveWards.wardBubbleColor.Value.g, ProtectiveWards.wardBubbleColor.Value.b));
				}
				if (!ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_bubbleColorAlpha))
				{
					zdo.Set(ProtectiveWards.s_bubbleColorAlpha, ProtectiveWards.wardBubbleColor.Value.a);
				}
				SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleRefractionIntensity, ProtectiveWards.wardBubbleRefractionIntensity.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleWaveVel, ProtectiveWards.wardBubbleWaveIntensity.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleGlossiness, ProtectiveWards.wardBubbleGlossiness.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleMetallic, ProtectiveWards.wardBubbleMetallic.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleNormalScale, ProtectiveWards.wardBubbleNormalScale.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleDepthFade, ProtectiveWards.wardBubbleDepthFade.Value);
				if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_circleEnabled))
				{
					zdo.Set(ProtectiveWards.s_circleEnabled, ProtectiveWards.wardAreaMarkerPatch.Value);
				}
				SetStringIfMissing(zdo, ProtectiveWards.s_circleStartColor, ColorUtility.ToHtmlStringRGBA(ProtectiveWards.wardAreaMarkerStartColor.Value));
				SetStringIfMissing(zdo, ProtectiveWards.s_circleEndColor, ColorUtility.ToHtmlStringRGBA(ProtectiveWards.wardAreaMarkerEndColor.Value));
				SetFloatIfMissing(zdo, ProtectiveWards.s_circleSpeed, ProtectiveWards.wardAreaMarkerSpeed.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_circleLength, ProtectiveWards.wardAreaMarkerLength.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_circleWidth, ProtectiveWards.wardAreaMarkerWidth.Value);
				SetFloatIfMissing(zdo, ProtectiveWards.s_circleAmount, ProtectiveWards.wardAreaMarkerAmount.Value);
				if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_permitEveryone))
				{
					zdo.Set(ProtectiveWards.s_permitEveryone, ProtectiveWards.permitEveryone.Value);
				}
				if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_permittedPlayersCanToggle))
				{
					zdo.Set(ProtectiveWards.s_permittedPlayersCanToggle, ProtectiveWards.wardPermittedPlayersCanToggle.Value);
				}
				zdo.Set(ProtectiveWards.s_wardSettingsVersion, 1, false);
			}
			UpdateWardRuntimeFields(zdo);
		}

		private static void SetFloatIfMissing(ZDO zdo, int key, float value)
		{
			if (!ProtectiveWards.HasZdoFloat(zdo, key))
			{
				zdo.Set(key, value);
			}
		}

		private static void SetStringIfMissing(ZDO zdo, int key, string value)
		{
			if (!ProtectiveWards.HasZdoString(zdo, key))
			{
				zdo.Set(key, value ?? string.Empty);
			}
		}

		internal static void UpdateWardRuntimeFields(ZDO zdo)
		{
			if (CanWriteWardZdo(zdo))
			{
				zdo.Set("HasFields", true);
				zdo.Set("HasFieldsPrivateArea", true);
				zdo.Set("PrivateArea.m_radius", GetWardRadius(zdo));
				zdo.Set("PrivateArea.m_flashAvailable", true);
			}
		}

		internal static void UpdateAllWardRuntimeFields()
		{
			ZDO[] array = GetAllWards().ToArray();
			foreach (ZDO zdo in array)
			{
				EnsureWardSettingsInitialized(zdo);
			}
		}

		internal static IEnumerable<ZDO> GetAllWards()
		{
			if (ShouldTrackServerWards())
			{
				EnsureWardObjectsInitialized();
				PruneWardObjects();
				foreach (ZDO s_wardObject in s_wardObjects)
				{
					yield return s_wardObject;
				}
				yield break;
			}
			HashSet<ZDOID> visited = ((s_visitedPool.Count > 0) ? s_visitedPool.Pop() : new HashSet<ZDOID>());
			try
			{
				foreach (PrivateArea area in PrivateArea.m_allAreas)
				{
					int num;
					if (area == null)
					{
						num = 0;
					}
					else
					{
						ZNetView nview = area.m_nview;
						num = ((((nview != null) ? new bool?(nview.IsValid()) : ((bool?)null)) == true) ? 1 : 0);
					}
					ZDO zdo = ((num != 0) ? area.m_nview.GetZDO() : null);
					if (IsWard(zdo) && visited.Add(zdo.m_uid))
					{
						yield return zdo;
					}
				}
			}
			finally
			{
				bool retain = visited.Count <= 4096;
				visited.Clear();
				if (retain && s_visitedPool.Count < 4)
				{
					s_visitedPool.Push(visited);
				}
			}
		}

		internal static bool TryFindActiveWardContainingPoint(Vector3 point, Func<ZDO, bool> isActive, out ZDO ward)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			ward = null;
			if (ShouldTrackServerWards())
			{
				EnsureWardObjectsInitialized();
				PruneWardObjects();
				foreach (ZDO s_wardObject in s_wardObjects)
				{
					if (!isActive(s_wardObject) || !ProtectiveWards.IsInsideWardXZ(s_wardObject, point))
					{
						continue;
					}
					ward = s_wardObject;
					return true;
				}
				return false;
			}
			foreach (PrivateArea allArea in PrivateArea.m_allAreas)
			{
				object obj;
				if (allArea != null)
				{
					ZNetView nview = allArea.m_nview;
					if (((nview != null) ? new bool?(nview.IsValid()) : ((bool?)null)) == true)
					{
						obj = allArea.m_nview.GetZDO();
						goto IL_00da;
					}
				}
				obj = null;
				goto IL_00da;
				IL_00da:
				ZDO val = (ZDO)obj;
				if (!IsWard(val) || !isActive(val) || !ProtectiveWards.IsInsideWardXZ(val, point))
				{
					continue;
				}
				ward = val;
				return true;
			}
			return false;
		}

		internal static int CountWardsByCreator(long creatorID)
		{
			if (creatorID == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (ZDO allWard in GetAllWards())
			{
				if (allWard.IsCreator(creatorID))
				{
					num++;
				}
			}
			return num;
		}

		internal static PrivateArea FindLoadedWard(ZDOID zdoID)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			foreach (PrivateArea allArea in PrivateArea.m_allAreas)
			{
				if (!((Object)(object)allArea == (Object)null) && !((Object)(object)allArea.m_nview == (Object)null) && allArea.m_nview.IsValid())
				{
					ZDO zDO = allArea.m_nview.GetZDO();
					if (zDO != null && ((ZDOID)(ref zDO.m_uid)).Equals(zdoID))
					{
						return allArea;
					}
				}
			}
			return null;
		}

		internal static ZDO GetWard(ZDOID zdoID)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			ZDOMan instance = ZDOMan.instance;
			ZDO val = ((instance != null) ? instance.GetZDO(zdoID) : null);
			return IsWard(val) ? val : null;
		}

		internal static bool TryGetWard(ZDOID zdoID, out ZDO zdo)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			zdo = GetWard(zdoID);
			return zdo != null;
		}

		internal static List<KeyValuePair<long, string>> GetPermittedPlayers(ZDO zdo)
		{
			List<KeyValuePair<long, string>> list = new List<KeyValuePair<long, string>>();
			if (!IsWard(zdo))
			{
				return list;
			}
			int num = Math.Max(zdo.GetInt(ZDOVars.s_permitted, 0), 0);
			for (int i = 0; i < num; i++)
			{
				long num2 = zdo.GetLong("pu_id" + i, 0L);
				if (num2 != 0)
				{
					list.Add(new KeyValuePair<long, string>(num2, zdo.GetString("pu_name" + i, "")));
				}
			}
			return list;
		}

		internal static bool IsExplicitlyPermitted(ZDO zdo, long playerID)
		{
			if (playerID == 0L || !IsWard(zdo))
			{
				return false;
			}
			int num = Math.Max(zdo.GetInt(ZDOVars.s_permitted, 0), 0);
			for (int i = 0; i < num; i++)
			{
				int num2 = ((i < s_permittedPlayerIdHashes.Length) ? s_permittedPlayerIdHashes[i] : StringExtensionMethods.GetStableHashCode("pu_id" + i));
				if (zdo.GetLong(num2, 0L) == playerID)
				{
					return true;
				}
			}
			return false;
		}

		internal static bool AddPermitted(ZDO zdo, long playerID, string playerName)
		{
			if (!IsWard(zdo) || playerID == 0)
			{
				return false;
			}
			List<KeyValuePair<long, string>> permittedPlayers = GetPermittedPlayers(zdo);
			if (permittedPlayers.Any((KeyValuePair<long, string> player) => player.Key == playerID))
			{
				return false;
			}
			permittedPlayers.Add(new KeyValuePair<long, string>(playerID, playerName ?? ""));
			SetPermittedPlayers(zdo, permittedPlayers);
			return true;
		}

		internal static bool RemovePermitted(ZDO zdo, long playerID, out string playerName)
		{
			playerName = "";
			if (!IsWard(zdo) || playerID == 0)
			{
				return false;
			}
			List<KeyValuePair<long, string>> permittedPlayers = GetPermittedPlayers(zdo);
			KeyValuePair<long, string> keyValuePair = permittedPlayers.FirstOrDefault((KeyValuePair<long, string> player) => player.Key == playerID);
			if (keyValuePair.Key == 0)
			{
				return false;
			}
			playerName = keyValuePair.Value ?? "";
			permittedPlayers.RemoveAll((KeyValuePair<long, string> player) => player.Key == playerID);
			SetPermittedPlayers(zdo, permittedPlayers);
			return true;
		}

		internal static void SetPermittedPlayers(ZDO zdo, List<KeyValuePair<long, string>> permitted)
		{
			if (IsWard(zdo))
			{
				if (permitted == null)
				{
					permitted = new List<KeyValuePair<long, string>>();
				}
				zdo.Set(ZDOVars.s_permitted, permitted.Count, false);
				for (int i = 0; i < permitted.Count; i++)
				{
					zdo.Set("pu_id" + i, permitted[i].Key);
					zdo.Set("pu_name" + i, permitted[i].Value ?? "");
				}
			}
		}

		internal static bool IsPermitted(ZDO zdo, long playerID)
		{
			if (zdo == null || playerID == 0)
			{
				return false;
			}
			if (ProtectiveWards.HasWardManagementAccess(zdo, playerID))
			{
				return true;
			}
			if (IsExplicitlyPermitted(zdo, playerID))
			{
				return true;
			}
			return GuildsCompat.HasWardGuildAccess(zdo, playerID);
		}

		internal static bool HasDirectAccessToWardZdo(ZDO zdo, long playerID)
		{
			if (zdo == null)
			{
				return true;
			}
			if (playerID == 0)
			{
				return false;
			}
			if (!IsWard(zdo))
			{
				return false;
			}
			if (zdo.IsCreator(playerID))
			{
				return true;
			}
			return IsPermitted(zdo, playerID);
		}

		internal static bool UseCustomWardRange(ZDO zdo)
		{
			if (!ProtectiveWards.ArePerWardSettingsEnabled())
			{
				return ProtectiveWards.setWardRange.Value;
			}
			if (zdo == null)
			{
				return false;
			}
			if (HasStoredWardSettings(zdo))
			{
				return zdo.GetBool(ProtectiveWards.s_customRange, false);
			}
			return ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range) || zdo.GetBool(ProtectiveWards.s_customRange, false);
		}

		internal static float GetConfiguredWardRange(ZDO zdo)
		{
			if (!ProtectiveWards.ArePerWardSettingsEnabled())
			{
				return ProtectiveWards.ClampWardRange(ProtectiveWards.wardRange.Value);
			}
			if (zdo == null)
			{
				return GetWardDefaultRadius();
			}
			return ProtectiveWards.ClampWardRange(zdo.GetFloat(ProtectiveWards.s_range, GetWardDefaultRadius()));
		}

		internal static float GetWardDefaultRadius()
		{
			if (s_wardDefaultRadiusCached)
			{
				return ProtectiveWards.ClampWardRange(s_wardDefaultRadius);
			}
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("guard_stone");
				PrivateArea val = ((prefab != null) ? prefab.GetComponent<PrivateArea>() : null);
				if ((Object)(object)val != (Object)null)
				{
					s_wardDefaultRadius = val.m_radius;
					s_wardDefaultRadiusCached = true;
				}
			}
			return ProtectiveWards.ClampWardRange(s_wardDefaultRadius);
		}

		internal static float GetWardRadius(ZDO zdo)
		{
			if (zdo == null)
			{
				return GetWardDefaultRadius();
			}
			float radius = default(float);
			if (ProtectiveWards.ArePerWardSettingsEnabled() && !HasStoredWardSettings(zdo) && zdo.GetFloat("PrivateArea.m_radius", ref radius))
			{
				return ProtectiveWards.ClampWardRange(radius);
			}
			return UseCustomWardRange(zdo) ? GetConfiguredWardRange(zdo) : GetWardDefaultRadius();
		}

		internal static bool AreWardZdosOverlapping(ZDO protectedWard, ZDO candidateWard)
		{
			//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)
			if (!IsWard(protectedWard) || !IsWard(candidateWard))
			{
				return false;
			}
			float wardRadius = GetWardRadius(protectedWard);
			float wardRadius2 = GetWardRadius(candidateWard);
			return ProtectiveWards.GetConfiguredWardDistance(protectedWard.GetPosition(), candidateWard.GetPosition()) <= wardRadius + wardRadius2;
		}

		internal static bool CanShareConnectedWardAccess(ZDO protectedWard, ZDO candidateWard, ProtectiveWards.WardConnectedAccessMode mode)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (mode == ProtectiveWards.WardConnectedAccessMode.Off)
			{
				return false;
			}
			if (!IsWard(protectedWard) || !IsWard(candidateWard))
			{
				return false;
			}
			if (protectedWard == candidateWard || ((ZDOID)(ref protectedWard.m_uid)).Equals(candidateWard.m_uid))
			{
				return true;
			}
			switch (mode)
			{
			case ProtectiveWards.WardConnectedAccessMode.SameCreatorOnly:
			{
				long creatorId = protectedWard.GetCreatorId();
				long creatorId2 = candidateWard.GetCreatorId();
				return creatorId != 0L && creatorId == creatorId2;
			}
			case ProtectiveWards.WardConnectedAccessMode.MutualTrust:
			{
				long creatorId = protectedWard.GetCreatorId();
				long creatorId2 = candidateWard.GetCreatorId();
				return creatorId != 0L && creatorId2 != 0L && HasDirectAccessToWardZdo(protectedWard, creatorId2) && HasDirectAccessToWardZdo(candidateWard, creatorId);
			}
			case ProtectiveWards.WardConnectedAccessMode.AnyConnected:
				return true;
			default:
				return false;
			}
		}

		internal static IEnumerable<ZDO> ConnectedAccessWardZdos(ZDO rootWard, ProtectiveWards.WardConnectedAccessMode mode, Func<ZDO, bool> isActiveCandidate)
		{
			if (!IsWard(rootWard))
			{
				yield break;
			}
			yield return rootWard;
			if (mode == ProtectiveWards.WardConnectedAccessMode.Off)
			{
				yield break;
			}
			WardTraversal traversal = ((s_traversalPool.Count > 0) ? s_traversalPool.Pop() : new WardTraversal());
			try
			{
				traversal.Visited.Add(rootWard.m_uid);
				traversal.Queue.Add(rootWard);
				foreach (ZDO candidate in GetAllWards())
				{
					traversal.Candidates.Add(candidate);
				}
				int queueIndex = 0;
				while (queueIndex < traversal.Queue.Count)
				{
					ZDO current = traversal.Queue[queueIndex++];
					if (queueIndex > 1)
					{
						yield return current;
					}
					foreach (ZDO candidate2 in traversal.Candidates)
					{
						if (IsWard(candidate2) && !traversal.Visited.Contains(candidate2.m_uid) && (isActiveCandidate == null || isActiveCandidate(candidate2)) && AreWardZdosOverlapping(current, candidate2) && CanShareConnectedWardAccess(rootWard, candidate2, mode))
						{
							traversal.Visited.Add(candidate2.m_uid);
							traversal.Queue.Add(candidate2);
						}
					}
				}
			}
			finally
			{
				((<ConnectedAccessWardZdos>d__45)/*Error near IL_0008: stateMachine*/).<retain>5__8 = traversal.Candidates.Count <= 4096 && traversal.Queue.Count <= 4096;
				traversal.Visited.Clear();
				traversal.Queue.Clear();
				traversal.Candidates.Clear();
				bool retain = default(bool);
				if (retain && s_traversalPool.Count < 4)
				{
					s_traversalPool.Push(traversal);
				}
			}
		}

		internal static bool HasAccessToWardOrConnectedWardZdo(ZDO rootWard, long playerID, ProtectiveWards.WardConnectedAccessMode mode, Func<ZDO, bool> isActiveCandidate)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (HasDirectAccessToWardZdo(rootWard, playerID))
			{
				return true;
			}
			if (mode == ProtectiveWards.WardConnectedAccessMode.Off)
			{
				return false;
			}
			foreach (ZDO item in ConnectedAccessWardZdos(rootWard, mode, isActiveCandidate))
			{
				if (item == null || ((ZDOID)(ref item.m_uid)).Equals(rootWard.m_uid) || !HasDirectAccessToWardZdo(item, playerID))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		private static bool ShouldTrackServerWards()
		{
			return (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer();
		}

		private static void AddIfWard(ZDO zdo)
		{
			if (ShouldTrackServerWards() && IsWard(zdo))
			{
				s_wardObjects.Add(zdo);
				EnsureWardSettingsInitialized(zdo);
			}
		}

		private static void RemoveIfWard(ZDO zdo)
		{
			if (zdo != null && IsWard(zdo))
			{
				s_wardObjects.Remove(zdo);
			}
		}

		private static void PruneWardObjects()
		{
			s_wardObjects.RemoveWhere((ZDO zdo) => zdo == null || !IsWard(zdo));
		}

		private static void EnsureWardObjectsInitialized()
		{
			if (ShouldTrackServerWards())
			{
				ZDOMan instance = ZDOMan.instance;
				if (instance != null && !s_wardObjectsInitialized)
				{
					RebuildWardObjects(instance);
				}
			}
		}

		private static void RebuildWardObjects(ZDOMan zdoMan)
		{
			s_wardObjects.Clear();
			if (!ShouldTrackServerWards() || zdoMan == null)
			{
				s_wardObjectsInitialized = false;
				return;
			}
			s_wardObjectsInitialized = true;
			foreach (KeyValuePair<ZDOID, ZDO> item in zdoMan.m_objectsByID)
			{
				AddIfWard(item.Value);
			}
		}
	}
	internal static class BackgroundProtection
	{
		private struct CachedBool
		{
			public float Time;

			public bool Value;
		}

		[HarmonyPatch(typeof(ZoneSystem), "Start")]
		private static class ZoneSystem_Start_ResetBackgroundProtectionCache
		{
			private static void Postfix()
			{
				ResetCache();
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "OnDestroy")]
		private static class ZoneSystem_OnDestroy_ResetBackgroundProtectionCache
		{
			private static void Postfix()
			{
				ResetCache();
			}
		}

		[HarmonyPatch(typeof(Player), "TryPlacePiece")]
		private static class Player_TryPlacePiece_PreventBuildingWithoutPermittedPlayersNearby
		{
			[HarmonyPriority(800)]
			private static bool Prefix(Player __instance, Piece piece, ref bool __result)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null || (Object)(object)piece == (Object)null || (Object)(object)__instance.m_placementGhost == (Object)null)
				{
					return true;
				}
				if (!IsBuildingRestricted(__instance, __instance.m_placementGhost.transform.position))
				{
					return true;
				}
				((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false);
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
		private static class Player_CheckCanRemovePiece_PreventDemolishingWithoutPermittedPlayersNearby
		{
			[HarmonyPriority(800)]
			private static bool Prefix(Player __instance, Piece piece, ref bool __result)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null || (Object)(object)piece == (Object)null)
				{
					return true;
				}
				if (piece.IsCreator())
				{
					return true;
				}
				if (!IsBuildingRestricted(__instance, ((Component)piece).transform.position))
				{
					return true;
				}
				((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false);
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(WearNTear), "Damage")]
		private static class WearNTear_Damage_BackgroundProtection
		{
			private static void Prefix(WearNTear __instance, HitData hit)
			{
				if (!((Object)(object)__instance == (Object)null) && hit != null)
				{
					bool flag = (Object)(object)((Component)__instance).GetComponentInParent<Ship>() != (Object)null;
					bool flag2 = (Object)(object)((Component)__instance).GetComponentInParent<Vagon>() != (Object)null;
					if ((!ProtectiveWards.vehiclesNeverProtected.Value || !(flag || flag2)) && (ShouldSuppressWearNTearDamage(__instance, hit, flag, flag2) || ShouldSuppressTameDamageToStructure(__instance, hit)))
					{
						((DamageTypes)(ref hit.m_damage)).Modify(0f);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		private static class Character_Damage_BackgroundTameProtection
		{
			private static void Prefix(Character __instance, HitData hit)
			{
				if (ShouldSuppressTameCharacterDamage(__instance))
				{
					((DamageTypes)(ref hit.m_damage)).Modify(0f);
				}
			}
		}

		[HarmonyPatch(typeof(BaseAI), "FindEnemy")]
		private static class BaseAI_FindEnemy_PacifyTames
		{
			private static bool Prefix(BaseAI __instance, ref Character __result)
			{
				if (!ShouldPacifyTame(__instance))
				{
					return true;
				}
				__result = null;
				return false;
			}
		}

		[HarmonyPatch(typeof(BaseAI), "FindRandomStaticTarget")]
		private static class BaseAI_FindRandomStaticTarget_PacifyTames
		{
			private static bool Prefix(BaseAI __instance, ref StaticTarget __result)
			{
				if (!ShouldPacifyTame(__instance))
				{
					return true;
				}
				__result = null;
				return false;
			}
		}

		[HarmonyPatch(typeof(BaseAI), "FindClosestStaticPriorityTarget")]
		private static class BaseAI_FindClosestStaticPriorityTarget_PacifyTames
		{
			private static bool Prefix(BaseAI __instance, ref StaticTarget __result)
			{
				if (!ShouldPacifyTame(__instance))
				{
					return true;
				}
				__result = null;
				return false;
			}
		}

		[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
		private static class MonsterAI_UpdateAI_PacifyTames
		{
			private static void Prefix(MonsterAI __instance)
			{
				if (ShouldPacifyTame((BaseAI)(object)__instance))
				{
					PacifyMonster(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(AnimalAI), "UpdateAI")]
		private static class AnimalAI_UpdateAI_PacifyTames
		{
			private static void Prefix(AnimalAI __instance)
			{
				if (ShouldPacifyTame((BaseAI)(object)__instance))
				{
					PacifyAnimal(__instance);
				}
			}
		}

		private static readonly Dictionary<ZDOID, CachedBool> s_qualifiedBaseCache = new Dictionary<ZDOID, CachedBool>();

		private const float QualifiedBaseCacheSeconds = 10f;

		private static readonly Func<ZDO, bool> activeWardPredicate = IsActiveBackgroundWard;

		internal static void ResetCache()
		{
			s_qualifiedBaseCache.Clear();
		}

		internal static bool IsBackgroundProtectionActiveAt(Vector3 point, out ZDO ward)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			ward = null;
			if (!TryFindBackgroundWard(point, point, out ward))
			{
				return false;
			}
			if (!IsQualifiedProtectedBase(ward))
			{
				return false;
			}
			return !HasEffectiveAccessPresence(ward, point);
		}

		internal static bool TryFindBackgroundWard(Vector3 sourcePoint, Vector3 targetPoint, out ZDO ward)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_004f: 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_0073: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			ward = null;
			bool flag = sourcePoint.x == targetPoint.x && sourcePoint.y == targetPoint.y && sourcePoint.z == targetPoint.z;
			if (!ProtectiveWards.TryResolveWardCheckPoint(sourcePoint, out sourcePoint))
			{
				return false;
			}
			if (flag)
			{
				targetPoint = sourcePoint;
			}
			else if (!ProtectiveWards.TryResolveWardCheckPoint(targetPoint, out targetPoint))
			{
				return false;
			}
			if (flag)
			{
				return WardZdoUtils.TryFindActiveWardContainingPoint(sourcePoint, activeWardPredicate, out ward);
			}
			ProtectiveWards.WardConnectedAccessMode wardConnectedAccessMode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off);
			foreach (ZDO allWard in WardZdoUtils.GetAllWards())
			{
				if (!IsActiveBackgroundWard(allWard) || !ProtectiveWards.IsInsideWardXZ(allWard, sourcePoint))
				{
					continue;
				}
				if (ProtectiveWards.IsInsideWardXZ(allWard, targetPoint))
				{
					ward = allWard;
					return true;
				}
				if (wardConnectedAccessMode == ProtectiveWards.WardConnectedAccessMode.Off)
				{
					continue;
				}
				foreach (ZDO item in WardZdoUtils.ConnectedAccessWardZdos(allWard, wardConnectedAccessMode, activeWardPredicate))
				{
					if (!ProtectiveWards.IsInsideWardXZ(item, targetPoint))
					{
						continue;
					}
					ward = allWard;
					return true;
				}
			}
			return false;
		}

		internal static bool HasEffectiveAccessPresence(ZDO ward, Vector3 point)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00d5: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			if (!WardZdoUtils.IsWard(ward))
			{
				return false;
			}
			ProtectiveWards.WardConnectedAccessMode wardConnectedAccessMode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off);
			float num = Mathf.Max(ProtectiveWards.wardBackgroundPresenceRadius.Value, 0f);
			if (!ProtectiveWards.TryResolveWardCheckPoint(point, out var resolvedPoint))
			{
				return false;
			}
			ProtectiveWards.WardBackgroundPresenceMode value = ProtectiveWards.wardBackgroundPresenceMode.Value;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer == (Object)null || !ProtectiveWards.TryResolveWardCheckPoint(((Component)allPlayer).transform.position, out var resolvedPoint2))
				{
					continue;
				}
				if (value != ProtectiveWards.WardBackgroundPresenceMode.PermittedOnline && value != ProtectiveWards.WardBackgroundPresenceMode.PermittedInsideConnectedArea)
				{
					float num2 = resolvedPoint2.x - resolvedPoint.x;
					float num3 = resolvedPoint2.z - resolvedPoint.z;
					if (!(num2 * num2 + num3 * num3 <= num * num))
					{
						continue;
					}
				}
				if (!ward.HasConnectedWardAccess(allPlayer.GetPlayerID(), wardConnectedAccessMode, activeWardPredicate))
				{
					continue;
				}
				if (value != ProtectiveWards.WardBackgroundPresenceMode.PermittedInsideConnectedArea)
				{
					return true;
				}
				if (ProtectiveWards.IsInsideWardXZ(ward, resolvedPoint2))
				{
					return true;
				}
				if (wardConnectedAccessMode == ProtectiveWards.WardConnectedAccessMode.Off)
				{
					continue;
				}
				foreach (ZDO item in WardZdoUtils.ConnectedAccessWardZdos(ward, wardConnectedAccessMode, activeWardPredicate))
				{
					if (ProtectiveWards.IsInsideWardXZ(item, resolvedPoint2))
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static bool IsQualifiedProtectedBase(ZDO ward)
		{
			//IL_003c: 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)
			if (!WardZdoUtils.IsWard(ward))
			{
				return false;
			}
			int num = Math.Max(ProtectiveWards.wardBackgroundProtectedBaseMinPieces.Value, 0);
			if (num == 0)
			{
				return true;
			}
			if (s_qualifiedBaseCache.TryGetValue(ward.m_uid, out var value) && Time.time - value.Time < 10f)
			{
				return value.Value;
			}
			bool flag = CountPlayerBuiltPiecesInNetwork(ward, num) >= num;
			s_qualifiedBaseCache[ward.m_uid] = new CachedBool
			{
				Time = Time.time,
				Value = flag
			};
			return flag;
		}

		private static int CountPlayerBuiltPiecesInNetwork(ZDO ward, int stopAt)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			ProtectiveWards.WardConnectedAccessMode mode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off);
			HashSet<Piece> hashSet = new HashSet<Piece>();
			List<Piece> list = new List<Piece>();
			foreach (ZDO item in WardZdoUtils.ConnectedAccessWardZdos(ward, mode, activeWardPredicate))
			{
				list.Clear();
				Piece.GetAllPiecesInRadius(item.GetPosition(), item.GetWardRadius(), list);
				foreach (Piece item2 in list)
				{
					if (!((Object)(object)item2 == (Object)null) && item2.IsPlacedByPlayer())
					{
						hashSet.Add(item2);
						if (hashSet.Count >= stopAt)
						{
							return hashSet.Count;
						}
					}
				}
			}
			return hashSet.Count;
		}

		private static bool IsActiveBackgroundWard(ZDO zdo)
		{
			return WardExpiration.IsWardActive(zdo);
		}

		internal static bool ShouldSuppressWearNTearDamage(WearNTear wearNTear, HitData hit, bool isShip, bool isCart)
		{
			//IL_0064: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)wearNTear == (Object)null || hit == null)
			{
				return false;
			}
			Piece val = wearNTear.m_piece ?? ((Component)wearNTear).GetComponent<Piece>();
			bool flag = (Object)(object)val != (Object)null && val.IsPlacedByPlayer();
			if (!flag && !isShip && !isCart)
			{
				return false;
			}
			if (!TryFindBackgroundWard(((Component)wearNTear).transform.position, ((Component)wearNTear).transform.position, out var ward))
			{
				return false;
			}
			if (!IsQualifiedProtectedBase(ward))
			{
				return false;
			}
			Character attacker = hit.GetAttacker();
			if (ProtectiveWards.wardBackgroundStructureProtection.Value == ProtectiveWards.WardBackgroundStructureProtectionMode.BlockNonPermittedPlayerDamage && flag && (Object)(object)attacker != (Object)null && attacker.IsPlayer())
			{
				ZDO zdo = ward;
				Character obj = ((attacker is Player) ? attacker : null);
				if (!zdo.HasConnectedWardAccess((obj != null) ? ((Player)obj).GetPlayerID() : 0, ProtectiveWards.wardBackgroundConnectedAccessMode.Value, IsActiveBackgroundWard))
				{
					return true;
				}
			}
			if (HasEffectiveAccessPresence(ward, ((Component)wearNTear).transform.position))
			{
				return false;
			}
			if (ProtectiveWards.wardBackgroundProtectBoats.Value && isShip)
			{
				return true;
			}
			if (ProtectiveWards.wardBackgroundProtectCarts.Value && isCart)
			{
				return true;
			}
			if (flag)
			{
				if (ProtectiveWards.wardBackgroundStructureProtection.Value == ProtectiveWards.WardBackgroundStructureProtectionMode.BlockAllDamageWhenNoPermittedNearby)
				{
					return true;
				}
				if (ProtectiveWards.wardBackgroundProtectFire.Value && IsFireDamage(hit))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool ShouldSuppressTameDamageToStructure(WearNTear wearNTear, HitData hit)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if (!ProtectiveWards.wardBackgroundTamesPreventDamageToStructures.Value)
			{
				return false;
			}
			if ((Object)(object)wearNTear == (Object)null || hit == null || !hit.HaveAttacker())
			{
				return false;
			}
			Piece val = wearNTear.m_piece ?? ((Component)wearNTear).GetComponent<Piece>();
			if ((Object)(object)val == (Object)null || !val.IsPlacedByPlayer())
			{
				return false;
			}
			Character attacker = hit.GetAttacker();
			if ((Object)(object)attacker == (Object)null || attacker.IsPlayer() || !attacker.IsTamed())
			{
				return false;
			}
			if (!TryFindBackgroundWard(((Component)attacker).transform.position, ((Component)wearNTear).transform.position, out var ward))
			{
				return false;
			}
			if (!IsQualifiedProtectedBase(ward))
			{
				return false;
			}
			return !HasEffectiveAccessPresence(ward, ((Component)attacker).transform.position) && !HasEffectiveAccessPresence(ward, ((Component)wearNTear).transform.position);
		}

		internal static bool ShouldSuppressTameCharacterDamage(Character character)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!ProtectiveWards.wardBackgroundProtectTames.Value)
			{
				return false;
			}
			if ((Object)(object)character == (Object)null || !character.IsTamed())
			{
				return false;
			}
			ZDO ward;
			return IsBackgroundProtectionActiveAt(((Component)character).transform.position, out ward);
		}

		internal static bool ShouldPacifyTame(BaseAI ai)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (ProtectiveWards.wardBackgroundTamePacify.Value == ProtectiveWards.WardBackgroundTamePacifyMode.Off)
			{
				return false;
			}
			if ((Object)(object)ai == (Object)null || (Object)(object)ai.m_character == (Object)null || !ai.m_character.IsTamed())
			{
				return false;
			}
			ZDO ward;
			return IsBackgroundProtectionActiveAt(((Component)ai).transform.position, out ward);
		}

		internal static void PacifyMonster(MonsterAI ai)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ai == (Object)null))
			{
				((BaseAI)ai).SetAlerted(false);
				ai.m_targetCreature = null;
				ai.m_targetStatic = null;
				ai.m_timeSinceAttacking = 0f;
				ai.m_timeSinceSensedTargetCreature = 99999f;
				((BaseAI)ai).SetTargetInfo(ZDOID.None);
			}
		}

		internal static void PacifyAnimal(AnimalAI ai)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ai == (Object)null))
			{
				((BaseAI)ai).SetAlerted(false);
				ai.m_target = null;
				((BaseAI)ai).SetTargetInfo(ZDOID.None);
			}
		}

		internal static bool IsBuildingRestricted(Player player, Vector3 point)
		{
			//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_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!ProtectiveWards.wardBackgroundPreventBuildingAndDemolishing.Value)
			{
				return false;
			}
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			long playerID = player.GetPlayerID();
			if (ProtectiveWards.HasWardAdminAccess(playerID))
			{
				return false;
			}
			if (!TryFindBackgroundWard(point, point, out var ward))
			{
				return false;
			}
			if (!IsQualifiedProtectedBase(ward))
			{
				return false;
			}
			if (ward.HasConnectedWardAccess(player.GetPlayerID(), ProtectiveWards.wardBackgroundConnectedAccessMode.Value, IsActiveBackgroundWard))
			{
				return false;
			}
			return !HasEffectiveAccessPresence(ward, point);
		}

		private static bool IsFireDamage(HitData hit)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			return hit != null && (hit.m_damage.m_fire > 0f || (int)hit.m_hitType == 5);
		}
	}
	internal static class EnumerableExtensions
	{
		public static bool AnySafe<T>(this IEnumerable<T> source, Func<T, bool> predicate)
		{
			if (source == null)
			{
				return false;
			}
			foreach (T item in source)
			{
				if (predicate(item))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal class FullProtection
	{
		[HarmonyPatch(typeof(PrivateArea), "CheckAccess")]
		public static class PrivateArea_CheckAccess_ScopedWardAccessBypass
		{
			private static bool Prefix(ref bool __result)
			{
				if (s_privateAreaCheckBypassDepth <= 0)
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Character), "AddFireDamage")]
		public static class Character_AddFireDamage_IndirectFireDamageProtection
		{
			private static void Prefix(Character __instance, ref float damage)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if (ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position))
				{
					damage = 0f;
				}
			}
		}

		[HarmonyPatch(typeof(Character), "UpdateSmoke")]
		public static class Character_UpdateSmoke_IndirectSmokeDamageProtection
		{
			private static void Prefix(Character __instance, ref float dt)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if (ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position))
				{
					dt = 0f;
				}
			}
		}

		[HarmonyPatch(typeof(WearNTear), "UpdateWear")]
		public static class WearNTear_UpdateWear_RainProtection
		{
			private static void Prefix(WearNTear __instance, float time, ref bool ___m_noRoofWear, ref bool __state)
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)__instance == (Object)null) && ProtectiveWards.wardRainProtection != null && ProtectiveWards.wardRainProtection.Value && ___m_noRoofWear && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && __instance.m_nview.IsOwner() && __instance.ShouldUpdate(time) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true))
				{
					__state = ___m_noRoofWear;
					___m_noRoofWear = false;
				}
			}

			private static void Postfix(ref bool ___m_noRoofWear, ref bool __state)
			{
				Restore(ref ___m_noRoofWear, ref __state);
			}

			private static void Finalizer(ref bool ___m_noRoofWear, ref bool __state)
			{
				Restore(ref ___m_noRoofWear, ref __state);
			}

			private static void Restore(ref bool noRoofWear, ref bool state)
			{
				if (state)
				{
					noRoofWear = true;
					state = false;
				}
			}
		}

		[HarmonyPatch(typeof(Ship), "UpdateUpsideDmg")]
		public static class Ship_UpdateUpsideDmg_PreventShipDamage
		{
			private static bool Prefix(Ship __instance)
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instanc