using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using Jotunn.GUI; using Jotunn.Managers; using Jotunn.Utils; using LocalizationManager; using Microsoft.CodeAnalysis; using ProtectiveWards; using ProtectiveWards.Compatibility; using SoftReferenceableAssets; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Protective Wards")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Protective Wards")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f71912b8-9b1c-4181-911a-1550f4ec2889")] [assembly: AssemblyFileVersion("2.0.6")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.6.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LocalizationManager { [PublicAPI] public class Localizer { private const string defaultLanguage = "English"; private static readonly Dictionary>> PlaceholderProcessors; private static readonly Dictionary> loadedTexts; private static readonly ConditionalWeakTable localizationLanguage; private static readonly List> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List 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 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> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder(string key, string placeholder, ConfigEntry config, Func? convertConfigValue = null) where T : notnull { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary>(); } 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> list = new List>(); foreach (WeakReference localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference item in list) { localizationObjects.Remove(item); } } public static IEnumerator Load() { yield return (object)new WaitUntil((Func)(() => 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(__instance)); } localizationLanguage.Add(__instance, language); Dictionary localizationFiles = new Dictionary(); 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 dictionary = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(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 dictionary2; try { dictionary2 = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(text) ?? new Dictionary(); } catch (Exception arg) { global::ProtectiveWards.ProtectiveWards.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}"); dictionary2 = new Dictionary(); } foreach (KeyValuePair item in dictionary2) { dictionary[item.Key] = item.Value; } } loadedTexts[language] = dictionary; foreach (KeyValuePair 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>>(); loadedTexts = new Dictionary>(); localizationLanguage = new ConditionalWeakTable(); localizationObjects = new List>(); fileExtensions = new List { ".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() == (Object)null || !WardZdoUtils.IsWardPrefab(((Component)__instance).gameObject)) { return; } ZNetView componentZNetView = ((Component)(object)__instance).GetComponentZNetView(); if ((Object)(object)componentZNetView == (Object)null || !componentZNetView.IsValid()) { return; } ZDO zDO = componentZNetView.GetZDO(); if (zDO != null) { ZDOID uid2 = zDO.m_uid; if (!s_requestedWardLimitChecks.Contains(uid2)) { s_requestedWardLimitChecks.Add(uid2); RequestWardBuildLimitCheck(uid, uid2); } } } } private const string RPC_PermitPlayer = "PW_PermitPlayer"; private const string RPC_UnpermitPlayer = "PW_UnpermitPlayer"; private const string RPC_SetWardEnabled = "PW_SetWardEnabled"; private const string RPC_SetWardExpired = "PW_SetWardExpired"; private const string RPC_CheckWardBuildLimit = "PW_CheckWardBuildLimit"; private const string RPC_DestroyWardForBuildLimit = "PW_DestroyWardForBuildLimit"; private static readonly HashSet s_requestedWardLimitChecks = new HashSet(); private static bool s_rpcRegistered; private static bool s_commandRegistered; internal static void RegisterRPCs() { if (!s_rpcRegistered && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register("PW_DestroyWardForBuildLimit", (Action)RPC_DestroyWardForBuildLimitClient); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { ZRoutedRpc.instance.Register("PW_PermitPlayer", (Action)RPC_PermitPlayerServer); ZRoutedRpc.instance.Register("PW_UnpermitPlayer", (Action)RPC_UnpermitPlayerServer); ZRoutedRpc.instance.Register("PW_SetWardEnabled", (Action)RPC_SetWardEnabledServer); ZRoutedRpc.instance.Register("PW_SetWardExpired", (Action)RPC_SetWardExpiredServer); ZRoutedRpc.instance.Register("PW_CheckWardBuildLimit", (Action)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", " - add an online player to the nearest ward within configured range", RequestPermit); RegisterPlayerListCommand("ward_permit", " - add an online player to the nearest ward within configured range", RequestPermit); RegisterPlayerListCommand("pw_unpermit", " - remove a player from the nearest ward permitted list", RequestUnpermit); RegisterPlayerListCommand("ward_unpermit", " - 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 action) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ValidateWardControlCommand(args.Context)) { if (args.Length < 2) { args.Context.AddString("Usage: "); } else { action(GetCommandQuery(args), args.Context); } } }, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static void RegisterWardStateCommand(string command, string description, bool enabled) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ValidateWardControlCommand(args.Context)) { RequestSetWardEnabled(enabled, args.Context); } }, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static void RegisterWardExpirationStateCommand(string command, string description, bool expired) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand(command, description, (ConsoleEvent)delegate(ConsoleEventArgs args) { if (ValidateWardControlCommand(args.Context)) { RequestSetWardExpired(expired, args.Context); } }, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static string GetCommandQuery(ConsoleEventArgs args) { return string.Join(" ", args.Args.Skip(1).ToArray()).Trim(); } private static bool ValidateWardControlCommand(Terminal context) { if (AreWardControlCommandsEnabled()) { return true; } context.AddString("Ward control commands are disabled."); return false; } private static bool AreWardControlCommandsEnabled() { return ProtectiveWards.wardExternalControlCommandsEnabled.Value; } private static float GetWardControlCommandRange() { return Math.Max(ProtectiveWards.wardExternalControlCommandRange.Value, 0f); } private static void RequestPermit(string query, Terminal context) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } if (!ProtectiveWards.HasAccessToWardOrConnectedWard(val, localPlayer)) { context.AddString("$pw_permit_no_access".Localize()); return; } List list = FindOnlinePlayers(query); if (list.Count == 0) { context.AddString("$pw_permit_no_match".Localize(query)); return; } if (list.Count > 1) { context.AddString("$pw_permit_multiple".Localize(string.Join(", ", list.Select((Player p) => p.GetPlayerName()).ToArray()))); return; } Player val2 = list[0]; if (IsPlayerInPermittedList(val, val2.GetPlayerID())) { context.AddString("$pw_permit_already".Localize()); return; } ZPackage val3 = new ZPackage(); val3.Write(val.m_nview.GetZDO().m_uid); val3.Write(localPlayer.GetPlayerID()); val3.Write(val2.GetPlayerID()); val3.Write(val2.GetPlayerName()); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_PermitPlayerServer(0L, new ZPackage(val3.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_PermitPlayer", new object[1] { val3 }); } context.AddString("$pw_permit_added".Localize(val2.GetPlayerName())); } private static void RequestUnpermit(string query, Terminal context) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } if (!ProtectiveWards.HasAccessToWardOrConnectedWard(val, localPlayer)) { context.AddString("$pw_permit_no_access".Localize()); return; } List> 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 p) => p.Value).ToArray())); return; } KeyValuePair keyValuePair = list[0]; ZPackage val2 = new ZPackage(); val2.Write(val.m_nview.GetZDO().m_uid); val2.Write(localPlayer.GetPlayerID()); val2.Write(keyValuePair.Key); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_UnpermitPlayerServer(0L, new ZPackage(val2.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_UnpermitPlayer", new object[1] { val2 }); } context.AddString("Removed " + keyValuePair.Value + " from ward permitted list."); } private static void RequestSetWardEnabled(bool enabled, Terminal context) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } if (!CanLocalToggleWard(val)) { context.AddString("$pw_permit_no_access".Localize()); return; } ZPackage val2 = new ZPackage(); val2.Write(val.m_nview.GetZDO().m_uid); val2.Write(localPlayer.GetPlayerID()); val2.Write(enabled); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_SetWardEnabledServer(0L, new ZPackage(val2.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_SetWardEnabled", new object[1] { val2 }); } context.AddString(enabled ? "Ward enable requested." : "Ward disable requested."); } private static void RequestSetWardExpired(bool expired, Terminal context) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { context.AddString("Player is not available."); return; } if (!ProtectiveWards.HasLocalWardAdminAccess()) { context.AddString("$pw_permit_no_access".Localize()); return; } PrivateArea val = FindNearestWard(((Component)localPlayer).transform.position, GetWardControlCommandRange()); if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { context.AddString("$pw_permit_no_ward".Localize()); return; } ZPackage val2 = new ZPackage(); val2.Write(val.m_nview.GetZDO().m_uid); val2.Write(localPlayer.GetPlayerID()); val2.Write(localPlayer.GetPlayerName()); val2.Write(expired); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_SetWardExpiredServer(0L, new ZPackage(val2.GetArray())); } else { ZRoutedRpc.instance.InvokeRoutedRPC("PW_SetWardExpired", new object[1] { val2 }); } context.AddString(expired ? "Ward expired state requested." : "Ward unexpired state requested."); } private static void RPC_PermitPlayerServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); long num = package.ReadLong(); string text = package.ReadString(); if (!AreWardControlCommandsEnabled() || !ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { return; } ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && CanRequesterPermit(ward, player.PlayerID)) { Player player2 = Player.GetPlayer(num); if (!((Object)(object)player2 == (Object)null) && !(player2.GetPlayerName() != text) && !WardZdoUtils.IsExplicitlyPermitted(ward, num)) { WardZdoUtils.AddPermitted(ward, num, text); ProtectiveWards.LogInfo($"Added {text} to ward {val} permitted list by command"); } } } private static void RPC_UnpermitPlayerServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); long playerID = package.ReadLong(); if (AreWardControlCommandsEnabled() && ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && CanRequesterPermit(ward, player.PlayerID) && WardZdoUtils.RemovePermitted(ward, playerID, out var playerName)) { ProtectiveWards.LogInfo($"Removed {playerName} from ward {val} permitted list by command"); } } } private static void RPC_SetWardEnabledServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); bool flag = package.ReadBool(); if (!AreWardControlCommandsEnabled() || !ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { return; } ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && CanRequesterToggleWard(ward, player.PlayerID) && ward.GetBool(ZDOVars.s_enabled, false) != flag) { ward.Set(ZDOVars.s_enabled, flag); if (flag) { ProtectiveWards.ActivateConnectedWardZdos(ward, player.PlayerID, player.PlayerName); } ProtectiveWards.LogInfo(string.Format("{0} ward {1} by command", flag ? "Enabled" : "Disabled", val)); } } private static void RPC_SetWardExpiredServer(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); package.ReadString(); bool flag = package.ReadBool(); if (AreWardControlCommandsEnabled() && ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { ZDO ward = WardZdoUtils.GetWard(val); if (ward != null && ProtectiveWards.HasWardManagementAccess(ward, player.PlayerID)) { WardExpiration.SetExpired(ward, flag, player.PlayerID, player.PlayerName); ProtectiveWards.LogInfo(string.Format("{0} ward {1} expired state by admin command", flag ? "Marked" : "Cleared", val)); } } } private static bool CanRequesterPermit(ZDO zdo, long requesterID) { if (!WardZdoUtils.IsWard(zdo) || requesterID == 0) { return false; } if (WardZdoUtils.HasDirectAccessToWardZdo(zdo, requesterID)) { return true; } if (!IsActiveWardZdoForCommandAccess(zdo)) { return false; } ProtectiveWards.WardConnectedAccessMode mode = ProtectiveWards.wardAccessConnectedAccessMode?.Value ?? ProtectiveWards.WardConnectedAccessMode.Off; return zdo.HasConnectedWardAccess(requesterID, mode, IsActiveWardZdoForCommandAccess); } private static bool CanLocalToggleWard(PrivateArea ward) { int result; if ((Object)(object)ward != (Object)null) { if (!((Object)(object)ward.m_piece != (Object)null) || !ward.m_piece.IsCreator()) { Player localPlayer = Player.m_localPlayer; result = (ProtectiveWards.HasWardManagementAccess(ward, (localPlayer != null) ? localPlayer.GetPlayerID() : 0) ? 1 : 0); } else { result = 1; } } else { result = 0; } return (byte)result != 0; } private static bool CanRequesterToggleWard(ZDO zdo, long requesterID) { if (!WardZdoUtils.IsWard(zdo) || requesterID == 0) { return false; } return ProtectiveWards.HasWardManagementAccess(zdo, requesterID) || zdo.IsCreator(requesterID); } private static bool IsActiveWardZdoForCommandAccess(ZDO zdo) { return WardZdoUtils.IsWard(zdo) && zdo.GetBool(ZDOVars.s_enabled, false) && !WardExpiration.IsExpired(zdo); } private static bool IsPlayerInPermittedList(PrivateArea ward, long playerID) { return (Object)(object)ward != (Object)null && ward.GetPermittedPlayers().Any((KeyValuePair player) => player.Key == playerID); } private static List> FindPermittedPlayers(PrivateArea ward, string query) { string normalized = query.Trim(); if (normalized.Length == 0) { return new List>(); } List> permittedPlayers = ward.GetPermittedPlayers(); List> list = permittedPlayers.Where((KeyValuePair player) => string.Equals(player.Value, normalized, StringComparison.OrdinalIgnoreCase)).ToList(); if (list.Count > 0) { return list; } return permittedPlayers.Where((KeyValuePair 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 FindOnlinePlayers(string query) { string normalized = query.Trim(); if (normalized.Length == 0) { return new List(); } List allPlayers = Player.GetAllPlayers(); List list = allPlayers.Where((Player player) => string.Equals(player.GetPlayerName(), normalized, StringComparison.OrdinalIgnoreCase)).ToList(); if (list.Count > 0) { return list; } return allPlayers.Where((Player player) => player.GetPlayerName().IndexOf(normalized, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); } private static void RequestWardBuildLimitCheck(long creatorID, ZDOID newWardID) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(creatorID); val.Write(newWardID); ZNet instance = ZNet.instance; if (instance != null && instance.IsServer()) { RPC_CheckWardBuildLimitServer(0L, new ZPackage(val.GetArray())); return; } ZRoutedRpc instance2 = ZRoutedRpc.instance; if (instance2 != null) { instance2.InvokeRoutedRPC("PW_CheckWardBuildLimit", new object[1] { val }); } } private static void RPC_CheckWardBuildLimitServer(long sender, ZPackage package) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) long num = package.ReadLong(); ZDOID val = package.ReadZDOID(); try { if (ProtectiveWards.wardBuildLimitPerPlayer.Value <= 0 || num == 0L || ((ZDOID)(ref val)).Equals(ZDOID.None) || !ProtectiveWards.TryGetRoutedPlayer(sender, num, out var player)) { return; } ZDOMan instance = ZDOMan.instance; ZDO val2 = ((instance != null) ? instance.GetZDO(val) : null); if (val2.IsWard() && val2.IsCreator(player.PlayerID) && (sender == 0L || val2.GetOwner() == sender)) { int value = ProtectiveWards.wardBuildLimitPerPlayer.Value; int num2 = WardZdoUtils.CountWardsByCreator(player.PlayerID); if (num2 > value) { int current = Math.Max(num2 - 1, 0); SendDestroyWardForBuildLimit(val2, current, value); } } } finally { s_requestedWardLimitChecks.Remove(val); } } private static void SendDestroyWardForBuildLimit(ZDO zdo, int current, int limit) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown if (zdo != null) { ZDOID uid = zdo.m_uid; long owner = zdo.GetOwner(); DestroyWardForBuildLimitServer(zdo); ZPackage val = new ZPackage(); val.Write(uid); val.Write(current); val.Write(limit); if (owner != 0L && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(owner, "PW_DestroyWardForBuildLimit", new object[1] { val }); } else if ((Object)(object)Player.m_localPlayer != (Object)null) { RPC_DestroyWardForBuildLimitClient(0L, new ZPackage(val.GetArray())); } } } private static void DestroyWardForBuildLimitServer(ZDO zdo) { if (zdo != null && ZDOMan.instance != null) { zdo.SetOwner(ZDOMan.instance.m_sessionID); ZDOMan.instance.DestroyZDO(zdo); } } private static void RPC_DestroyWardForBuildLimitClient(long sender, ZPackage package) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) ZDOID wardID = package.ReadZDOID(); int num = package.ReadInt(); int num2 = package.ReadInt(); DestroyLocalWard(wardID); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "$pw_ward_limit_reached".Localize(num.ToString(), num2.ToString()), 0, (Sprite)null); } } private static void DestroyLocalWard(ZDOID wardID) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNetScene.instance == (Object)null)) { GameObject val = ZNetScene.instance.FindInstance(wardID); if ((Object)(object)val != (Object)null) { ZNetScene.instance.Destroy(val); } } } } internal static class ItemNameTokens { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_UpdateItemNameTokens { private static void Postfix() { UpdateRegisters(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDB_CopyOtherDB_UpdateItemNameTokens { private static void Postfix() { UpdateRegisters(); } } [HarmonyPatch(typeof(Player), "Load")] private static class Player_Load_UpdateItemNameTokens { private static void Prefix() { UpdateRegisters(); } } private static readonly Dictionary s_itemNames = new Dictionary(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(); if (component != null) { SharedData val = component.m_itemData?.m_shared; if (val != null && !string.IsNullOrWhiteSpace(val.m_name) && val.m_name.StartsWith("$")) { Register(((Object)item).name, val.m_name); Register(val.m_name, val.m_name); Localization instance = Localization.instance; Register((instance != null) ? instance.Localize(val.m_name) : null, val.m_name); } } } } internal static string GetItemName(this string input) { if (string.IsNullOrWhiteSpace(input)) { return ""; } string text = input.Trim(); string value; return s_itemNames.TryGetValue(text, out value) ? value : text; } private static void Register(string key, string token) { if (!string.IsNullOrWhiteSpace(key)) { s_itemNames[key.Trim()] = token; } } } public static class StringExtensions { public static string Localize(this string text) { return (Localization.instance != null) ? Localization.instance.Localize(text) : text; } public static string Localize(this string text, params string[] words) { return (Localization.instance != null) ? Localization.instance.Localize(text, words) : text; } } internal static class ComponentExtensions { internal static ZNetView GetComponentZNetView(this Component component) { if ((Object)(object)component == (Object)null) { return null; } PrivateArea val = (PrivateArea)(object)((component is PrivateArea) ? component : null); if (val != null) { return val.m_nview; } Ship val2 = (Ship)(object)((component is Ship) ? component : null); if (val2 != null) { return val2.m_nview; } ShipControlls val3 = (ShipControlls)(object)((component is ShipControlls) ? component : null); if (val3 != null) { return val3.m_nview; } Vagon val4 = (Vagon)(object)((component is Vagon) ? component : null); if (val4 != null) { return val4.m_nview; } Catapult val5 = (Catapult)(object)((component is Catapult) ? component : null); if (val5 != null) { return val5.m_nview; } MapTable val6 = (MapTable)(object)((component is MapTable) ? component : null); if (val6 != null) { return val6.m_nview; } Turret val7 = (Turret)(object)((component is Turret) ? component : null); if (val7 != null) { return val7.m_nview; } Fireplace val8 = (Fireplace)(object)((component is Fireplace) ? component : null); if (val8 != null) { return val8.m_nview; } Tameable val9 = (Tameable)(object)((component is Tameable) ? component : null); if (val9 != null) { return val9.m_nview; } Sadle val10 = (Sadle)(object)((component is Sadle) ? component : null); if (val10 != null) { return val10.m_nview; } TeleportWorld val11 = (TeleportWorld)(object)((component is TeleportWorld) ? component : null); if (val11 != null) { return val11.m_nview; } return component.GetComponent() ?? component.GetComponentInParent(); } internal static ZDO GetWardZDO(this Component component) { ZNetView componentZNetView = component.GetComponentZNetView(); return ((Object)(object)componentZNetView != (Object)null && componentZNetView.IsValid()) ? componentZNetView.GetZDO() : null; } } internal static class PrivateAreaExtensions { internal static ZDO GetWardZDO(this PrivateArea ward) { ZNetView componentZNetView = ((Component)(object)ward).GetComponentZNetView(); return ((Object)(object)componentZNetView != (Object)null && componentZNetView.IsValid()) ? componentZNetView.GetZDO() : null; } internal static bool HasDirectWardAccess(this PrivateArea ward, long playerID) { return ProtectiveWards.HasDirectAccessToWard(ward, playerID); } internal static bool HasConnectedWardAccess(this PrivateArea ward, long playerID, ProtectiveWards.WardConnectedAccessMode mode) { return ProtectiveWards.HasAccessToWardOrConnectedWard(ward, playerID, mode); } } internal static class WardZdoExtensions { internal static bool IsWard(this ZDO zdo) { return WardZdoUtils.IsWard(zdo); } internal static long GetCreatorId(this ZDO zdo) { return (zdo != null) ? zdo.GetLong(ZDOVars.s_creator, 0L) : 0; } internal static bool IsCreator(this ZDO zdo, long creatorID) { return zdo.GetCreatorId() == creatorID; } internal static bool HasDirectWardAccess(this ZDO zdo, long playerID) { return WardZdoUtils.HasDirectAccessToWardZdo(zdo, playerID); } internal static bool HasConnectedWardAccess(this ZDO zdo, long playerID, ProtectiveWards.WardConnectedAccessMode mode, Func isActiveCandidate) { return WardZdoUtils.HasAccessToWardOrConnectedWardZdo(zdo, playerID, mode, isActiveCandidate); } internal static float GetWardRadius(this ZDO zdo) { return WardZdoUtils.GetWardRadius(zdo); } internal static bool IsWardPermitted(this ZDO zdo, long playerID) { return WardZdoUtils.IsPermitted(zdo, playerID); } } internal static class WardZdoUtils { [HarmonyPatch(typeof(ZDOMan), "Load")] private static class ZDOMan_Load_WardListInit { private static void Postfix(ZDOMan __instance) { RebuildWardObjects(__instance); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] private static class ZoneSystem_Start_WardListInit { private static void Postfix() { EnsureWardObjectsInitialized(); } } [HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[] { typeof(ZDOID), typeof(Vector3), typeof(int) })] private static class ZDOMan_CreateNewZDO_WardListAddNew { private static void Postfix(int prefabHashIn, ZDO __result) { if (ShouldTrackServerWards() && (prefabHashIn == 0 || prefabHashIn == s_wardPrefabHash)) { AddIfWard(__result); } } } [HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")] private static class ZDOMan_HandleDestroyedZDO_WardListRemove { private static void Prefix(ZDOMan __instance, ZDOID uid) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (__instance != null) { RemoveIfWard(__instance.GetZDO(uid)); } } } [HarmonyPatch(typeof(ZDO), "Deserialize")] private static class ZDO_Deserialize_WardListAdd { private static void Postfix(ZDO __instance) { AddIfWard(__instance); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] private static class ZoneSystem_OnDestroy_WardListClear { private static void Postfix() { s_wardObjects.Clear(); s_wardObjectsInitialized = false; } } internal const string WardPrefabName = "guard_stone"; internal static readonly int s_wardPrefabHash = StringExtensionMethods.GetStableHashCode("guard_stone"); private static readonly HashSet s_wardObjects = new HashSet(); private static bool s_wardObjectsInitialized; private static bool s_wardDefaultRadiusCached; private static float s_wardDefaultRadius = 32f; internal static bool IsWardPrefab(GameObject gameObject) { return (Object)(object)gameObject != (Object)null && Utils.GetPrefabName(gameObject) == "guard_stone"; } internal static bool IsWard(ZDO zdo) { return zdo != null && zdo.GetPrefab() == s_wardPrefabHash; } internal static IEnumerable GetAllWards() { if (ShouldTrackServerWards()) { EnsureWardObjectsInitialized(); PruneWardObjects(); foreach (ZDO s_wardObject in s_wardObjects) { yield return s_wardObject; } yield break; } HashSet visited = new HashSet(); foreach (PrivateArea area in PrivateArea.m_allAreas) { int num; if (area == null) { num = 0; } else { ZNetView nview = area.m_nview; num = ((((nview != null) ? new bool?(nview.IsValid()) : ((bool?)null)) == true) ? 1 : 0); } ZDO zdo = ((num != 0) ? area.m_nview.GetZDO() : null); if (IsWard(zdo) && visited.Add(zdo.m_uid)) { yield return zdo; } } } internal static int CountWardsByCreator(long creatorID) { if (creatorID == 0) { return 0; } int num = 0; foreach (ZDO allWard in GetAllWards()) { if (allWard.IsCreator(creatorID)) { num++; } } return num; } internal static PrivateArea FindLoadedWard(ZDOID zdoID) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) foreach (PrivateArea allArea in PrivateArea.m_allAreas) { if (!((Object)(object)allArea == (Object)null) && !((Object)(object)allArea.m_nview == (Object)null) && allArea.m_nview.IsValid()) { ZDO zDO = allArea.m_nview.GetZDO(); if (zDO != null && ((ZDOID)(ref zDO.m_uid)).Equals(zdoID)) { return allArea; } } } return null; } internal static ZDO GetWard(ZDOID zdoID) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) ZDOMan instance = ZDOMan.instance; ZDO val = ((instance != null) ? instance.GetZDO(zdoID) : null); return IsWard(val) ? val : null; } internal static bool TryGetWard(ZDOID zdoID, out ZDO zdo) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) zdo = GetWard(zdoID); return zdo != null; } internal static List> GetPermittedPlayers(ZDO zdo) { List> list = new List>(); 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(num2, zdo.GetString("pu_name" + i, ""))); } } return list; } internal static bool IsExplicitlyPermitted(ZDO zdo, long playerID) { return playerID != 0L && GetPermittedPlayers(zdo).Any((KeyValuePair player) => player.Key == playerID); } internal static bool AddPermitted(ZDO zdo, long playerID, string playerName) { if (!IsWard(zdo) || playerID == 0) { return false; } List> permittedPlayers = GetPermittedPlayers(zdo); if (permittedPlayers.Any((KeyValuePair player) => player.Key == playerID)) { return false; } permittedPlayers.Add(new KeyValuePair(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> permittedPlayers = GetPermittedPlayers(zdo); KeyValuePair keyValuePair = permittedPlayers.FirstOrDefault((KeyValuePair player) => player.Key == playerID); if (keyValuePair.Key == 0) { return false; } playerName = keyValuePair.Value ?? ""; permittedPlayers.RemoveAll((KeyValuePair player) => player.Key == playerID); SetPermittedPlayers(zdo, permittedPlayers); return true; } internal static void SetPermittedPlayers(ZDO zdo, List> permitted) { if (IsWard(zdo)) { if (permitted == null) { permitted = new List>(); } zdo.Set(ZDOVars.s_permitted, permitted.Count, false); for (int i = 0; i < permitted.Count; i++) { zdo.Set("pu_id" + i, permitted[i].Key); zdo.Set("pu_name" + i, permitted[i].Value ?? ""); } } } internal static bool IsPermitted(ZDO zdo, long playerID) { if (zdo == null || playerID == 0) { return false; } if (ProtectiveWards.HasWardManagementAccess(zdo, playerID)) { return true; } if (IsExplicitlyPermitted(zdo, playerID)) { return true; } return GuildsCompat.HasWardGuildAccess(zdo, playerID); } internal static bool HasDirectAccessToWardZdo(ZDO zdo, long playerID) { if (zdo == null) { return true; } if (playerID == 0) { return false; } if (!IsWard(zdo)) { return false; } if (zdo.IsCreator(playerID)) { return true; } return IsPermitted(zdo, playerID); } internal static bool UseCustomWardRange(ZDO zdo) { if (!ProtectiveWards.ArePerWardSettingsEnabled()) { return ProtectiveWards.setWardRange.Value; } if (zdo == null) { return false; } bool flag = ProtectiveWards.wardSettingsUseDefaultsForAllWards.Value && ProtectiveWards.setWardRange.Value; if (ProtectiveWards.HasZdoFloat(zdo, ProtectiveWards.s_range)) { flag = true; } return zdo.GetBool(ProtectiveWards.s_customRange, flag); } internal static float GetConfiguredWardRange(ZDO zdo) { if (!ProtectiveWards.ArePerWardSettingsEnabled()) { return ProtectiveWards.wardRange.Value; } return (zdo != null) ? zdo.GetFloat(ProtectiveWards.s_range, ProtectiveWards.wardSettingsUseDefaultsForAllWards.Value ? ProtectiveWards.wardRange.Value : GetWardDefaultRadius()) : ProtectiveWards.wardRange.Value; } internal static float GetWardDefaultRadius() { if (s_wardDefaultRadiusCached) { return s_wardDefaultRadius; } if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab = instance.GetPrefab("guard_stone"); obj = ((prefab != null) ? prefab.GetComponent() : null); } PrivateArea val = (PrivateArea)obj; if ((Object)(object)val != (Object)null) { s_wardDefaultRadius = val.m_radius; } } s_wardDefaultRadiusCached = true; return s_wardDefaultRadius; } internal static float GetWardRadius(ZDO zdo) { if (zdo == null) { return GetWardDefaultRadius(); } return UseCustomWardRange(zdo) ? GetConfiguredWardRange(zdo) : GetWardDefaultRadius(); } internal static bool AreWardZdosOverlapping(ZDO protectedWard, ZDO candidateWard) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!IsWard(protectedWard) || !IsWard(candidateWard)) { return false; } float wardRadius = GetWardRadius(protectedWard); float wardRadius2 = GetWardRadius(candidateWard); return ProtectiveWards.GetConfiguredWardDistance(protectedWard.GetPosition(), candidateWard.GetPosition()) <= wardRadius + wardRadius2; } internal static bool CanShareConnectedWardAccess(ZDO protectedWard, ZDO candidateWard, ProtectiveWards.WardConnectedAccessMode mode) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (mode == ProtectiveWards.WardConnectedAccessMode.Off) { return false; } if (!IsWard(protectedWard) || !IsWard(candidateWard)) { return false; } if (protectedWard == candidateWard || ((ZDOID)(ref protectedWard.m_uid)).Equals(candidateWard.m_uid)) { return true; } switch (mode) { case ProtectiveWards.WardConnectedAccessMode.SameCreatorOnly: { long creatorId = protectedWard.GetCreatorId(); long creatorId2 = candidateWard.GetCreatorId(); return creatorId != 0L && creatorId == creatorId2; } case ProtectiveWards.WardConnectedAccessMode.MutualTrust: { long creatorId = protectedWard.GetCreatorId(); long creatorId2 = candidateWard.GetCreatorId(); return creatorId != 0L && creatorId2 != 0L && HasDirectAccessToWardZdo(protectedWard, creatorId2) && HasDirectAccessToWardZdo(candidateWard, creatorId); } case ProtectiveWards.WardConnectedAccessMode.AnyConnected: return true; default: return false; } } internal static IEnumerable ConnectedAccessWardZdos(ZDO rootWard, ProtectiveWards.WardConnectedAccessMode mode, Func isActiveCandidate) { if (!IsWard(rootWard)) { yield break; } HashSet visited = new HashSet(); List queue = new List(); int queueIndex = 0; visited.Add(rootWard.m_uid); queue.Add(rootWard); while (queueIndex < queue.Count) { ZDO current = queue[queueIndex++]; yield return current; if (mode == ProtectiveWards.WardConnectedAccessMode.Off) { continue; } foreach (ZDO candidate in GetAllWards()) { if (candidate != null && !visited.Contains(candidate.m_uid) && (isActiveCandidate == null || isActiveCandidate(candidate)) && AreWardZdosOverlapping(current, candidate) && CanShareConnectedWardAccess(rootWard, candidate, mode)) { visited.Add(candidate.m_uid); queue.Add(candidate); } } } } internal static bool HasAccessToWardOrConnectedWardZdo(ZDO rootWard, long playerID, ProtectiveWards.WardConnectedAccessMode mode, Func isActiveCandidate) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (HasDirectAccessToWardZdo(rootWard, playerID)) { return true; } if (mode == ProtectiveWards.WardConnectedAccessMode.Off) { return false; } foreach (ZDO item in ConnectedAccessWardZdos(rootWard, mode, isActiveCandidate)) { if (item == null || ((ZDOID)(ref item.m_uid)).Equals(rootWard.m_uid) || !HasDirectAccessToWardZdo(item, playerID)) { continue; } return true; } return false; } private static bool ShouldTrackServerWards() { return (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); } private static void AddIfWard(ZDO zdo) { if (ShouldTrackServerWards() && IsWard(zdo)) { s_wardObjects.Add(zdo); } } private static void RemoveIfWard(ZDO zdo) { if (zdo != null && IsWard(zdo)) { s_wardObjects.Remove(zdo); } } private static void PruneWardObjects() { s_wardObjects.RemoveWhere((ZDO zdo) => zdo == null || !IsWard(zdo)); } private static void EnsureWardObjectsInitialized() { if (!ShouldTrackServerWards()) { return; } ZDOMan instance = ZDOMan.instance; if (instance != null) { if (!s_wardObjectsInitialized) { RebuildWardObjects(instance); } else if (s_wardObjects.Count == 0 && instance.m_objectsByID.Count > 0) { RebuildWardObjects(instance); } } } private static void RebuildWardObjects(ZDOMan zdoMan) { s_wardObjects.Clear(); if (!ShouldTrackServerWards() || zdoMan == null) { s_wardObjectsInitialized = false; return; } s_wardObjectsInitialized = true; foreach (KeyValuePair item in zdoMan.m_objectsByID) { AddIfWard(item.Value); } } } internal static class BackgroundProtection { private struct CachedBool { public float Time; public bool Value; } [HarmonyPatch(typeof(ZoneSystem), "Start")] private static class ZoneSystem_Start_ResetBackgroundProtectionCache { private static void Postfix() { ResetCache(); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] private static class ZoneSystem_OnDestroy_ResetBackgroundProtectionCache { private static void Postfix() { ResetCache(); } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] private static class Player_TryPlacePiece_PreventBuildingWithoutPermittedPlayersNearby { [HarmonyPriority(800)] private static bool Prefix(Player __instance, Piece piece, ref bool __result) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)piece == (Object)null || (Object)(object)__instance.m_placementGhost == (Object)null) { return true; } if (!IsBuildingRestricted(__instance, __instance.m_placementGhost.transform.position)) { return true; } ((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null); __result = false; return false; } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] private static class Player_CheckCanRemovePiece_PreventDemolishingWithoutPermittedPlayersNearby { [HarmonyPriority(800)] private static bool Prefix(Player __instance, Piece piece, ref bool __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)piece == (Object)null) { return true; } if (piece.IsCreator()) { return true; } if (!IsBuildingRestricted(__instance, ((Component)piece).transform.position)) { return true; } ((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null); __result = false; return false; } } [HarmonyPatch(typeof(WearNTear), "Damage")] private static class WearNTear_Damage_BackgroundProtection { private static void Prefix(WearNTear __instance, HitData hit) { if (ShouldSuppressWearNTearDamage(__instance, hit) || ShouldSuppressTameDamageToStructure(__instance, hit)) { ((DamageTypes)(ref hit.m_damage)).Modify(0f); } } } [HarmonyPatch(typeof(Character), "Damage")] private static class Character_Damage_BackgroundTameProtection { private static void Prefix(Character __instance, HitData hit) { if (ShouldSuppressTameCharacterDamage(__instance)) { ((DamageTypes)(ref hit.m_damage)).Modify(0f); } } } [HarmonyPatch(typeof(BaseAI), "FindEnemy")] private static class BaseAI_FindEnemy_PacifyTames { private static bool Prefix(BaseAI __instance, ref Character __result) { if (!ShouldPacifyTame(__instance)) { return true; } __result = null; return false; } } [HarmonyPatch(typeof(BaseAI), "FindRandomStaticTarget")] private static class BaseAI_FindRandomStaticTarget_PacifyTames { private static bool Prefix(BaseAI __instance, ref StaticTarget __result) { if (!ShouldPacifyTame(__instance)) { return true; } __result = null; return false; } } [HarmonyPatch(typeof(BaseAI), "FindClosestStaticPriorityTarget")] private static class BaseAI_FindClosestStaticPriorityTarget_PacifyTames { private static bool Prefix(BaseAI __instance, ref StaticTarget __result) { if (!ShouldPacifyTame(__instance)) { return true; } __result = null; return false; } } [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] private static class MonsterAI_UpdateAI_PacifyTames { private static void Prefix(MonsterAI __instance) { if (ShouldPacifyTame((BaseAI)(object)__instance)) { PacifyMonster(__instance); } } } [HarmonyPatch(typeof(AnimalAI), "UpdateAI")] private static class AnimalAI_UpdateAI_PacifyTames { private static void Prefix(AnimalAI __instance) { if (ShouldPacifyTame((BaseAI)(object)__instance)) { PacifyAnimal(__instance); } } } private static readonly Dictionary s_qualifiedBaseCache = new Dictionary(); private const float QualifiedBaseCacheSeconds = 10f; private static void ResetCache() { s_qualifiedBaseCache.Clear(); } internal static bool IsBackgroundProtectionActiveAt(Vector3 point, out ZDO ward) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ward = null; if (!TryFindBackgroundWard(point, point, out ward)) { return false; } if (!IsQualifiedProtectedBase(ward)) { return false; } return !HasEffectiveAccessPresence(ward, point); } internal static bool TryFindBackgroundWard(Vector3 sourcePoint, Vector3 targetPoint, out ZDO ward) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) ward = null; if (!ProtectiveWards.TryResolveWardCheckPoint(sourcePoint, out sourcePoint) || !ProtectiveWards.TryResolveWardCheckPoint(targetPoint, out targetPoint)) { return false; } ProtectiveWards.WardConnectedAccessMode mode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off); foreach (ZDO allWard in WardZdoUtils.GetAllWards()) { if (!IsActiveBackgroundWard(allWard) || !ProtectiveWards.IsInsideWardXZ(allWard, sourcePoint) || !WardZdoUtils.ConnectedAccessWardZdos(allWard, mode, IsActiveBackgroundWard).AnySafe((ZDO candidate) => ProtectiveWards.IsInsideWardXZ(candidate, targetPoint))) { continue; } ward = allWard; return true; } return false; } internal static bool HasEffectiveAccessPresence(ZDO ward, Vector3 point) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) if (!WardZdoUtils.IsWard(ward)) { return false; } ProtectiveWards.WardConnectedAccessMode mode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off); float num = Mathf.Max(ProtectiveWards.wardBackgroundPresenceRadius.Value, 0f); if (!ProtectiveWards.TryResolveWardCheckPoint(point, out var resolvedPoint)) { return false; } foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer == (Object)null) { continue; } long playerID = allPlayer.GetPlayerID(); if (!ward.HasConnectedWardAccess(playerID, mode, IsActiveBackgroundWard) || !ProtectiveWards.TryResolveWardCheckPoint(((Component)allPlayer).transform.position, out var resolvedPlayerPoint)) { continue; } switch (ProtectiveWards.wardBackgroundPresenceMode.Value) { case ProtectiveWards.WardBackgroundPresenceMode.PermittedOnline: return true; case ProtectiveWards.WardBackgroundPresenceMode.PermittedInsideConnectedArea: if (WardZdoUtils.ConnectedAccessWardZdos(ward, mode, IsActiveBackgroundWard).AnySafe((ZDO area) => ProtectiveWards.IsInsideWardXZ(area, resolvedPlayerPoint))) { return true; } break; default: if (Utils.DistanceXZ(resolvedPlayerPoint, resolvedPoint) <= num) { return true; } break; } } return false; } internal static bool IsQualifiedProtectedBase(ZDO ward) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (!WardZdoUtils.IsWard(ward)) { return false; } int num = Math.Max(ProtectiveWards.wardBackgroundProtectedBaseMinPieces.Value, 0); if (num == 0) { return true; } if (s_qualifiedBaseCache.TryGetValue(ward.m_uid, out var value) && Time.time - value.Time < 10f) { return value.Value; } bool flag = CountPlayerBuiltPiecesInNetwork(ward, num) >= num; s_qualifiedBaseCache[ward.m_uid] = new CachedBool { Time = Time.time, Value = flag }; return flag; } private static int CountPlayerBuiltPiecesInNetwork(ZDO ward, int stopAt) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) ProtectiveWards.WardConnectedAccessMode mode = ((ProtectiveWards.wardBackgroundConnectedAccessMode != null) ? ProtectiveWards.wardBackgroundConnectedAccessMode.Value : ProtectiveWards.WardConnectedAccessMode.Off); HashSet hashSet = new HashSet(); List list = new List(); foreach (ZDO item in WardZdoUtils.ConnectedAccessWardZdos(ward, mode, IsActiveBackgroundWard)) { list.Clear(); Piece.GetAllPiecesInRadius(item.GetPosition(), item.GetWardRadius(), list); foreach (Piece item2 in list) { if (!((Object)(object)item2 == (Object)null) && item2.IsPlacedByPlayer()) { hashSet.Add(item2); if (hashSet.Count >= stopAt) { return hashSet.Count; } } } } return hashSet.Count; } private static bool IsActiveBackgroundWard(ZDO zdo) { return WardZdoUtils.IsWard(zdo) && zdo.GetBool(ZDOVars.s_enabled, false) && !WardExpiration.IsExpired(zdo); } internal static bool ShouldSuppressWearNTearDamage(WearNTear wearNTear, HitData hit) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)wearNTear == (Object)null || hit == null) { return false; } Piece val = wearNTear.m_piece ?? ((Component)wearNTear).GetComponent(); bool flag = (Object)(object)val != (Object)null && val.IsPlacedByPlayer(); bool flag2 = (Object)(object)((Component)wearNTear).GetComponent() != (Object)null || (Object)(object)((Component)wearNTear).GetComponentInParent() != (Object)null; bool flag3 = (Object)(object)((Component)wearNTear).GetComponent() != (Object)null || (Object)(object)((Component)wearNTear).GetComponentInParent() != (Object)null; if (!flag && !flag2 && !flag3) { return false; } if (!TryFindBackgroundWard(((Component)wearNTear).transform.position, ((Component)wearNTear).transform.position, out var ward)) { return false; } if (!IsQualifiedProtectedBase(ward)) { return false; } Character attacker = hit.GetAttacker(); if (ProtectiveWards.wardBackgroundStructureProtection.Value == ProtectiveWards.WardBackgroundStructureProtectionMode.BlockNonPermittedPlayerDamage && flag && (Object)(object)attacker != (Object)null && attacker.IsPlayer()) { ZDO zdo = ward; Character obj = ((attacker is Player) ? attacker : null); if (!zdo.HasConnectedWardAccess((obj != null) ? ((Player)obj).GetPlayerID() : 0, ProtectiveWards.wardBackgroundConnectedAccessMode.Value, IsActiveBackgroundWard)) { return true; } } if (HasEffectiveAccessPresence(ward, ((Component)wearNTear).transform.position)) { return false; } if (ProtectiveWards.wardBackgroundProtectBoats.Value && flag2) { return true; } if (ProtectiveWards.wardBackgroundProtectCarts.Value && flag3) { return true; } if (flag) { if (ProtectiveWards.wardBackgroundStructureProtection.Value == ProtectiveWards.WardBackgroundStructureProtectionMode.BlockAllDamageWhenNoPermittedNearby) { return true; } if (ProtectiveWards.wardBackgroundProtectFire.Value && IsFireDamage(hit)) { return true; } } return false; } internal static bool ShouldSuppressTameDamageToStructure(WearNTear wearNTear, HitData hit) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.wardBackgroundTamesPreventDamageToStructures.Value) { return false; } if ((Object)(object)wearNTear == (Object)null || hit == null || !hit.HaveAttacker()) { return false; } Piece val = wearNTear.m_piece ?? ((Component)wearNTear).GetComponent(); 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(this IEnumerable source, Func predicate) { if (source == null) { return false; } foreach (T item in source) { if (predicate(item)) { return true; } } return false; } } internal class FullProtection { [HarmonyPatch(typeof(PrivateArea), "CheckAccess")] public static class PrivateArea_CheckAccess_ScopedWardAccessBypass { private static bool Prefix(ref bool __result) { if (s_privateAreaCheckBypassDepth <= 0) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Character), "AddFireDamage")] public static class Character_AddFireDamage_IndirectFireDamageProtection { private static void Prefix(Character __instance, ref float damage) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { damage = 0f; } } } [HarmonyPatch(typeof(Character), "UpdateSmoke")] public static class Character_UpdateSmoke_IndirectSmokeDamageProtection { private static void Prefix(Character __instance, ref float dt) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { dt = 0f; } } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] public static class WearNTear_UpdateWear_RainProtection { private static void Prefix(WearNTear __instance, ref bool ___m_noRoofWear, ref bool __state) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && ProtectiveWards.wardRainProtection != null && ProtectiveWards.wardRainProtection.Value && ___m_noRoofWear && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __state = ___m_noRoofWear; ___m_noRoofWear = false; } } private static void Postfix(ref bool ___m_noRoofWear, bool __state) { if (ProtectiveWards.wardRainProtection != null && ProtectiveWards.wardRainProtection.Value && __state) { ___m_noRoofWear = __state; } } } [HarmonyPatch(typeof(Ship), "UpdateUpsideDmg")] public static class Ship_UpdateUpsideDmg_PreventShipDamage { private static bool Prefix(Ship __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || ProtectiveWards.wardShipProtection == null || ProtectiveWards.wardShipProtection.Value == ProtectiveWards.ShipDamageType.Off) { return true; } return !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position); } } [HarmonyPatch(typeof(Ship), "UpdateWaterForce")] public static class Ship_UpdateWaterForce_PreventShipDamage { private static void Prefix(Ship __instance, ref float __state) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && ProtectiveWards.wardShipProtection != null && ProtectiveWards.wardShipProtection.Value != ProtectiveWards.ShipDamageType.Off && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { __state = __instance.m_waterImpactDamage; __instance.m_waterImpactDamage = 0f; } } private static void Postfix(Ship __instance, float __state) { if (__state != 0f) { __instance.m_waterImpactDamage = __state; } } } [HarmonyPatch(typeof(Container), "Interact")] public static class Container_Interact_PreventUnauthorizedAccess { [HarmonyPriority(800)] private static bool Prefix(Container __instance, Humanoid character, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectChests.Value) { return true; } if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character)) { if (__instance.m_checkGuardStone) { StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state); } return true; } __result = true; return false; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(Door), "Interact")] public static class Door_Interact_PreventUnauthorizedAccess { private static bool Prefix(Door __instance, Humanoid character, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectDoors.Value) { return true; } if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character)) { if (__instance.m_checkGuardStone) { StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state); } return true; } __result = true; return false; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(Pickable), "Interact")] public static class Pickable_Interact_PreventUnauthorizedAccess { private static bool Prefix(Pickable __instance, Humanoid character, ref bool __result) { if (!ProtectiveWards.wardAccessProtectPlants.Value) { return true; } if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character)) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(ShipControlls), "Interact")] public static class ShipControlls_Interact_PreventUnauthorizedAccess { private static bool Prefix(ShipControlls __instance, Humanoid character, ref bool __result) { if (!ProtectiveWards.wardAccessProtectBoats.Value) { return true; } if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character)) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Sadle), "Interact")] public static class Sadle_Interact_PreventUnauthorizedAccess { private static bool Prefix(Sadle __instance, Humanoid character, ref bool __result) { if (!ProtectiveWards.wardAccessProtectTames.Value) { return true; } if (!ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, character)) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Tameable), "Interact")] public static class Tameable_Interact_PreventUnauthorizedAccess { private static bool Prefix(Tameable __instance, Humanoid user, bool hold, ref bool __result) { if (!ProtectiveWards.wardAccessProtectTames.Value) { return true; } if (hold) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Tameable), "UseItem")] public static class Tameable_UseItem_PreventUnauthorizedAccess { private static bool Prefix(Tameable __instance, Humanoid user, ItemData item, ref bool __result) { if (!ProtectiveWards.wardAccessProtectTames.Value) { return true; } if (!IsProtectedTameUseItem(__instance, item)) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } private static bool IsProtectedTameUseItem(Tameable tameable, ItemData item) { if ((Object)(object)tameable == (Object)null || item == null || (Object)(object)tameable.m_saddleItem == (Object)null || tameable.m_saddleItem.m_itemData == null) { return false; } return tameable.IsTamed() && item.m_shared.m_name == tameable.m_saddleItem.m_itemData.m_shared.m_name; } } [HarmonyPatch(typeof(Petable), "Interact")] public static class Petable_Interact_PreventUnauthorizedAccess { private static bool Prefix(Petable __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectTames.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Pet), "Interact")] public static class Pet_Interact_PreventUnauthorizedAccess { private static bool Prefix(Pet __instance, Humanoid user, bool hold, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectTames.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { if (IsProtectedPetItemStandInteraction(__instance, hold)) { StartPrivateAreaCheckBypass((Component)(object)__instance.m_itemStand, user, ref __state); } return true; } return false; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } private static bool IsProtectedPetItemStandInteraction(Pet pet, bool hold) { return hold && (Object)(object)pet != (Object)null && (Object)(object)pet.m_itemStand != (Object)null && pet.m_itemStand.HaveAttachment(); } } [HarmonyPatch(typeof(Pet), "UseItem")] public static class Pet_UseItem_PreventUnauthorizedAccess { private static bool Prefix(Pet __instance, Humanoid user, ItemData item, ref bool __result) { if (!ProtectiveWards.wardAccessProtectTames.Value) { return true; } if (!IsProtectedPetUseItem(__instance, item)) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } private static bool IsProtectedPetUseItem(Pet pet, ItemData item) { if ((Object)(object)pet == (Object)null || item == null || (Object)(object)pet.m_FeedItem == (Object)null || pet.m_FeedItem.m_itemData == null) { return false; } return item.m_shared.m_name == pet.m_FeedItem.m_itemData.m_shared.m_name; } } [HarmonyPatch(typeof(Vagon), "Interact")] public static class Vagon_Interact_PreventUnauthorizedAccess { private static bool Prefix(Vagon __instance, Humanoid character, ref bool __result) { if (!ProtectiveWards.wardAccessProtectCarts.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, character, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Feast), "Interact")] public static class Feast_Interact_PreventUnauthorizedAccess { private static bool Prefix(Feast __instance, Humanoid human, ref bool __result) { if (!ProtectiveWards.wardAccessProtectFood.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, human, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(ItemDrop), "Interact")] public static class ItemDrop_Interact_PreventUnauthorizedFoodAccess { private static bool Prefix(ItemDrop __instance, Humanoid character, bool alt, ref bool __result) { if (!ProtectiveWards.wardAccessProtectFood.Value) { return true; } if (alt || !IsPlacedConsumable(__instance)) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, character, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(ItemDrop), "Pickup")] public static class ItemDrop_Pickup_PreventUnauthorizedAccess { private static bool Prefix(ItemDrop __instance, Humanoid character) { return !ShouldBlockItemPickup(__instance, character); } } [HarmonyPatch(typeof(Humanoid), "Pickup", new Type[] { typeof(GameObject), typeof(bool), typeof(bool) })] public static class Humanoid_Pickup_PreventUnauthorizedAccess { private static bool Prefix(GameObject go, Humanoid __instance) { return !ShouldBlockItemPickup((go != null) ? go.GetComponent() : null, __instance); } } [HarmonyPatch(typeof(Player), "AutoPickup")] public static class Player_AutoPickup_PreventBlockedItemPull { private static void Prefix(Player __instance) { s_autoPickupPlayer = __instance; } private static void Finalizer(Player __instance) { if ((Object)(object)s_autoPickupPlayer == (Object)(object)__instance) { s_autoPickupPlayer = null; } } } [HarmonyPatch(typeof(ItemDrop), "InTar")] public static class ItemDrop_InTar_PreventBlockedAutoPickupPull { private static void Postfix(ItemDrop __instance, ref bool __result) { if (!__result && !((Object)(object)s_autoPickupPlayer == (Object)null) && ShouldBlockItemPickup(__instance, (Humanoid)(object)s_autoPickupPlayer, silent: true)) { __result = true; } } } [HarmonyPatch(typeof(ShieldGenerator), "OnAddFuel")] public static class ShieldGenerator_OnAddFuel_PreventUnauthorizedAccess { private static bool Prefix(ShieldGenerator __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectShieldGenerators.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Incinerator), "OnIncinerate")] public static class Incinerator_OnIncinerate_PreventUnauthorizedAccess { private static bool Prefix(Incinerator __instance, Humanoid user, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectIncinerators.Value) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(TeleportWorld), "Interact")] public static class TeleportWorld_Interact_PreventUnauthorizedAccess { private static bool Prefix(TeleportWorld __instance, Humanoid human, bool hold, ref bool __result, ref bool __state) { if (ProtectiveWards.wardAccessProtectPortals.Value == ProtectiveWards.WardPortalAccessMode.AllowAll) { return true; } if (hold) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, human, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, human, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(TeleportWorld), "SetText")] public static class TeleportWorld_SetText_PreventUnauthorizedAccess { private static bool Prefix(TeleportWorld __instance) { if (ProtectiveWards.wardAccessProtectPortals.Value == ProtectiveWards.WardPortalAccessMode.AllowAll) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } return !ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance, (Humanoid)(object)localPlayer); } } [HarmonyPatch(typeof(TeleportWorldTrigger), "OnTriggerEnter")] public static class TeleportWorldTrigger_OnTriggerEnter_PreventUnauthorizedTargetAccess { private static bool Prefix(TeleportWorldTrigger __instance, Collider colliderIn) { if (ProtectiveWards.wardAccessProtectPortals.Value != ProtectiveWards.WardPortalAccessMode.BlockAll) { return true; } if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_teleportWorld == (Object)null || (Object)(object)colliderIn == (Object)null) { return true; } Player component = ((Component)colliderIn).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)Player.m_localPlayer != (Object)(object)component) { return true; } if (ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)__instance.m_teleportWorld, (Humanoid)(object)component)) { return false; } if (TeleportTargetAccessCheckStarted(__instance.m_teleportWorld, component)) { return false; } return true; } } [HarmonyPatch(typeof(CookingStation), "Interact")] public static class CookingStation_Interact_PreventUnauthorizedAccess { private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(CookingStation), "UseItem")] public static class CookingStation_UseItem_PreventUnauthorizedAccess { private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")] public static class CookingStation_OnAddFuelSwitch_PreventUnauthorizedAccess { private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(CookingStation), "OnAddFoodSwitch")] public static class CookingStation_OnAddFoodSwitch_PreventUnauthorizedAccess { private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Smelter), "OnAddOre")] public static class Smelter_OnAddOre_PreventUnauthorizedAccess { private static bool Prefix(Smelter __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Smelter), "OnEmpty")] public static class Smelter_OnEmpty_PreventUnauthorizedAccess { private static bool Prefix(Smelter __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Smelter), "OnAddFuel")] public static class Smelter_OnAddFuel_PreventUnauthorizedAccess { private static bool Prefix(Smelter __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Fermenter), "Interact")] public static class Fermenter_Interact_PreventUnauthorizedAccess { private static bool Prefix(Fermenter __instance, Humanoid user, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(Fermenter), "UseItem")] public static class Fermenter_UseItem_PreventUnauthorizedAccess { private static bool Prefix(Fermenter __instance, Humanoid user, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(Beehive), "Interact")] public static class Beehive_Interact_PreventUnauthorizedAccess { private static bool Prefix(Beehive __instance, Humanoid character, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, character, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(SapCollector), "Interact")] public static class SapCollector_Interact_PreventUnauthorizedAccess { private static bool Prefix(SapCollector __instance, Humanoid character, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectProductionStations.Value) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, character, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, character, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(ItemStand), "Interact")] public static class ItemStand_Interact_PreventUnauthorizedAccess { private static bool Prefix(ItemStand __instance, Humanoid user, bool hold, bool alt, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectItemStands.Value) { return true; } if (!IsProtectedItemStandInteraction(__instance, hold, alt)) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } private static bool IsProtectedItemStandInteraction(ItemStand itemStand, bool hold, bool alt) { if ((Object)(object)itemStand == (Object)null) { return false; } if (!itemStand.HaveAttachment()) { return itemStand.m_autoAttach && itemStand.m_supportedItems.Count == 1; } if (hold && itemStand.m_canBeRemoved) { return true; } return alt && (Object)(object)itemStand.m_visualItemDrop != (Object)null && itemStand.m_orientationSettings.Count > 1; } } [HarmonyPatch(typeof(ItemStand), "UseItem")] public static class ItemStand_UseItem_PreventUnauthorizedAccess { private static bool Prefix(ItemStand __instance, Humanoid user, ItemData item, ref bool __result) { if (!ProtectiveWards.wardAccessProtectItemStands.Value) { return true; } if (item == null || __instance.HaveAttachment() || !__instance.CanAttach(item)) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Switch), "Interact")] public static class Switch_Interact_PreventUnauthorizedExplicitAccess { private static bool Prefix(Switch __instance, Humanoid character, ref bool __result, ref bool __state) { Component protectedSwitchTarget = GetProtectedSwitchTarget(__instance); if ((Object)(object)protectedSwitchTarget == (Object)null) { return true; } if (BlockProtectedInteraction(protectedSwitchTarget, character, ref __result)) { return false; } StartPrivateAreaCheckBypass(protectedSwitchTarget, character, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(Switch), "UseItem")] public static class Switch_UseItem_PreventUnauthorizedExplicitAccess { private static bool Prefix(Switch __instance, Humanoid user, ref bool __result, ref bool __state) { Component protectedSwitchTarget = GetProtectedSwitchTarget(__instance); if ((Object)(object)protectedSwitchTarget == (Object)null) { return true; } if (BlockProtectedInteraction(protectedSwitchTarget, user, ref __result)) { return false; } StartPrivateAreaCheckBypass(protectedSwitchTarget, user, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(ArmorStand), "UseItem")] public static class ArmorStand_UseItem_PreventUnauthorizedAccess { private static bool Prefix(ArmorStand __instance, Humanoid user, ref bool __result, ref bool __state) { if (!ProtectiveWards.wardAccessProtectItemStands.Value) { return true; } if (BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return false; } StartPrivateAreaCheckBypass((Component)(object)__instance, user, ref __state); return true; } private static void Finalizer(bool __state) { StopPrivateAreaCheckBypass(__state); } } [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData), typeof(bool) })] public static class MapTable_OnRead_PreventUnauthorizedAccess { private static bool Prefix(MapTable __instance, Humanoid user) { if (!ProtectiveWards.wardAccessProtectMapTables.Value) { return true; } return !ShouldBlockProtectedInteraction((Component)(object)__instance, user); } } [HarmonyPatch(typeof(MapTable), "OnWrite")] public static class MapTable_OnWrite_PreventUnauthorizedAccess { private static bool Prefix(MapTable __instance, Humanoid user) { if (!ProtectiveWards.wardAccessProtectMapTables.Value) { return true; } return !ShouldBlockProtectedInteraction((Component)(object)__instance, user); } } [HarmonyPatch(typeof(Fireplace), "Interact")] public static class Fireplace_Interact_PreventUnauthorizedAccess { private static bool Prefix(Fireplace __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectFireplaces.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Fireplace), "UseItem")] public static class Fireplace_UseItem_PreventUnauthorizedAccess { private static bool Prefix(Fireplace __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectFireplaces.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Turret), "Interact")] public static class Turret_Interact_PreventUnauthorizedAccess { private static bool Prefix(Turret __instance, Humanoid character, ref bool __result) { if (!ProtectiveWards.wardAccessProtectTurrets.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, character, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Turret), "UseItem")] public static class Turret_UseItem_PreventUnauthorizedAccess { private static bool Prefix(Turret __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectTurrets.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(CraftingStation), "Interact")] public static class CraftingStation_Interact_PreventUnauthorizedAccess { private static bool Prefix(CraftingStation __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectCraftingStations.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Player), "AddKnownStation")] public static class Player_AddKnownStation_PreventUnauthorizedStationDiscovery { [HarmonyPriority(800)] private static bool Prefix(Player __instance, CraftingStation station) { if (!ProtectiveWards.wardAccessProtectCraftingStations.Value) { return true; } if ((Object)(object)__instance == (Object)null || (Object)(object)station == (Object)null) { return true; } int level = station.GetLevel(true); if (__instance.m_knownStations.TryGetValue(station.m_name, out var value) && value >= level) { return true; } return !ShouldSilentlyBlockProtectedInteraction((Component)(object)station, (Humanoid)(object)__instance); } } [HarmonyPatch(typeof(Bed), "Interact")] public static class Bed_Interact_PreventUnauthorizedSleep { [HarmonyPriority(800)] private static bool Prefix(Bed __instance, Humanoid human, ref bool __result) { if (!ProtectiveWards.wardAccessProtectBeds.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, human, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Catapult), "OnLegUse")] public static class Catapult_OnLegUse_PreventUnauthorizedAccess { private static bool Prefix(Catapult __instance, Humanoid user) { if (!ProtectiveWards.wardAccessProtectCatapults.Value) { return true; } return !ShouldBlockProtectedInteraction((Component)(object)__instance, user); } } [HarmonyPatch(typeof(Catapult), "OnLoadPointUse")] public static class Catapult_OnLoadPointUse_PreventUnauthorizedAccess { private static bool Prefix(Catapult __instance, Humanoid user) { if (!ProtectiveWards.wardAccessProtectCatapults.Value) { return true; } return !ShouldBlockProtectedInteraction((Component)(object)__instance, user); } } [HarmonyPatch(typeof(ArcheryTarget), "Interact")] public static class ArcheryTarget_Interact_PreventUnauthorizedAccess { private static bool Prefix(ArcheryTarget __instance, Humanoid user, ref bool __result) { if (!ProtectiveWards.wardAccessProtectArcheryTargets.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, user, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Barber), "Interact")] public static class Barber_Interact_PreventUnauthorizedAccess { private static bool Prefix(Barber __instance, Humanoid human, ref bool __result) { if (!ProtectiveWards.wardAccessProtectBarbers.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, human, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(PrivateArea), "Interact")] public static class PrivateArea_Interact_PreventInactiveWardAccessInsideOtherWard { [HarmonyPriority(800)] private static bool Prefix(PrivateArea __instance, Humanoid human, ref bool __result) { if (!ProtectiveWards.wardAccessProtectInactiveWards.Value) { return true; } if ((Object)(object)__instance == (Object)null || __instance.IsEnabled()) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, human, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(ZoneSystem), "Start")] public static class ZoneSystem_Start_RegisterSaddleUserRPC { private static void Postfix() { RegisterSaddleUserRPC(); RegisterTeleportAccessRPC(); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] public static class ZoneSystem_OnDestroy_ResetFullProtectionRPCs { private static void Postfix() { ResetRPCRegistration(); } } [HarmonyPatch(typeof(Sadle), "RPC_RequestRespons")] public static class Sadle_RPC_RequestRespons_RecordLastUser { private static void Postfix(Sadle __instance, bool granted) { if (granted && !((Object)(object)Player.m_localPlayer == (Object)null)) { long playerID = Player.m_localPlayer.GetPlayerID(); if (playerID != 0) { SetLastSaddleUserLocal(__instance, playerID); RequestSetLastSaddleUser(__instance, playerID); } } } } [HarmonyPatch(typeof(ShipControlls), "RPC_RequestRespons")] public static class ShipControlls_RPC_RequestRespons_RecordLastController { private static void Postfix(ShipControlls __instance, bool granted) { if (granted && !((Object)(object)__instance?.m_ship == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { long playerID = Player.m_localPlayer.GetPlayerID(); if (playerID != 0) { ZNetView componentZNetView = ((Component)(object)__instance.m_ship).GetComponentZNetView(); SetLastVehicleControllerLocal(componentZNetView, playerID); RequestSetLastVehicleController(componentZNetView, playerID); } } } } [HarmonyPatch(typeof(Vagon), "AttachTo")] public static class Vagon_AttachTo_RecordLastController { private static void Postfix(Vagon __instance) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } GameObject attachedObject = __instance.m_attachedObject; Player val = ((attachedObject != null) ? attachedObject.GetComponent() : null); if (val == null) { val = Player.GetClosestPlayer(((Component)__instance).transform.position, 10f); } if (!((Object)(object)val == (Object)null)) { long playerID = val.GetPlayerID(); if (playerID != 0) { ZNetView componentZNetView = ((Component)(object)__instance).GetComponentZNetView(); SetLastVehicleControllerLocal(componentZNetView, playerID); RequestSetLastVehicleController(componentZNetView, playerID); } } } } public static class Interactable_PreventUnauthorizedAccess { private static readonly HashSet ExcludedInteractableTypes = new HashSet { typeof(Container), typeof(Door), typeof(Pickable), typeof(PrivateArea), typeof(Ladder), typeof(ShipControlls), typeof(Sadle), typeof(Switch), typeof(Chair), typeof(TombStone), typeof(TeleportWorld), typeof(Vagon), typeof(Feast), typeof(ShieldGenerator), typeof(Tameable), typeof(Pet), typeof(Petable), typeof(ItemStand), typeof(CookingStation), typeof(Fermenter), typeof(Beehive), typeof(SapCollector), typeof(ItemDrop), typeof(PickableItem), typeof(Fish), typeof(RopeAttachment), typeof(Teleport), typeof(MapTable), typeof(Fireplace), typeof(Turret), typeof(CraftingStation), typeof(Bed), typeof(Catapult), typeof(ArcheryTarget), typeof(Barber) }; internal static void ExcludeType(Type type) { if (type != null) { ExcludedInteractableTypes.Add(type); } } internal static IEnumerable TargetMethods() { HashSet methods = new HashSet(); foreach (Type type in GetLoadedInteractableTypes()) { MethodInfo interact = AccessTools.Method(type, "Interact", new Type[3] { typeof(Humanoid), typeof(bool), typeof(bool) }, (Type[])null); if (ShouldPatchInteractableMethod(interact) && methods.Add(interact)) { yield return interact; } MethodInfo useItem = AccessTools.Method(type, "UseItem", new Type[2] { typeof(Humanoid), typeof(ItemData) }, (Type[])null); if (ShouldPatchInteractableMethod(useItem) && methods.Add(useItem)) { yield return useItem; } } } private static IEnumerable GetLoadedInteractableTypes() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly == null || assembly.IsDynamic) { continue; } Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { ReflectionTypeLoadException ex2 = ex; types = ex2.Types; } catch { continue; } Type[] array = types; foreach (Type type in array) { if (!(type == null) && !(type == typeof(Interactable)) && !type.IsAbstract && !type.ContainsGenericParameters && !ExcludedInteractableTypes.Contains(type) && SafeIsInteractableType(type)) { yield return type; } } } } private static bool SafeIsInteractableType(Type type) { try { return typeof(Interactable).IsAssignableFrom(type); } catch (Exception ex) { ProtectiveWards.LogInfo("Skipping interactable type scan for " + (type?.FullName ?? "unknown") + ": " + ex.GetType().Name); return false; } } private static bool ShouldPatchInteractableMethod(MethodInfo method) { if (method == null || method.DeclaringType == null || method.DeclaringType == typeof(Interactable) || method.IsAbstract || method.IsVirtual || ExcludedInteractableTypes.Contains(method.DeclaringType)) { return false; } try { return method.GetMethodBody() != null; } catch (Exception ex) { ProtectiveWards.LogInfo("Skipping interactable method patch for " + method.DeclaringType.FullName + "." + method.Name + ": " + ex.GetType().Name); return false; } } public static bool Prefix(object __instance, Humanoid __0, ref bool __result) { if (!ProtectiveWards.wardAccessProtectInteractables.Value) { return true; } if (!(__0 is Player)) { return true; } Component val = (Component)((__instance is Component) ? __instance : null); if (val == null) { return true; } if (!ProtectiveWards.BlockUnauthorizedWardInteraction(val, __0)) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Trap), "Interact")] public static class Trap_Interact_PreventUnauthorizedAccess { private static bool Prefix(Trap __instance, Humanoid character, ref bool __result) { if (!ProtectiveWards.wardTrapProtection.Value) { return true; } if (!BlockProtectedInteraction((Component)(object)__instance, character, ref __result)) { return true; } return false; } } [HarmonyPatch(typeof(Trap), "OnTriggerEnter")] private static class Trap_OnTriggerEnter_TrapProtection { private static bool Prefix(Trap __instance, Collider collider) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.wardTrapProtection.Value) { return true; } Player componentInParent = ((Component)collider).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null) { return true; } if (!ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, out var _, checkCache: true)) { return true; } if (BackgroundProtection.IsBackgroundProtectionActiveAt(((Component)__instance).transform.position, out var ward) && ward != null && !ward.HasConnectedWardAccess(componentInParent.GetPlayerID(), ProtectiveWards.wardBackgroundConnectedAccessMode.Value, IsActiveWardZdo)) { return true; } return false; } } [HarmonyPatch(typeof(Destructible), "Damage")] public static class Destructible_Damage_PlantProtection { private static void ModifyHitDamage(HitData hit, float value) { ((DamageTypes)(ref hit.m_damage)).Modify(Math.Max(value, 0f)); } private static void Prefix(Destructible __instance, HitData hit) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.wardPlantProtection.Value || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner() || __instance.m_destroyed || (int)__instance.GetDestructibleType() != 1 || __instance.m_health != 1f || hit == null || !hit.HaveAttacker() || !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, out var area, checkCache: true)) { return; } Pickable val = default(Pickable); if ((Object)(object)((Component)__instance).GetComponent() != (Object)null) { ModifyHitDamage(hit, 0f); area.FlashShield(false); } else if (((Component)__instance).TryGetComponent(ref val)) { GameObject itemPrefab = val.m_itemPrefab; SharedData val2 = ((itemPrefab == null) ? null : itemPrefab.GetComponent()?.m_itemData.m_shared); string item = ((itemPrefab == null) ? null : ((Object)itemPrefab).name?.ToLower()); if (val2 != null && (ProtectiveWards._wardPlantProtectionList.Contains(val2.m_name.ToLower()) || ProtectiveWards._wardPlantProtectionList.Contains(item))) { ModifyHitDamage(hit, 0f); area.FlashShield(false); } } } } private const string RPC_SetLastSaddleUser = "PW_SetLastSaddleUser"; private const string RPC_SetLastVehicleController = "PW_SetLastVehicleController"; private const string RPC_CheckTeleportTargetAccess = "PW_CheckTeleportTargetAccess"; private const string RPC_TeleportTargetAccessResponse = "PW_TeleportTargetAccessResponse"; private const float saddleUserRecordMaxDistance = 10f; private const float vehicleControllerRecordMaxDistance = 10f; private const float portalSourceValidationDistance = 8f; private static int s_privateAreaCheckBypassDepth; private static bool s_saddleRpcRegistered; private static bool s_teleportAccessRpcRegistered; private static bool s_interactablePatchesApplied; private static Player s_autoPickupPlayer; internal static bool BlockProtectedInteraction(Component component, Humanoid human, ref bool result) { if (!ProtectiveWards.BlockUnauthorizedWardInteraction(component, human)) { return false; } result = true; return true; } private static bool ShouldBlockProtectedInteraction(Component component, Humanoid human) { return (Object)(object)human != (Object)null && ProtectiveWards.BlockUnauthorizedWardInteraction(component, human); } private static bool ShouldSilentlyBlockProtectedInteraction(Component component, Humanoid human) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)component == (Object)null)) { Player val = (Player)(object)((human is Player) ? human : null); if (val != null) { foreach (PrivateArea allArea in PrivateArea.m_allAreas) { if (!ProtectiveWards.IsActivePlayerWard(allArea) || !ProtectiveWards.IsPointInsideWardArea(allArea, component.transform.position) || ProtectiveWards.HasAccessToWardOrConnectedWard(allArea, val) || ProtectiveWards.IsObjectOwnedByPlayerWithWardAccess(component, val)) { continue; } return true; } return false; } } return false; } private static void StartPrivateAreaCheckBypass(Component component, Humanoid human, ref bool state) { if (ProtectiveWards.ShouldBypassVanillaPrivateAreaCheck(component, human)) { s_privateAreaCheckBypassDepth++; state = true; } } private static void StopPrivateAreaCheckBypass(bool state) { if (state) { s_privateAreaCheckBypassDepth = Math.Max(0, s_privateAreaCheckBypassDepth - 1); } } private static void RegisterTeleportAccessRPC() { if (!s_teleportAccessRpcRegistered && ZRoutedRpc.instance != null) { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ZRoutedRpc.instance.Register("PW_CheckTeleportTargetAccess", (Action)RPC_CheckTeleportTargetAccessServer); } ZRoutedRpc.instance.Register("PW_TeleportTargetAccessResponse", (Action)RPC_TeleportTargetAccessResponseClient); s_teleportAccessRpcRegistered = true; } } private static void ResetRPCRegistration() { s_saddleRpcRegistered = false; s_teleportAccessRpcRegistered = false; } internal static void PatchLoadedInteractables(Harmony harmony) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if (s_interactablePatchesApplied || harmony == null) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(Interactable_PreventUnauthorizedAccess), "Prefix", (Type[])null, (Type[])null); if (methodInfo == null) { return; } foreach (MethodBase item in Interactable_PreventUnauthorizedAccess.TargetMethods()) { harmony.Patch(item, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } s_interactablePatchesApplied = true; } internal static void ResetDynamicPatchState() { s_interactablePatchesApplied = false; } internal static void ExcludeInteractableType(Type type) { Interactable_PreventUnauthorizedAccess.ExcludeType(type); } private static bool TeleportTargetAccessCheckStarted(TeleportWorld teleport, Player player) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown if (!((Object)(object)player == (Object)null) && teleport != null && teleport.TargetFound()) { ZNetView nview = teleport.m_nview; if (nview != null && nview.IsValid()) { ZDO zDO = teleport.m_nview.GetZDO(); if (zDO == null) { return false; } ZPackage val = new ZPackage(); val.Write(zDO.m_uid); val.Write(player.GetPlayerID()); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { RPC_CheckTeleportTargetAccessServer(0L, new ZPackage(val.GetArray())); } else { if (ZRoutedRpc.instance == null) { return false; } ZRoutedRpc.instance.InvokeRoutedRPC("PW_CheckTeleportTargetAccess", new object[1] { val }); } return true; } } return false; } private static void RPC_CheckTeleportTargetAccessServer(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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long claimedPlayerID = package.ReadLong(); if (ZDOMan.instance == null || !ProtectiveWards.TryGetRoutedPlayer(sender, claimedPlayerID, out var player)) { return; } ZDO zDO = ZDOMan.instance.GetZDO(val); if (zDO == null) { SendTeleportTargetAccessResponse(sender, val, granted: false, ""); return; } if (!IsSourcePortalUsableByRequester(zDO, player, out var blockingOwnerName)) { SendTeleportTargetAccessResponse(sender, val, granted: false, blockingOwnerName); return; } ZDOID connectionZDOID = zDO.GetConnectionZDOID((ConnectionType)1); ZDO zDO2 = ZDOMan.instance.GetZDO(connectionZDOID); if (zDO2 == null) { SendTeleportTargetAccessResponse(sender, val, granted: false, ""); return; } bool granted = IsTeleportTargetAccessibleToPlayer(zDO2.GetPosition(), player.PlayerID, out blockingOwnerName); SendTeleportTargetAccessResponse(sender, val, granted, blockingOwnerName); } private static bool IsSourcePortalUsableByRequester(ZDO sourceZdo, ProtectiveWards.RoutedPlayerContext requester, out string blockingOwnerName) { //IL_000d: 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_0053: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) blockingOwnerName = ""; if (sourceZdo == null || sourceZdo.GetConnectionZDOID((ConnectionType)1) == ZDOID.None) { return false; } if (!requester.HasPosition) { return false; } float num = 8f; ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject obj2 = instance.FindInstance(sourceZdo.m_uid); obj = ((obj2 != null) ? obj2.GetComponent() : null); } TeleportWorld val = (TeleportWorld)obj; if ((Object)(object)val != (Object)null) { num = Math.Max(num, val.m_activationRange + 2f); } if (Vector3.Distance(requester.Position, sourceZdo.GetPosition()) > num) { return false; } if (IsTeleportTargetAccessibleToPlayer(sourceZdo.GetPosition(), requester.PlayerID, out blockingOwnerName)) { return true; } return sourceZdo.IsCreator(requester.PlayerID); } private static void SendTeleportTargetAccessResponse(long peerID, ZDOID sourceZdoID, bool granted, string blockingOwnerName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(sourceZdoID); val.Write(granted); val.Write(blockingOwnerName ?? ""); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZRoutedRpc.instance != null && peerID != 0) { ZRoutedRpc.instance.InvokeRoutedRPC(peerID, "PW_TeleportTargetAccessResponse", new object[1] { val }); } else { RPC_TeleportTargetAccessResponseClient(0L, new ZPackage(val.GetArray())); } } private static void RPC_TeleportTargetAccessResponseClient(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) ZDOID val = package.ReadZDOID(); bool flag = package.ReadBool(); string ownerName = package.ReadString(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } GameObject val2 = ZNetScene.instance.FindInstance(val); TeleportWorld val3 = ((val2 != null) ? val2.GetComponent() : null); if (!((Object)(object)val3 == (Object)null)) { if (!flag) { ((Character)localPlayer).Message((MessageType)2, ProtectiveWards.GetPrivateZoneDeniedMessage(ownerName), 0, (Sprite)null); } else { val3.Teleport(localPlayer); } } } private static bool IsTeleportTargetAccessibleToPlayer(Vector3 targetPoint, long playerID, out string blockingOwnerName) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) blockingOwnerName = ""; if (playerID == 0) { return true; } ProtectiveWards.WardConnectedAccessMode mode = ProtectiveWards.wardAccessConnectedAccessMode?.Value ?? ProtectiveWards.WardConnectedAccessMode.Off; foreach (ZDO allWard in WardZdoUtils.GetAllWards()) { if (!IsActiveWardZdo(allWard) || !ProtectiveWards.IsPointInsideWardArea(allWard, targetPoint) || allWard.HasConnectedWardAccess(playerID, mode, IsActiveWardZdo)) { continue; } blockingOwnerName = ProtectiveWards.GetWardOwnerName(allWard); return false; } return true; } private static bool IsActiveWardZdo(ZDO zdo) { return zdo.IsWard() && zdo.GetBool(ZDOVars.s_enabled, false) && !zdo.GetBool(WardExpiration.s_expirationExpired, false); } private static void RegisterSaddleUserRPC() { if (!s_saddleRpcRegistered && ZRoutedRpc.instance != null) { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ZRoutedRpc.instance.Register("PW_SetLastSaddleUser", (Action)RPC_SetLastSaddleUserServer); ZRoutedRpc.instance.Register("PW_SetLastVehicleController", (Action)RPC_SetLastVehicleControllerServer); } s_saddleRpcRegistered = true; } } private static void RequestSetLastSaddleUser(Sadle sadle, long playerID) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown ZNetView componentZNetView = ((Component)(object)sadle).GetComponentZNetView(); ZDO val = (((Object)(object)componentZNetView != (Object)null && componentZNetView.IsValid()) ? componentZNetView.GetZDO() : null); if (val == null || playerID == 0) { return; } ZPackage val2 = new ZPackage(); val2.Write(val.m_uid); val2.Write(playerID); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { RPC_SetLastSaddleUserServer(0L, new ZPackage(val2.GetArray())); return; } ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("PW_SetLastSaddleUser", new object[1] { val2 }); } } private static void RPC_SetLastSaddleUserServer(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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) ZDOID val = package.ReadZDOID(); long num = package.ReadLong(); if (num == 0L || ZDOMan.instance == null || !ProtectiveWards.TryGetRoutedPlayer(sender, num, out var player)) { return; } ZDO zDO = ZDOMan.instance.GetZDO(val); if (zDO != null) { long num2 = zDO.GetLong(ZDOVars.s_user, 0L); ZDOID characterID = player.CharacterID; if (num2 == ((ZDOID)(ref characterID)).UserID || (player.HasPosition && !(Vector3.Distance(player.Position, zDO.GetPosition()) > 10f))) { zDO.Set(ProtectiveWards.s_lastSaddleUser, player.PlayerID); } } } private static void SetLastSaddleUserLocal(Sadle sadle, long playerID) { if (!((Object)(object)sadle == (Object)null) && playerID != 0) { SetLastSaddleUserOnView(((Component)(object)sadle).GetComponentZNetView(), playerID); if ((Object)(object)sadle.m_character != (Object)null) { SetLastSaddleUserOnView(((Component)(object)sadle.m_character).GetComponentZNetView(), playerID); } } } private static void SetLastSaddleUserOnView(ZNetView nview, long playerID) { ZDO val = (((Object)(object)nview != (Object)null && nview.IsValid()) ? nview.GetZDO() : null); if (val != null && playerID != 0) { val.Set(ProtectiveWards.s_lastSaddleUser, playerID); } } private static void RequestSetLastVehicleController(ZNetView nview, long playerID) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown ZDO val = (((Object)(object)nview != (Object)null && nview.IsValid()) ? nview.GetZDO() : null); if (val == null || playerID == 0) { return; } ZPackage val2 = new ZPackage(); val2.Write(val.m_uid); val2.Write(playerID); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { RPC_SetLastVehicleControllerServer(0L, new ZPackage(val2.GetArray())); return; } ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("PW_SetLastVehicleController", new object[1] { val2 }); } } private static void RPC_SetLastVehicleControllerServer(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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_00b6: 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 num = package.ReadLong(); if (num == 0L || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || !ProtectiveWards.TryGetRoutedPlayer(sender, num, out var player)) { return; } ZDO zDO = ZDOMan.instance.GetZDO(val); if (zDO == null) { return; } GameObject val2 = ZNetScene.instance.FindInstance(val); if ((Object)(object)val2 == (Object)null) { return; } if ((Object)(object)val2.GetComponent() != (Object)null) { if (zDO.GetLong(ZDOVars.s_user, 0L) != player.PlayerID && (!player.HasPosition || Vector3.Distance(player.Position, zDO.GetPosition()) > 10f)) { return; } } else if (!((Object)(object)val2.GetComponent() != (Object)null) || !player.HasPosition || Vector3.Distance(player.Position, zDO.GetPosition()) > 10f) { return; } zDO.Set(ProtectiveWards.s_lastVehicleController, player.PlayerID); } private static void SetLastVehicleControllerLocal(ZNetView nview, long playerID) { ZDO val = (((Object)(object)nview != (Object)null && nview.IsValid()) ? nview.GetZDO() : null); if (val != null && playerID != 0) { val.Set(ProtectiveWards.s_lastVehicleController, playerID); } } private static Component GetProtectedSwitchTarget(Switch sw) { if ((Object)(object)sw == (Object)null) { return null; } ArmorStand componentInParent = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && ProtectiveWards.wardAccessProtectItemStands.Value) { return (Component)(object)componentInParent; } MapTable componentInParent2 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null && ProtectiveWards.wardAccessProtectMapTables.Value) { return (Component)(object)componentInParent2; } Catapult componentInParent3 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent3 != (Object)null && ProtectiveWards.wardAccessProtectCatapults.Value) { return (Component)(object)componentInParent3; } Barber componentInParent4 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent4 != (Object)null && ProtectiveWards.wardAccessProtectBarbers.Value) { return (Component)(object)componentInParent4; } CraftingStation componentInParent5 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent5 != (Object)null && ProtectiveWards.wardAccessProtectCraftingStations.Value) { return (Component)(object)componentInParent5; } Fireplace componentInParent6 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent6 != (Object)null && ProtectiveWards.wardAccessProtectFireplaces.Value) { return (Component)(object)componentInParent6; } Turret componentInParent7 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent7 != (Object)null && ProtectiveWards.wardAccessProtectTurrets.Value) { return (Component)(object)componentInParent7; } if (ProtectiveWards.wardAccessProtectProductionStations.Value) { CookingStation componentInParent8 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent8 != (Object)null) { return (Component)(object)componentInParent8; } Smelter componentInParent9 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent9 != (Object)null) { return (Component)(object)componentInParent9; } Fermenter componentInParent10 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent10 != (Object)null) { return (Component)(object)componentInParent10; } Beehive componentInParent11 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent11 != (Object)null) { return (Component)(object)componentInParent11; } SapCollector componentInParent12 = ((Component)sw).GetComponentInParent(); if ((Object)(object)componentInParent12 != (Object)null) { return (Component)(object)componentInParent12; } } return null; } private static bool IsPlacedConsumable(ItemDrop itemDrop) { return IsConsumableItem(itemDrop) && itemDrop.IsPiece(); } private static bool IsConsumableItem(ItemDrop itemDrop) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 return (Object)(object)itemDrop != (Object)null && itemDrop.m_itemData != null && itemDrop.m_itemData.m_shared != null && (int)itemDrop.m_itemData.m_shared.m_itemType == 2; } private static bool ShouldBlockItemPickup(ItemDrop itemDrop, Humanoid character, bool silent = false) { if ((Object)(object)itemDrop == (Object)null || IsConsumableItem(itemDrop)) { return false; } switch (ProtectiveWards.wardAccessProtectItemPickupMode.Value) { case ProtectiveWards.WardItemPickupMode.AllowAll: return false; case ProtectiveWards.WardItemPickupMode.AllowNonPlayerDropped: if (itemDrop.m_autoPickup) { return false; } break; default: return false; case ProtectiveWards.WardItemPickupMode.BlockAll: break; } return silent ? ShouldSilentlyBlockProtectedInteraction((Component)(object)itemDrop, character) : ProtectiveWards.BlockUnauthorizedWardInteraction((Component)(object)itemDrop, character); } } internal class Multipliers { [HarmonyPatch(typeof(SEMan), "ModifyFallDamage")] public static class SEMan_ModifyFallDamage_FallDamageMultiplier { private static void Postfix(Character ___m_character, ZNetView ___m_nview, ref float damage) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)___m_nview == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)___m_character).transform.position)) { damage *= Math.Max(ProtectiveWards.fallDamageTakenMultiplier.Value, 0f); } } } [HarmonyPatch(typeof(Character), "Damage")] public static class Character_Damage_DamageMultipliers { private static void Prefix(Character __instance, ref HitData hit, ZNetView ___m_nview) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)___m_nview == (Object)null || !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, out var area) || (hit.HaveAttacker() && hit.GetAttacker().IsBoss())) { return; } if (__instance.IsPlayer()) { ModifyHitDamage(ref hit, ProtectiveWards.playerDamageTakenMultiplier.Value); } else if (__instance.IsTamed()) { ModifyHitDamage(ref hit, ProtectiveWards.tamedDamageTakenMultiplier.Value); if (ProtectiveWards.boarsHensProtection.Value && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && (!hit.HaveAttacker() || !hit.GetAttacker().IsPlayer())) { if (hit.GetTotalDamage() != hit.m_damage.m_fire) { area.FlashShield(false); } ModifyHitDamage(ref hit, 0f); } } else { ModifyHitDamage(ref hit, ProtectiveWards.playerDamageDealtMultiplier.Value); } } } [HarmonyPatch(typeof(WearNTear), "Damage")] public static class WearNTear_Damage_DamageTakenMultiplier { private static void Prefix(WearNTear __instance, ref HitData hit, ZNetView ___m_nview) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 if (!((Object)(object)___m_nview == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { if (ProtectiveWards.fireplaceProtection.Value && (int)hit.m_hitType == 14 && (Object)(object)((Component)__instance).GetComponent() != (Object)null) { ModifyHitDamage(ref hit, 0f); } else if (ProtectiveWards.wardShipProtection.Value == ProtectiveWards.ShipDamageType.AnyButPlayerDamage && (int)hit.m_hitType != 2 && (Object)(object)((Component)__instance).GetComponent() != (Object)null) { ModifyHitDamage(ref hit, 0f); } else if (ProtectiveWards.wardShipProtection.Value == ProtectiveWards.ShipDamageType.AnyDamage && (Object)(object)((Component)__instance).GetComponent() != (Object)null) { ModifyHitDamage(ref hit, 0f); } else if ((Object)(object)((Component)__instance).GetComponent() != (Object)null && (!hit.HaveAttacker() || !hit.GetAttacker().IsBoss())) { ModifyHitDamage(ref hit, ProtectiveWards.structureDamageTakenMultiplier.Value); } } } } [HarmonyPatch(typeof(Player), "UpdateFood")] public static class Player_UpdateFood_FoodDrainMultiplier { private static void Prefix(Player __instance, float dt, bool forceUpdate) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.foodDrainMultiplier.Value == 1f || (Object)(object)__instance == (Object)null || !(dt + __instance.m_foodUpdateTimer >= 1f || forceUpdate) || !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { return; } foreach (Food food in __instance.m_foods) { food.m_time += 1f - Math.Max(0f, ProtectiveWards.foodDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Player), "UseStamina")] public static class Player_UseStamina_StaminaDrainMultiplier { private static void Prefix(Player __instance, ref float v) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.staminaDrainMultiplier.Value != 1f && !((Object)(object)__instance == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { v *= Math.Max(0f, ProtectiveWards.staminaDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] public static class Player_UseStamina_HammerDurabilityDrainMultiplier { private static void Prefix(Player __instance, ref float __state) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.hammerDurabilityDrainMultiplier.Value != 1f && !((Object)(object)__instance == (Object)null) && ((Character)__instance).InPlaceMode() && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); __state = rightItem.m_shared.m_useDurabilityDrain; SharedData shared = rightItem.m_shared; shared.m_useDurabilityDrain *= Math.Max(0f, ProtectiveWards.hammerDurabilityDrainMultiplier.Value); } } private static void Postfix(Player __instance, float __state) { if (__state != 0f) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); rightItem.m_shared.m_useDurabilityDrain = __state; } } } [HarmonyPatch(typeof(Player), "Repair")] public static class Player_Repair_HammerDurabilityDrainMultiplier { private static void Prefix(Player __instance, ItemData toolItem, ref float __state) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.hammerDurabilityDrainMultiplier.Value != 1f && !((Object)(object)__instance == (Object)null) && ((Character)__instance).InPlaceMode() && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { __state = toolItem.m_shared.m_useDurabilityDrain; SharedData shared = toolItem.m_shared; shared.m_useDurabilityDrain *= Math.Max(0f, ProtectiveWards.hammerDurabilityDrainMultiplier.Value); } } private static void Postfix(Player __instance, ItemData toolItem, float __state) { if (__state != 0f) { toolItem.m_shared.m_useDurabilityDrain = __state; } } } [HarmonyPatch(typeof(Skills), "LowerAllSkills")] private static class Skills_OnDeath_SkillDrainMultiplier { private static void Prefix(ref float factor, Player ___m_player) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)___m_player == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)___m_player).transform.position)) { factor *= Math.Max(0f, ProtectiveWards.skillsDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Fireplace), "GetTimeSinceLastUpdate")] private static class Fireplace_GetTimeSinceLastUpdate_FireplaceDrainMultiplier { private static void Postfix(Fireplace __instance, ref double __result) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.fireplaceDrainMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.fireplaceDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Smelter), "GetDeltaTime")] private static class Smelter_GetDeltaTime_FireplaceDrainMultiplier_SmeltingSpeedMultiplier { private static void Postfix(Smelter __instance, ref double __result) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) float num = ((__instance.m_name == "$piece_bathtub") ? ProtectiveWards.fireplaceDrainMultiplier.Value : ProtectiveWards.smeltingSpeedMultiplier.Value); if (num != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, num); } } } [HarmonyPatch(typeof(CookingStation), "GetDeltaTime")] private static class CookingStation_GetDeltaTime_CookingSpeedMultiplier { private static void Postfix(Smelter __instance, ref float __result) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.cookingSpeedMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.cookingSpeedMultiplier.Value); } } } [HarmonyPatch(typeof(CookingStation), "UpdateFuel")] private static class CookingStation_UpdateFuel_FireplaceDrainMultiplier { private static void Prefix(Smelter __instance, ref float dt, ref float __state) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if ((ProtectiveWards.fireplaceDrainMultiplier.Value != 1f || ProtectiveWards.cookingSpeedMultiplier.Value != 1f) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __state = dt; dt *= Math.Max(0f, ProtectiveWards.fireplaceDrainMultiplier.Value); if (ProtectiveWards.cookingSpeedMultiplier.Value > 0f) { dt /= ProtectiveWards.cookingSpeedMultiplier.Value; } } } private static void Postfix(Smelter __instance, ref float dt, float __state) { if (__state != 0f) { dt = __state; } } } [HarmonyPatch(typeof(Fermenter), "GetFermentationTime")] private static class Fermenter_GetFermentationTime_FermentingSpeedMultiplier { private static void Postfix(Fermenter __instance, ref double __result) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.fermentingSpeedMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.fermentingSpeedMultiplier.Value); } } } [HarmonyPatch(typeof(SapCollector), "GetTimeSinceLastUpdate")] private static class SapCollector_GetTimeSinceLastUpdate_SapCollectingSpeedMultiplier { private static void Postfix(SapCollector __instance, ref float __result) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.sapCollectingSpeedMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.sapCollectingSpeedMultiplier.Value); } } } [HarmonyPatch(typeof(Turret), "IsCoolingDown")] private static class Turret_IsCoolingDown_turretFireRateMultiplier { private static void Prefix(Turret __instance, ref float ___m_attackCooldown, ref float __state) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.turretFireRateMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __state = ___m_attackCooldown; ___m_attackCooldown *= Math.Max(0f, ProtectiveWards.turretFireRateMultiplier.Value); } } private static void Postfix(ref float ___m_attackCooldown, float __state) { if (__state > 0f) { ___m_attackCooldown = __state; } } } private static void ModifyHitDamage(ref HitData hit, float value) { ((DamageTypes)(ref hit.m_damage)).Modify(Math.Max(value, 0f)); } } internal class RaidProtection { [HarmonyPatch(typeof(Player), "UpdateBaseValue")] public static class Player_UpdateBaseValue_SittingRaidProtection { public static void Postfix(Player __instance, float ___m_baseValueUpdateTimer, ref int ___m_baseValue, ZNetView ___m_nview) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.sittingRaidProtection.Value && ___m_baseValueUpdateTimer == 0f && ___m_baseValue >= 3 && ((Character)__instance).IsSitting() && __instance.m_attached && ((Character)__instance).m_seman.HaveStatusEffect(SEMan.s_statusEffectCampFire) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { ___m_baseValue = ProtectiveWards.baseValueProtected; ZNet.instance.m_serverSyncedPlayerData["baseValue"] = ___m_baseValue.ToString(); ___m_nview.GetZDO().Set(ZDOVars.s_baseValue, ___m_baseValue, false); } } } [HarmonyPatch(typeof(RandEventSystem), "CheckBase")] public static class RandEventSystem_CheckBase_SittingRaidProtection { public static void Postfix(PlayerEventData player, ref bool __result) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.sittingRaidProtection.Value && __result && player.baseValue == ProtectiveWards.baseValueProtected) { ProtectiveWards.LogInfo($"Player at {player.position.x} {player.position.z} is in raid protected state."); __result = false; } } } } public static class WardOfferings { [HarmonyPatch(typeof(PrivateArea), "UseItem")] public static class PrivateArea_UseItem_Offerings { private static bool Prefix(PrivateArea __instance, Humanoid user, ItemData item, ref bool __result) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Invalid comparison between Unknown and I4 //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Invalid comparison between Unknown and I4 //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Invalid comparison between Unknown and I4 //IL_03b1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || item == null || item.m_shared == null) { return true; } if ((int)__instance.m_ownerFaction != 0 || !WardZdoUtils.IsWardPrefab(((Component)__instance).gameObject)) { return true; } if (!__instance.IsEnabled()) { ProtectiveWards.LogInfo("Ward disabled"); return true; } Player val = (Player)(object)((user is Player) ? user : null); if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer) { ProtectiveWards.LogInfo("UseItem user not a player"); return true; } if (ProtectiveWards.offeringProtectFromNonPermitted.Value && !ProtectiveWards.HasAccessToWardOrConnectedWard(__instance, val)) { ProtectiveWards.LogInfo("No access"); return true; } ProtectiveWards.LogInfo($"{val.GetPlayerName()} used {item.m_shared.m_name} on {__instance.m_nview.GetZDO()}"); bool flag = ProtectiveWards.offeringTaxi.Value && WardTaxi.IsTaxiOfferingItem(item.m_shared.m_name); bool flag2 = !flag && item.m_shared.m_name == "$item_blackcore" && ProtectiveWards.offeringAugmenting.Value; bool flag3 = flag2 || (!flag && item.m_shared.m_name == "$item_surtlingcore" && ProtectiveWards.offeringActiveRepair.Value); bool flag4 = (int)item.m_shared.m_itemType == 2; bool flag5 = !flag && ProtectiveWards.offeringFood.Value && item.m_shared.m_food > 0f; bool flag6 = !flag && ProtectiveWards.offeringMead.Value && item.m_shared.m_food <= 0f && Object.op_Implicit((Object)(object)item.m_shared.m_consumeStatusEffect); bool flag7 = flag4 && (flag5 || flag6); bool flag8 = !flag && ProtectiveWards.offeringThundertone.Value && item.m_shared.m_name == "$item_thunderstone"; bool flag9 = !flag && ProtectiveWards.offeringTrophy.Value && (int)item.m_shared.m_itemType == 13; bool flag10 = !flag && ProtectiveWards.offeringEitr.Value && item.m_shared.m_name == "$item_eitr"; bool flag11 = (!flag && ProtectiveWards.offeringYmirRemains.Value && item.m_shared.m_name == "$item_ymirremains") || flag10; bool flag12 = !flag && ProtectiveWards.offeringDragonEgg.Value && item.m_shared.m_name == "$item_dragonegg" && ZoneSystem.instance.GetGlobalKey((GlobalKeys)34); if (!flag3 && !flag7 && !flag8 && !flag9 && !flag11 && !flag12 && !flag) { if ((int)item.m_shared.m_itemType == 2) { __result = true; return false; } return true; } if (flag3) { RepairNearestStructures(flag2, __instance, val, item); } if (flag7) { ApplyConsumableEffectToNearestPlayers(__instance, item, val); } if (flag8) { ApplyThunderstrikeOnNearbyEnemies(__instance, item, val); } if (flag9) { ApplyTrophyEffectOnNearbyEnemies(__instance, item, val); } if (flag11) { ApplyInstantGrowthEffectOnNearbyPlants(__instance, item, val, !flag10); } if (flag12) { ApplyModerPowerEffectToNearbyPlayers(__instance, item, val); } if (flag) { WardTaxi.TryStartTaxiFromOffering(item, val, ((Component)__instance).transform.position); } __result = true; return false; } } internal static int moderPowerHash = StringExtensionMethods.GetStableHashCode("GP_Moder"); private static readonly WaitForSeconds wait1sec = new WaitForSeconds(1f); public static IEnumerator PassiveHealingEffect(PrivateArea ward, float amount, int seconds) { while (true) { if ((Object)(object)ward == (Object)null) { yield break; } if (Game.IsPaused()) { yield return (object)new WaitForSeconds(2f); } if (!ProtectiveWards.wardIsHealing.TryGetValue(ward, out var secondsLeft)) { yield break; } if (secondsLeft <= 0) { break; } ProtectiveWards.wardIsHealing[ward] -= seconds; List characters = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Character.GetCharactersInRange(((Component)area).transform.position, area.m_radius, characters); }); CollectionExtensions.DoIf((IEnumerable)characters.ToHashSet(), (Func)((Character character) => character.IsTamed() || character.IsPlayer()), (Action)delegate(Character character) { character.Heal(amount * (float)seconds, true); }); yield return (object)new WaitForSecondsRealtime((float)seconds); } ProtectiveWards.wardIsHealing.Remove(ward); ProtectiveWards.LogInfo("Passive healing stopped"); } public static IEnumerator LightningStrikeEffect(PrivateArea ward) { if (!((Object)(object)ward == (Object)null)) { List players = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Player.GetPlayersInRange(((Component)area).transform.position, area.m_radius, players); }); CollectionExtensions.Do((IEnumerable)players.ToHashSet(), (Action)delegate(Player player) { //IL_000b: 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) ProtectiveWards.preLightning.Create(((Component)player).transform.position, ((Component)player).transform.rotation, (Transform)null, 1f, -1); }); ProtectiveWards.LogInfo("Thor is preparing his strike"); yield return (object)new WaitForSeconds(Random.Range(5f, 7f)); if (Game.IsPaused()) { yield return wait1sec; } List characters = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Character.GetCharactersInRange(((Component)area).transform.position, area.m_radius, characters); }); CollectionExtensions.DoIf((IEnumerable)characters.ToHashSet(), (Func)((Character character) => character.IsMonsterFaction(Time.time)), (Action)delegate(Character character) { //IL_000b: 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) Object.Instantiate(ProtectiveWards.lightningAOE, ((Component)character).transform.position, ((Component)character).transform.rotation); }); } } public static IEnumerator InstantGrowthEffect(PrivateArea ward, List plants) { if ((Object)(object)ward == (Object)null) { yield break; } ProtectiveWards.LogInfo("Instant growth started"); yield return wait1sec; foreach (Plant plant in plants.ToHashSet()) { if (Object.op_Implicit((Object)(object)plant) && !((Object)(object)plant.m_nview == (Object)null) && plant.m_nview.IsValid() && plant.m_nview.IsOwner()) { if ((int)plant.m_status > 0) { plant.UpdateHealth(0.0); } plant.Grow(); yield return (object)new WaitForSeconds(0.25f); } } ProtectiveWards.LogInfo("Instant growth ended"); } private static void RepairNearestStructures(bool augment, PrivateArea ward, Player initiator, ItemData item) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; List pieces = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Piece.GetAllPiecesInRadius(((Component)area).transform.position, area.m_radius, pieces); }); WearNTear val = default(WearNTear); foreach (Piece item2 in pieces.Where((Piece piece) => piece.IsPlacedByPlayer())) { if (((Component)item2).TryGetComponent(ref val)) { if (val.Repair()) { num++; item2.m_placeEffect.Create(((Component)item2).transform.position, ((Component)item2).transform.rotation, (Transform)null, 1f, -1); } if (augment && (Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid() && val.m_nview.IsOwner() && val.m_nview.GetZDO().GetFloat(ZDOVars.s_health, val.m_health) < val.m_health * 2f) { val.m_nview.GetZDO().Set(ZDOVars.s_health, val.m_health * 2f); val.m_nview.InvokeRPC(ZNetView.Everybody, "WNTHealthChanged", new object[1] { val.m_health * 2f }); num2++; } } } if (num + num2 > 0) { ((Humanoid)initiator).GetInventory().RemoveOneItem(item); } if (num2 > 0) { ((Character)initiator).Message((MessageType)2, "$msg_offerdone".Localize(), 0, (Sprite)null); if (num > 0) { ((Character)initiator).Message((MessageType)1, "$msg_repaired".Localize(num.ToString()), 0, (Sprite)null); } } else if (num > 0) { ((Character)initiator).Message((MessageType)2, "$msg_repaired".Localize(num.ToString()), 0, (Sprite)null); } else if (augment) { ((Character)initiator).Message((MessageType)2, "$msg_cantoffer".Localize(), 0, (Sprite)null); } else { string text = "$msg_doesnotneedrepair".Localize(); ((Character)initiator).Message((MessageType)2, char.ToUpper(text[0]) + text.Substring(1), 0, (Sprite)null); } } private static void GetPlantsInRange(Vector3 point, float radius, List plants, bool growableOnly) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Invalid comparison between Unknown and I4 List allInstaces = SlowUpdate.GetAllInstaces(); float num = radius * radius; Plant val = default(Plant); foreach (SlowUpdate item in allInstaces) { if (((Component)item).TryGetComponent(ref val) && !((Object)(object)val.m_nview == (Object)null) && val.m_nview.IsValid() && val.m_nview.IsOwner() && Utils.DistanceSqr(((Component)item).transform.position, point) < num && (!growableOnly || (int)val.m_status == 0)) { plants.Add(val); } } } private static void ApplyTrophyEffectOnNearbyEnemies(PrivateArea ward, ItemData item, Player initiator) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) ProtectiveWards.trophyTargets = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Turret ws) => ((Object)ws).name == "piece_turret"))?.m_configTargets; if (ProtectiveWards.trophyTargets == null) { return; } bool flag = false; foreach (TrophyTarget item2 in ProtectiveWards.trophyTargets.Where((TrophyTarget configTarget) => item.m_shared.m_name == configTarget.m_item.m_itemData.m_shared.m_name)) { List characters = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Character.GetCharactersInRange(((Component)area).transform.position, area.m_radius, characters); }); foreach (Character item3 in from character in characters.ToHashSet() where character.IsMonsterFaction(Time.time) select character) { foreach (Character target in item2.m_targets) { if (item3.m_name == target.m_name) { item3.SetHealth(0f); flag = true; } } } } if (flag) { ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ((Character)initiator).Message((MessageType)2, "$msg_offerdone".Localize(), 0, (Sprite)null); } else { ((Character)initiator).Message((MessageType)2, "$msg_offerwrong".Localize(), 0, (Sprite)null); } } private static void ApplyThunderstrikeOnNearbyEnemies(PrivateArea ward, ItemData item, Player initiator) { if (!Object.op_Implicit((Object)(object)ProtectiveWards.lightningAOE)) { Incinerator val = Resources.FindObjectsOfTypeAll().FirstOrDefault(); ProtectiveWards.lightningAOE = val.m_lightingAOEs; ProtectiveWards.preLightning = val.m_leverEffects; } ((MonoBehaviour)ProtectiveWards.instance).StartCoroutine(LightningStrikeEffect(ward)); ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ((Character)initiator).Message((MessageType)2, "$piece_incinerator_conversion".Localize(), 0, (Sprite)null); } private static void ApplyConsumableEffectToNearestPlayers(PrivateArea ward, ItemData item, Player initiator) { if (item.m_shared.m_food > 0f) { if (ProtectiveWards.wardIsHealing.ContainsKey(ward)) { ((Character)initiator).Message((MessageType)2, "$msg_offerwrong".Localize(), 0, (Sprite)null); return; } ProtectiveWards.wardIsHealing.Add(ward, 180); ((MonoBehaviour)ProtectiveWards.instance).StartCoroutine(PassiveHealingEffect(ward, item.m_shared.m_foodRegen / 2f, 1)); ProtectiveWards.LogInfo("Passive healing begins"); ((Character)initiator).Message((MessageType)2, "$msg_consumed".Localize() + ": " + item.m_shared.m_name, 0, (Sprite)null); ((Humanoid)initiator).GetInventory().RemoveOneItem(item); } else { if (!Object.op_Implicit((Object)(object)item.m_shared.m_consumeStatusEffect)) { return; } ProtectiveWards.LogInfo("Consumable effect offered"); List players = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Player.GetPlayersInRange(((Component)area).transform.position, area.m_radius, players); }); bool flag = false; foreach (Player item2 in from player in players.ToHashSet() where ((Humanoid)player).CanConsumeItem(item, false) select player) { ((Character)item2).m_seman.AddStatusEffect(item.m_shared.m_consumeStatusEffect.NameHash(), true, 0, 0f); flag = true; } if (!flag) { ((Character)initiator).Message((MessageType)2, "$msg_cantoffer".Localize(), 0, (Sprite)null); return; } ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ((Character)initiator).Message((MessageType)2, "$msg_offerdone".Localize(), 0, (Sprite)null); } } private static void ApplyInstantGrowthEffectOnNearbyPlants(PrivateArea ward, ItemData item, Player initiator, bool growableOnly = true) { List plants = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) GetPlantsInRange(((Component)area).transform.position, area.m_radius, plants, growableOnly); }); if (plants.Count == 0) { ((Character)initiator).Message((MessageType)2, "$msg_cantoffer".Localize(), 0, (Sprite)null); return; } Inventory inventory = ((Humanoid)initiator).GetInventory(); if (item.m_shared.m_name == "$item_eitr" && inventory.CountItems("$item_eitr", -1, true) < 5) { ((Character)initiator).Message((MessageType)2, "$msg_incompleteoffering".Localize(), 0, (Sprite)null); return; } ((MonoBehaviour)ward).StartCoroutine(InstantGrowthEffect(ward, plants)); if (item.m_shared.m_name == "$item_eitr") { ((Humanoid)initiator).GetInventory().RemoveItem("$item_eitr", 5, -1, true); ProtectiveWards.LogInfo("Offered " + item.m_shared.m_name + " x5"); } else { ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ProtectiveWards.LogInfo("Offered " + item.m_shared.m_name); } ((Character)initiator).Message((MessageType)2, "$msg_offerdone".Localize(), 0, (Sprite)null); } private static void ApplyModerPowerEffectToNearbyPlayers(PrivateArea ward, ItemData item, Player initiator) { ProtectiveWards.LogInfo("Dragon egg offered"); List players = new List(); CollectionExtensions.Do(ProtectiveWards.ConnectedAreas(ward), (Action)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Player.GetPlayersInRange(((Component)area).transform.position, area.m_radius, players); }); foreach (Player item2 in players.ToHashSet()) { StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(moderPowerHash); ((Character)item2).GetSEMan().AddStatusEffect(statusEffect.NameHash(), true, 0, 0f); } ((Humanoid)initiator).GetInventory().RemoveOneItem(item); } internal static bool IsBossTrophy(string itemName) { itemName = itemName.GetItemName(); int result; switch (itemName) { default: result = ((itemName == "$item_trophy_fader") ? 1 : 0); break; case "$item_trophy_eikthyr": case "$item_trophy_elder": case "$item_trophy_bonemass": case "$item_trophy_dragonqueen": case "$item_trophy_goblinking": case "$item_trophy_seekerqueen": result = 1; break; } return (byte)result != 0; } internal static bool IsHildirChestItem(string itemName) { itemName = itemName.GetItemName(); return itemName == "$item_chest_hildir1" || itemName == "$item_chest_hildir2" || itemName == "$item_chest_hildir3"; } public static bool IsTeleportable(Player player) { if (((Humanoid)player).IsTeleportable()) { return true; } foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems()) { if (IsHildirChestItem(allItem.m_shared.m_name) || allItem.m_shared.m_teleportable) { continue; } return false; } return true; } } internal static class WardTaxi { private enum TaxiState { Idle, WaitingOutbound, OutboundFlight, FallingBeforeReturn, WaitingReturn, WaitingRetry, ReturnFlight, Falling } internal struct TaxiOffer { public string LocationName; public string ItemName; public int Stack; public bool ConsumeItem; } internal sealed class SE_WardTaxi : SE_Stats { public override void UpdateStatusEffect(float dt) { ((SE_Stats)this).UpdateStatusEffect(dt); WardTaxi.UpdateStatusEffect(this, dt); } public override void Stop() { OnStatusStopped(this); ((StatusEffect)this).Stop(); } } [HarmonyPatch(typeof(Valkyrie), "Awake")] private static class Valkyrie_Awake_Taxi { private static bool Prefix(Valkyrie __instance) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.offeringTaxi.Value) { return true; } if ((s_state != TaxiState.OutboundFlight && s_state != TaxiState.ReturnFlight) || (Object)(object)s_player == (Object)null || !s_waitingForValkyrieSpawn) { return true; } __instance.m_nview = ((Component)__instance).GetComponent(); __instance.m_animator = ((Component)__instance).GetComponentInChildren(); if ((Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsOwner() || ((Object)(object)Valkyrie.m_instance != (Object)null && (Object)(object)Valkyrie.m_instance != (Object)(object)__instance)) { ((Behaviour)__instance).enabled = false; return false; } ZDO zDO = __instance.m_nview.GetZDO(); if (zDO == null) { ((Behaviour)__instance).enabled = false; return false; } Valkyrie.m_instance = __instance; s_activeValkyrieId = zDO.m_uid; __instance.m_startAltitude = 30f; __instance.m_textDuration = 0f; __instance.m_descentAltitude = 150f; __instance.m_attachOffset = new Vector3(-0.1f, 1.5f, 0.1f); __instance.m_targetPoint = s_currentFlightTargetPosition + new Vector3(0f, __instance.m_dropHeight, 0f); Vector3 position = ((Component)s_player).transform.position; position.y += __instance.m_startAltitude; float num = (__instance.m_startDistance = Utils.DistanceXZ(__instance.m_targetPoint, position)); __instance.m_startDescentDistance = Math.Min(200f, num / 5f); __instance.m_speed = Math.Max(Math.Min(num / 90f, ProtectiveWards.maxTaxiSpeed.Value), 10f); if (__instance.m_speed <= 15f) { EnvMan.instance.m_introEnvironment = EnvMan.instance.m_currentEnv.m_name; } else { EnvMan.instance.m_introEnvironment = "ThunderStorm"; } s_player.m_intro = true; ((Component)__instance).transform.position = position; ((Component)__instance).transform.rotation = s_currentFlightSpawnRotation; float val = Utils.DistanceXZ(__instance.m_targetPoint, ((Component)__instance).transform.position); float num2 = Mathf.Clamp(__instance.m_descentAltitude / Math.Max(val, 1f), 0.2f, 0.8f); __instance.m_descentStart = Vector3.Lerp(__instance.m_targetPoint, ((Component)__instance).transform.position, num2); __instance.m_descentStart.y = __instance.m_descentAltitude; Vector3 val2 = __instance.m_targetPoint - __instance.m_descentStart; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 1f) { val2 = ((Component)s_player).transform.forward; } else { ((Vector3)(ref val2)).Normalize(); } __instance.m_flyAwayPoint = __instance.m_targetPoint + val2 * __instance.m_startDescentDistance; __instance.m_flyAwayPoint.y += 100f; __instance.SyncPlayer(true); ResetTaxiProgressWatch(s_player); ProtectiveWards.LogInfo($"Setting up Valkyrie passage from {((Component)__instance).transform.position} to {__instance.m_targetPoint} distance {num:0.0} speed {__instance.m_speed:0.0} yaw {((Component)__instance).transform.eulerAngles.y:0.0} yawOffset {s_currentFlightSpawnYawOffset:0.0} reference {ZNet.instance.GetReferencePosition()}"); return false; } } [HarmonyPatch(typeof(Valkyrie), "OnDestroy")] private static class Valkyrie_OnDestroy_Taxi { private static void Prefix(Valkyrie __instance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (IsActiveTaxiValkyrie(__instance)) { s_activeValkyrieId = ZDOID.None; if ((s_state == TaxiState.OutboundFlight || s_state == TaxiState.ReturnFlight) && (Object)(object)s_player != (Object)null && !((Character)s_player).InIntro()) { HandleFlightEnded(s_player, dropped: false); } } } } [HarmonyPatch(typeof(Valkyrie), "DropPlayer")] private static class Valkyrie_DropPlayer_Taxi { private static void Postfix(Valkyrie __instance) { if (ProtectiveWards.offeringTaxi.Value && IsActiveTaxiValkyrie(__instance) && !((Object)(object)s_player == (Object)null) && !((Object)(object)Player.m_localPlayer != (Object)(object)s_player)) { HandleFlightEnded(s_player, dropped: true); } } } [HarmonyPatch(typeof(Player), "SetIntro")] private static class Player_SetIntro_Taxi { private static void Postfix(Player __instance) { if (!((Character)__instance).InIntro() && !((Object)(object)__instance != (Object)(object)s_player) && (s_state == TaxiState.OutboundFlight || s_state == TaxiState.ReturnFlight)) { HandleFlightEnded(__instance, dropped: false); } } } [HarmonyPatch(typeof(SEMan), "Update")] private static class SEMan_Update_TaxiStatusConsistency { private static void Postfix(SEMan __instance) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || __instance != ((Character)localPlayer).m_seman) { return; } bool flag = HasTaxiStatusEffect(localPlayer); if (s_deferredStatusRemoval) { s_deferredStatusRemoval = false; if (flag) { RemoveTaxiStatusEffect(localPlayer, controlled: true); } } else if (s_statusExpected && !flag) { ProtectiveWards.LogInfo("Valkyrie passage status effect disappeared. Cleaning up taxi state."); CleanupActiveValkyrie(); ResetState(); } else if (!s_statusExpected && flag) { RemoveTaxiStatusEffect(localPlayer, controlled: true); } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_RegisterTaxiStatusEffect { private static void Postfix() { RegisterTaxiStatusEffect(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDB_CopyOtherDB_RegisterTaxiStatusEffect { private static void Postfix() { RegisterTaxiStatusEffect(); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] private static class ZoneSystem_Start_Taxi { private static void Postfix() { CleanupActiveValkyrie(); ResetState(); RegisterRPCs(); } } private const string WardTaxiStatusEffectName = "PW_WardTaxiStatus"; internal static readonly int wardTaxiStatusHash = StringExtensionMethods.GetStableHashCode("PW_WardTaxiStatus"); private static readonly int slowFallHash = StringExtensionMethods.GetStableHashCode("SlowFall"); private const float MinTaxiDistance = 200f; private const float MaxTaxiOfferingSourceDistance = 50f; private const float TaxiStartAltitude = 30f; private const float TaxiDescentAltitude = 150f; private const float TaxiProgressDistance = 3f; private const float TaxiStuckSeconds = 10f; private const int TaxiOutboundWaitSeconds = 10; private const string EikthyrAltarLocation = "Eikthyrnir"; private const string ElderAltarLocation = "GDKing"; private const string BonemassAltarLocation = "Bonemass"; private const string ModerAltarLocation = "Dragonqueen"; private const string YagluthAltarLocation = "GoblinKing"; private const string QueenAltarLocation = "Mistlands_DvergrBossEntrance1"; private const string FaderAltarLocation = "FaderLocation"; private static TaxiState s_state = TaxiState.Idle; private static Player s_player; private static Vector3 s_targetPosition; private static Vector3 s_returnPosition; private static Vector3 s_currentFlightTargetPosition; private static Quaternion s_currentFlightSpawnRotation = Quaternion.identity; private static float s_currentFlightSpawnYawOffset; private static TaxiOffer s_offer; private static bool s_returnBack; private static bool s_waitingForValkyrieSpawn; private static bool s_statusExpected; private static bool s_controlledStatusRemoval; private static bool s_deferredStatusRemoval; private static ZDOID s_activeValkyrieId = ZDOID.None; private static Vector3 s_lastProgressPosition; private static float s_lastProgressTime; internal static bool IsTaxiOfferingItem(string itemName) { TaxiOffer offer; return TryGetTaxiOffer(itemName, out offer); } internal static void TryStartTaxiFromOffering(ItemData item, Player initiator, Vector3 offeringPosition) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (item == null || item.m_shared == null || (Object)(object)initiator == (Object)null || !TryGetTaxiOffer(item.m_shared.m_name, out var offer)) { return; } if (((Character)initiator).IsEncumbered()) { ((Character)initiator).Message((MessageType)2, "$se_encumbered_start".Localize(), 0, (Sprite)null); return; } if (!WardOfferings.IsTeleportable(initiator)) { ((Character)initiator).Message((MessageType)2, "$pw_msg_notravel".Localize(), 0, (Sprite)null); return; } Vector3 target = Vector3.zero; if (TryGetFoundLocation(offer.LocationName, offeringPosition, ref target)) { TryStartPassage(initiator, offeringPosition, target, offer); } else if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { ClosestLocationRequest(offer, offeringPosition); } else { ProtectiveWards.LogInfo("Location " + offer.LocationName + " is not found"); } } internal static void RegisterRPCs() { if (ZRoutedRpc.instance != null && !((Object)(object)ZNet.instance == (Object)null)) { if (ZNet.instance.IsServer()) { ZRoutedRpc.instance.Register("ClosestLocationRequest", (Action)RPC_ClosestLocationRequest); } else { ZRoutedRpc.instance.Register("StartTaxi", (Action)RPC_StartTaxi); } } } private static void ClosestLocationRequest(TaxiOffer offer, Vector3 offeringPosition) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) ProtectiveWards.LogInfo(offer.LocationName + " closest location request"); ZPackage val = new ZPackage(); val.Write(offer.LocationName); val.Write(offer.ItemName); val.Write(offer.Stack); val.Write(offeringPosition); ZRoutedRpc.instance.InvokeRoutedRPC("ClosestLocationRequest", new object[1] { val }); } private static void RPC_ClosestLocationRequest(long sender, ZPackage pkg) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0094: 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) string text = pkg.ReadString(); string itemName = pkg.ReadString().GetItemName(); int num = pkg.ReadInt(); Vector3 offeringPosition = pkg.ReadVector3(); if (TryGetTaxiRequester(sender, out var requester) && IsValidServerTaxiRequest(text, itemName, num)) { Vector3 target = Vector3.zero; Vector3 validatedOfferingSourcePosition = GetValidatedOfferingSourcePosition(requester, offeringPosition); if (!TryGetFoundLocation(text, validatedOfferingSourcePosition, ref target)) { ProtectiveWards.LogInfo("Location " + text + " is not found"); return; } ZPackage val = new ZPackage(); val.Write(target); val.Write(text); val.Write(itemName); val.Write(num); val.Write(validatedOfferingSourcePosition); val.Write(ShouldConsumeTaxiItem(text, itemName)); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "StartTaxi", new object[1] { val }); } } private static void RPC_StartTaxi(long sender, ZPackage pkg) { //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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) Vector3 position = pkg.ReadVector3(); string locationName = pkg.ReadString(); string itemName = pkg.ReadString().GetItemName(); int stack = pkg.ReadInt(); Vector3 offeringPosition = pkg.ReadVector3(); bool consumeItem = pkg.ReadBool(); ProtectiveWards.LogInfo("Server responded with closest location"); TryStartPassage(Player.m_localPlayer, offeringPosition, position, new TaxiOffer { LocationName = locationName, ItemName = itemName, Stack = stack, ConsumeItem = consumeItem }); } private static bool TryGetTaxiRequester(long sender, out ProtectiveWards.RoutedPlayerContext requester) { requester = default(ProtectiveWards.RoutedPlayerContext); return sender != 0L && ProtectiveWards.TryGetRoutedPlayer(sender, out requester); } private static bool IsValidServerTaxiRequest(string name, string itemName, int stack) { itemName = itemName.GetItemName(); if (1 == 0) { } bool result = name switch { "StartTemple" => ProtectiveWards.offeringTaxiStartTempleEnabled.Value && WardOfferings.IsBossTrophy(itemName) && stack == GetSacrificialStonesTaxiStack(), "Vendor_BlackForest" => ProtectiveWards.offeringTaxiHaldorEnabled.Value && IsItemForHaldorTravel(itemName) && stack == GetExpectedHaldorTaxiPrice(), "Hildir_camp" => ProtectiveWards.offeringTaxiHildirEnabled.Value && ((ProtectiveWards.offeringTaxiHildirChestsEnabled.Value && WardOfferings.IsHildirChestItem(itemName) && stack == 1) || (IsItemForHildirTravel(itemName) && stack == GetHildirTaxiPrice())), "BogWitch_Camp" => ProtectiveWards.offeringTaxiBogWitchEnabled.Value && IsItemForBogWitchTravel(itemName) && stack == ProtectiveWards.offeringTaxiPriceBogWitchAmount.Value, _ => IsValidBossAltarTaxiRequest(name, itemName, stack), }; if (1 == 0) { } return result; } private static void TryStartPassage(Player initiator, Vector3 offeringPosition, Vector3 position, TaxiOffer offer) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)initiator == (Object)null) { return; } Vector3 position2 = ((Component)initiator).transform.position; if (IsTaxiDestinationTooClose(position2, position)) { ProtectiveWards.LogInfo($"Valkyrie passage destination is too close. Source: {position2}, destination: {position}, distance: {GetTaxiDistance(position2, position):0.0}"); ((Character)initiator).Message((MessageType)2, "$pw_msg_tooclose".Localize(), 0, (Sprite)null); return; } if (HasTaxiStatusEffect(initiator) || s_statusExpected || s_state != TaxiState.Idle) { if (ProtectiveWards.offeringTaxiExistingFlightMode.Value == ProtectiveWards.WardTaxiExistingFlightMode.StopActivePassage) { StopActivePassage(initiator, showMessage: true); } else { ((Character)initiator).Message((MessageType)2, "$pw_msg_taxi_already_active".Localize(), 0, (Sprite)null); } return; } if (!HasTaxiPayment(initiator, offer)) { ((Character)initiator).Message((MessageType)2, "$msg_incompleteoffering".Localize(), 0, (Sprite)null); return; } s_player = initiator; float taxiDistance = GetTaxiDistance(position2, position); ProtectiveWards.LogInfo($"Valkyrie passage destination accepted. Source: {position2}, destination: {position}, distance: {taxiDistance:0.0}"); s_targetPosition = position; s_returnPosition = position2; s_offer = offer; s_returnBack = ProtectiveWards.offeringTaxiSecondsToFlyBack.Value > 0; s_activeValkyrieId = ZDOID.None; s_waitingForValkyrieSpawn = false; SetState(TaxiState.WaitingOutbound, 10); ((Character)initiator).Message((MessageType)2, "$pw_msg_valkyrie_coming".Localize(), 0, (Sprite)null); } private static void StopActivePassage(Player player, bool showMessage) { if (showMessage && player != null) { ((Character)player).Message((MessageType)2, "$pw_msg_taxi_stopped".Localize(), 0, (Sprite)null); } CleanupActiveValkyrie(); RemoveTaxiStatusEffect(player ?? s_player, controlled: true); ResetState(); } private static void UpdateStatusEffect(SE_WardTaxi status, float dt) { Player val = s_player; if ((Object)(object)val == (Object)null || (Object)(object)Player.m_localPlayer != (Object)(object)val) { return; } switch (s_state) { case TaxiState.WaitingOutbound: if (((StatusEffect)status).m_time >= (float)Math.Max(10, 1)) { TryStartFlight(isReturnFlight: false); } break; case TaxiState.OutboundFlight: case TaxiState.ReturnFlight: UpdateActiveFlight(); break; case TaxiState.FallingBeforeReturn: ApplyTaxiSlowFall(status); if (PlayerIsGrounded(val)) { StartWaitingReturn(val); } break; case TaxiState.WaitingReturn: if (((StatusEffect)status).m_time >= (float)Math.Max(ProtectiveWards.offeringTaxiSecondsToFlyBack.Value, 1)) { TryStartFlight(isReturnFlight: true); } break; case TaxiState.WaitingRetry: { if (CanStartValkyrieFlight(val, silent: true)) { TryStartFlight(isReturnFlight: true); break; } int num = Math.Max(ProtectiveWards.offeringTaxiReturnWaitLimitSeconds.Value, 0); if (num > 0 && ((StatusEffect)status).m_time >= (float)num) { ((Character)val).Message((MessageType)2, "$pw_msg_taxi_return_wait_expired".Localize(), 0, (Sprite)null); FinishTaxiStatus(val); } break; } case TaxiState.Falling: ApplyTaxiSlowFall(status); if (PlayerIsGrounded(val)) { ((Character)val).Message((MessageType)2, "$pw_msg_taxi_complete".Localize(), 0, (Sprite)null); FinishTaxiStatus(val); } break; } } private static void TryStartFlight(bool isReturnFlight) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) Player val = s_player; if ((Object)(object)val == (Object)null) { return; } if (!CanStartValkyrieFlight(val, silent: false)) { if (isReturnFlight) { SetState(TaxiState.WaitingRetry, Math.Max(ProtectiveWards.offeringTaxiReturnWaitLimitSeconds.Value, 0)); ((Character)val).Message((MessageType)2, "$pw_msg_taxi_waiting".Localize(), 0, (Sprite)null); } else { ((Character)val).Message((MessageType)2, "$pw_msg_canttravel".Localize(), 0, (Sprite)null); FinishTaxiStatus(val); } return; } Vector3 val2 = (isReturnFlight ? s_returnPosition : s_targetPosition); if (IsTaxiDestinationTooClose(((Component)val).transform.position, val2)) { if (isReturnFlight) { ((Character)val).Message((MessageType)2, "$pw_msg_taxi_complete".Localize(), 0, (Sprite)null); } else { ((Character)val).Message((MessageType)2, "$pw_msg_tooclose".Localize(), 0, (Sprite)null); } FinishTaxiStatus(val); } else if (!isReturnFlight && !TryConsumeTaxiPayment(val, s_offer)) { ((Character)val).Message((MessageType)2, "$msg_incompleteoffering".Localize(), 0, (Sprite)null); FinishTaxiStatus(val); } else if (!TrySpawnValkyrie(val, val2, isReturnFlight)) { ((Character)val).Message((MessageType)2, "$pw_msg_canttravel".Localize(), 0, (Sprite)null); FinishTaxiStatus(val); } } private static Vector3 GetValidatedOfferingSourcePosition(ProtectiveWards.RoutedPlayerContext requester, Vector3 offeringPosition) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!requester.HasPosition) { return offeringPosition; } return (Vector3.Distance(requester.Position, offeringPosition) <= 50f) ? offeringPosition : requester.Position; } private static bool IsTaxiDestinationTooClose(Vector3 sourcePosition, Vector3 destinationPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return GetTaxiDistance(sourcePosition, destinationPosition) < 200f; } private static float GetTaxiDistance(Vector3 sourcePosition, Vector3 destinationPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Utils.DistanceXZ(sourcePosition, destinationPosition); } private static bool CanStartValkyrieFlight(Player player, bool silent) { if ((Object)(object)player == (Object)null || ((Character)player).IsDead()) { return false; } if ((Object)(object)Valkyrie.m_instance != (Object)null && ((Behaviour)Valkyrie.m_instance).enabled && (Object)(object)Valkyrie.m_instance.m_nview != (Object)null && Valkyrie.m_instance.m_nview.IsOwner()) { if (!silent) { ((Character)player).Message((MessageType)2, "$menu_pleasewait".Localize(), 0, (Sprite)null); } return false; } if (((Character)player).IsAttachedToShip() || ((Character)player).IsAttached() || ((Character)player).IsRiding() || player.IsSleeping() || ((Character)player).IsTeleporting() || ((Character)player).InPlaceMode() || ((Character)player).InBed() || ((Character)player).InCutscene() || ((Character)player).InInterior()) { if (!silent) { ((Character)player).Message((MessageType)1, "$pw_msg_travel_inside".Localize(""), 0, (Sprite)null); } return false; } if (((Character)player).IsEncumbered()) { if (!silent) { ((Character)player).Message((MessageType)2, "$se_encumbered_start".Localize(), 0, (Sprite)null); } return false; } if (!WardOfferings.IsTeleportable(player)) { if (!silent) { ((Character)player).Message((MessageType)2, "$pw_msg_notravel".Localize(), 0, (Sprite)null); } return false; } return true; } private static bool TrySpawnValkyrie(Player player, Vector3 targetPosition, bool isReturnFlight) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown bool flag = false; try { Player.m_localPlayer.m_valkyrie.Load(); flag = true; GameObject asset = Player.m_localPlayer.m_valkyrie.Asset; if ((Object)(object)asset == (Object)null || !Object.op_Implicit((Object)(object)asset.GetComponent())) { throw new InvalidOperationException("Failed to load Valkyrie passage prefab."); } s_currentFlightTargetPosition = targetPosition; s_currentFlightSpawnRotation = GetValkyrieSpawnRotation(((Component)player).transform.position, targetPosition, ((Component)player).transform, out var yawOffset); s_currentFlightSpawnYawOffset = yawOffset; s_activeValkyrieId = ZDOID.None; s_waitingForValkyrieSpawn = true; SetState(isReturnFlight ? TaxiState.ReturnFlight : TaxiState.OutboundFlight, 0); ResetTaxiProgressWatch(player); ((Character)player).Message((MessageType)2, "$pw_msg_travel_start".Localize(), 0, (Sprite)null); GameObject val = Object.Instantiate(asset, ((Component)player).transform.position, s_currentFlightSpawnRotation); s_waitingForValkyrieSpawn = false; ZNetView val2 = default(ZNetView); if ((Object)(object)val == (Object)null || !val.TryGetComponent(ref val2)) { throw new InvalidOperationException("Failed to create Valkyrie passage instance."); } val2.HoldReferenceTo((IReferenceCounted)(object)Player.m_localPlayer.m_valkyrie); return true; } catch (Exception arg) { s_waitingForValkyrieSpawn = false; ProtectiveWards.LogInfo($"Valkyrie passage start failed: {arg}"); return false; } finally { if (flag) { Player.m_localPlayer.m_valkyrie.Release(); } } } private static Quaternion GetValkyrieSpawnRotation(Vector3 sourcePosition, Vector3 targetPosition, Transform fallbackTransform, out float yawOffset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = targetPosition - sourcePosition; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = (((Object)(object)fallbackTransform != (Object)null) ? fallbackTransform.forward : Vector3.forward); val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); yawOffset = Random.Range(-60f, 60f); return Quaternion.LookRotation(val, Vector3.up) * Quaternion.Euler(0f, yawOffset, 0f); } private static void UpdateActiveFlight() { Valkyrie activeValkyrie = GetActiveValkyrie(); if (!((Object)(object)activeValkyrie == (Object)null)) { UpdateTaxiProgressWatch(activeValkyrie); if ((ZInput.GetButton("Use") && ZInput.GetButton("AltPlace")) || (ZInput.GetButton("JoyUse") && ZInput.GetButton("JoyAltPlace"))) { activeValkyrie.DropPlayer(true); } } } private static void HandleFlightEnded(Player player, bool dropped) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } TaxiState taxiState = s_state; s_activeValkyrieId = ZDOID.None; s_waitingForValkyrieSpawn = false; if (dropped) { s_returnBack = false; SetState(TaxiState.Falling, 0); return; } ((Character)player).Message((MessageType)2, "$pw_msg_taxi_complete".Localize(), 0, (Sprite)null); if (taxiState == TaxiState.OutboundFlight && s_returnBack && ProtectiveWards.offeringTaxiSecondsToFlyBack.Value > 0) { SetState(TaxiState.FallingBeforeReturn, 0); } else { SetState(TaxiState.Falling, 0); } } private static void StartWaitingReturn(Player player) { if (!((Object)(object)player == (Object)null)) { int num = Math.Max(ProtectiveWards.offeringTaxiSecondsToFlyBack.Value, 0); if (num <= 0) { FinishTaxiStatus(player); return; } s_returnBack = false; SetState(TaxiState.WaitingReturn, num); } } private static void SetState(TaxiState state, int durationSeconds) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Player val = s_player; s_state = state; RegisterTaxiStatusEffect(); SE_WardTaxi taxiStatusEffect = GetTaxiStatusEffect(val); if ((Object)(object)taxiStatusEffect == (Object)null && (Object)(object)val != (Object)null && ((Character)val).m_seman != null && state != TaxiState.Idle) { s_statusExpected = true; ((Character)val).m_seman.AddStatusEffect(wardTaxiStatusHash, true, 0, 0f); taxiStatusEffect = GetTaxiStatusEffect(val); } if ((Object)(object)taxiStatusEffect == (Object)null) { if (state != TaxiState.Idle) { ProtectiveWards.LogInfo("Failed to add Valkyrie passage status effect. Cleaning up taxi state."); ResetState(); } return; } ((StatusEffect)taxiStatusEffect).m_time = 0f; ((StatusEffect)taxiStatusEffect).m_ttl = Math.Max(durationSeconds, 0); ((StatusEffect)taxiStatusEffect).m_name = "$pw_se_ward_taxi_status"; ((StatusEffect)taxiStatusEffect).m_icon = GetTaxiStatusEffectIcon(); ((StatusEffect)taxiStatusEffect).m_startMessage = "$pw_msg_valkyrie_coming"; ((StatusEffect)taxiStatusEffect).m_startMessageType = (MessageType)2; ((StatusEffect)taxiStatusEffect).m_stopMessage = "$pw_msg_taxi_stopped"; ((StatusEffect)taxiStatusEffect).m_stopMessageType = (MessageType)2; ClearTaxiSlowFall(taxiStatusEffect); SE_WardTaxi sE_WardTaxi = taxiStatusEffect; if (1 == 0) { } string tooltip; switch (state) { case TaxiState.WaitingOutbound: tooltip = "$pw_se_ward_taxi_waiting_outbound_tooltip".Localize(); break; case TaxiState.OutboundFlight: case TaxiState.ReturnFlight: tooltip = "$pw_se_ward_taxi_flight_tooltip".Localize(GetDropHotkeyText()); break; case TaxiState.WaitingReturn: tooltip = "$pw_se_ward_taxi_return_tooltip".Localize(); break; case TaxiState.WaitingRetry: tooltip = "$pw_se_ward_taxi_waiting_retry_tooltip".Localize(); break; case TaxiState.FallingBeforeReturn: case TaxiState.Falling: tooltip = "$pw_se_ward_taxi_falling_tooltip".Localize(); break; default: tooltip = ""; break; } if (1 == 0) { } ((StatusEffect)sE_WardTaxi).m_tooltip = tooltip; if (state == TaxiState.FallingBeforeReturn || state == TaxiState.Falling) { ApplyTaxiSlowFall(taxiStatusEffect); } } private static void FinishTaxiStatus(Player player) { ResetState(); s_deferredStatusRemoval = true; } private static void OnStatusStopped(SE_WardTaxi status) { if (!s_controlledStatusRemoval && s_statusExpected) { ProtectiveWards.LogInfo("Valkyrie passage status effect stopped unexpectedly. Cleaning up taxi state."); CleanupActiveValkyrie(); ResetState(); } } private static void RegisterTaxiStatusEffect() { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ObjectDB.instance == (Object)null) { return; } StatusEffect val = null; for (int num = ObjectDB.instance.m_StatusEffects.Count - 1; num >= 0; num--) { StatusEffect val2 = ObjectDB.instance.m_StatusEffects[num]; if (!((Object)(object)val2 == (Object)null) && !(((Object)val2).name != "PW_WardTaxiStatus")) { if ((Object)(object)val == (Object)null && val2 is SE_WardTaxi) { val = val2; } else { ObjectDB.instance.m_StatusEffects.RemoveAt(num); } } } if ((Object)(object)val == (Object)null) { val = (StatusEffect)(object)ScriptableObject.CreateInstance(); ((Object)val).name = "PW_WardTaxiStatus"; val.m_name = "$pw_se_ward_taxi_status"; val.m_icon = GetTaxiStatusEffectIcon(); val.m_startMessage = "$pw_msg_valkyrie_coming"; val.m_startMessageType = (MessageType)2; val.m_stopMessage = "$pw_msg_taxi_stopped"; val.m_stopMessageType = (MessageType)2; ObjectDB.instance.m_StatusEffects.Add(val); } } private static SE_WardTaxi GetTaxiStatusEffect(Player player) { object obj; if (player == null) { obj = null; } else { SEMan seman = ((Character)player).m_seman; obj = ((seman != null) ? seman.GetStatusEffect(wardTaxiStatusHash) : null); } return obj as SE_WardTaxi; } private static bool HasTaxiStatusEffect(Player player) { return (Object)(object)player != (Object)null && ((Character)player).m_seman != null && ((Character)player).m_seman.HaveStatusEffect(wardTaxiStatusHash); } private static void RemoveTaxiStatusEffect(Player player, bool controlled) { if (!HasTaxiStatusEffect(player)) { return; } bool flag = s_controlledStatusRemoval; s_controlledStatusRemoval = controlled; try { ((Character)player).m_seman.RemoveStatusEffect(wardTaxiStatusHash, true); } finally { s_controlledStatusRemoval = flag; } } private static void ResetState() { //IL_000d: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) s_state = TaxiState.Idle; s_player = null; s_targetPosition = Vector3.zero; s_returnPosition = Vector3.zero; s_offer = default(TaxiOffer); s_returnBack = false; s_waitingForValkyrieSpawn = false; s_currentFlightTargetPosition = Vector3.zero; s_currentFlightSpawnRotation = Quaternion.identity; s_currentFlightSpawnYawOffset = 0f; s_statusExpected = false; s_controlledStatusRemoval = false; s_activeValkyrieId = ZDOID.None; s_lastProgressPosition = Vector3.zero; s_lastProgressTime = 0f; } private static void CleanupActiveValkyrie() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) GameObject activeValkyrieObject = GetActiveValkyrieObject(); s_activeValkyrieId = ZDOID.None; s_waitingForValkyrieSpawn = false; if (!((Object)(object)activeValkyrieObject == (Object)null)) { Valkyrie component = activeValkyrieObject.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)s_player != (Object)null && ((Character)s_player).InIntro()) { component.DropPlayer(true); } else if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(activeValkyrieObject); } } } private static GameObject GetActiveValkyrieObject() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (((ZDOID)(ref s_activeValkyrieId)).Equals(ZDOID.None) || (Object)(object)ZNetScene.instance == (Object)null) { return null; } return ZNetScene.instance.FindInstance(s_activeValkyrieId); } private static Valkyrie GetActiveValkyrie() { GameObject activeValkyrieObject = GetActiveValkyrieObject(); return (activeValkyrieObject != null) ? activeValkyrieObject.GetComponent() : null; } private static bool IsActiveTaxiValkyrie(Valkyrie valkyrie) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)valkyrie == (Object)null || (Object)(object)valkyrie.m_nview == (Object)null || !valkyrie.m_nview.IsValid()) { return false; } ZDO zDO = valkyrie.m_nview.GetZDO(); return zDO != null && !((ZDOID)(ref s_activeValkyrieId)).Equals(ZDOID.None) && ((ZDOID)(ref zDO.m_uid)).Equals(s_activeValkyrieId); } private static void ResetTaxiProgressWatch(Player player) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { s_lastProgressPosition = ((Component)player).transform.position; s_lastProgressTime = Time.time; } } private static void UpdateTaxiProgressWatch(Valkyrie valkyrie) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)s_player == (Object)null) && IsActiveTaxiValkyrie(valkyrie)) { if (Vector3.Distance(((Component)s_player).transform.position, s_lastProgressPosition) >= 3f) { ResetTaxiProgressWatch(s_player); } else if (!(Time.time - s_lastProgressTime < 10f)) { ProtectiveWards.LogInfo("Valkyrie passage appears stuck. Dropping player."); valkyrie.DropPlayer(true); ResetTaxiProgressWatch(s_player); } } } private static bool PlayerIsGrounded(Player player) { return (Object)(object)player == (Object)null || ((Character)player).IsOnGround() || ((Character)player).IsSwimming(); } private static void ApplyTaxiSlowFall(SE_WardTaxi status) { if (!((Object)(object)status == (Object)null)) { ObjectDB instance = ObjectDB.instance; StatusEffect obj = ((instance != null) ? instance.GetStatusEffect(slowFallHash) : null); SE_Stats val = (SE_Stats)(object)((obj is SE_Stats) ? obj : null); if ((Object)(object)val != (Object)null) { ((SE_Stats)status).m_maxMaxFallSpeed = val.m_maxMaxFallSpeed; ((SE_Stats)status).m_fallDamageModifier = val.m_fallDamageModifier; } else { ((SE_Stats)status).m_maxMaxFallSpeed = 5f; ((SE_Stats)status).m_fallDamageModifier = -1f; } } } private static void ClearTaxiSlowFall(SE_WardTaxi status) { if (!((Object)(object)status == (Object)null)) { ((SE_Stats)status).m_maxMaxFallSpeed = 0f; ((SE_Stats)status).m_fallDamageModifier = 0f; } } private static Sprite GetTaxiStatusEffectIcon() { ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab("CelestialFeather") : null); ItemDrop val2 = ((val != null) ? val.GetComponent() : null); return (val2 != null) ? val2.m_itemData.GetIcon() : null; } private static string GetDropHotkeyText() { string text = "$KEY_AltPlace".Localize(); string text2 = "$KEY_Use".Localize(); if (text == "$KEY_AltPlace") { text = "AltPlace"; } if (text2 == "$KEY_Use") { text2 = "Use"; } return text + " + " + text2; } internal static bool TryGetFoundLocation(string name, Vector3 position, ref Vector3 target) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } ZoneSystem.instance.tempIconList.Clear(); ZoneSystem.instance.GetLocationIcons(ZoneSystem.instance.tempIconList); bool flag = false; float num = float.MaxValue; foreach (KeyValuePair tempIcon in ZoneSystem.instance.tempIconList) { if (!(tempIcon.Value != name)) { float num2 = Utils.DistanceXZ(position, tempIcon.Key); if (!(num2 >= num)) { num = num2; target = tempIcon.Key; flag = true; } } } if (flag) { ProtectiveWards.LogInfo("Found closest " + name + " in icon list"); return true; } LocationInstance val = default(LocationInstance); if (ZoneSystem.instance.FindClosestLocation(name, position, ref val)) { target = val.m_position; ProtectiveWards.LogInfo("Found closest " + name + " in location list"); return true; } return false; } private static bool HasTaxiPayment(Player player, TaxiOffer offer) { return offer.Stack <= 0 || ((Humanoid)player).GetInventory().CountItems(offer.ItemName, -1, true) >= offer.Stack; } private static bool TryConsumeTaxiPayment(Player player, TaxiOffer offer) { if (!HasTaxiPayment(player, offer)) { return false; } if (offer.ConsumeItem && offer.Stack > 0) { ((Humanoid)player).GetInventory().RemoveItem(offer.ItemName, offer.Stack, -1, true); } return true; } private static bool TryGetTaxiOffer(string itemName, out TaxiOffer offer) { offer = default(TaxiOffer); itemName = itemName.GetItemName(); if (ProtectiveWards.offeringTaxiStartTempleEnabled.Value && WardOfferings.IsBossTrophy(itemName)) { offer = new TaxiOffer { LocationName = "StartTemple", ItemName = itemName, Stack = GetSacrificialStonesTaxiStack(), ConsumeItem = ProtectiveWards.offeringTaxiStartTempleConsumeItem.Value }; return true; } if (ProtectiveWards.offeringTaxiHaldorEnabled.Value && IsItemForHaldorTravel(itemName)) { offer = new TaxiOffer { LocationName = "Vendor_BlackForest", ItemName = itemName, Stack = GetExpectedHaldorTaxiPrice(), ConsumeItem = ProtectiveWards.offeringTaxiHaldorConsumeItem.Value }; return true; } if (ProtectiveWards.offeringTaxiHildirEnabled.Value && ProtectiveWards.offeringTaxiHildirChestsEnabled.Value && WardOfferings.IsHildirChestItem(itemName)) { offer = new TaxiOffer { LocationName = "Hildir_camp", ItemName = itemName, Stack = 1, ConsumeItem = false }; return true; } if (ProtectiveWards.offeringTaxiHildirEnabled.Value && IsItemForHildirTravel(itemName)) { offer = new TaxiOffer { LocationName = "Hildir_camp", ItemName = itemName, Stack = GetHildirTaxiPrice(), ConsumeItem = ProtectiveWards.offeringTaxiHildirConsumeItem.Value }; return true; } if (ProtectiveWards.offeringTaxiBogWitchEnabled.Value && IsItemForBogWitchTravel(itemName)) { offer = new TaxiOffer { LocationName = "BogWitch_Camp", ItemName = itemName, Stack = ProtectiveWards.offeringTaxiPriceBogWitchAmount.Value, ConsumeItem = ProtectiveWards.offeringTaxiBogWitchConsumeItem.Value }; return true; } return TryGetBossAltarTaxiOffer(itemName, out offer); } private static bool IsItemForHaldorTravel(string itemName) { return ConfiguredItemName(ProtectiveWards.offeringTaxiPriceHaldorItem) != "" && itemName.GetItemName() == ConfiguredItemName(ProtectiveWards.offeringTaxiPriceHaldorItem); } private static bool IsItemForHildirTravel(string itemName) { return ConfiguredItemName(ProtectiveWards.offeringTaxiPriceHildirItem) != "" && itemName.GetItemName() == ConfiguredItemName(ProtectiveWards.offeringTaxiPriceHildirItem); } private static bool IsItemForBogWitchTravel(string itemName) { return ConfiguredItemName(ProtectiveWards.offeringTaxiPriceBogWitchItem) != "" && itemName.GetItemName() == ConfiguredItemName(ProtectiveWards.offeringTaxiPriceBogWitchItem); } private static string ConfiguredItemName(ConfigEntry entry) { return entry.Value.GetItemName(); } private static int GetExpectedHaldorTaxiPrice() { return HasLocationIcon("Vendor_BlackForest") ? ProtectiveWards.offeringTaxiPriceHaldorDiscovered.Value : ProtectiveWards.offeringTaxiPriceHaldorUndiscovered.Value; } private static int GetHildirTaxiPrice() { return Math.Max(ProtectiveWards.offeringTaxiPriceHildirAmount.Value, 0); } private static int GetSacrificialStonesTaxiStack() { return ProtectiveWards.offeringTaxiStartTempleConsumeItem.Value ? 1 : 0; } private static bool HasLocationIcon(string name) { if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } ZoneSystem.instance.tempIconList.Clear(); ZoneSystem.instance.GetLocationIcons(ZoneSystem.instance.tempIconList); return ZoneSystem.instance.tempIconList.Any((KeyValuePair icon) => icon.Value == name); } private static bool ShouldConsumeTaxiItem(string locationName, string itemName) { itemName = itemName.GetItemName(); if (1 == 0) { } bool consumeItem; bool result = locationName switch { "StartTemple" => ProtectiveWards.offeringTaxiStartTempleConsumeItem.Value, "Vendor_BlackForest" => ProtectiveWards.offeringTaxiHaldorConsumeItem.Value, "Hildir_camp" => !WardOfferings.IsHildirChestItem(itemName) && ProtectiveWards.offeringTaxiHildirConsumeItem.Value, "BogWitch_Camp" => ProtectiveWards.offeringTaxiBogWitchConsumeItem.Value, _ => TryGetBossAltarConsumeItem(locationName, itemName, out consumeItem) && consumeItem, }; if (1 == 0) { } return result; } private static bool TryGetBossAltarTaxiOffer(string itemName, out TaxiOffer offer) { itemName = itemName.GetItemName(); return TryGetBossAltarTaxiOffer(ProtectiveWards.offeringTaxiEikthyrAltarEnabled, "Eikthyrnir", ProtectiveWards.offeringTaxiEikthyrAltarItem, ProtectiveWards.offeringTaxiEikthyrAltarAmount, ProtectiveWards.offeringTaxiEikthyrAltarConsumeItem, itemName, out offer) || TryGetBossAltarTaxiOffer(ProtectiveWards.offeringTaxiElderAltarEnabled, "GDKing", ProtectiveWards.offeringTaxiElderAltarItem, ProtectiveWards.offeringTaxiElderAltarAmount, ProtectiveWards.offeringTaxiElderAltarConsumeItem, itemName, out offer) || TryGetBossAltarTaxiOffer(ProtectiveWards.offeringTaxiBonemassAltarEnabled, "Bonemass", ProtectiveWards.offeringTaxiBonemassAltarItem, ProtectiveWards.offeringTaxiBonemassAltarAmount, ProtectiveWards.offeringTaxiBonemassAltarConsumeItem, itemName, out offer) || TryGetBossAltarTaxiOffer(ProtectiveWards.offeringTaxiModerAltarEnabled, "Dragonqueen", ProtectiveWards.offeringTaxiModerAltarItem, ProtectiveWards.offeringTaxiModerAltarAmount, ProtectiveWards.offeringTaxiModerAltarConsumeItem, itemName, out offer) || TryGetBossAltarTaxiOffer(ProtectiveWards.offeringTaxiYagluthAltarEnabled, "GoblinKing", ProtectiveWards.offeringTaxiYagluthAltarItem, ProtectiveWards.offeringTaxiYagluthAltarAmount, ProtectiveWards.offeringTaxiYagluthAltarConsumeItem, itemName, out offer) || TryGetBossAltarTaxiOffer(ProtectiveWards.offeringTaxiQueenAltarEnabled, "Mistlands_DvergrBossEntrance1", ProtectiveWards.offeringTaxiQueenAltarItem, ProtectiveWards.offeringTaxiQueenAltarAmount, ProtectiveWards.offeringTaxiQueenAltarConsumeItem, itemName, out offer) || TryGetBossAltarTaxiOffer(ProtectiveWards.offeringTaxiFaderAltarEnabled, "FaderLocation", ProtectiveWards.offeringTaxiFaderAltarItem, ProtectiveWards.offeringTaxiFaderAltarAmount, ProtectiveWards.offeringTaxiFaderAltarConsumeItem, itemName, out offer); } private static bool TryGetBossAltarTaxiOffer(ConfigEntry enabled, string locationName, ConfigEntry item, ConfigEntry amount, ConfigEntry consume, string itemName, out TaxiOffer offer) { offer = default(TaxiOffer); string text = ConfiguredItemName(item); if (!enabled.Value || text == "" || itemName != text) { return false; } offer = new TaxiOffer { LocationName = locationName, ItemName = text, Stack = Math.Max(amount.Value, 0), ConsumeItem = consume.Value }; return true; } private static bool IsValidBossAltarTaxiRequest(string locationName, string itemName, int stack) { itemName = itemName.GetItemName(); return IsValidBossAltarTaxiRequest(ProtectiveWards.offeringTaxiEikthyrAltarEnabled, "Eikthyrnir", ProtectiveWards.offeringTaxiEikthyrAltarItem, ProtectiveWards.offeringTaxiEikthyrAltarAmount, locationName, itemName, stack) || IsValidBossAltarTaxiRequest(ProtectiveWards.offeringTaxiElderAltarEnabled, "GDKing", ProtectiveWards.offeringTaxiElderAltarItem, ProtectiveWards.offeringTaxiElderAltarAmount, locationName, itemName, stack) || IsValidBossAltarTaxiRequest(ProtectiveWards.offeringTaxiBonemassAltarEnabled, "Bonemass", ProtectiveWards.offeringTaxiBonemassAltarItem, ProtectiveWards.offeringTaxiBonemassAltarAmount, locationName, itemName, stack) || IsValidBossAltarTaxiRequest(ProtectiveWards.offeringTaxiModerAltarEnabled, "Dragonqueen", ProtectiveWards.offeringTaxiModerAltarItem, ProtectiveWards.offeringTaxiModerAltarAmount, locationName, itemName, stack) || IsValidBossAltarTaxiRequest(ProtectiveWards.offeringTaxiYagluthAltarEnabled, "GoblinKing", ProtectiveWards.offeringTaxiYagluthAltarItem, ProtectiveWards.offeringTaxiYagluthAltarAmount, locationName, itemName, stack) || IsValidBossAltarTaxiRequest(ProtectiveWards.offeringTaxiQueenAltarEnabled, "Mistlands_DvergrBossEntrance1", ProtectiveWards.offeringTaxiQueenAltarItem, ProtectiveWards.offeringTaxiQueenAltarAmount, locationName, itemName, stack) || IsValidBossAltarTaxiRequest(ProtectiveWards.offeringTaxiFaderAltarEnabled, "FaderLocation", ProtectiveWards.offeringTaxiFaderAltarItem, ProtectiveWards.offeringTaxiFaderAltarAmount, locationName, itemName, stack); } private static bool IsValidBossAltarTaxiRequest(ConfigEntry enabled, string expectedLocationName, ConfigEntry item, ConfigEntry amount, string locationName, string itemName, int stack) { return enabled.Value && locationName == expectedLocationName && itemName == ConfiguredItemName(item) && stack == Math.Max(amount.Value, 0); } private static bool TryGetBossAltarConsumeItem(string locationName, string itemName, out bool consumeItem) { itemName = itemName.GetItemName(); return TryGetBossAltarConsumeItem("Eikthyrnir", ProtectiveWards.offeringTaxiEikthyrAltarItem, ProtectiveWards.offeringTaxiEikthyrAltarConsumeItem, locationName, itemName, out consumeItem) || TryGetBossAltarConsumeItem("GDKing", ProtectiveWards.offeringTaxiElderAltarItem, ProtectiveWards.offeringTaxiElderAltarConsumeItem, locationName, itemName, out consumeItem) || TryGetBossAltarConsumeItem("Bonemass", ProtectiveWards.offeringTaxiBonemassAltarItem, ProtectiveWards.offeringTaxiBonemassAltarConsumeItem, locationName, itemName, out consumeItem) || TryGetBossAltarConsumeItem("Dragonqueen", ProtectiveWards.offeringTaxiModerAltarItem, ProtectiveWards.offeringTaxiModerAltarConsumeItem, locationName, itemName, out consumeItem) || TryGetBossAltarConsumeItem("GoblinKing", ProtectiveWards.offeringTaxiYagluthAltarItem, ProtectiveWards.offeringTaxiYagluthAltarConsumeItem, locationName, itemName, out consumeItem) || TryGetBossAltarConsumeItem("Mistlands_DvergrBossEntrance1", ProtectiveWards.offeringTaxiQueenAltarItem, ProtectiveWards.offeringTaxiQueenAltarConsumeItem, locationName, itemName, out consumeItem) || TryGetBossAltarConsumeItem("FaderLocation", ProtectiveWards.offeringTaxiFaderAltarItem, ProtectiveWards.offeringTaxiFaderAltarConsumeItem, locationName, itemName, out consumeItem); } private static bool TryGetBossAltarConsumeItem(string expectedLocationName, ConfigEntry item, ConfigEntry consume, string locationName, string itemName, out bool consumeItem) { consumeItem = false; if (locationName != expectedLocationName || itemName != ConfiguredItemName(item)) { return false; } consumeItem = consume.Value; return true; } } internal static class WardSettingsUI { private enum SettingsPage { Main, Visuals, BubbleVisual, CircleVisual, Access } private enum FieldId { BubbleEnabled, BubbleColor, BubbleRefraction, BubbleWave, BubbleGlossiness, BubbleMetallic, BubbleNormalScale, BubbleDepthFade, CustomRange, Range, CustomColor, EmissionColor, EmissionColorMultiplier, CircleEnabled, CircleStartColor, CircleEndColor, CircleSpeed, CircleLength, CircleWidth, CircleAmount, PermitEveryone } private sealed class WardSettingValue { public bool UseDefault; public bool BoolValue; public float FloatValue; public Color ColorValue; } private abstract class WardSettingRow { protected readonly FieldId Field; private readonly string m_labelToken; protected Toggle UseDefaultToggle; public FieldId FieldId => Field; protected bool UseDefault { get; private set; } protected WardSettingRow(FieldId field, string labelToken, bool hasOverride) { Field = field; m_labelToken = labelToken; UseDefault = !hasOverride; } public WardSettingValue Capture() { WardSettingValue wardSettingValue = new WardSettingValue { UseDefault = UseDefault }; CaptureValue(wardSettingValue); return wardSettingValue; } public void Create(Transform parent, float y) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) CreateRowText(parent, m_labelToken.Localize(), new Vector2(s_labelX, y), s_labelWidth, Color.white); GameObject val = GUIManager.Instance.CreateToggle(parent, 26f, 26f); SetRect(val, new Vector2(s_useDefaultX, y), 26f, 26f); UseDefaultToggle = val.GetComponent(); UseDefaultToggle.isOn = UseDefault; ((UnityEvent)(object)UseDefaultToggle.onValueChanged).AddListener((UnityAction)delegate(bool value) { UseDefault = value; SetValueInteractable(!value); }); CreateValueControl(parent, y); SetValueInteractable(!UseDefault); } public void Write(ZPackage package) { package.Write((int)Field); package.Write(UseDefault); if (!UseDefault) { WriteValue(package); } } protected abstract void CreateValueControl(Transform parent, float y); protected abstract void SetValueInteractable(bool interactable); protected abstract void CaptureValue(WardSettingValue value); protected abstract void WriteValue(ZPackage package); } private sealed class BoolRow : WardSettingRow { private readonly bool m_initialValue; private Toggle m_valueToggle; public BoolRow(FieldId field, string labelToken, bool hasOverride, bool initialValue) : base(field, labelToken, hasOverride) { m_initialValue = initialValue; } protected override void CreateValueControl(Transform parent, float y) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateToggle(parent, 26f, 26f); SetRect(val, new Vector2(s_valueBoolX, y), 26f, 26f); m_valueToggle = val.GetComponent(); m_valueToggle.isOn = m_initialValue; } protected override void SetValueInteractable(bool interactable) { if ((Object)(object)m_valueToggle != (Object)null) { ((Selectable)m_valueToggle).interactable = interactable; } } protected override void CaptureValue(WardSettingValue value) { value.BoolValue = (Object)(object)m_valueToggle != (Object)null && m_valueToggle.isOn; } protected override void WriteValue(ZPackage package) { package.Write((Object)(object)m_valueToggle != (Object)null && m_valueToggle.isOn); } } private sealed class FloatRow : WardSettingRow { private readonly float m_initialValue; private InputField m_input; public FloatRow(FieldId field, string labelToken, bool hasOverride, float initialValue) : base(field, labelToken, hasOverride) { m_initialValue = initialValue; } protected override void CreateValueControl(Transform parent, float y) { //IL_0011: 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_002b: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateInputField(parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(s_valueX, y), (ContentType)3, (string)null, 17, 99f, 30f); m_input = val.GetComponent(); InputField input = m_input; float initialValue = m_initialValue; input.text = initialValue.ToString(CultureInfo.InvariantCulture); if ((Object)(object)m_input.textComponent != (Object)null) { m_input.textComponent.alignment = (TextAnchor)3; } } protected override void SetValueInteractable(bool interactable) { if ((Object)(object)m_input != (Object)null) { ((Selectable)m_input).interactable = interactable; } } protected override void CaptureValue(WardSettingValue value) { if ((Object)(object)m_input == (Object)null || !float.TryParse(m_input.text, NumberStyles.Float, CultureInfo.InvariantCulture, out value.FloatValue)) { value.FloatValue = 0f; } } protected override void WriteValue(ZPackage package) { if (!float.TryParse(m_input.text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { result = 0f; } package.Write(result); } } private class ColorRow : WardSettingRow { protected readonly Color InitialValue; protected InputField Input; private Button m_pickerButton; public ColorRow(FieldId field, string labelToken, bool hasOverride, Color initialValue) : base(field, labelToken, hasOverride) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) InitialValue = initialValue; } protected override void CreateValueControl(Transform parent, float y) { //IL_0011: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown GameObject val = GUIManager.Instance.CreateInputField(parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(s_colorInputX, y), (ContentType)0, "#RRGGBBAA", 17, 99f, 30f); Input = val.GetComponent(); Input.text = ColorToHtml(InitialValue, includeAlpha: true); ConfigureColorInputText(); ((UnityEvent)(object)Input.onValueChanged).AddListener((UnityAction)delegate { ConfigureColorInputText(); }); GameObject val2 = GUIManager.Instance.CreateButton("$pw_ward_settings_set_color".Localize(), parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(s_colorButtonX, y), 99f, 30f); m_pickerButton = val2.GetComponent