Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ProtectiveWards v2.0.11
ProtectiveWards.dll
Decompiled 4 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using Jotunn.GUI; using Jotunn.Managers; using Jotunn.Utils; using LocalizationManager; using Microsoft.CodeAnalysis; using ProtectiveWards; using ProtectiveWards.Compatibility; using SoftReferenceableAssets; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Protective Wards")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Protective Wards")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f71912b8-9b1c-4181-911a-1550f4ec2889")] [assembly: AssemblyFileVersion("2.0.11")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.11.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LocalizationManager { [PublicAPI] public class Localizer { private const string defaultLanguage = "English"; private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin Plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out string value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary<string, Func<string>>(); } config.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } public static IEnumerator Load() { yield return (object)new WaitUntil((Func<bool>)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized)); if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", ""))) { PlatformPrefs.SetString("language", "English"); } LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> localizationFiles = new Dictionary<string, string>(); string[] prefixes = new string[2] { Plugin.Info.Metadata.Name + ".", Plugin.Info.Metadata.Name.Replace(" ", "") + "." }; Scan(Paths.ConfigPath, warn: true); byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml."); } Dictionary<string, string> dictionary = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array)); if (dictionary == null) { throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text = null; if (language != "English") { if (localizationFiles.ContainsKey(language)) { text = File.ReadAllText(localizationFiles[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text = Encoding.UTF8.GetString(array2); } } } if (text == null && localizationFiles.ContainsKey("English")) { text = File.ReadAllText(localizationFiles["English"]); } if (text != null) { Dictionary<string, string> dictionary2; try { dictionary2 = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>(); } catch (Exception arg) { global::ProtectiveWards.ProtectiveWards.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}"); dictionary2 = new Dictionary<string, string>(); } foreach (KeyValuePair<string, string> item in dictionary2) { dictionary[item.Key] = item.Value; } } loadedTexts[language] = dictionary; foreach (KeyValuePair<string, string> item2 in dictionary) { UpdatePlaceholderText(__instance, item2.Key); } void Scan(string root, bool warn) { foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories) where fileExtensions.Contains(Path.GetExtension(f)) select f) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3); string[] array3 = prefixes; foreach (string text2 in array3) { if (fileNameWithoutExtension.StartsWith(text2)) { string text3 = fileNameWithoutExtension.Substring(text2.Length); if (!string.IsNullOrWhiteSpace(text3)) { if (localizationFiles.ContainsKey(text3)) { if (warn) { global::ProtectiveWards.ProtectiveWards.LogInfo("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3); } } else { localizationFiles[text3] = item3; } } break; } } } } } static Localizer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string> { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace ProtectiveWards { internal static class AdminServerFeatures { [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class Terminal_InitTerminal_RegisterCommands { private static void Postfix() { RegisterCommands(); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] private static class ZoneSystem_Start_RegisterAdminRPCs { private static void Postfix() { RegisterRPCs(); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] private static class ZoneSystem_OnDestroy_ResetAdminRPCs { private static void Postfix() { ResetRPCRegistration(); } } [HarmonyPatch(typeof(Piece), "SetCreator")] private static class Piece_SetCreator_CheckWardBuildLimit { private static void Postfix(Piece __instance, long uid) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.wardBuildLimitPerPlayer.Value <= 0 || (Object)(object)__instance == (Object)null || uid == 0L || (Object)(object)((Component)__instance).GetComponent<PrivateArea>() == (Object)null || !WardZdoUtils.IsWardPrefab(((Component)__instance).gameObject)) { return; } ZNetView componentZNetView = ((Component)(object)__instance).GetComponentZNetView(); if ((Object)(object)componentZNetView == (Object)null || !componentZNetView.IsValid()) { return; } ZDO zDO = componentZNetView.GetZDO(); if (zDO != null) { ZDOID uid2 = zDO.m_uid; if (!s_requestedWardLimitChecks.Contains(uid2)) { s_requestedWardLimitChecks.Add(uid2); RequestWardBuildLimitCheck(uid, uid2); } } } } private const string RPC_PermitPlayer = "PW_PermitPlayer"; private const string RPC_UnpermitPlayer = "PW_UnpermitPlayer"; private const string RPC_SetWardEnabled = "PW_SetWardEnabled"; private const string RPC_ToggleWardPermitted = "PW_ToggleWardPermitted"; private const string RPC_SetWardExpired = "PW_SetWardExpired"; private const string RPC_CheckWardBuildLimit = "PW_CheckWardBuildLimit"; private const string RPC_DestroyWardForBuildLimit = "PW_DestroyWardForBuildLimit"; private static readonly HashSet<ZDOID> s_requestedWardLimitChecks = new HashSet<ZDOID>(); private static bool s_rpcRegistered; private static bool s_commandRegistered; internal static void RegisterRPCs() { if (!s_rpcRegistered && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<ZPackage>("PW_DestroyWardForBuildLimit", (Action<long, ZPackage>)RPC_DestroyWardForBuildLimitClient); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { ZRoutedRpc.instance.Register<ZPackage>("PW_PermitPlayer", (Action<long, ZPackage>)RPC_PermitPlayerServer); ZRoutedRpc.instance.Register<ZPackage>("PW_UnpermitPlayer", (Action<long, ZPackage>)RPC_UnpermitPlayerServer); ZRoutedRpc.instance.Register<ZPackage>("PW_SetWardEnabled", (Action<long, ZPackage>)RPC_SetWardEnabledServer); ZRoutedRpc.instance.Register<ZPackage>("PW_ToggleWardPermitted", (Action<long, ZPackage>)RPC_ToggleWardPermittedServer); ZRoutedRpc.instance.Register<ZPackage>("PW_SetWardExpired", (Action<long, ZPackage>)RPC_SetWardExpiredServer); ZRoutedRpc.instance.Register<ZPackage>("PW_CheckWardBuildLimit", (Action<long, ZPackage>)RPC_CheckWardBuildLimitServer); } s_rpcRegistered = true; } } internal static void ResetRPCRegistration() { s_rpcRegistered = false; s_requestedWardLimitChecks.Clear(); } private static void RegisterCommands() { if (!s_commandRegistered) { RegisterPlayerListCommand("pw_permit", "<player name> - add an online player to the nearest ward within configured range", RequestPermit); RegisterPlayerListCommand("ward_permit", "<player name> - add an online player to the nearest ward within configured range", RequestPermit); RegisterPlayerListCommand("pw_unpermit", "<player name> - remove a player from the nearest ward permitted list", RequestUnpermit); RegisterPlayerListCommand("ward_unpermit", "<player name> - remove a player from the nearest ward permitted list", RequestUnpermit); RegisterWardStateCommand("pw_enable", "enable the nearest ward within configured range", enabled: true); RegisterWardStateCommand("ward_enable", "enable the nearest ward within configured range", enabled: true); RegisterWardStateCommand("pw_disable", "disable the nearest ward within configured range", enabled: false); RegisterWardStateCommand("ward_disable", "disable the nearest ward within configured range", enabled: false); RegisterWardExpirationStateCommand("pw_set_expired", "mark the nearest ward as expired", expired: true); RegisterWardExpirationStateCommand("ward_set_expired", "mark the nearest ward as expired", expired: true); RegisterWardExpirationStateCommand("pw_set_unexpired", "clear expired state from the nearest ward", expired: false); RegisterWardExpirationStateCommand("ward_set_unexpired", "clear expired state from the nearest ward", expired: false); s_commandRegistered = true; } } private static void RegisterPlayerListCommand(string command, string description, Action<string, Terminal> action) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ValidateWardControlCommand(args.Context)) { if (args.Length < 2) { args.Context.AddString("Usage: <player name>"); } else { action(GetCommandQuery(args), args.Context); } } }, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static void RegisterWardStateCommand(string command, string description, bool enabled) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ValidateWardControlCommand(args.Context)) { RequestSetWardEnabled(enabled, args.Context); } }, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static void RegisterWardExpirationStateCommand(string command, string description, bool expired) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ValidateWardControlCommand(args.Context)) { RequestSetWardExpired(expired, args.Context); } }, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static string GetCommandQuery(ConsoleEventArgs args) { return string.Join(" ", args.Args.Skip(1).ToArray()).Trim(); } private static bool ValidateWardControlCommand(Terminal context) { if (AreWardControlCommandsEnabled()) { return true; } context.AddString("Ward control commands are disabled."); return false; } private static bool AreWardControlCommandsEnabled() { return ProtectiveWards.wardExternalControlCommandsEnabled.Value; } private static float GetWardControlCommandRange() { return Math.Max(ProtectiveWards.wardExternalControlCommandRange.Value, 0f); } private static void RequestPermit(string query, Terminal context) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } if (!ProtectiveWards.HasAccessToWardOrConnectedWard(val, localPlayer)) { context.AddString("$pw_permit_no_access".Localize()); return; } List<Player> list = FindOnlinePlayers(query); if (list.Count == 0) { context.AddString("$pw_permit_no_match".Localize(query)); return; } if (list.Count > 1) { context.AddString("$pw_permit_multiple".Localize(string.Join(", ", list.Select((Player p) => p.GetPlayerName()).ToArray()))); return; } Player val2 = list[0]; if (IsPlayerInPermittedList(val, val2.GetPlayerID())) { context.AddString("$pw_permit_already".Localize()); return; } ZPackage val3 = new ZPackage(); val3.Write(val.m_nview.GetZDO().m_uid); val3.Write(localPlayer.GetPlayerID()); val3.Write(val2.GetPlayerID()); val3.Write(val2.GetPlayerName()); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_PermitPlayerServer(0L, new ZPackage(val3.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_PermitPlayer", new object[1] { val3 }); } context.AddString("Permit for " + val2.GetPlayerName() + " requested."); } private static void RequestUnpermit(string query, Terminal context) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } if (!ProtectiveWards.HasAccessToWardOrConnectedWard(val, localPlayer)) { context.AddString("$pw_permit_no_access".Localize()); return; } List<KeyValuePair<long, string>> list = FindPermittedPlayers(val, query); if (list.Count == 0) { context.AddString("No permitted player matched: " + query); return; } if (list.Count > 1) { context.AddString("Multiple permitted players matched: " + string.Join(", ", list.Select((KeyValuePair<long, string> p) => p.Value).ToArray())); return; } KeyValuePair<long, string> keyValuePair = list[0]; ZPackage val2 = new ZPackage(); val2.Write(val.m_nview.GetZDO().m_uid); val2.Write(localPlayer.GetPlayerID()); val2.Write(keyValuePair.Key); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_UnpermitPlayerServer(0L, new ZPackage(val2.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_UnpermitPlayer", new object[1] { val2 }); } context.AddString("Unpermit for " + keyValuePair.Value + " requested."); } internal static void RequestPermittedWardToggle(PrivateArea ward, long playerID) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown if (ward == null) { return; } ZNetView nview = ward.m_nview; if (((nview != null) ? new bool?(nview.IsValid()) : ((bool?)null)) == true && playerID != 0) { ZPackage val = new ZPackage(); val.Write(ward.m_nview.GetZDO().m_uid); val.Write(playerID); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_ToggleWardPermittedServer(0L, new ZPackage(val.GetArray())); } else if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC("PW_ToggleWardPermitted", new object[1] { val }); } } } private static void RequestSetWardEnabled(bool enabled, Terminal context) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } if (!CanLocalToggleWard(val)) { context.AddString("$pw_permit_no_access".Localize()); return; } ZPackage val2 = new ZPackage(); val2.Write(val.m_nview.GetZDO().m_uid); val2.Write(localPlayer.GetPlayerID()); val2.Write(enabled); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_SetWardEnabledServer(0L, new ZPackage(val2.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_SetWardEnabled", new object[1] { val2 }); } context.AddString(enabled ? "Ward enable requested." : "Ward disable requested."); } private static void RequestSetWardExpired(bool expired, Terminal context) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } if (!ProtectiveWards.HasLocalWardAdminAccess()) { context.AddString("$pw_permit_no_access".Localize()); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } ZPackage val2 = new ZPackage(); val2.Write(val.m_nview.GetZDO().m_uid); val2.Write(localPlayer.GetPlayerID()); val2.Write(localPlayer.GetPlayerName()); val2.Write(expired); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_SetWardExpiredServer(0L, new ZPackage(val2.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_SetWardExpired", new object[1] { val2 }); } context.AddString(expired ? "Ward expired state requested." : "Ward unexpired state requested."); } private static void RPC_PermitPlayerServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); long num = package.ReadLong(); string text = package.ReadString(); if (!AreWardControlCommandsEnabled() || !ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { return; } ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && CanRequesterPermit(ward, player.PlayerID)) { Player player2 = Player.GetPlayer(num); if (!((Object)(object)player2 == (Object)null) && !(player2.GetPlayerName() != text) && !WardZdoUtils.IsExplicitlyPermitted(ward, num)) { WardZdoUtils.AddPermitted(ward, num, text); ProtectiveWards.LogInfo($"Added {text} to ward {val} permitted list by command"); } } } private static void RPC_UnpermitPlayerServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); long playerID = package.ReadLong(); if (AreWardControlCommandsEnabled() && ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && CanRequesterPermit(ward, player.PlayerID) && WardZdoUtils.RemovePermitted(ward, playerID, out var playerName)) { ProtectiveWards.LogInfo($"Removed {playerName} from ward {val} permitted list by command"); } } } private static void RPC_ToggleWardPermittedServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); if (ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && ProtectiveWards.CanPermittedPlayersToggleWard(ward, player.PlayerID)) { bool flag = !ward.GetBool(ZDOVars.s_enabled, false); ward.Set(ZDOVars.s_enabled, flag); ProtectiveWards.LogInfo(string.Format("{0} ward {1} by permitted player", flag ? "Enabled" : "Disabled", val)); } } } private static void RPC_SetWardEnabledServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); bool flag = package.ReadBool(); if (!AreWardControlCommandsEnabled() || !ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { return; } ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && CanRequesterToggleWard(ward, player.PlayerID) && ward.GetBool(ZDOVars.s_enabled, false) != flag) { ward.Set(ZDOVars.s_enabled, flag); if (flag) { ProtectiveWards.ActivateConnectedWardZdos(ward, player.PlayerID, player.PlayerName); } ProtectiveWards.LogInfo(string.Format("{0} ward {1} by command", flag ? "Enabled" : "Disabled", val)); } } private static void RPC_SetWardExpiredServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); package.ReadString(); bool flag = package.ReadBool(); if (AreWardControlCommandsEnabled() && ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && ProtectiveWards.HasWardManagementAccess(ward, player.PlayerID)) { WardExpiration.SetExpired(ward, flag, player.PlayerID, player.PlayerName); ProtectiveWards.LogInfo(string.Format("{0} ward {1} expired state by admin command", flag ? "Marked" : "Cleared", val)); } } } private static bool CanRequesterPermit(ZDO zdo, long requesterID) { if (!WardZdoUtils.IsWard(zdo) || requesterID == 0) { return false; } if (WardZdoUtils.HasDirectAccessToWardZdo(zdo, requesterID)) { return true; } if (!IsActiveWardZdoForCommandAccess(zdo)) { return false; } ProtectiveWards.WardConnectedAccessMode mode = ProtectiveWards.wardAccessConnectedAccessMode?.Value ?? ProtectiveWards.WardConnectedAccessMode.Off; return zdo.HasConnectedWardAccess(requesterID, mode, IsActiveWardZdoForCommandAccess); } private static bool CanLocalToggleWard(PrivateArea ward) { int result; if ((Object)(object)ward != (Object)null) { if (!((Object)(object)ward.m_piece != (Object)null) || !ward.m_piece.IsCreator()) { Player localPlayer = Player.m_localPlayer; result = (ProtectiveWards.HasWardManagementAccess(ward, (localPlayer != null) ? localPlayer.GetPlayerID() : 0) ? 1 : 0); } else { result = 1; } } else { result = 0; } return (byte)result != 0; } private static bool CanRequesterToggleWard(ZDO zdo, long requesterID) { if (!WardZdoUtils.IsWard(zdo) || requesterID == 0) { return false; } return ProtectiveWards.HasWardManagementAccess(zdo, requesterID) || zdo.IsCreator(requesterID); } private static bool IsActiveWardZdoForCommandAccess(ZDO zdo) { return WardZdoUtils.IsWard(zdo) && zdo.GetBool(ZDOVars.s_enabled, false) && !WardExpiration.IsExpired(zdo); } private static bool IsPlayerInPermittedList(PrivateArea ward, long playerID) { return (Object)(object)ward != (Object)null && ward.GetPermittedPlayers().Any((KeyValuePair<long, string> player) => player.Key == playerID); } private static List<KeyValuePair<long, string>> FindPermittedPlayers(PrivateArea ward, string query) { string normalized = query.Trim(); if (normalized.Length == 0) { return new List<KeyValuePair<long, string>>(); } List<KeyValuePair<long, string>> permittedPlayers = ward.GetPermittedPlayers(); List<KeyValuePair<long, string>> list = permittedPlayers.Where((KeyValuePair<long, string> player) => string.Equals(player.Value, normalized, StringComparison.OrdinalIgnoreCase)).ToList(); if (list.Count > 0) { return list; } return permittedPlayers.Where((KeyValuePair<long, string> player) => player.Value.IndexOf(normalized, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); } private static PrivateArea FindNearestWard(Vector3 point, float range) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) PrivateArea result = null; float num = Math.Max(range, 0f); foreach (PrivateArea allArea in PrivateArea.m_allAreas) { if (!((Object)(object)allArea == (Object)null) && (int)allArea.m_ownerFaction <= 0) { float num2 = Utils.DistanceXZ(((Component)allArea).transform.position, point); if (num2 <= num) { num = num2; result = allArea; } } } return result; } private static List<Player> FindOnlinePlayers(string query) { string normalized = query.Trim(); if (normalized.Length == 0) { return new List<Player>(); } List<Player> allPlayers = Player.GetAllPlayers(); List<Player> list = allPlayers.Where((Player player) => string.Equals(player.GetPlayerName(), normalized, StringComparison.OrdinalIgnoreCase)).ToList(); if (list.Count > 0) { return list; } return allPlayers.Where((Player player) => player.GetPlayerName().IndexOf(normalized, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); } private static void RequestWardBuildLimitCheck(long creatorID, ZDOID newWardID) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(creatorID); val.Write(newWardID); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_CheckWardBuildLimitServer(0L, new ZPackage(val.GetArray())); return; } ZRoutedRpc instance2 = ZRoutedRpc.instance; if (instance2 != null) { instance2.InvokeRoutedRPC("PW_CheckWardBuildLimit", new object[1] { val }); } } private static void RPC_CheckWardBuildLimitServer(long sender, ZPackage package) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) long num = package.ReadLong(); ZDOID val = package.ReadZDOID(); try { if (ProtectiveWards.wardBuildLimitPerPlayer.Value <= 0 || num == 0L || ((ZDOID)(ref val)).Equals(ZDOID.None) || !ProtectiveWards.TryGetRoutedPlayer(sender, num, out var player)) { return; } ZDOMan instance = ZDOMan.instance; ZDO val2 = ((instance != null) ? instance.GetZDO(val) : null); if (val2.IsWard() && val2.IsCreator(player.PlayerID) && (sender == 0L || val2.GetOwner() == sender)) { int value = ProtectiveWards.wardBuildLimitPerPlayer.Value; int num2 = WardZdoUtils.CountWardsByCreator(player.PlayerID); if (num2 > value) { int current = Math.Max(num2 - 1, 0); SendDestroyWardForBuildLimit(val2, current, value); } } } finally { s_requestedWardLimitChecks.Remove(val); } } private static void SendDestroyWardForBuildLimit(ZDO zdo, int current, int limit) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown if (zdo != null) { ZDOID uid = zdo.m_uid; long owner = zdo.GetOwner(); DestroyWardForBuildLimitServer(zdo); ZPackage val = new ZPackage(); val.Write(uid); val.Write(current); val.Write(limit); if (owner != 0L && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(owner, "PW_DestroyWardForBuildLimit", new object[1] { val }); } else if ((Object)(object)Player.m_localPlayer != (Object)null) { RPC_DestroyWardForBuildLimitClient(0L, new ZPackage(val.GetArray())); } } } private static void DestroyWardForBuildLimitServer(ZDO zdo) { if (zdo != null && ZDOMan.instance != null) { zdo.SetOwner(ZDOMan.instance.m_sessionID); ZDOMan.instance.DestroyZDO(zdo); } } private static void RPC_DestroyWardForBuildLimitClient(long sender, ZPackage package) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.IsServerRpcSender(sender)) { ZDOID wardID = package.ReadZDOID(); int num = package.ReadInt(); int num2 = package.ReadInt(); DestroyLocalWard(wardID); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "$pw_ward_limit_reached".Localize(num.ToString(), num2.ToString()), 0, (Sprite)null, false); } } } private static void DestroyLocalWard(ZDOID wardID) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNetScene.instance == (Object)null)) { GameObject val = ZNetScene.instance.FindInstance(wardID); if ((Object)(object)val != (Object)null) { ZNetScene.instance.Destroy(val); } } } } internal static class ItemNameTokens { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_UpdateItemNameTokens { private static void Postfix() { UpdateRegisters(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDB_CopyOtherDB_UpdateItemNameTokens { private static void Postfix() { UpdateRegisters(); } } [HarmonyPatch(typeof(Player), "Load")] private static class Player_Load_UpdateItemNameTokens { private static void Prefix() { UpdateRegisters(); } } private static readonly Dictionary<string, string> s_itemNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); internal static void UpdateRegisters() { if (!Object.op_Implicit((Object)(object)ObjectDB.instance)) { return; } s_itemNames.Clear(); foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if (component != null) { SharedData val = component.m_itemData?.m_shared; if (val != null && !string.IsNullOrWhiteSpace(val.m_name) && val.m_name.StartsWith("$")) { Register(((Object)item).name, val.m_name); Register(val.m_name, val.m_name); Localization instance = Localization.instance; Register((instance != null) ? instance.Localize(val.m_name) : null, val.m_name); } } } } internal static string GetItemName(this string input) { if (string.IsNullOrWhiteSpace(input)) { return ""; } string text = input.Trim(); string value; return s_itemNames.TryGetValue(text, out value) ? value : text; } private static void Register(string key, string token) { if (!string.IsNullOrWhiteSpace(key)) { s_itemNames[key.Trim()] = token; } } } public static class StringExtensions { public static string Localize(this string text) { return (Localization.instance != null) ? Localization.instance.Localize(text) : text; } public static string Localize(this string text, params string[] words) { return (Localization.instance != null) ? Localization.instance.Localize(text, words) : text; } } internal static class ComponentExtensions { internal static bool IsVehicle(this Component component) { return (Object)(object)component != (Object)null && ((Object)(object)component.GetComponentInParent<Ship>() != (Object)null || (Object)(object)component.GetComponentInParent<Vagon>() != (Object)null); } internal static ZNetView GetComponentZNetView(this Component component) { if ((Object)(object)component == (Object)null) { return null; } PrivateArea val = (PrivateArea)(object)((component is PrivateArea) ? component : null); if (val != null) { return val.m_nview; } Ship val2 = (Ship)(object)((component is Ship) ? component : null); if (val2 != null) { return val2.m_nview; } ShipControlls val3 = (ShipControlls)(object)((component is ShipControlls) ? component : null); if (val3 != null) { return val3.m_nview; } Vagon val4 = (Vagon)(object)((component is Vagon) ? component : null); if (val4 != null) { return val4.m_nview; } Catapult val5 = (Catapult)(object)((component is Catapult) ? component : null); if (val5 != null) { return val5.m_nview; } MapTable val6 = (MapTable)(object)((component is MapTable) ? component : null); if (val6 != null) { return val6.m_nview; } Turret val7 = (Turret)(object)((component is Turret) ? component : null); if (val7 != null) { return val7.m_nview; } Fireplace val8 = (Fireplace)(object)((component is Fireplace) ? component : null); if (val8 != null) { return val8.m_nview; } Tameable val9 = (Tameable)(object)((component is Tameable) ? component : null); if (val9 != null) { return val9.m_nview; } Sadle val10 = (Sadle)(object)((component is Sadle) ? component : null); if (val10 != null) { return val10.m_nview; } TeleportWorld val11 = (TeleportWorld)(object)((component is TeleportWorld) ? component : null); if (val11 != null) { return val11.m_nview; } return component.GetComponent<ZNetView>() ?? component.GetComponentInParent<ZNetView>(); } internal static ZDO GetWardZDO(this Component component) { ZNetView componentZNetView = component.GetComponentZNetView(); return ((Object)(object)componentZNetView != (Object)null && componentZNetView.IsValid()) ? componentZNetView.GetZDO() : null; } } internal static class UIExtensions { internal static void KeepClickSfxOnly(this GameObject button) { ButtonSfx val = default(ButtonSfx); if ((Object)(object)button != (Object)null && button.TryGetComponent<ButtonSfx>(ref val)) { val.m_selectSfxPrefab = null; val.m_selectSfxPrefabVibrationOnly = null; } } } internal static class PrivateAreaExtensions { internal static ZDO GetWardZDO(this PrivateArea ward) { ZNetView componentZNetView = ((Component)(object)ward).GetComponentZNetView(); return ((Object)(object)componentZNetView != (Object)null && componentZNetView.IsValid()) ? componentZNetView.GetZDO() : null; } internal static bool HasDirectWardAccess(this PrivateArea ward, long playerID) { return ProtectiveWards.HasDirectAccessToWard(ward, playerID); } internal static bool HasConnectedWardAccess(this PrivateArea ward, long playerID, ProtectiveWards.WardConnectedAccessMode mode) { return ProtectiveWards.HasAccessToWardOrConnectedWard(ward, playerID, mode); } } internal static class WardZdoExtensions { internal static bool IsWard(this ZDO zdo) { return WardZdoUtils.IsWard(zdo); } internal static long GetCreatorId(this ZDO zdo) { return (zdo != null) ? zdo.GetLong(ZDOVars.s_creator, 0L) : 0; } internal static bool IsCreator(this ZDO zdo, long creatorID) { return zdo.GetCreatorId() == creatorID; } internal static bool HasDirectWardAccess(this ZDO zdo, long playerID) { return WardZdoUtils.HasDirectAccessToWardZdo(zdo, playerID); } internal static bool HasConnectedWardAccess(this ZDO zdo, long playerID, ProtectiveWards.WardConnectedAccessMode mode, Func<ZDO, bool> isActiveCandidate) { return WardZdoUtils.HasAccessToWardOrConnectedWardZdo(zdo, playerID, mode, isActiveCandidate); } internal static float GetWardRadius(this ZDO zdo) { return WardZdoUtils.GetWardRadius(zdo); } internal static bool IsWardPermitted(this ZDO zdo, long playerID) { return WardZdoUtils.IsPermitted(zdo, playerID); } } internal static class WardZdoUtils { private sealed class WardTraversal { internal readonly HashSet<ZDOID> Visited = new HashSet<ZDOID>(); internal readonly List<ZDO> Queue = new List<ZDO>(); internal readonly List<ZDO> Candidates = new List<ZDO>(); } [HarmonyPatch] private static class ZDOMan_Load_WardListInit { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(ZDOMan), "Load", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZDOMan), "LoadChunks", (Type[])null, (Type[])null); } private static void Postfix(ZDOMan __instance) { RebuildWardObjects(__instance); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] private static class ZoneSystem_Start_WardListInit { private static void Postfix() { EnsureWardObjectsInitialized(); UpdateAllWardRuntimeFields(); } } [HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[] { typeof(ZDOID), typeof(Vector3), typeof(int) })] private static class ZDOMan_CreateNewZDO_WardListAddNew { private static void Postfix(int prefabHashIn, ZDO __result) { if (ShouldTrackServerWards() && (prefabHashIn == 0 || prefabHashIn == s_wardPrefabHash)) { AddIfWard(__result); } } } [HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")] private static class ZDOMan_HandleDestroyedZDO_WardListRemove { private static void Prefix(ZDOMan __instance, ZDOID uid) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (__instance != null) { RemoveIfWard(__instance.GetZDO(uid)); } } } [HarmonyPatch(typeof(ZDO), "SetPrefab")] private static class ZDO_SetPrefab_WardListUpdate { private static void Postfix(ZDO __instance) { if (ShouldTrackServerWards()) { if (IsWard(__instance)) { s_wardObjects.Add(__instance); EnsureWardSettingsInitialized(__instance); } else { s_wardObjects.Remove(__instance); } } } } [HarmonyPatch(typeof(ZDO), "Deserialize")] private static class ZDO_Deserialize_WardListAdd { private static void Postfix(ZDO __instance) { AddIfWard(__instance); ProtectiveWards.NotifyWardZdoSynchronized(__instance); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] private static class ZoneSystem_OnDestroy_WardListClear { private static void Postfix() { s_wardObjects.Clear(); s_wardObjectsInitialized = false; s_wardDefaultRadius = 32f; s_wardDefaultRadiusCached = false; } } [CompilerGenerated] private sealed class <ConnectedAccessWardZdos>d__45 : IEnumerable<ZDO>, IEnumerable, IEnumerator<ZDO>, IDisposable, IEnumerator { private int <>1__state; private ZDO <>2__current; private int <>l__initialThreadId; private ZDO rootWard; public ZDO <>3__rootWard; private ProtectiveWards.WardConnectedAccessMode mode; public ProtectiveWards.WardConnectedAccessMode <>3__mode; private Func<ZDO, bool> isActiveCandidate; public Func<ZDO, bool> <>3__isActiveCandidate; private WardTraversal <traversal>5__1; private int <queueIndex>5__2; private IEnumerator<ZDO> <>s__3; private ZDO <candidate>5__4; private ZDO <current>5__5; private List<ZDO>.Enumerator <>s__6; private ZDO <candidate>5__7; private bool <retain>5__8; ZDO IEnumerator<ZDO>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ConnectedAccessWardZdos>d__45(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } <traversal>5__1 = null; <>s__3 = null; <candidate>5__4 = null; <current>5__5 = null; <>s__6 = default(List<ZDO>.Enumerator); <candidate>5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!IsWard(rootWard)) { return false; } <>2__current = rootWard; <>1__state = 1; return true; case 1: <>1__state = -1; if (mode == ProtectiveWards.WardConnectedAccessMode.Off) { return false; } <traversal>5__1 = ((s_traversalPool.Count > 0) ? s_traversalPool.Pop() : new WardTraversal()); <>1__state = -3; <traversal>5__1.Visited.Add(rootWard.m_uid); <traversal>5__1.Queue.Add(rootWard); <>s__3 = GetAllWards().GetEnumerator(); try { while (<>s__3.MoveNext()) { <candidate>5__4 = <>s__3.Current; <traversal>5__1.Candidates.Add(<candidate>5__4); <candidate>5__4 = null; } } finally { if (<>s__3 != null) { <>s__3.Dispose(); } } <>s__3 = null; <queueIndex>5__2 = 0; goto IL_02f3; case 2: { <>1__state = -3; goto IL_01b6; } IL_02f3: if (<queueIndex>5__2 < <traversal>5__1.Queue.Count) { <current>5__5 = <traversal>5__1.Queue[<queueIndex>5__2++]; if (<queueIndex>5__2 > 1) { <>2__current = <current>5__5; <>1__state = 2; return true; } goto IL_01b6; } <>m__Finally1(); return false; IL_01b6: <>s__6 = <traversal>5__1.Candidates.GetEnumerator(); try { while (<>s__6.MoveNext()) { <candidate>5__7 = <>s__6.Current; if (IsWard(<candidate>5__7) && !<traversal>5__1.Visited.Contains(<candidate>5__7.m_uid) && (isActiveCandidate == null || isActiveCandidate(<candidate>5__7)) && AreWardZdosOverlapping(<current>5__5, <candidate>5__7) && CanShareConnectedWardAccess(rootWard, <candidate>5__7, mode)) { <traversal>5__1.Visited.Add(<candidate>5__7.m_uid); <traversal>5__1.Queue.Add(<candidate>5__7); <candidate>5__7 = null; } } } finally { ((IDisposable)<>s__6/*cast due to .constrained prefix*/).Dispose(); } <>s__6 = default(List<ZDO>.Enumerator); <current>5__5 = null; goto IL_02f3; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; <retain>5__8 = <traversal>5__1.Candidates.Count <= 4096 && <traversal>5__1.Queue.Count <= 4096; <traversal>5__1.Visited.Clear(); <traversal>5__1.Queue.Clear(); <traversal>5__1.Candidates.Clear(); if (<retain>5__8 && s_traversalPool.Count < 4) { s_traversalPool.Push(<traversal>5__1); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<ZDO> IEnumerable<ZDO>.GetEnumerator() { <ConnectedAccessWardZdos>d__45 <ConnectedAccessWardZdos>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <ConnectedAccessWardZdos>d__ = this; } else { <ConnectedAccessWardZdos>d__ = new <ConnectedAccessWardZdos>d__45(0); } <ConnectedAccessWardZdos>d__.rootWard = <>3__rootWard; <ConnectedAccessWardZdos>d__.mode = <>3__mode; <ConnectedAccessWardZdos>d__.isActiveCandidate = <>3__isActiveCandidate; return <ConnectedAccessWardZdos>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<ZDO>)this).GetEnumerator(); } } internal const string WardPrefabName = "guard_stone"; internal static readonly int s_wardPrefabHash = StringExtensionMethods.GetStableHashCode("guard_stone"); private static readonly HashSet<ZDO> s_wardObjects = new HashSet<ZDO>(); private static bool s_wardObjectsInitialized; private static bool s_wardDefaultRadiusCached; private static float s_wardDefaultRadius = 32f; private const int MaximumPooledBuffers = 4; private const int MaximumRetainedEntries = 4096; private static readonly Stack<HashSet<ZDOID>> s_visitedPool = new Stack<HashSet<ZDOID>>(); private static readonly Stack<WardTraversal> s_traversalPool = new Stack<WardTraversal>(); private static readonly int[] s_permittedPlayerIdHashes = CreatePermittedPlayerIdHashes(); private const string HasFieldsKey = "HasFields"; private const string HasPrivateAreaFieldsKey = "HasFieldsPrivateArea"; internal const string PrivateAreaRadiusField = "PrivateArea.m_radius"; private const string PrivateAreaFlashAvailableField = "PrivateArea.m_flashAvailable"; private static int[] CreatePermittedPlayerIdHashes() { int[] array = new int[64]; for (int i = 0; i < array.Length; i++) { array[i] = StringExtensionMethods.GetStableHashCode("pu_id" + i); } return array; } internal static bool IsWardPrefab(GameObject gameObject) { return (Object)(object)gameObject != (Object)null && Utils.GetPrefabName(gameObject) == "guard_stone"; } internal static bool IsWard(ZDO zdo) { return zdo != null && zdo.GetPrefab() == s_wardPrefabHash; } internal static bool HasStoredWardSettings(ZDO zdo) { return IsWard(zdo) && zdo.GetInt(ProtectiveWards.s_wardSettingsVersion, 0) >= 1; } private static bool CanWriteWardZdo(ZDO zdo) { int result; if (IsWard(zdo)) { ZNet instance = ZNet.instance; result = ((instance != null && instance.IsServer()) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } internal static void EnsureWardSettingsInitialized(ZDO zdo) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) if (!CanWriteWardZdo(zdo)) { return; } if (!HasStoredWardSettings(zdo)) { bool flag = ProtectiveWards.HasZdoVec3(zdo, ProtectiveWards.s_color); if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_customRange)) { zdo.Set(ProtectiveWards.s_customRange, ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range) || ProtectiveWards.setWardRange.Value); } if (!ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range)) { zdo.Set(ProtectiveWards.s_range, ProtectiveWards.ClampWardRange(ProtectiveWards.wardRange.Value)); } if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_customColor)) { zdo.Set(ProtectiveWards.s_customColor, flag || ProtectiveWards.wardEmissionColorEnabled.Value); } if (!ProtectiveWards.HasZdoVec3(zdo, ProtectiveWards.s_color)) { zdo.Set(ProtectiveWards.s_color, new Vector3(ProtectiveWards.wardEmissionColor.Value.r, ProtectiveWards.wardEmissionColor.Value.g, ProtectiveWards.wardEmissionColor.Value.b)); } if (!ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_colorMultiplier)) { zdo.Set(ProtectiveWards.s_colorMultiplier, flag ? 1f : ProtectiveWards.wardEmissionColorMultiplier.Value); } if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_bubbleEnabled)) { zdo.Set(ProtectiveWards.s_bubbleEnabled, ProtectiveWards.wardBubbleShow.Value); } if (!ProtectiveWards.HasZdoVec3(zdo, ProtectiveWards.s_bubbleColor)) { zdo.Set(ProtectiveWards.s_bubbleColor, new Vector3(ProtectiveWards.wardBubbleColor.Value.r, ProtectiveWards.wardBubbleColor.Value.g, ProtectiveWards.wardBubbleColor.Value.b)); } if (!ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_bubbleColorAlpha)) { zdo.Set(ProtectiveWards.s_bubbleColorAlpha, ProtectiveWards.wardBubbleColor.Value.a); } SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleRefractionIntensity, ProtectiveWards.wardBubbleRefractionIntensity.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleWaveVel, ProtectiveWards.wardBubbleWaveIntensity.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleGlossiness, ProtectiveWards.wardBubbleGlossiness.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleMetallic, ProtectiveWards.wardBubbleMetallic.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleNormalScale, ProtectiveWards.wardBubbleNormalScale.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_bubbleDepthFade, ProtectiveWards.wardBubbleDepthFade.Value); if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_circleEnabled)) { zdo.Set(ProtectiveWards.s_circleEnabled, ProtectiveWards.wardAreaMarkerPatch.Value); } SetStringIfMissing(zdo, ProtectiveWards.s_circleStartColor, ColorUtility.ToHtmlStringRGBA(ProtectiveWards.wardAreaMarkerStartColor.Value)); SetStringIfMissing(zdo, ProtectiveWards.s_circleEndColor, ColorUtility.ToHtmlStringRGBA(ProtectiveWards.wardAreaMarkerEndColor.Value)); SetFloatIfMissing(zdo, ProtectiveWards.s_circleSpeed, ProtectiveWards.wardAreaMarkerSpeed.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_circleLength, ProtectiveWards.wardAreaMarkerLength.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_circleWidth, ProtectiveWards.wardAreaMarkerWidth.Value); SetFloatIfMissing(zdo, ProtectiveWards.s_circleAmount, ProtectiveWards.wardAreaMarkerAmount.Value); if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_permitEveryone)) { zdo.Set(ProtectiveWards.s_permitEveryone, ProtectiveWards.permitEveryone.Value); } if (!ProtectiveWards.HasZdoBool(zdo, ProtectiveWards.s_permittedPlayersCanToggle)) { zdo.Set(ProtectiveWards.s_permittedPlayersCanToggle, ProtectiveWards.wardPermittedPlayersCanToggle.Value); } zdo.Set(ProtectiveWards.s_wardSettingsVersion, 1, false); } UpdateWardRuntimeFields(zdo); } private static void SetFloatIfMissing(ZDO zdo, int key, float value) { if (!ProtectiveWards.HasZdoFloat(zdo, key)) { zdo.Set(key, value); } } private static void SetStringIfMissing(ZDO zdo, int key, string value) { if (!ProtectiveWards.HasZdoString(zdo, key)) { zdo.Set(key, value ?? string.Empty); } } internal static void UpdateWardRuntimeFields(ZDO zdo) { if (CanWriteWardZdo(zdo)) { zdo.Set("HasFields", true); zdo.Set("HasFieldsPrivateArea", true); zdo.Set("PrivateArea.m_radius", GetWardRadius(zdo)); zdo.Set("PrivateArea.m_flashAvailable", true); } } internal static void UpdateAllWardRuntimeFields() { ZDO[] array = GetAllWards().ToArray(); foreach (ZDO zdo in array) { EnsureWardSettingsInitialized(zdo); } } internal static IEnumerable<ZDO> GetAllWards() { if (ShouldTrackServerWards()) { EnsureWardObjectsInitialized(); PruneWardObjects(); foreach (ZDO s_wardObject in s_wardObjects) { yield return s_wardObject; } yield break; } HashSet<ZDOID> visited = ((s_visitedPool.Count > 0) ? s_visitedPool.Pop() : new HashSet<ZDOID>()); try { foreach (PrivateArea area in PrivateArea.m_allAreas) { int num; if (area == null) { num = 0; } else { ZNetView nview = area.m_nview; num = ((((nview != null) ? new bool?(nview.IsValid()) : ((bool?)null)) == true) ? 1 : 0); } ZDO zdo = ((num != 0) ? area.m_nview.GetZDO() : null); if (IsWard(zdo) && visited.Add(zdo.m_uid)) { yield return zdo; } } } finally { bool retain = visited.Count <= 4096; visited.Clear(); if (retain && s_visitedPool.Count < 4) { s_visitedPool.Push(visited); } } } internal static bool TryFindActiveWardContainingPoint(Vector3 point, Func<ZDO, bool> isActive, out ZDO ward) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) ward = null; if (ShouldTrackServerWards()) { EnsureWardObjectsInitialized(); PruneWardObjects(); foreach (ZDO s_wardObject in s_wardObjects) { if (!isActive(s_wardObject) || !ProtectiveWards.IsInsideWardXZ(s_wardObject, point)) { continue; } ward = s_wardObject; return true; } return false; } foreach (PrivateArea allArea in PrivateArea.m_allAreas) { object obj; if (allArea != null) { ZNetView nview = allArea.m_nview; if (((nview != null) ? new bool?(nview.IsValid()) : ((bool?)null)) == true) { obj = allArea.m_nview.GetZDO(); goto IL_00da; } } obj = null; goto IL_00da; IL_00da: ZDO val = (ZDO)obj; if (!IsWard(val) || !isActive(val) || !ProtectiveWards.IsInsideWardXZ(val, point)) { continue; } ward = val; return true; } return false; } internal static int CountWardsByCreator(long creatorID) { if (creatorID == 0) { return 0; } int num = 0; foreach (ZDO allWard in GetAllWards()) { if (allWard.IsCreator(creatorID)) { num++; } } return num; } internal static PrivateArea FindLoadedWard(ZDOID zdoID) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) foreach (PrivateArea allArea in PrivateArea.m_allAreas) { if (!((Object)(object)allArea == (Object)null) && !((Object)(object)allArea.m_nview == (Object)null) && allArea.m_nview.IsValid()) { ZDO zDO = allArea.m_nview.GetZDO(); if (zDO != null && ((ZDOID)(ref zDO.m_uid)).Equals(zdoID)) { return allArea; } } } return null; } internal static ZDO GetWard(ZDOID zdoID) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) ZDOMan instance = ZDOMan.instance; ZDO val = ((instance != null) ? instance.GetZDO(zdoID) : null); return IsWard(val) ? val : null; } internal static bool TryGetWard(ZDOID zdoID, out ZDO zdo) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) zdo = GetWard(zdoID); return zdo != null; } internal static List<KeyValuePair<long, string>> GetPermittedPlayers(ZDO zdo) { List<KeyValuePair<long, string>> list = new List<KeyValuePair<long, string>>(); if (!IsWard(zdo)) { return list; } int num = Math.Max(zdo.GetInt(ZDOVars.s_permitted, 0), 0); for (int i = 0; i < num; i++) { long num2 = zdo.GetLong("pu_id" + i, 0L); if (num2 != 0) { list.Add(new KeyValuePair<long, string>(num2, zdo.GetString("pu_name" + i, ""))); } } return list; } internal static bool IsExplicitlyPermitted(ZDO zdo, long playerID) { if (playerID == 0L || !IsWard(zdo)) { return false; } int num = Math.Max(zdo.GetInt(ZDOVars.s_permitted, 0), 0); for (int i = 0; i < num; i++) { int num2 = ((i < s_permittedPlayerIdHashes.Length) ? s_permittedPlayerIdHashes[i] : StringExtensionMethods.GetStableHashCode("pu_id" + i)); if (zdo.GetLong(num2, 0L) == playerID) { return true; } } return false; } internal static bool AddPermitted(ZDO zdo, long playerID, string playerName) { if (!IsWard(zdo) || playerID == 0) { return false; } List<KeyValuePair<long, string>> permittedPlayers = GetPermittedPlayers(zdo); if (permittedPlayers.Any((KeyValuePair<long, string> player) => player.Key == playerID)) { return false; } permittedPlayers.Add(new KeyValuePair<long, string>(playerID, playerName ?? "")); SetPermittedPlayers(zdo, permittedPlayers); return true; } internal static bool RemovePermitted(ZDO zdo, long playerID, out string playerName) { playerName = ""; if (!IsWard(zdo) || playerID == 0) { return false; } List<KeyValuePair<long, string>> permittedPlayers = GetPermittedPlayers(zdo); KeyValuePair<long, string> keyValuePair = permittedPlayers.FirstOrDefault((KeyValuePair<long, string> player) => player.Key == playerID); if (keyValuePair.Key == 0) { return false; } playerName = keyValuePair.Value ?? ""; permittedPlayers.RemoveAll((KeyValuePair<long, string> player) => player.Key == playerID); SetPermittedPlayers(zdo, permittedPlayers); return true; } internal static void SetPermittedPlayers(ZDO zdo, List<KeyValuePair<long, string>> permitted) { if (IsWard(zdo)) { if (permitted == null) { permitted = new List<KeyValuePair<long, string>>(); } zdo.Set(ZDOVars.s_permitted, permitted.Count, false); for (int i = 0; i < permitted.Count; i++) { zdo.Set("pu_id" + i, permitted[i].Key); zdo.Set("pu_name" + i, permitted[i].Value ?? ""); } } } internal static bool IsPermitted(ZDO zdo, long playerID) { if (zdo == null || playerID == 0) { return false; } if (ProtectiveWards.HasWardManagementAccess(zdo, playerID)) { return true; } if (IsExplicitlyPermitted(zdo, playerID)) { return true; } return GuildsCompat.HasWardGuildAccess(zdo, playerID); } internal static bool HasDirectAccessToWardZdo(ZDO zdo, long playerID) { if (zdo == null) { return true; } if (playerID == 0) { return false; } if (!IsWard(zdo)) { return false; } if (zdo.IsCreator(playerID)) { return true; } return IsPermitted(zdo, playerID); } internal static bool UseCustomWardRange(ZDO zdo) { if (!ProtectiveWards.ArePerWardSettingsEnabled()) { return ProtectiveWards.setWardRange.Value; } if (zdo == null) { return false; } if (HasStoredWardSettings(zdo)) { return zdo.GetBool(ProtectiveWards.s_customRange, false); } return ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range) || zdo.GetBool(ProtectiveWards.s_customRange, false); } internal static float GetConfiguredWardRange(ZDO zdo) { if (!ProtectiveWards.ArePerWardSettingsEnabled()) { return ProtectiveWards.ClampWardRange(ProtectiveWards.wardRange.Value); } if (zdo == null) { return GetWardDefaultRadius(); } return ProtectiveWards.ClampWardRange(zdo.GetFloat(ProtectiveWards.s_range, GetWardDefaultRadius())); } internal static float GetWardDefaultRadius() { if (s_wardDefaultRadiusCached) { return ProtectiveWards.ClampWardRange(s_wardDefaultRadius); } if ((Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab("guard_stone"); PrivateArea val = ((prefab != null) ? prefab.GetComponent<PrivateArea>() : null); if ((Object)(object)val != (Object)null) { s_wardDefaultRadius = val.m_radius; s_wardDefaultRadiusCached = true; } } return ProtectiveWards.ClampWardRange(s_wardDefaultRadius); } internal static float GetWardRadius(ZDO zdo) { if (zdo == null) { return GetWardDefaultRadius(); } float radius = default(float); if (ProtectiveWards.ArePerWardSettingsEnabled() && !HasStoredWardSettings(zdo) && zdo.GetFloat("PrivateArea.m_radius", ref radius)) { return ProtectiveWards.ClampWardRange(radius); } return UseCustomWardRange(zdo) ? GetConfiguredWardRange(zdo) : GetWardDefaultRadius(); } internal static bool AreWardZdosOverlapping(ZDO protectedWard, ZDO candidateWard) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!IsWard(protectedWard) || !IsWard(candidateWard)) { return false; } float wardRadius = GetWardRadius(protectedWard); float wardRadius2 = GetWardRadius(candidateWard); return ProtectiveWards.GetConfiguredWardDistance(protectedWard.GetPosition(), candidateWard.GetPosition()) <= wardRadius + wardRadius2; } internal static bool CanShareConnectedWardAccess(ZDO protectedWard, ZDO candidateWard, ProtectiveWards.WardConnectedAccessMode mode) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (mode == ProtectiveWards.WardConnectedAccessMode.Off) { return false; } if (!IsWard(protectedWard) || !IsWard(candidateWard)) { return false; } if (protectedWard == candidateWard || ((ZDOID)(ref protectedWard.m_uid)).Equals(candidateWard.m_uid)) { return true; } switch (mode) { case ProtectiveWards.WardConnectedAccessMode.SameCreatorOnly: { long creatorId = protectedWard.GetCreatorId(); long creatorId2 = candidateWard.GetCreatorId(); return creatorId != 0L && creatorId == creatorId2; } case ProtectiveWards.WardConnectedAccessMode.MutualTrust: { long creatorId = protectedWard.GetCreatorId(); long creatorId2 = candidateWard.GetCreatorId(); return creatorId != 0L && creatorId2 != 0L && HasDirectAccessToWardZdo(protectedWard, creatorId2) && HasDirectAccessToWardZdo(candidateWard, creatorId); } case ProtectiveWards.WardConnectedAccessMode.AnyConnected: return true; default: return false; } } internal static IEnumerable<ZDO> ConnectedAccessWardZdos(ZDO rootWard, ProtectiveWards.WardConnectedAccessMode mode, Func<ZDO, bool> isActiveCandidate) { if (!IsWard(rootWard)) { yield break; } yield return rootWard; if (mode == ProtectiveWards.WardConnectedAccessMode.Off) { yield break; } WardTraversal traversal = ((s_traversalPool.Count > 0) ? s_traversalPool.Pop() : new WardTraversal()); try { traversal.Visited.Add(rootWard.m_uid); traversal.Queue.Add(rootWard); foreach (ZDO candidate in GetAllWards()) { traversal.Candidates.Add(candidate); } int queueIndex = 0; while (queueIndex < traversal.Queue.Count) { ZDO current = traversal.Queue[queueIndex++]; if (queueIndex > 1) { yield return current; } foreach (ZDO candidate2 in traversal.Candidates) { if (IsWard(candidate2) && !traversal.Visited.Contains(candidate2.m_uid) && (isActiveCandidate == null || isActiveCandidate(candidate2)) && AreWardZdosOverlapping(current, candidate2) && CanShareConnectedWardAccess(rootWard, candidate2, mode)) { traversal.Visited.Add(candidate2.m_uid); traversal.Queue.Add(candidate2); } } } } finally { ((<ConnectedAccessWardZdos>d__45)/*Error near IL_0008: stateMachine*/).<retain>5__8 = traversal.Candidates.Count <= 4096 && traversal.Queue.Count <= 4096; traversal.Visited.Clear(); traversal.Queue.Clear(); traversal.Candidates.Clear(); bool retain = default(bool); if (retain && s_traversalPool.Count < 4) { s_traversalPool.Push(traversal); } } } internal static bool HasAccessToWardOrConnectedWardZdo(ZDO rootWard, long playerID, ProtectiveWards.WardConnectedAccessMode mode, Func<ZDO, bool> isActiveCandidate) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (HasDirectAccessToWardZdo(rootWard, playerID)) { return true; } if (mode == ProtectiveWards.WardConnectedAccessMode.Off) { return false; } foreach (ZDO item in ConnectedAccessWardZdos(rootWard, mode, isActiveCandidate)) { if (item == null || ((ZDOID)(ref item.m_uid)).Equals(rootWard.m_uid) || !HasDirectAccessToWardZdo(item, playerID)) { continue; } return true; } return false; } private static bool ShouldTrackServerWards() { return (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); } private static void AddIfWard(ZDO zdo) { if (ShouldTrackServerWards() && IsWard(zdo)) { s_wardObjects.Add(zdo); EnsureWardSettingsInitialized(zdo); } } private static void RemoveIfWard(ZDO zdo) { if (zdo != null && IsWard(zdo)) { s_wardObjects.Remove(zdo); } } private static void PruneWardObjects() { s_wardObjects.RemoveWhere((ZDO zdo) => zdo == null || !IsWard(zdo)); } private static void EnsureWardObjectsInitialized() { if (ShouldTrackServerWards()) { ZDOMan instance = ZDOMan.instance; if (instance != null && !s_wardObjectsInitialized) { RebuildWardObjects(instance); } } } private static void RebuildWardObjects(ZDOMan zdoMan) { s_wardObjects.Clear(); if (!ShouldTrackServerWards() || zdoMan == null) { s_wardObjectsInitialized = false; return; } s_wardObjectsInitialized = true; foreach (KeyValuePair<ZDOID, ZDO> item in zdoMan.m_objectsByID) { AddIfWard(item.Value); } } } internal static class BackgroundProtection { private struct CachedBool { public float Time; public bool Value; } [HarmonyPatch(typeof(ZoneSystem), "Start")] private static class ZoneSystem_Start_ResetBackgroundProtectionCache { private static void Postfix() { ResetCache(); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] private static class ZoneSystem_OnDestroy_ResetBackgroundProtectionCache { private static void Postfix() { ResetCache(); } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] private static class Player_TryPlacePiece_PreventBuildingWithoutPermittedPlayersNearby { [HarmonyPriority(800)] private static bool Prefix(Player __instance, Piece piece, ref bool __result) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)piece == (Object)null || (Object)(object)__instance.m_placementGhost == (Object)null) { return true; } if (!IsBuildingRestricted(__instance, __instance.m_placementGhost.transform.position)) { return true; } ((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false); __result = false; return false; } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] private static class Player_CheckCanRemovePiece_PreventDemolishingWithoutPermittedPlayersNearby { [HarmonyPriority(800)] private static bool Prefix(Player __instance, Piece piece, ref bool __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)piece == (Object)null) { return true; } if (piece.IsCreator()) { return true; } if (!IsBuildingRestricted(__instance, ((Component)piece).transform.position)) { return true; } ((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false); __result = false; return false; } } [HarmonyPatch(typeof(WearNTear), "Damage")] private static class WearNTear_Damage_BackgroundProtection { private static void Prefix(WearNTear __instance, HitData hit) { if (!((Object)(object)__instance == (Object)null) && hit != null) { bool flag = (Object)(object)((Component)__instance).GetComponentInParent<Ship>() != (Object)null; bool flag2 = (Object)(object)((Component)__instance).GetComponentInParent<Vagon>() != (Object)null; if ((!ProtectiveWards.vehiclesNeverProtected.Value || !(flag || flag2)) && (ShouldSuppressWearNTearDamage(__instance, hit, flag, flag2) || ShouldSuppressTameDamageToStructure(__instance, hit))) { ((DamageTypes)(ref hit.m_damage)).Modify(0f); } } } } [HarmonyPatch(typeof(Character), "Damage")] private static class Character_Damage_BackgroundTameProtection { private static void Prefix(Character __instance, HitData hit) { if (ShouldSuppressTameCharacterDamage(__instance)) { ((DamageTypes)(ref hit.m_damage)).Modify(0f); } } } [HarmonyPatch(typeof(BaseAI), "FindEnemy")] private static class BaseAI_FindEnemy_PacifyTames { private static bool Prefix(BaseAI __instance, ref Character __result) { if (!ShouldPacifyTame(__instance)) { return true; } __result = null; return false; } } [HarmonyPatch(typeof(BaseAI), "FindRandomStaticTarget")] private static class BaseAI_FindRandomStaticTarget_PacifyTames { private static bool Prefix(BaseAI __instance, ref StaticTarget __result) { if (!ShouldPacifyTame(__instance)) { return true; } __result = null; return false; } } [HarmonyPatch(typeof(BaseAI), "FindClosestStaticPriorityTarget")] private static class BaseAI_FindClosestStaticPriorityTarget_PacifyTames { private static bool Prefix(BaseAI __instance, ref StaticTarget __result) { if (!ShouldPacifyTame(__instance)) { return true; } __result = null; return false; } } [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] private static class MonsterAI_UpdateAI_PacifyTames { private static void Prefix(MonsterAI __instance) { if (ShouldPacifyTame((BaseAI)(object)__instance)) { PacifyMonster(__instance); } } } [HarmonyPatch(typeof(AnimalAI), "UpdateAI")] private static class AnimalAI_UpdateAI_PacifyTames { private static void Prefix(AnimalAI __instance) { if (ShouldPacifyTame((BaseAI)(object)__instance)) { PacifyAnimal(__instance); } } } private static readonly Dictionary<ZDOID, CachedBool> s_qualifiedBaseCache = new Dictionary<ZDOID, CachedBool>(); private const float QualifiedBaseCacheSeconds = 10f; private static readonly Func<ZDO, bool> activeWardPredicate = IsActiveBackgroundWard; internal static void ResetCache() { s_qualifiedBaseCache.Clear(); } internal static bool IsBackgroundProtectionActiveAt(Vector3 point, out ZDO ward) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ward = null; if (!TryFindBackgroundWard(point, point, out ward)) { return false; } if (!IsQualifiedProtectedBase(ward)) { return false; } return !HasEffectiveAccessPresence(ward, point); } internal static bool TryFindBackgroundWard(Vector3 sourcePoint, Vector3 targetPoint, out ZDO ward) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) ward = null; bool flag = sourcePoint.x == targetPoint.x && sourcePoint.y == targetPoint.y && sourcePoint.z == targetPoint.z; if (!ProtectiveWards.TryResolveWardCheckPoint(sourcePoint, out sourcePoint)) { return false; } if (flag) { targetPoint = sourcePoint; } else if (!ProtectiveWards.TryResolveWardCheckPoint(targetPoint, out targetPoint)) { return false; } if (flag) { return WardZdoUtils.TryFindActiveWardContainingPoint(sourcePoint, activeWardPredicate, out ward); } ProtectiveWards.WardConnectedAccessMode wardConnectedAccessMode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off); foreach (ZDO allWard in WardZdoUtils.GetAllWards()) { if (!IsActiveBackgroundWard(allWard) || !ProtectiveWards.IsInsideWardXZ(allWard, sourcePoint)) { continue; } if (ProtectiveWards.IsInsideWardXZ(allWard, targetPoint)) { ward = allWard; return true; } if (wardConnectedAccessMode == ProtectiveWards.WardConnectedAccessMode.Off) { continue; } foreach (ZDO item in WardZdoUtils.ConnectedAccessWardZdos(allWard, wardConnectedAccessMode, activeWardPredicate)) { if (!ProtectiveWards.IsInsideWardXZ(item, targetPoint)) { continue; } ward = allWard; return true; } } return false; } internal static bool HasEffectiveAccessPresence(ZDO ward, Vector3 point) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) if (!WardZdoUtils.IsWard(ward)) { return false; } ProtectiveWards.WardConnectedAccessMode wardConnectedAccessMode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off); float num = Mathf.Max(ProtectiveWards.wardBackgroundPresenceRadius.Value, 0f); if (!ProtectiveWards.TryResolveWardCheckPoint(point, out var resolvedPoint)) { return false; } ProtectiveWards.WardBackgroundPresenceMode value = ProtectiveWards.wardBackgroundPresenceMode.Value; foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer == (Object)null || !ProtectiveWards.TryResolveWardCheckPoint(((Component)allPlayer).transform.position, out var resolvedPoint2)) { continue; } if (value != ProtectiveWards.WardBackgroundPresenceMode.PermittedOnline && value != ProtectiveWards.WardBackgroundPresenceMode.PermittedInsideConnectedArea) { float num2 = resolvedPoint2.x - resolvedPoint.x; float num3 = resolvedPoint2.z - resolvedPoint.z; if (!(num2 * num2 + num3 * num3 <= num * num)) { continue; } } if (!ward.HasConnectedWardAccess(allPlayer.GetPlayerID(), wardConnectedAccessMode, activeWardPredicate)) { continue; } if (value != ProtectiveWards.WardBackgroundPresenceMode.PermittedInsideConnectedArea) { return true; } if (ProtectiveWards.IsInsideWardXZ(ward, resolvedPoint2)) { return true; } if (wardConnectedAccessMode == ProtectiveWards.WardConnectedAccessMode.Off) { continue; } foreach (ZDO item in WardZdoUtils.ConnectedAccessWardZdos(ward, wardConnectedAccessMode, activeWardPredicate)) { if (ProtectiveWards.IsInsideWardXZ(item, resolvedPoint2)) { return true; } } } return false; } internal static bool IsQualifiedProtectedBase(ZDO ward) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!WardZdoUtils.IsWard(ward)) { return false; } int num = Math.Max(ProtectiveWards.wardBackgroundProtectedBaseMinPieces.Value, 0); if (num == 0) { return true; } if (s_qualifiedBaseCache.TryGetValue(ward.m_uid, out var value) && Time.time - value.Time < 10f) { return value.Value; } bool flag = CountPlayerBuiltPiecesInNetwork(ward, num) >= num; s_qualifiedBaseCache[ward.m_uid] = new CachedBool { Time = Time.time, Value = flag }; return flag; } private static int CountPlayerBuiltPiecesInNetwork(ZDO ward, int stopAt) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) ProtectiveWards.WardConnectedAccessMode mode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off); HashSet<Piece> hashSet = new HashSet<Piece>(); List<Piece> list = new List<Piece>(); foreach (ZDO item in WardZdoUtils.ConnectedAccessWardZdos(ward, mode, activeWardPredicate)) { list.Clear(); Piece.GetAllPiecesInRadius(item.GetPosition(), item.GetWardRadius(), list); foreach (Piece item2 in list) { if (!((Object)(object)item2 == (Object)null) && item2.IsPlacedByPlayer()) { hashSet.Add(item2); if (hashSet.Count >= stopAt) { return hashSet.Count; } } } } return hashSet.Count; } private static bool IsActiveBackgroundWard(ZDO zdo) { return WardExpiration.IsWardActive(zdo); } internal static bool ShouldSuppressWearNTearDamage(WearNTear wearNTear, HitData hit, bool isShip, bool isCart) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)wearNTear == (Object)null || hit == null) { return false; } Piece val = wearNTear.m_piece ?? ((Component)wearNTear).GetComponent<Piece>(); bool flag = (Object)(object)val != (Object)null && val.IsPlacedByPlayer(); if (!flag && !isShip && !isCart) { return false; } if (!TryFindBackgroundWard(((Component)wearNTear).transform.position, ((Component)wearNTear).transform.position, out var ward)) { return false; } if (!IsQualifiedProtectedBase(ward)) { return false; } Character attacker = hit.GetAttacker(); if (ProtectiveWards.wardBackgroundStructureProtection.Value == ProtectiveWards.WardBackgroundStructureProtectionMode.BlockNonPermittedPlayerDamage && flag && (Object)(object)attacker != (Object)null && attacker.IsPlayer()) { ZDO zdo = ward; Character obj = ((attacker is Player) ? attacker : null); if (!zdo.HasConnectedWardAccess((obj != null) ? ((Player)obj).GetPlayerID() : 0, ProtectiveWards.wardBackgroundConnectedAccessMode.Value, IsActiveBackgroundWard)) { return true; } } if (HasEffectiveAccessPresence(ward, ((Component)wearNTear).transform.position)) { return false; } if (ProtectiveWards.wardBackgroundProtectBoats.Value && isShip) { return true; } if (ProtectiveWards.wardBackgroundProtectCarts.Value && isCart) { return true; } if (flag) { if (ProtectiveWards.wardBackgroundStructureProtection.Value == ProtectiveWards.WardBackgroundStructureProtectionMode.BlockAllDamageWhenNoPermittedNearby) { return true; } if (ProtectiveWards.wardBackgroundProtectFire.Value && IsFireDamage(hit)) { return true; } } return false; } internal static bool ShouldSuppressTameDamageToStructure(WearNTear wearNTear, HitData hit) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.wardBackgroundTamesPreventDamageToStructures.Value) { return false; } if ((Object)(object)wearNTear == (Object)null || hit == null || !hit.HaveAttacker()) { return false; } Piece val = wearNTear.m_piece ?? ((Component)wearNTear).GetComponent<Piece>(); if ((Object)(object)val == (Object)null || !val.IsPlacedByPlayer()) { return false; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || attacker.IsPlayer() || !attacker.IsTamed()) { return false; } if (!TryFindBackgroundWard(((Component)attacker).transform.position, ((Component)wearNTear).transform.position, out var ward)) { return false; } if (!IsQualifiedProtectedBase(ward)) { return false; } return !HasEffectiveAccessPresence(ward, ((Component)attacker).transform.position) && !HasEffectiveAccessPresence(ward, ((Component)wearNTear).transform.position); } internal static bool ShouldSuppressTameCharacterDamage(Character character) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.wardBackgroundProtectTames.Value) { return false; } if ((Object)(object)character == (Object)null || !character.IsTamed()) { return false; } ZDO ward; return IsBackgroundProtectionActiveAt(((Component)character).transform.position, out ward); } internal static bool ShouldPacifyTame(BaseAI ai) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.wardBackgroundTamePacify.Value == ProtectiveWards.WardBackgroundTamePacifyMode.Off) { return false; } if ((Object)(object)ai == (Object)null || (Object)(object)ai.m_character == (Object)null || !ai.m_character.IsTamed()) { return false; } ZDO ward; return IsBackgroundProtectionActiveAt(((Component)ai).transform.position, out ward); } internal static void PacifyMonster(MonsterAI ai) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ai == (Object)null)) { ((BaseAI)ai).SetAlerted(false); ai.m_targetCreature = null; ai.m_targetStatic = null; ai.m_timeSinceAttacking = 0f; ai.m_timeSinceSensedTargetCreature = 99999f; ((BaseAI)ai).SetTargetInfo(ZDOID.None); } } internal static void PacifyAnimal(AnimalAI ai) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ai == (Object)null)) { ((BaseAI)ai).SetAlerted(false); ai.m_target = null; ((BaseAI)ai).SetTargetInfo(ZDOID.None); } } internal static bool IsBuildingRestricted(Player player, Vector3 point) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.wardBackgroundPreventBuildingAndDemolishing.Value) { return false; } if ((Object)(object)player == (Object)null) { return false; } long playerID = player.GetPlayerID(); if (ProtectiveWards.HasWardAdminAccess(playerID)) { return false; } if (!TryFindBackgroundWard(point, point, out var ward)) { return false; } if (!IsQualifiedProtectedBase(ward)) { return false; } if (ward.HasConnectedWardAccess(player.GetPlayerID(), ProtectiveWards.wardBackgroundConnectedAccessMode.Value, IsActiveBackgroundWard)) { return false; } return !HasEffectiveAccessPresence(ward, point); } private static bool IsFireDamage(HitData hit) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 return hit != null && (hit.m_damage.m_fire > 0f || (int)hit.m_hitType == 5); } } internal static class EnumerableExtensions { public static bool AnySafe<T>(this IEnumerable<T> source, Func<T, bool> predicate) { if (source == null) { return false; } foreach (T item in source) { if (predicate(item)) { return true; } } return false; } } internal class FullProtection { [HarmonyPatch(typeof(PrivateArea), "CheckAccess")] public static class PrivateArea_CheckAccess_ScopedWardAccessBypass { private static bool Prefix(ref bool __result) { if (s_privateAreaCheckBypassDepth <= 0) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Character), "AddFireDamage")] public static class Character_AddFireDamage_IndirectFireDamageProtection { private static void Prefix(Character __instance, ref float damage) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { damage = 0f; } } } [HarmonyPatch(typeof(Character), "UpdateSmoke")] public static class Character_UpdateSmoke_IndirectSmokeDamageProtection { private static void Prefix(Character __instance, ref float dt) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { dt = 0f; } } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] public static class WearNTear_UpdateWear_RainProtection { private static void Prefix(WearNTear __instance, float time, ref bool ___m_noRoofWear, ref bool __state) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && ProtectiveWards.wardRainProtection != null && ProtectiveWards.wardRainProtection.Value && ___m_noRoofWear && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && __instance.m_nview.IsOwner() && __instance.ShouldUpdate(time) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __state = ___m_noRoofWear; ___m_noRoofWear = false; } } private static void Postfix(ref bool ___m_noRoofWear, ref bool __state) { Restore(ref ___m_noRoofWear, ref __state); } private static void Finalizer(ref bool ___m_noRoofWear, ref bool __state) { Restore(ref ___m_noRoofWear, ref __state); } private static void Restore(ref bool noRoofWear, ref bool state) { if (state) { noRoofWear = true; state = false; } } } [HarmonyPatch(typeof(Ship), "UpdateUpsideDmg")] public static class Ship_UpdateUpsideDmg_PreventShipDamage { private static bool Prefix(Ship __instance) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instanc