Decompiled source of ProtectiveWards v2.0.6

ProtectiveWards.dll

Decompiled a day 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.6")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.6.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_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_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_002a: Expected O, but got Unknown
			//IL_0025: 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, (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_002a: Expected O, but got Unknown
			//IL_0025: 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, (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_002a: Expected O, but got Unknown
			//IL_0025: 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, (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("$pw_permit_added".Localize(val2.GetPlayerName()));
		}

		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("Removed " + keyValuePair.Value + " from ward permitted list.");
		}

		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_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_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_0016: Unknown result type (might be due to invalid IL or missing references)
			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);
			}
		}

		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 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 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
	{
		[HarmonyPatch(typeof(ZDOMan), "Load")]
		private static class ZDOMan_Load_WardListInit
		{
			private static void Postfix(ZDOMan __instance)
			{
				RebuildWardObjects(__instance);
			}
		}

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

		[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), "Deserialize")]
		private static class ZDO_Deserialize_WardListAdd
		{
			private static void Postfix(ZDO __instance)
			{
				AddIfWard(__instance);
			}
		}

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

		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;

		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 IEnumerable<ZDO> GetAllWards()
		{
			if (ShouldTrackServerWards())
			{
				EnsureWardObjectsInitialized();
				PruneWardObjects();
				foreach (ZDO s_wardObject in s_wardObjects)
				{
					yield return s_wardObject;
				}
				yield break;
			}
			HashSet<ZDOID> visited = new HashSet<ZDOID>();
			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;
				}
			}
		}

		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)
		{
			return playerID != 0L && GetPermittedPlayers(zdo).Any((KeyValuePair<long, string> player) => player.Key == playerID);
		}

		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;
			}
			bool flag = ProtectiveWards.wardSettingsUseDefaultsForAllWards.Value && ProtectiveWards.setWardRange.Value;
			if (ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range))
			{
				flag = true;
			}
			return zdo.GetBool(ProtectiveWards.s_customRange, flag);
		}

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

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

		internal static float GetWardRadius(ZDO zdo)
		{
			if (zdo == null)
			{
				return GetWardDefaultRadius();
			}
			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;
			}
			HashSet<ZDOID> visited = new HashSet<ZDOID>();
			List<ZDO> queue = new List<ZDO>();
			int queueIndex = 0;
			visited.Add(rootWard.m_uid);
			queue.Add(rootWard);
			while (queueIndex < queue.Count)
			{
				ZDO current = queue[queueIndex++];
				yield return current;
				if (mode == ProtectiveWards.WardConnectedAccessMode.Off)
				{
					continue;
				}
				foreach (ZDO candidate in GetAllWards())
				{
					if (candidate != null && !visited.Contains(candidate.m_uid) && (isActiveCandidate == null || isActiveCandidate(candidate)) && AreWardZdosOverlapping(current, candidate) && CanShareConnectedWardAccess(rootWard, candidate, mode))
					{
						visited.Add(candidate.m_uid);
						queue.Add(candidate);
					}
				}
			}
		}

		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);
			}
		}

		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())
			{
				return;
			}
			ZDOMan instance = ZDOMan.instance;
			if (instance != null)
			{
				if (!s_wardObjectsInitialized)
				{
					RebuildWardObjects(instance);
				}
				else if (s_wardObjects.Count == 0 && instance.m_objectsByID.Count > 0)
				{
					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);
				__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);
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(WearNTear), "Damage")]
		private static class WearNTear_Damage_BackgroundProtection
		{
			private static void Prefix(WearNTear __instance, HitData hit)
			{
				if (ShouldSuppressWearNTearDamage(__instance, hit) || 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 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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			ward = null;
			if (!ProtectiveWards.TryResolveWardCheckPoint(sourcePoint, out sourcePoint) || !ProtectiveWards.TryResolveWardCheckPoint(targetPoint, out targetPoint))
			{
				return false;
			}
			ProtectiveWards.WardConnectedAccessMode mode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off);
			foreach (ZDO allWard in WardZdoUtils.GetAllWards())
			{
				if (!IsActiveBackgroundWard(allWard) || !ProtectiveWards.IsInsideWardXZ(allWard, sourcePoint) || !WardZdoUtils.ConnectedAccessWardZdos(allWard, mode, IsActiveBackgroundWard).AnySafe((ZDO candidate) => ProtectiveWards.IsInsideWardXZ(candidate, targetPoint)))
				{
					continue;
				}
				ward = allWard;
				return true;
			}
			return false;
		}

		internal static bool HasEffectiveAccessPresence(ZDO ward, Vector3 point)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			if (!WardZdoUtils.IsWard(ward))
			{
				return false;
			}
			ProtectiveWards.WardConnectedAccessMode mode = ((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;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer == (Object)null)
				{
					continue;
				}
				long playerID = allPlayer.GetPlayerID();
				if (!ward.HasConnectedWardAccess(playerID, mode, IsActiveBackgroundWard) || !ProtectiveWards.TryResolveWardCheckPoint(((Component)allPlayer).transform.position, out var resolvedPlayerPoint))
				{
					continue;
				}
				switch (ProtectiveWards.wardBackgroundPresenceMode.Value)
				{
				case ProtectiveWards.WardBackgroundPresenceMode.PermittedOnline:
					return true;
				case ProtectiveWards.WardBackgroundPresenceMode.PermittedInsideConnectedArea:
					if (WardZdoUtils.ConnectedAccessWardZdos(ward, mode, IsActiveBackgroundWard).AnySafe((ZDO area) => ProtectiveWards.IsInsideWardXZ(area, resolvedPlayerPoint)))
					{
						return true;
					}
					break;
				default:
					if (Utils.DistanceXZ(resolvedPlayerPoint, resolvedPoint) <= num)
					{
						return true;
					}
					break;
				}
			}
			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_0062: 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, IsActiveBackgroundWard))
			{
				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 WardZdoUtils.IsWard(zdo) && zdo.GetBool(ZDOVars.s_enabled, false) && !WardExpiration.IsExpired(zdo);
		}

		internal static bool ShouldSuppressWearNTearDamage(WearNTear wearNTear, HitData hit)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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();
			bool flag2 = (Object)(object)((Component)wearNTear).GetComponent<Ship>() != (Object)null || (Object)(object)((Component)wearNTear).GetComponentInParent<Ship>() != (Object)null;
			bool flag3 = (Object)(object)((Component)wearNTear).GetComponent<Vagon>() != (Object)null || (Object)(object)((Component)wearNTear).GetComponentInParent<Vagon>() != (Object)null;
			if (!flag && !flag2 && !flag3)
			{
				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 && flag2)
			{
				return true;
			}
			if (ProtectiveWards.wardBackgroundProtectCarts.Value && flag3)
			{
				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, ref bool ___m_noRoofWear, ref bool __state)
			{
				//IL_0053: 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() && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true))
				{
					__state = ___m_noRoofWear;
					___m_noRoofWear = false;
				}
			}

			private static void Postfix(ref bool ___m_noRoofWear, bool __state)
			{
				if (ProtectiveWards.wardRainProtection != null && ProtectiveWards.wardRainProtection.Value && __state)
				{
					___m_noRoofWear = __state;
				}
			}
		}

		[HarmonyPatch(typeof(Ship), "UpdateUpsideDmg")]
		public static class Ship_UpdateUpsideDmg_PreventShipDamage
		{
			private static bool Prefix(Ship __instance)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null || ProtectiveWards.wardShipProtection == null || ProtectiveWards.wardShipProtection.Value == ProtectiveWards.ShipDamageType.Off)
				{
					return true;
				}
				return !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position);
			}
		}

		[HarmonyPatch(typeof(Ship), "UpdateWaterForce")]
		public static class Ship_UpdateWaterForce_PreventShipDamage
		{
			private static void Prefix(Ship __instance, ref float __state)
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)__instance == (Object)null) && ProtectiveWards.wardShipProtection != null && ProtectiveWards.wardShipProtection.Value != ProtectiveWards.ShipDamageType.Off && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position))
				{
					__state = __instance.m_waterImpactDamage;
					__instance.m_waterImpactDamage = 0f;
				}
			}

			private static void Postfix(Ship __instance, float __state)
			{
				if (__state != 0f)
				{
					__instance.m_waterImpactDamage = __state;
				}
			}
		}

		[HarmonyPatch(typeof(Container), "Interact")]
		public static class Container_Interact_PreventUnauthorizedAccess
		{
			[HarmonyPriority(800)]
			private static bool Prefix(Container __instance, Humanoid character, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectChests.Value)
				{
					return true;
				}
				if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character))
				{
					if (__instance.m_checkGuardStone)
					{
						StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state);
					}
					return true;
				}
				__result = true;
				return false;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(Door), "Interact")]
		public static class Door_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Door __instance, Humanoid character, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectDoors.Value)
				{
					return true;
				}
				if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character))
				{
					if (__instance.m_checkGuardStone)
					{
						StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state);
					}
					return true;
				}
				__result = true;
				return false;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(Pickable), "Interact")]
		public static class Pickable_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Pickable __instance, Humanoid character, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectPlants.Value)
				{
					return true;
				}
				if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character))
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(ShipControlls), "Interact")]
		public static class ShipControlls_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(ShipControlls __instance, Humanoid character, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectBoats.Value)
				{
					return true;
				}
				if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character))
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Sadle), "Interact")]
		public static class Sadle_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Sadle __instance, Humanoid character, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectTames.Value)
				{
					return true;
				}
				if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character))
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Tameable), "Interact")]
		public static class Tameable_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Tameable __instance, Humanoid user, bool hold, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectTames.Value)
				{
					return true;
				}
				if (hold)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Tameable), "UseItem")]
		public static class Tameable_UseItem_PreventUnauthorizedAccess
		{
			private static bool Prefix(Tameable __instance, Humanoid user, ItemData item, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectTames.Value)
				{
					return true;
				}
				if (!IsProtectedTameUseItem(__instance, item))
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}

			private static bool IsProtectedTameUseItem(Tameable tameable, ItemData item)
			{
				if ((Object)(object)tameable == (Object)null || item == null || (Object)(object)tameable.m_saddleItem == (Object)null || tameable.m_saddleItem.m_itemData == null)
				{
					return false;
				}
				return tameable.IsTamed() && item.m_shared.m_name == tameable.m_saddleItem.m_itemData.m_shared.m_name;
			}
		}

		[HarmonyPatch(typeof(Petable), "Interact")]
		public static class Petable_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Petable __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectTames.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Pet), "Interact")]
		public static class Pet_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Pet __instance, Humanoid user, bool hold, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectTames.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					if (IsProtectedPetItemStandInteraction(__instance, hold))
					{
						StartPrivateAreaCheckBypass((Component)(object)__instance.m_itemStand, user, ref __state);
					}
					return true;
				}
				return false;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}

			private static bool IsProtectedPetItemStandInteraction(Pet pet, bool hold)
			{
				return hold && (Object)(object)pet != (Object)null && (Object)(object)pet.m_itemStand != (Object)null && pet.m_itemStand.HaveAttachment();
			}
		}

		[HarmonyPatch(typeof(Pet), "UseItem")]
		public static class Pet_UseItem_PreventUnauthorizedAccess
		{
			private static bool Prefix(Pet __instance, Humanoid user, ItemData item, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectTames.Value)
				{
					return true;
				}
				if (!IsProtectedPetUseItem(__instance, item))
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}

			private static bool IsProtectedPetUseItem(Pet pet, ItemData item)
			{
				if ((Object)(object)pet == (Object)null || item == null || (Object)(object)pet.m_FeedItem == (Object)null || pet.m_FeedItem.m_itemData == null)
				{
					return false;
				}
				return item.m_shared.m_name == pet.m_FeedItem.m_itemData.m_shared.m_name;
			}
		}

		[HarmonyPatch(typeof(Vagon), "Interact")]
		public static class Vagon_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Vagon __instance, Humanoid character, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectCarts.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, character, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Feast), "Interact")]
		public static class Feast_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Feast __instance, Humanoid human, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectFood.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, human, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "Interact")]
		public static class ItemDrop_Interact_PreventUnauthorizedFoodAccess
		{
			private static bool Prefix(ItemDrop __instance, Humanoid character, bool alt, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectFood.Value)
				{
					return true;
				}
				if (alt || !IsPlacedConsumable(__instance))
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, character, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "Pickup")]
		public static class ItemDrop_Pickup_PreventUnauthorizedAccess
		{
			private static bool Prefix(ItemDrop __instance, Humanoid character)
			{
				return !ShouldBlockItemPickup(__instance, character);
			}
		}

		[HarmonyPatch(typeof(Humanoid), "Pickup", new Type[]
		{
			typeof(GameObject),
			typeof(bool),
			typeof(bool)
		})]
		public static class Humanoid_Pickup_PreventUnauthorizedAccess
		{
			private static bool Prefix(GameObject go, Humanoid __instance)
			{
				return !ShouldBlockItemPickup((go != null) ? go.GetComponent<ItemDrop>() : null, __instance);
			}
		}

		[HarmonyPatch(typeof(Player), "AutoPickup")]
		public static class Player_AutoPickup_PreventBlockedItemPull
		{
			private static void Prefix(Player __instance)
			{
				s_autoPickupPlayer = __instance;
			}

			private static void Finalizer(Player __instance)
			{
				if ((Object)(object)s_autoPickupPlayer == (Object)(object)__instance)
				{
					s_autoPickupPlayer = null;
				}
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "InTar")]
		public static class ItemDrop_InTar_PreventBlockedAutoPickupPull
		{
			private static void Postfix(ItemDrop __instance, ref bool __result)
			{
				if (!__result && !((Object)(object)s_autoPickupPlayer == (Object)null) && ShouldBlockItemPickup(__instance, (Humanoid)(object)s_autoPickupPlayer, silent: true))
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(ShieldGenerator), "OnAddFuel")]
		public static class ShieldGenerator_OnAddFuel_PreventUnauthorizedAccess
		{
			private static bool Prefix(ShieldGenerator __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectShieldGenerators.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Incinerator), "OnIncinerate")]
		public static class Incinerator_OnIncinerate_PreventUnauthorizedAccess
		{
			private static bool Prefix(Incinerator __instance, Humanoid user, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectIncinerators.Value)
				{
					return true;
				}
				if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return false;
				}
				StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state);
				return true;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "Interact")]
		public static class TeleportWorld_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(TeleportWorld __instance, Humanoid human, bool hold, ref bool __result, ref bool __state)
			{
				if (ProtectiveWards.wardAccessProtectPortals.Value == ProtectiveWards.WardPortalAccessMode.AllowAll)
				{
					return true;
				}
				if (hold)
				{
					return true;
				}
				if (BlockProtectedInteraction((Component)(object)__instance, human, ref __result))
				{
					return false;
				}
				StartPrivateAreaCheckBypass((Component)(object)__instance, human, ref __state);
				return true;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "SetText")]
		public static class TeleportWorld_SetText_PreventUnauthorizedAccess
		{
			private static bool Prefix(TeleportWorld __instance)
			{
				if (ProtectiveWards.wardAccessProtectPortals.Value == ProtectiveWards.WardPortalAccessMode.AllowAll)
				{
					return true;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					return true;
				}
				return !ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, (Humanoid)(object)localPlayer);
			}
		}

		[HarmonyPatch(typeof(TeleportWorldTrigger), "OnTriggerEnter")]
		public static class TeleportWorldTrigger_OnTriggerEnter_PreventUnauthorizedTargetAccess
		{
			private static bool Prefix(TeleportWorldTrigger __instance, Collider colliderIn)
			{
				if (ProtectiveWards.wardAccessProtectPortals.Value != ProtectiveWards.WardPortalAccessMode.BlockAll)
				{
					return true;
				}
				if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_teleportWorld == (Object)null || (Object)(object)colliderIn == (Object)null)
				{
					return true;
				}
				Player component = ((Component)colliderIn).GetComponent<Player>();
				if ((Object)(object)component == (Object)null || (Object)(object)Player.m_localPlayer != (Object)(object)component)
				{
					return true;
				}
				if (ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance.m_teleportWorld, (Humanoid)(object)component))
				{
					return false;
				}
				if (TeleportTargetAccessCheckStarted(__instance.m_teleportWorld, component))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "Interact")]
		public static class CookingStation_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "UseItem")]
		public static class CookingStation_UseItem_PreventUnauthorizedAccess
		{
			private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")]
		public static class CookingStation_OnAddFuelSwitch_PreventUnauthorizedAccess
		{
			private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "OnAddFoodSwitch")]
		public static class CookingStation_OnAddFoodSwitch_PreventUnauthorizedAccess
		{
			private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnAddOre")]
		public static class Smelter_OnAddOre_PreventUnauthorizedAccess
		{
			private static bool Prefix(Smelter __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnEmpty")]
		public static class Smelter_OnEmpty_PreventUnauthorizedAccess
		{
			private static bool Prefix(Smelter __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
		public static class Smelter_OnAddFuel_PreventUnauthorizedAccess
		{
			private static bool Prefix(Smelter __instance, Humanoid user, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Fermenter), "Interact")]
		public static class Fermenter_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Fermenter __instance, Humanoid user, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return false;
				}
				StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state);
				return true;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(Fermenter), "UseItem")]
		public static class Fermenter_UseItem_PreventUnauthorizedAccess
		{
			private static bool Prefix(Fermenter __instance, Humanoid user, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return false;
				}
				StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state);
				return true;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(Beehive), "Interact")]
		public static class Beehive_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(Beehive __instance, Humanoid character, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (BlockProtectedInteraction((Component)(object)__instance, character, ref __result))
				{
					return false;
				}
				StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state);
				return true;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(SapCollector), "Interact")]
		public static class SapCollector_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(SapCollector __instance, Humanoid character, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectProductionStations.Value)
				{
					return true;
				}
				if (BlockProtectedInteraction((Component)(object)__instance, character, ref __result))
				{
					return false;
				}
				StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state);
				return true;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}
		}

		[HarmonyPatch(typeof(ItemStand), "Interact")]
		public static class ItemStand_Interact_PreventUnauthorizedAccess
		{
			private static bool Prefix(ItemStand __instance, Humanoid user, bool hold, bool alt, ref bool __result, ref bool __state)
			{
				if (!ProtectiveWards.wardAccessProtectItemStands.Value)
				{
					return true;
				}
				if (!IsProtectedItemStandInteraction(__instance, hold, alt))
				{
					return true;
				}
				if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result))
				{
					return false;
				}
				StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state);
				return true;
			}

			private static void Finalizer(bool __state)
			{
				StopPrivateAreaCheckBypass(__state);
			}

			private static bool IsProtectedItemStandInteraction(ItemStand itemStand, bool hold, bool alt)
			{
				if ((Object)(object)itemStand == (Object)null)
				{
					return false;
				}
				if (!itemStand.HaveAttachment())
				{
					return itemStand.m_autoAttach && itemStand.m_supportedItems.Count == 1;
				}
				if (hold && itemStand.m_canBeRemoved)
				{
					return true;
				}
				return alt && (Object)(object)itemStand.m_visualItemDrop != (Object)null && itemStand.m_orientationSettings.Count > 1;
			}
		}

		[HarmonyPatch(typeof(ItemStand), "UseItem")]
		public static class ItemStand_UseItem_PreventUnauthorizedAccess
		{
			private static bool Prefix(ItemStand __instance, Humanoid user, ItemData item, ref bool __result)
			{
				if (!ProtectiveWards.wardAccessProtectItemStands.Value)
				{
					return true;
				}
				if (item == null || __instance.HaveAtta