Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PotentialDraught v1.3.9
PotentialDraught.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Potential Draught")] [assembly: AssemblyDescription("A server-synchronized Forge of Potential potion for Valheim.")] [assembly: AssemblyCompany("Potential Draught contributors")] [assembly: AssemblyProduct("Potential Draught")] [assembly: AssemblyCopyright("Copyright © 2026 Potential Draught contributors")] [assembly: AssemblyFileVersion("1.3.9.0")] [assembly: AssemblyVersion("1.3.9.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PotentialDraught { [BepInPlugin("com.forgepotential.potentialdraught", "Potential Draught", "1.3.9")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class PotentialDraughtPlugin : BaseUnityPlugin { private enum FallbackParticleKind { None, Shield, Fist } private sealed class ArmorQualityState { internal int ChestHash; internal int ChestQuality; internal int LegHash; internal int LegQuality; internal int HelmetHash; internal int HelmetQuality; internal int ShoulderHash; internal int ShoulderQuality; internal int UtilityHash; internal int UtilityQuality; } private sealed class PurgeAdminPotionsCommand : ConsoleCommand { public override string Name => "purgeadminpotions"; public override string Help => "purgeadminpotions - removes all admin potions from every other currently connected player"; public override bool IsCheat => true; public override void Run(string[] args) { //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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown if (args != null && args.Length != 0) { Console instance = Console.instance; if (instance != null) { instance.Print("Usage: " + ((ConsoleCommand)this).Help + "."); } return; } if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null || (Object)(object)Player.m_localPlayer == (Object)null) { Console instance2 = Console.instance; if (instance2 != null) { instance2.Print("The purge command is only available while playing in a world."); } return; } RegisterAdminPotionRpcs(); ZPackage val = new ZPackage(); val.Write((byte)7); val.Write(Player.m_localPlayer.GetPlayerID()); SendAdminPotionRequestToServer(val); Console instance3 = Console.instance; if (instance3 != null) { instance3.Print("Requesting removal of all admin potions from other players and world storage..."); } } } private abstract class SetAdminPotionPermissionCommand : ConsoleCommand { protected abstract bool Allowed { get; } public override bool IsCheat => true; public override List<string> CommandOptionList() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); if ((Object)(object)ZNet.instance == (Object)null) { return list; } foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { string text = player.m_name?.Trim(); if (!string.IsNullOrEmpty(text) && !list.Contains(text)) { list.Add(text); } } list.Sort(StringComparer.OrdinalIgnoreCase); return list; } public override void Run(string[] args) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown if (args == null || args.Length == 0) { Console instance = Console.instance; if (instance != null) { instance.Print("Usage: " + ((ConsoleCommand)this).Help + "."); } return; } if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null || (Object)(object)Player.m_localPlayer == (Object)null) { Console instance2 = Console.instance; if (instance2 != null) { instance2.Print("This command is only available while playing in a world."); } return; } string text = string.Join(" ", args).Trim(); ZPackage val = new ZPackage(); val.Write((byte)2); val.Write(Player.m_localPlayer.GetPlayerID()); val.Write(text); val.Write(Allowed); SendAdminPotionRequestToServer(val); Console instance3 = Console.instance; if (instance3 != null) { instance3.Print("Requesting server permission change for '" + text + "'..."); } } } private sealed class AllowAdminPotionCommand : SetAdminPotionPermissionCommand { public override string Name => "allowadminpotion"; public override string Help => "allowadminpotion <player name> - permits a connected player to use admin potions"; protected override bool Allowed => true; } private sealed class DisableAdminPotionCommand : SetAdminPotionPermissionCommand { public override string Name => "disableadminpotion"; public override string Help => "disableadminpotion <player name> - revokes a connected player's admin-potion permission"; protected override bool Allowed => false; } private sealed class MaximumItemQualityCommand : ConsoleCommand { public override string Name => "maximumitemquality"; public override string Help => "maximumitemquality <quality> - changes the server's normal Forge upgrade cap"; public override bool IsCheat => true; public override void Run(string[] args) { //IL_0079: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown if (args == null || args.Length != 1 || !int.TryParse(args[0], out var result) || result < 1) { Console instance = Console.instance; if (instance != null) { instance.Print($"Usage: {((ConsoleCommand)this).Help}. Current cap: {MaximumItemQuality}."); } return; } if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null || (Object)(object)Player.m_localPlayer == (Object)null) { Console instance2 = Console.instance; if (instance2 != null) { instance2.Print("This command is only available while playing in a world."); } return; } ZPackage val = new ZPackage(); val.Write((byte)5); val.Write(Player.m_localPlayer.GetPlayerID()); val.Write(result); SendAdminPotionRequestToServer(val); Console instance3 = Console.instance; if (instance3 != null) { instance3.Print($"Requesting maximum item quality {result} from the server..."); } } } private sealed class PotentialLevelsCommand : ConsoleCommand { public override string Name => "potentiallevels"; public override string Help => "potentiallevels <levels> - sets the number of levels added by your next admin-potion Forge upgrade"; public override bool IsCheat => true; public override void Run(string[] args) { if (args == null || args.Length != 1 || !int.TryParse(args[0], out var result) || result < 1) { Console instance = Console.instance; if (instance != null) { instance.Print($"Usage: {((ConsoleCommand)this).Help}. Current value: {PendingAdminUpgradeLevels}."); } return; } PendingAdminUpgradeLevels = result; AdminLevelOverrideArmed = true; Console instance2 = Console.instance; if (instance2 != null) { instance2.Print("The next Forge of Potential upgrade made while Absolute Potential is active will add " + string.Format("{0} level{1}. The setting resets to 1 after that click.", result, (result == 1) ? string.Empty : "s")); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class AdminPotionPermissionSyncPatch { private static void Postfix(Player __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ZRoutedRpc.instance != null) { _localAdminPotionUseAllowed = false; ZPackage val = new ZPackage(); val.Write((byte)1); val.Write(__instance.GetPlayerID()); SendAdminPotionRequestToServer(val); } } } [HarmonyPatch(typeof(Player), "ConsumeItem")] private static class AdminPotionConsumptionPatch { private static bool Prefix(Player __instance, ItemData item, ref bool __result) { //IL_0040: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !IsAdminPotionItem(item) || _localAdminPotionUseAllowed) { return true; } ((Character)__instance).Message((MessageType)2, "You are not authorized to use admin potions.", 0, (Sprite)null, false); __result = false; if (ZRoutedRpc.instance != null) { ZPackage val = new ZPackage(); val.Write((byte)1); val.Write(__instance.GetPlayerID()); SendAdminPotionRequestToServer(val); } return false; } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] private static class ForgeCraftingPatch { private struct PatchState { internal SharedData SharedData; internal float OriginalChance; internal float OriginalBreakChance; internal ItemData UpgradeItem; internal int OriginalQuality; internal bool Changed; internal bool QualityChanged; internal bool ConsumeAdminLevels; } private static bool Prefix(Player player, Recipe ___m_craftRecipe, ItemData ___m_craftUpgradeItem, ref PatchState __state) { bool flag = HasAdminPotionEffect(player); if (___m_craftRecipe?.m_resources == null) { return true; } Requirement[] resources = ___m_craftRecipe.m_resources; foreach (Requirement val in resources) { if (val == null || !val.m_upgraderResource || (Object)(object)val.m_resItem == (Object)null) { continue; } SharedData val2 = val.m_resItem.m_itemData?.m_shared; if (val2 == null) { continue; } bool flag2 = flag && AdminLevelOverrideArmed; int num = ((!flag2) ? 1 : PendingAdminUpgradeLevels); long num2 = ((___m_craftUpgradeItem == null) ? 1 : ((long)___m_craftUpgradeItem.m_quality + (long)num)); int maximumItemQuality = MaximumItemQuality; if (___m_craftUpgradeItem != null && num2 > maximumItemQuality && !flag2) { if (player != null) { ((Character)player).Message((MessageType)2, $"The Forge of Potential is capped at level {maximumItemQuality}. " + "Use potentiallevels with the admin potion to override it.", 0, (Sprite)null, false); } return false; } if (!flag && !HasPotionEffect(player)) { return true; } __state.SharedData = val2; __state.OriginalChance = val2.m_upgradeChance; __state.OriginalBreakChance = val2.m_breakChance; __state.Changed = true; val2.m_upgradeChance = (flag ? 1f : 0.75f); val2.m_breakChance = (flag ? 0f : 0.1f); if (flag && ___m_craftUpgradeItem != null) { int num3 = ((!flag2) ? 1 : PendingAdminUpgradeLevels); __state.ConsumeAdminLevels = flag2; if (num3 > 1) { __state.UpgradeItem = ___m_craftUpgradeItem; __state.OriginalQuality = ___m_craftUpgradeItem.m_quality; __state.QualityChanged = true; long num4 = (long)___m_craftUpgradeItem.m_quality + (long)num3 - 1; ___m_craftUpgradeItem.m_quality = (int)((num4 > int.MaxValue) ? int.MaxValue : num4); } } ((BaseUnityPlugin)Instance).Logger.LogDebug((object)($"Potential Draught active: this attempt uses {val2.m_upgradeChance:P0} success, " + $"{val2.m_breakChance:P0} break" + (flag ? $", adding {PendingAdminUpgradeLevels} level(s)." : "."))); return true; } return true; } private static void Postfix(PatchState __state) { Restore(__state); } private static Exception Finalizer(Exception __exception, PatchState __state) { Restore(__state); return __exception; } private static void Restore(PatchState state) { if (state.Changed && state.SharedData != null) { state.SharedData.m_upgradeChance = state.OriginalChance; state.SharedData.m_breakChance = state.OriginalBreakChance; } if (state.QualityChanged && state.UpgradeItem != null) { state.UpgradeItem.m_quality = state.OriginalQuality; } if (state.ConsumeAdminLevels) { PendingAdminUpgradeLevels = 1; AdminLevelOverrideArmed = false; } } } [HarmonyPatch(typeof(ParticleIntensityScaler), "EvaluateIntensityColor")] private static class PotentialGlowColorPatch { private static void Postfix(int ___lastItemDropLevel, ref Color __result) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (___lastItemDropLevel >= 5) { __result = GetPotentialGlowColor(___lastItemDropLevel); } } } [HarmonyPatch(typeof(VisEquipment), "AttachItem")] private static class EquippedItemGlowPatch { private static void Prefix(VisEquipment __instance, int itemHash, ref int quality) { quality = ResolveEquipmentQuality(__instance, itemHash, quality); } private static void Postfix(VisEquipment __instance, int itemHash, int quality, ref GameObject __result) { ApplyPotentialGlow(__result, quality, IsArmorVisual(__instance, itemHash), GetFallbackParticleKind(itemHash)); } } [HarmonyPatch(typeof(VisEquipment), "AttachArmor")] private static class EquippedArmorGlowPatch { private static void Prefix(VisEquipment __instance, int itemHash, ref int quality) { quality = ResolveEquipmentQuality(__instance, itemHash, quality); } private static void Postfix(VisEquipment __instance, int itemHash, int quality, ref List<GameObject> __result) { if (__result == null || __result.Count <= 0) { return; } bool subtleArmorGlow = IsArmorPrefab(itemHash); foreach (GameObject item in __result) { ApplyPotentialGlow(item, quality, subtleArmorGlow, GetFallbackParticleKind(itemHash)); } } } [HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")] private static class FinalHandVisualGlowPatch { private static void Postfix(VisEquipment __instance, GameObject ___m_leftItemInstance, GameObject ___m_rightItemInstance, int ___m_leftItem, int ___m_rightItem, int ___m_leftItemQuality, int ___m_rightItemQuality) { int quality = ResolveEquipmentQuality(__instance, ___m_leftItem, ___m_leftItemQuality); int quality2 = ResolveEquipmentQuality(__instance, ___m_rightItem, ___m_rightItemQuality); ApplyPotentialGlow(___m_leftItemInstance, quality, subtleArmorGlow: false, GetFallbackParticleKind(___m_leftItem)); ApplyPotentialGlow(___m_rightItemInstance, quality2, subtleArmorGlow: false, GetFallbackParticleKind(___m_rightItem)); } } [HarmonyPatch(typeof(VisEquipment), "CustomUpdate")] private static class FistHandGlowPatch { private static void Postfix(Transform ___m_leftHand, Transform ___m_rightHand, int ___m_leftItem, int ___m_rightItem, int ___m_leftItemQuality, int ___m_rightItemQuality) { bool equipped = IsFistWeaponPrefab(___m_leftItem) || IsFistWeaponPrefab(___m_rightItem); int quality = Mathf.Max(___m_leftItemQuality, ___m_rightItemQuality); UpdateFistHandFog(___m_leftHand, equipped, quality); UpdateFistHandFog(___m_rightHand, equipped, quality); } } [HarmonyPatch(typeof(ArmorStand), "SetVisualItem")] private static class ArmorStandStoredQualityPatch { private struct QualityState { internal ItemDrop PrefabDrop; internal int OriginalQuality; internal bool Changed; } private static void Prefix(int index, int itemHash, ZNetView ___m_nview, ref QualityState __state) { if (itemHash == 0 || (Object)(object)___m_nview == (Object)null || !___m_nview.IsValid()) { return; } ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(itemHash) : null); ItemDrop val = ((obj != null) ? obj.GetComponent<ItemDrop>() : null); ZDO zDO = ___m_nview.GetZDO(); if (!((Object)(object)val == (Object)null) && zDO != null) { ItemData val2 = val.m_itemData.Clone(); ItemDrop.LoadFromZDO(val2, zDO, index); if (val2.m_quality > val.m_itemData.m_quality) { __state.PrefabDrop = val; __state.OriginalQuality = val.m_itemData.m_quality; __state.Changed = true; val.m_itemData.m_quality = val2.m_quality; } } } private static void Postfix(QualityState __state) { Restore(__state); } private static Exception Finalizer(Exception __exception, QualityState __state) { Restore(__state); return __exception; } private static void Restore(QualityState state) { if (state.Changed && (Object)(object)state.PrefabDrop != (Object)null) { state.PrefabDrop.m_itemData.m_quality = state.OriginalQuality; } } } [HarmonyPatch(typeof(ItemStand), "SetVisualItem")] private static class ItemStandGlowPatch { private static void Postfix(int itemHash, int quality, GameObject ___m_visualItem) { ApplyPotentialGlow(___m_visualItem, quality, IsArmorPrefab(itemHash), GetFallbackParticleKind(itemHash)); } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] private static class InventoryItemIconGlowPatch { private static void Postfix(Inventory ___m_inventory, List<InventoryElement> ___m_elements) { UpdateInventoryIconGlows(___m_inventory, ___m_elements); } } [HarmonyPatch(typeof(HotkeyBar), "UpdateIcons")] private static class HotkeyItemIconGlowPatch { private static void Postfix(HotkeyBar __instance) { UpdateHotkeyIconGlows(__instance); } } [HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")] private static class ChestGlowCleanupPatch { private static void Postfix(VisEquipment __instance, int hash) { if (hash == 0) { RemoveBodyArmorGlow(__instance, "Chest"); } } } [HarmonyPatch(typeof(VisEquipment), "SetLegEquipped")] private static class LegGlowCleanupPatch { private static void Postfix(VisEquipment __instance, int hash) { if (hash == 0) { RemoveBodyArmorGlow(__instance, "Legs"); } } } [HarmonyPatch(typeof(VisEquipment), "SetShoulderEquipped")] private static class CapeGlowCleanupPatch { private static void Postfix(VisEquipment __instance, int hash) { if (hash == 0) { RemoveBodyArmorGlow(__instance, "Cape"); } } } [HarmonyPatch(typeof(VisEquipment), "SetUtilityEquipped")] private static class UtilityGlowCleanupPatch { private static void Postfix(VisEquipment __instance, int hash) { if (hash == 0) { RemoveBodyArmorGlow(__instance, "Utility"); } } } [HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")] private static class ArmorQualityTrackingPatch { private static void Postfix(VisEquipment __0, ItemData ___m_rightItem, ItemData ___m_leftItem, ItemData ___m_hiddenLeftItem, ItemData ___m_hiddenRightItem, ItemData ___m_chestItem, ItemData ___m_legItem, ItemData ___m_helmetItem, ItemData ___m_shoulderItem, ItemData ___m_utilityItem) { RecordArmorQualities(__0, ___m_chestItem, ___m_legItem, ___m_helmetItem, ___m_shoulderItem, ___m_utilityItem); RecordHandQualities(__0, ___m_rightItem, ___m_leftItem, ___m_hiddenLeftItem, ___m_hiddenRightItem); } } [HarmonyPatch(typeof(ItemDrop), "Start")] private static class DroppedItemGlowPatch { private static void Postfix(ItemDrop __instance) { if (__instance?.m_itemData != null && !IsArmorItem(__instance.m_itemData)) { int itemHash = GetItemHash(__instance.m_itemData); ApplyPotentialGlow(((Component)__instance).gameObject, __instance.m_itemData.m_quality, subtleArmorGlow: false, GetFallbackParticleKind(itemHash)); } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] private static class ForgeDurationPatch { private struct DurationState { internal float OriginalBaseDuration; internal float OriginalPerLevelDuration; internal bool Changed; } private static void Prefix(Player player, ref float ___m_upgraderDuration, ref float ___m_upgraderDurationPerLevel, ref DurationState __state) { CraftingStation val = ((player != null) ? player.GetCurrentCraftingStation() : null); bool flag = HasAdminPotionEffect(player); if ((flag || HasPotionEffect(player)) && !((Object)(object)val == (Object)null) && val.m_upgrader) { __state.OriginalBaseDuration = ___m_upgraderDuration; __state.OriginalPerLevelDuration = ___m_upgraderDurationPerLevel; __state.Changed = true; float num = (flag ? 0.01f : 0.5f); ___m_upgraderDuration *= num; ___m_upgraderDurationPerLevel *= num; } } private static void Postfix(ref float ___m_upgraderDuration, ref float ___m_upgraderDurationPerLevel, DurationState __state) { Restore(ref ___m_upgraderDuration, ref ___m_upgraderDurationPerLevel, __state); } private static Exception Finalizer(Exception __exception, ref float ___m_upgraderDuration, ref float ___m_upgraderDurationPerLevel, DurationState __state) { Restore(ref ___m_upgraderDuration, ref ___m_upgraderDurationPerLevel, __state); return __exception; } private static void Restore(ref float baseDuration, ref float perLevelDuration, DurationState state) { if (state.Changed) { baseDuration = state.OriginalBaseDuration; perLevelDuration = state.OriginalPerLevelDuration; } } } [CompilerGenerated] private static class <>O { public static CoroutineHandler <0>__AdminPotionPermissionServerReceive; public static CoroutineHandler <1>__AdminPotionPermissionClientReceive; public static Action<long, long> <2>__RPC_RequestAdminPotionPurge; public static Action<long, long> <3>__RPC_ExecuteAdminPotionPurge; public static Action<long, long> <4>__RPC_RequestAdminPotionPermission; public static Action<long, long, string, bool> <5>__RPC_SetAdminPotionPermission; public static Action<long, long, bool> <6>__RPC_SyncAdminPotionPermission; public static Action<long, long, string> <7>__RPC_AdminPotionCommandResult; } public const string PluginGuid = "com.forgepotential.potentialdraught"; public const string PluginName = "Potential Draught"; public const string PluginVersion = "1.3.9"; internal const float PotionSuccessChance = 0.75f; internal const float PotionBreakChance = 0.1f; internal const float PotionDurationSeconds = 300f; internal const int DefaultForgeMaxQuality = 25; internal const string ItemPrefabName = "PotionPotentialDraught"; internal const string StatusEffectPrefabName = "SE_PotentialDraught"; internal const string AdminItemPrefabName = "PotionPotentialDraughtAdmin"; internal const string AdminStatusEffectPrefabName = "SE_PotentialDraughtAdmin"; private Harmony _harmony; private Sprite _icon; private static readonly FieldInfo VisEquipmentNetViewField = AccessTools.Field(typeof(VisEquipment), "m_nview"); private static readonly FieldInfo VisEquipmentBodyModelField = AccessTools.Field(typeof(VisEquipment), "m_bodyModel"); private static readonly FieldInfo VisEquipmentBoneMapField = AccessTools.Field(typeof(VisEquipment), "m_boneMap"); private static readonly FieldInfo ZNetPeerSocketField = AccessTools.Field(typeof(ZNetPeer), "m_socket"); private static readonly FieldInfo PlayFabSocketPlatformUserIdField = AccessTools.Field(typeof(ZPlayFabSocket), "m_platformPlayerId"); private static readonly FieldInfo ZdoObjectsByIdField = AccessTools.Field(typeof(ZDOMan), "m_objectsByID"); private static readonly MethodInfo ContainerSaveMethod = AccessTools.Method(typeof(Container), "Save", (Type[])null, (Type[])null); private static readonly FieldInfo InventoryElementButtonField = AccessTools.Field(typeof(InventoryElement), "m_button"); private static readonly FieldInfo HotkeyElementsField = AccessTools.Field(typeof(HotkeyBar), "m_elements"); private static readonly FieldInfo HotkeyItemsField = AccessTools.Field(typeof(HotkeyBar), "m_items"); private static readonly Type HotkeyElementDataType = AccessTools.Inner(typeof(HotkeyBar), "ElementData"); private static readonly FieldInfo HotkeyElementObjectField = AccessTools.Field(HotkeyElementDataType, "m_go"); private static readonly Dictionary<VisEquipment, ArmorQualityState> ArmorQualities = new Dictionary<VisEquipment, ArmorQualityState>(); private static Shader _surfaceGlowShader; private static ParticleIntensityScaler _nativeGlowTemplate; private static GameObject _frostnerFogContainerTemplate; private static GameObject _shieldParticleTemplate; private static GameObject _fistParticleTemplate; private static ZRoutedRpc _registeredAdminPotionRpcInstance; private static CustomRPC _adminPotionPermissionRpc; private static ConfigEntry<string> _allowedAdminPotionPlayerIdentitiesConfig; private static ConfigEntry<int> _maximumItemQualityConfig; private static int _synchronizedMaximumItemQuality; private static readonly HashSet<string> AllowedAdminPotionPlayerIdentities = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static bool _localAdminPotionUseAllowed; private static readonly MethodInfo ParticleApplyIntensityMethod = AccessTools.Method(typeof(ParticleIntensityScaler), "ApplyIntensity", (Type[])null, (Type[])null); private static readonly MethodInfo RoutedRpcGetServerPeerIdMethod = AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null); private const string RequestAdminPotionPurgeRpc = "PotentialDraught_RequestAdminPotionPurge"; private const string ExecuteAdminPotionPurgeRpc = "PotentialDraught_ExecuteAdminPotionPurge"; private const string RequestAdminPotionPermissionRpc = "PotentialDraught_RequestAdminPotionPermission"; private const string SetAdminPotionPermissionRpc = "PotentialDraught_SetAdminPotionPermission"; private const string SyncAdminPotionPermissionRpc = "PotentialDraught_SyncAdminPotionPermission"; private const string AdminPotionCommandResultRpc = "PotentialDraught_AdminPotionCommandResult"; private const byte AdminPotionRequestPermissionMessage = 1; private const byte AdminPotionSetPermissionMessage = 2; private const byte AdminPotionSyncPermissionMessage = 3; private const byte AdminPotionCommandResultMessage = 4; private const byte SetMaximumItemQualityMessage = 5; private const byte SyncMaximumItemQualityMessage = 6; private const byte RequestAdminPotionPurgeMessage = 7; private const byte ExecuteAdminPotionPurgeMessage = 8; private const string SurfaceGlowPrefix = "PotentialDraught_SurfaceGlow_"; private const string ArmorElectricPrefix = "PotentialDraught_ArmorElectric_"; private const string FistFogName = "PotentialDraught_FistFog"; private const string ChestQualityZdoKey = "PotentialDraught_ChestQuality"; private const string LegQualityZdoKey = "PotentialDraught_LegQuality"; private const string HelmetQualityZdoKey = "PotentialDraught_HelmetQuality"; private const string UtilityQualityZdoKey = "PotentialDraught_UtilityQuality"; private const string LeftHandQualityZdoKey = "PotentialDraught_LeftHandQuality"; private const string RightHandQualityZdoKey = "PotentialDraught_RightHandQuality"; private const string LeftBackQualityZdoKey = "PotentialDraught_LeftBackQuality"; private const string RightBackQualityZdoKey = "PotentialDraught_RightBackQuality"; internal static PotentialDraughtPlugin Instance { get; private set; } internal static CustomStatusEffect PotentialStatusEffect { get; private set; } internal static CustomStatusEffect AdminPotentialStatusEffect { get; private set; } internal static int PendingAdminUpgradeLevels { get; set; } = 1; internal static bool AdminLevelOverrideArmed { get; set; } public static int MaximumItemQuality { get { if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && _synchronizedMaximumItemQuality > 0) { return _synchronizedMaximumItemQuality; } return Mathf.Max(1, _maximumItemQualityConfig?.Value ?? 25); } } private void Awake() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown Instance = this; _allowedAdminPotionPlayerIdentitiesConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Admin Potion", "AllowedPlayerIdentities", string.Empty, "Pipe-separated stable network identities permitted to consume the admin potion. Manage this with allowadminpotion and disableadminpotion."); _maximumItemQualityConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Forge", "MaximumItemQuality", 25, "Maximum item quality permitted by normal Forge of Potential upgrades. Change this with maximumitemquality."); LoadAllowedAdminPotionPlayerIdentities(); NetworkManager instance = NetworkManager.Instance; object obj = <>O.<0>__AdminPotionPermissionServerReceive; if (obj == null) { CoroutineHandler val = AdminPotionPermissionServerReceive; <>O.<0>__AdminPotionPermissionServerReceive = val; obj = (object)val; } object obj2 = <>O.<1>__AdminPotionPermissionClientReceive; if (obj2 == null) { CoroutineHandler val2 = AdminPotionPermissionClientReceive; <>O.<1>__AdminPotionPermissionClientReceive = val2; obj2 = (object)val2; } _adminPotionPermissionRpc = instance.AddRPC("AdminPotionPermission", (CoroutineHandler)obj, (CoroutineHandler)obj2); AddLocalization(); RegisterStatusEffect(); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new PotentialLevelsCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new PurgeAdminPotionsCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new AllowAdminPotionCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new DisableAdminPotionCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new MaximumItemQualityCommand()); PrefabManager.OnVanillaPrefabsAvailable += RegisterPotion; _harmony = new Harmony("com.forgepotential.potentialdraught"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)(string.Format("{0} {1} loaded. Fixed chances: {2:P0} success, ", "Potential Draught", "1.3.9", 0.75f) + $"{0.1f:P0} break; " + $"duration: {300f:0}s.")); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void AddLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "item_potentialdraught", "Draught of Tempered Potential" }, { "item_potentialdraught_description", "A volatile golden draught that steadies the Forge of Potential without silencing its danger." }, { "se_potentialdraught", "Tempered Potential" }, { "se_potentialdraught_tooltip", "Improves the Forge of Potential refinement chance while active. Failure can still destroy the item." }, { "se_potentialdraught_start", "The threads of possibility burn brighter." }, { "se_potentialdraught_stop", "The golden certainty fades." }, { "item_potentialdraught_admin", "Draught of Absolute Potential [Admin]" }, { "item_potentialdraught_admin_description", "An admin-only draught of absolute certainty. Spawn ID: PotionPotentialDraughtAdmin" }, { "se_potentialdraught_admin", "Absolute Potential" }, { "se_potentialdraught_admin_tooltip", "Forge of Potential attempts always succeed and complete almost instantly." }, { "se_potentialdraught_admin_start", "Every possible path becomes one." }, { "se_potentialdraught_admin_stop", "Absolute certainty releases its hold." } }); } private void RegisterStatusEffect() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown _icon = LoadEmbeddedIcon(); StatusEffect obj = ScriptableObject.CreateInstance<StatusEffect>(); ((Object)obj).name = "SE_PotentialDraught"; obj.m_name = "$se_potentialdraught"; obj.m_tooltip = "$se_potentialdraught_tooltip"; obj.m_icon = _icon; obj.m_category = "potion"; obj.m_ttl = 300f; obj.m_startMessageType = (MessageType)2; obj.m_startMessage = "$se_potentialdraught_start"; obj.m_stopMessageType = (MessageType)2; obj.m_stopMessage = "$se_potentialdraught_stop"; obj.m_cooldownIcon = false; obj.m_flashIcon = false; obj.m_effectsOnlyOnPlayer = true; PotentialStatusEffect = new CustomStatusEffect(obj, false); if (!ItemManager.Instance.AddStatusEffect(PotentialStatusEffect)) { throw new InvalidOperationException("Could not register the Potential Draught status effect."); } StatusEffect obj2 = ScriptableObject.CreateInstance<StatusEffect>(); ((Object)obj2).name = "SE_PotentialDraughtAdmin"; obj2.m_name = "$se_potentialdraught_admin"; obj2.m_tooltip = "$se_potentialdraught_admin_tooltip"; obj2.m_icon = _icon; obj2.m_category = "potential_admin_potion"; obj2.m_ttl = 300f; obj2.m_startMessageType = (MessageType)2; obj2.m_startMessage = "$se_potentialdraught_admin_start"; obj2.m_stopMessageType = (MessageType)2; obj2.m_stopMessage = "$se_potentialdraught_admin_stop"; obj2.m_cooldownIcon = false; obj2.m_flashIcon = true; obj2.m_effectsOnlyOnPlayer = true; AdminPotentialStatusEffect = new CustomStatusEffect(obj2, false); if (!ItemManager.Instance.AddStatusEffect(AdminPotentialStatusEffect)) { throw new InvalidOperationException("Could not register the admin Potential Draught status effect."); } } private void RegisterPotion() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= RegisterPotion; RegisterAdminPotionRpcs(); CacheNativeGlowTemplate(); ItemConfig val = new ItemConfig(); val.Name = "$item_potentialdraught"; val.Description = "$item_potentialdraught_description"; val.Amount = 1; val.CraftingStation = "piece_cauldron"; val.MinStationLevel = 3; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig("Honey", 10, 0, false), new RequirementConfig("Bloodbag", 5, 0, false), new RequirementConfig("DragonTear", 5, 0, false), new RequirementConfig("GreydwarfEye", 5, 0, false) }; ItemConfig val2 = val; CustomItem val3 = new CustomItem("PotionPotentialDraught", "MeadFrostResist", val2); val3.ItemDrop.m_itemData.m_shared.m_name = "$item_potentialdraught"; val3.ItemDrop.m_itemData.m_shared.m_description = "$item_potentialdraught_description"; val3.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { _icon }; val3.ItemDrop.m_itemData.m_shared.m_consumeStatusEffect = PotentialStatusEffect.StatusEffect; val3.ItemDrop.m_itemData.m_shared.m_maxStackSize = 10; if (!ItemManager.Instance.AddItem(val3)) { throw new InvalidOperationException("Could not register the Potential Draught item."); } CustomItem val4 = new CustomItem("PotionPotentialDraughtAdmin", "MeadFrostResist"); val4.ItemDrop.m_itemData.m_shared.m_name = "$item_potentialdraught_admin"; val4.ItemDrop.m_itemData.m_shared.m_description = "$item_potentialdraught_admin_description"; val4.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { _icon }; val4.ItemDrop.m_itemData.m_shared.m_consumeStatusEffect = AdminPotentialStatusEffect.StatusEffect; val4.ItemDrop.m_itemData.m_shared.m_maxStackSize = 10; if (!ItemManager.Instance.AddItem(val4)) { throw new InvalidOperationException("Could not register the admin Potential Draught item."); } } private static void CacheNativeGlowTemplate() { if (ObjectDB.instance?.m_items == null) { return; } _shieldParticleTemplate = FindItemParticleTemplate("FistGold_FrostFire", "FistGold_BloodLightning", "FistGold"); _fistParticleTemplate = FindItemParticleTemplate("FistGold_FrostFire", "FistGold_BloodLightning", "FistGold"); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Frostner"); if ((Object)(object)itemPrefab != (Object)null) { Transform val = itemPrefab.transform.Find("attach"); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInChildren<ParticleSystem>(true) != (Object)null) { _frostnerFogContainerTemplate = ((Component)val).gameObject; _nativeGlowTemplate = ((Component)val).GetComponentInChildren<ParticleIntensityScaler>(true); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Using Frostner attach particles directly ({((Component)val).GetComponentsInChildren<ParticleSystem>(true).Length} systems)."); return; } } if (TryCacheGlowTemplate(itemPrefab, "Frostner")) { return; } foreach (GameObject item in ObjectDB.instance.m_items) { if (TryCacheGlowTemplate(item, (item != null) ? ((Object)item).name : null)) { return; } } ((BaseUnityPlugin)Instance).Logger.LogWarning((object)"No native potential glow template was found; material emission will be used as a fallback."); } private static GameObject FindItemParticleTemplate(params string[] prefabNames) { foreach (string text in prefabNames) { ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(text) : null); if (!((Object)(object)val == (Object)null)) { Transform val2 = val.transform.Find("attach"); if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).GetComponentInChildren<ParticleSystem>(true) != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Using '" + text + "' attach particles as a specialized fallback.")); return ((Component)val2).gameObject; } ParticleIntensityScaler componentInChildren = val.GetComponentInChildren<ParticleIntensityScaler>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Component)componentInChildren).GetComponentInChildren<ParticleSystem>(true) != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Using '" + text + "' particle scaler as a specialized fallback.")); return ((Component)componentInChildren).gameObject; } } } return null; } private static bool TryCacheGlowTemplate(GameObject itemPrefab, string sourceName) { if ((Object)(object)itemPrefab == (Object)null) { return false; } ParticleIntensityScaler[] componentsInChildren = itemPrefab.GetComponentsInChildren<ParticleIntensityScaler>(true); foreach (ParticleIntensityScaler val in componentsInChildren) { if (!((Object)(object)((Component)val).GetComponentInChildren<ParticleSystem>(true) == (Object)null)) { _nativeGlowTemplate = val; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Using Frostner-style fog container '" + ((Object)val).name + "' from '" + sourceName + "'.")); return true; } } return false; } private static bool CreateNativeFogGlow(GameObject visual, int quality, Bounds? forcedBounds = null, string glowObjectName = "PotentialDraught_FogGlow", GameObject preferredTemplate = null) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: 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_0302: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_frostnerFogContainerTemplate == (Object)null && (Object)(object)_nativeGlowTemplate == (Object)null) { CacheNativeGlowTemplate(); } GameObject val = preferredTemplate ?? _frostnerFogContainerTemplate ?? (((Object)(object)_nativeGlowTemplate == (Object)null) ? null : ((Component)_nativeGlowTemplate).gameObject); if ((Object)(object)val == (Object)null) { return false; } GameObject val2 = new GameObject(glowObjectName); val2.transform.SetParent(visual.transform, false); Vector3 lossyScale = visual.transform.lossyScale; val2.transform.localScale = new Vector3(Mathf.Clamp(1f / Mathf.Max(0.0001f, Mathf.Abs(lossyScale.x)), 0.05f, 20f), Mathf.Clamp(1f / Mathf.Max(0.0001f, Mathf.Abs(lossyScale.y)), 0.05f, 20f), Mathf.Clamp(1f / Mathf.Max(0.0001f, Mathf.Abs(lossyScale.z)), 0.05f, 20f)); Bounds bounds; if (forcedBounds.HasValue) { bounds = forcedBounds.Value; } else if (!TryGetLocalEquipmentBounds(visual, out bounds)) { Object.Destroy((Object)(object)val2); return false; } val2.transform.localPosition = ((Bounds)(ref bounds)).center; GameObject val3 = Object.Instantiate<GameObject>(val, val2.transform, false); ((Object)val3).name = "PotentialFallbackParticles"; val3.transform.localPosition = Vector3.zero; val3.transform.localRotation = Quaternion.identity; val3.transform.localScale = Vector3.one; Renderer[] componentsInChildren = val3.GetComponentsInChildren<Renderer>(true); foreach (Renderer val4 in componentsInChildren) { if (!(val4 is ParticleSystemRenderer)) { val4.enabled = false; } } Collider[] componentsInChildren2 = val3.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Light[] componentsInChildren3 = val3.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = false; } ParticleSystem[] componentsInChildren4 = val3.GetComponentsInChildren<ParticleSystem>(true); if (componentsInChildren4.Length == 0) { Object.Destroy((Object)(object)val2); return false; } ShapeModule shape = componentsInChildren4[0].shape; Vector3 val5 = ((Component)componentsInChildren4[0]).transform.TransformPoint(((ShapeModule)(ref shape)).enabled ? ((ShapeModule)(ref shape)).position : Vector3.zero); Bounds val6 = default(Bounds); ((Bounds)(ref val6))..ctor(val3.transform.InverseTransformPoint(val5), Vector3.zero); for (int j = 1; j < componentsInChildren4.Length; j++) { ShapeModule shape2 = componentsInChildren4[j].shape; Vector3 val7 = ((Component)componentsInChildren4[j]).transform.TransformPoint(((ShapeModule)(ref shape2)).enabled ? ((ShapeModule)(ref shape2)).position : Vector3.zero); ((Bounds)(ref val6)).Encapsulate(val3.transform.InverseTransformPoint(val7)); } Vector3 val8 = Vector3.one * 0.75f; val3.transform.localScale = val8; Vector3 localPosition = -Vector3.Scale(((Bounds)(ref val6)).center, val8); val3.transform.localPosition = localPosition; ParticleIntensityScaler componentInChildren = val3.GetComponentInChildren<ParticleIntensityScaler>(true); MonoBehaviour[] componentsInChildren5 = val3.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val9 in componentsInChildren5) { if ((Object)(object)val9 != (Object)(object)componentInChildren) { ((Behaviour)val9).enabled = false; } } val3.SetActive(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.CacheOriginalValues(); componentInChildren.SetQuality(quality); componentInChildren.intensity *= 0.8f; ParticleApplyIntensityMethod?.Invoke(componentInChildren, null); ((Behaviour)componentInChildren).enabled = false; } ParticleSystem[] array = componentsInChildren4; foreach (ParticleSystem obj in array) { ((Component)obj).gameObject.SetActive(true); obj.Clear(true); obj.Play(true); } ((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"Attached vanilla fallback particles from '{((Object)val).name}' to '{((Object)visual).name}' at 80% native intensity and quality {quality}."); return true; } private static bool TryGetLocalEquipmentBounds(GameObject visual, out Bounds bounds) { //IL_0001: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0079: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); bool flag = false; Renderer[] componentsInChildren = visual.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (val is ParticleSystemRenderer || ((Object)((Component)val).gameObject).name.StartsWith("PotentialDraught_SurfaceGlow_")) { continue; } Bounds bounds2 = val.bounds; for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { for (int l = -1; l <= 1; l += 2) { Vector3 val2 = ((Bounds)(ref bounds2)).center + Vector3.Scale(((Bounds)(ref bounds2)).extents, new Vector3((float)j, (float)k, (float)l)); Vector3 val3 = visual.transform.InverseTransformPoint(val2); if (!flag) { bounds = new Bounds(val3, Vector3.zero); flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val3); } } } } } return flag; } internal static Color GetPotentialGlowColor(int quality) { //IL_0019: 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_0057: 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_00af: 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) if (quality >= 30) { return new Color(1f, 0.05f, 0.55f, 1f); } if (quality >= 25) { return new Color(1f, 0.04f, 0.04f, 1f); } if (quality >= 20) { return new Color(1f, 0.62f, 0.05f, 1f); } if (quality >= 15) { return new Color(0.65f, 0.18f, 1f, 1f); } if (quality >= 10) { return new Color(0.12f, 1f, 0.22f, 1f); } return new Color(0.12f, 0.42f, 1f, 1f); } private static void ConfigureItemIconGlow(GameObject slot, int quality) { if (!((Object)(object)slot == (Object)null)) { PotentialItemIconGlow potentialItemIconGlow = slot.GetComponent<PotentialItemIconGlow>(); if ((Object)(object)potentialItemIconGlow == (Object)null) { potentialItemIconGlow = slot.AddComponent<PotentialItemIconGlow>(); } potentialItemIconGlow.Configure(quality); } } private static void UpdateInventoryIconGlows(Inventory inventory, List<InventoryElement> elements) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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 (inventory == null || elements == null) { return; } foreach (InventoryElement element in elements) { if (!((Object)(object)element == (Object)null)) { Vector2i position = element.Position; ItemData itemAt = inventory.GetItemAt(position.x, position.y); object? obj = InventoryElementButtonField?.GetValue(element); object? obj2 = ((obj is Button) ? obj : null); ConfigureItemIconGlow((obj2 != null) ? ((Component)obj2).gameObject : null, itemAt?.m_quality ?? 0); } } } private static void UpdateHotkeyIconGlows(HotkeyBar hotkeyBar) { IList list = HotkeyElementsField?.GetValue(hotkeyBar) as IList; IList list2 = HotkeyItemsField?.GetValue(hotkeyBar) as IList; if (list != null) { for (int i = 0; i < list.Count; i++) { object obj = list[i]; ConfigureItemIconGlow((GameObject)((obj == null) ? null : /*isinst with value type is only supported in some contexts*/), ((ItemData)(((list2 != null && i < list2.Count) ? /*isinst with value type is only supported in some contexts*/: null)?)).m_quality ?? 0); } } } private static void ConfigureRainbowGlow(GameObject visual, int quality, bool animateSurface = false) { if (!((Object)(object)visual == (Object)null)) { PotentialRainbowGlowController component = visual.GetComponent<PotentialRainbowGlowController>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; Object.Destroy((Object)(object)component); } } } internal static void RefreshRainbowParticleColors(GameObject visual) { if (!((Object)(object)visual == (Object)null) && !(ParticleApplyIntensityMethod == null)) { ParticleIntensityScaler[] componentsInChildren = visual.GetComponentsInChildren<ParticleIntensityScaler>(true); foreach (ParticleIntensityScaler obj in componentsInChildren) { ParticleApplyIntensityMethod.Invoke(obj, null); } } } private static void ApplyPotentialGlow(GameObject visual, int quality, bool subtleArmorGlow = false, FallbackParticleKind fallbackKind = FallbackParticleKind.None) { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visual == (Object)null) { return; } if (quality < 5) { ConfigureRainbowGlow(visual, quality); return; } Transform val = visual.transform.Find("PotentialDraught_FogGlow"); if (fallbackKind == FallbackParticleKind.Shield || fallbackKind == FallbackParticleKind.Fist) { ConfigureRainbowGlow(visual, 0); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } ParticleSystem[] componentsInChildren = visual.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem obj in componentsInChildren) { obj.Stop(true, (ParticleSystemStopBehavior)0); ((Component)obj).gameObject.SetActive(false); } return; } if ((Object)(object)val != (Object)null) { ConfigureRainbowGlow(visual, quality); return; } ParticleIntensityScaler[] componentsInChildren2 = visual.GetComponentsInChildren<ParticleIntensityScaler>(true); ParticleIntensityScaler[] array; if (subtleArmorGlow) { ConfigureRainbowGlow(visual, 0); array = componentsInChildren2; foreach (ParticleIntensityScaler obj2 in array) { obj2.SetQuality(obj2.maxQuality); } return; } ParticleSystem[] componentsInChildren3 = visual.GetComponentsInChildren<ParticleSystem>(true); if (componentsInChildren3.Length != 0 && fallbackKind == FallbackParticleKind.None) { array = componentsInChildren2; for (int i = 0; i < array.Length; i++) { array[i].SetQuality(quality); } ParticleSystem[] componentsInChildren = componentsInChildren3; foreach (ParticleSystem val2 in componentsInChildren) { ((Component)val2).gameObject.SetActive(true); if (!val2.isPlaying) { val2.Play(true); } } ConfigureRainbowGlow(visual, quality); return; } array = componentsInChildren2; foreach (ParticleIntensityScaler obj3 in array) { obj3.SetQuality(obj3.maxQuality); } if (CreateNativeFogGlow(visual, quality, null, "PotentialDraught_FogGlow", (GameObject)(fallbackKind switch { FallbackParticleKind.Fist => _fistParticleTemplate, FallbackParticleKind.Shield => _shieldParticleTemplate, _ => null, }))) { ConfigureRainbowGlow(visual, quality); return; } Color val3 = GetPotentialGlowColor(quality) * 0.54f; val3.a = 1f; Renderer[] componentsInChildren4 = visual.GetComponentsInChildren<Renderer>(true); foreach (Renderer val4 in componentsInChildren4) { if (((Object)((Component)val4).gameObject).name.StartsWith("PotentialDraught_SurfaceGlow_")) { continue; } bool flag = false; Material[] materials = val4.materials; foreach (Material val5 in materials) { if (val5.HasProperty("_EmissionColor")) { val5.EnableKeyword("_EMISSION"); val5.SetColor("_EmissionColor", val3); flag = true; } else if (val5.HasProperty("_EmissiveColor")) { val5.SetColor("_EmissiveColor", val3); flag = true; } } if (!flag) { EnsureSurfaceGlowOverlay(val4, val3, null, "Item", 0.28f); } } ConfigureRainbowGlow(visual, quality, animateSurface: true); } private static Shader GetSurfaceGlowShader() { if ((Object)(object)_surfaceGlowShader != (Object)null) { return _surfaceGlowShader; } _surfaceGlowShader = Shader.Find("Legacy Shaders/Particles/Additive"); if ((Object)(object)_surfaceGlowShader == (Object)null) { _surfaceGlowShader = Shader.Find("Particles/Standard Unlit"); } if ((Object)(object)_surfaceGlowShader == (Object)null) { _surfaceGlowShader = Shader.Find("Unlit/Transparent"); } return _surfaceGlowShader; } private static string GetSurfaceGlowName(Renderer source, string slot) { return "PotentialDraught_SurfaceGlow_" + slot + "_" + ((Object)source).GetInstanceID(); } private static Material CreateSurfaceGlowMaterial(Material sourceMaterial, Texture textureOverride, Color emission, float overlayAlpha) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) Shader surfaceGlowShader = GetSurfaceGlowShader(); if ((Object)(object)surfaceGlowShader == (Object)null) { return null; } Material val = new Material(surfaceGlowShader) { name = "PotentialDraught_SurfaceGlowMaterial", renderQueue = 3100 }; Texture val2 = textureOverride; if ((Object)(object)val2 == (Object)null && (Object)(object)sourceMaterial != (Object)null && sourceMaterial.HasProperty("_MainTex")) { val2 = sourceMaterial.GetTexture("_MainTex"); } if ((Object)(object)val2 != (Object)null && val.HasProperty("_MainTex")) { val.SetTexture("_MainTex", val2); } Color val3 = emission; val3.a = overlayAlpha; if (val.HasProperty("_TintColor")) { val.SetColor("_TintColor", val3); } if (val.HasProperty("_Color")) { val.SetColor("_Color", val3); } return val; } private static void EnsureSurfaceGlowOverlay(Renderer source, Color emission, Texture textureOverride, string slot, float overlayAlpha) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_008e: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || (Object)(object)((Component)source).transform.parent == (Object)null) { return; } string surfaceGlowName = GetSurfaceGlowName(source, slot); Transform obj = ((Component)source).transform.parent.Find(surfaceGlowName); Renderer val = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null); if ((Object)(object)val == (Object)null) { GameObject val2 = new GameObject(surfaceGlowName); val2.layer = ((Component)source).gameObject.layer; val2.transform.SetParent(((Component)source).transform.parent, false); val2.transform.localPosition = ((Component)source).transform.localPosition; val2.transform.localRotation = ((Component)source).transform.localRotation; val2.transform.localScale = ((Component)source).transform.localScale * 1.003f; SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((source is SkinnedMeshRenderer) ? source : null); if ((Object)(object)val3 != (Object)null) { SkinnedMeshRenderer obj2 = val2.AddComponent<SkinnedMeshRenderer>(); obj2.sharedMesh = val3.sharedMesh; obj2.bones = val3.bones; obj2.rootBone = val3.rootBone; ((Renderer)obj2).localBounds = ((Renderer)val3).localBounds; obj2.updateWhenOffscreen = val3.updateWhenOffscreen; val = (Renderer)(object)obj2; } else { MeshFilter component = ((Component)source).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { Object.Destroy((Object)(object)val2); return; } val2.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh; val = (Renderer)(object)val2.AddComponent<MeshRenderer>(); } val.receiveShadows = false; val.sortingLayerID = source.sortingLayerID; val.sortingOrder = source.sortingOrder + 1; } Material[] sharedMaterials = source.sharedMaterials; int num = Mathf.Max(1, sharedMaterials.Length); Material[] array = (Material[])(object)new Material[num]; for (int i = 0; i < num; i++) { Material sourceMaterial = ((sharedMaterials.Length > i) ? sharedMaterials[i] : null); array[i] = CreateSurfaceGlowMaterial(sourceMaterial, textureOverride, emission, overlayAlpha); } val.sharedMaterials = array; val.enabled = source.enabled; } private static void RemoveBodyArmorGlow(VisEquipment equipment, string slot) { object? obj = VisEquipmentBodyModelField?.GetValue(equipment); SkinnedMeshRenderer val = (SkinnedMeshRenderer)((obj is SkinnedMeshRenderer) ? obj : null); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform.parent != (Object)null) { Transform val2 = ((Component)val).transform.parent.Find(GetSurfaceGlowName((Renderer)(object)val, slot)); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } if ((Object)(object)equipment == (Object)null) { return; } ArmorElectricArcController[] componentsInChildren = ((Component)equipment).GetComponentsInChildren<ArmorElectricArcController>(true); foreach (ArmorElectricArcController armorElectricArcController in componentsInChildren) { if (((Object)((Component)armorElectricArcController).gameObject).name == "PotentialDraught_ArmorElectric_" + slot) { Object.Destroy((Object)(object)((Component)armorElectricArcController).gameObject); } } } private static Transform FindArmorBone(VisEquipment equipment, bool upperBody) { if (!(VisEquipmentBoneMapField?.GetValue(equipment) is Dictionary<string, Transform> { Count: not 0 } dictionary)) { return null; } string[] array = ((!upperBody) ? new string[4] { "Hips", "Pelvis", "Hip", "Root" } : new string[5] { "Spine2", "UpperChest", "Chest", "Spine1", "Spine" }); foreach (string b in array) { foreach (KeyValuePair<string, Transform> item in dictionary) { if (string.Equals(item.Key, b, StringComparison.OrdinalIgnoreCase)) { return item.Value; } } } array = ((!upperBody) ? new string[3] { "hips", "pelvis", "hip" } : new string[5] { "spine2", "upperchest", "chest", "spine1", "spine" }); foreach (string value in array) { foreach (KeyValuePair<string, Transform> item2 in dictionary) { if (item2.Key.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return item2.Value; } } } object? obj = VisEquipmentBodyModelField?.GetValue(equipment); object? obj2 = ((obj is SkinnedMeshRenderer) ? obj : null); if (obj2 == null) { return null; } return ((SkinnedMeshRenderer)obj2).rootBone; } private static void EnsureArmorElectricEffect(GameObject visual, int quality, string slot, Vector3? worldPosition = null) { //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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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) //IL_00e7: 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_00ae: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)visual == (Object)null) && quality >= 5) { string text = "PotentialDraught_ArmorElectric_" + slot; Transform obj = visual.transform.Find(text); ArmorElectricArcController armorElectricArcController = ((obj != null) ? ((Component)obj).GetComponent<ArmorElectricArcController>() : null); if ((Object)(object)armorElectricArcController == (Object)null) { GameObject val = new GameObject(text); val.transform.SetParent(visual.transform, false); val.transform.localPosition = Vector3.zero; armorElectricArcController = val.AddComponent<ArmorElectricArcController>(); } if (worldPosition.HasValue) { ((Component)armorElectricArcController).transform.position = worldPosition.Value; } Vector3 areaScale = ((slot == "Chest") ? new Vector3(0.38f, 0.32f, 0.24f) : ((slot == "Legs") ? new Vector3(0.32f, 0.4f, 0.22f) : new Vector3(0.28f, 0.28f, 0.28f))); armorElectricArcController.Configure(GetPotentialGlowColor(quality), areaScale); } } private static bool ApplyAnchoredArmorElectricity(VisEquipment equipment, int itemHash, int quality) { ZDO equipmentZdo = GetEquipmentZdo(equipment); ArmorQualities.TryGetValue(equipment, out var value); bool flag = (value != null && value.ChestHash == itemHash) || (equipmentZdo != null && equipmentZdo.GetInt(ZDOVars.s_chestItem, 0) == itemHash); bool flag2 = (value != null && value.LegHash == itemHash) || (equipmentZdo != null && equipmentZdo.GetInt(ZDOVars.s_legItem, 0) == itemHash); bool flag3 = (value != null && value.ShoulderHash == itemHash) || (equipmentZdo != null && equipmentZdo.GetInt(ZDOVars.s_shoulderItem, 0) == itemHash); bool flag4 = (value != null && value.UtilityHash == itemHash) || (equipmentZdo != null && equipmentZdo.GetInt(ZDOVars.s_utilityItem, 0) == itemHash); if (!flag && !flag2 && !flag3 && !flag4) { return false; } string slot = (flag ? "Chest" : (flag2 ? "Legs" : (flag3 ? "Cape" : "Utility"))); RemoveBodyArmorGlow(equipment, slot); if (quality < 5) { return true; } Transform val = FindArmorBone(equipment, !flag2); if ((Object)(object)val == (Object)null) { return true; } EnsureArmorElectricEffect(((Component)val).gameObject, quality, slot); return true; } private static bool IsArmorVisual(VisEquipment equipment, int itemHash) { if ((Object)(object)equipment == (Object)null || itemHash == 0) { return false; } if (ArmorQualities.TryGetValue(equipment, out var value) && (value.ChestHash == itemHash || value.LegHash == itemHash || value.HelmetHash == itemHash || value.ShoulderHash == itemHash || value.UtilityHash == itemHash)) { return true; } ZDO equipmentZdo = GetEquipmentZdo(equipment); if (equipmentZdo != null) { if (equipmentZdo.GetInt(ZDOVars.s_chestItem, 0) != itemHash && equipmentZdo.GetInt(ZDOVars.s_legItem, 0) != itemHash && equipmentZdo.GetInt(ZDOVars.s_helmetItem, 0) != itemHash && equipmentZdo.GetInt(ZDOVars.s_shoulderItem, 0) != itemHash) { return equipmentZdo.GetInt(ZDOVars.s_utilityItem, 0) == itemHash; } return true; } return false; } private static bool IsArmorItem(ItemData item) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 if (item?.m_shared == null) { return false; } ItemType itemType = item.m_shared.m_itemType; if ((int)itemType != 6 && (int)itemType != 7 && (int)itemType != 11 && (int)itemType != 17) { return (int)itemType == 18; } return true; } private static bool IsArmorPrefab(int itemHash) { ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(itemHash) : null); ItemDrop val = ((obj != null) ? obj.GetComponent<ItemDrop>() : null); if ((Object)(object)val != (Object)null) { return IsArmorItem(val.m_itemData); } return false; } private static bool IsFistWeaponPrefab(int itemHash) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(itemHash) : null); SharedData val = ((obj != null) ? obj.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared; if (val != null) { if ((int)val.m_itemType != 12) { return (int)val.m_skillType == 11; } return true; } return false; } private static bool IsShieldPrefab(int itemHash) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(itemHash) : null); ItemDrop val = ((obj != null) ? obj.GetComponent<ItemDrop>() : null); if (val?.m_itemData?.m_shared != null) { return (int)val.m_itemData.m_shared.m_itemType == 5; } return false; } private static FallbackParticleKind GetFallbackParticleKind(int itemHash) { if (IsShieldPrefab(itemHash)) { return FallbackParticleKind.Shield; } if (IsFistWeaponPrefab(itemHash)) { return FallbackParticleKind.Fist; } return FallbackParticleKind.None; } private static void UpdateFistHandFog(Transform hand, bool equipped, int quality) { if (!((Object)(object)hand == (Object)null)) { Transform val = hand.Find("PotentialDraught_FistFog"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } private static int GetItemHash(ItemData item) { if (!((Object)(object)item?.m_dropPrefab == (Object)null)) { return GetStableHashCode(((Object)item.m_dropPrefab).name); } return 0; } private static int GetStableHashCode(string value) { if (string.IsNullOrEmpty(value)) { return 0; } int num = 5381; int num2 = num; for (int i = 0; i < value.Length; i += 2) { num = ((num << 5) + num) ^ value[i]; if (i == value.Length - 1) { break; } num2 = ((num2 << 5) + num2) ^ value[i + 1]; } return num + num2 * 1566083941; } private static ZDO GetEquipmentZdo(VisEquipment equipment) { object? obj = VisEquipmentNetViewField?.GetValue(equipment); object? obj2 = ((obj is ZNetView) ? obj : null); if (obj2 == null) { return null; } return ((ZNetView)obj2).GetZDO(); } private static void RecordArmorQualities(VisEquipment equipment, ItemData chest, ItemData legs, ItemData helmet, ItemData shoulder, ItemData utility) { if (!((Object)(object)equipment == (Object)null)) { if (!ArmorQualities.TryGetValue(equipment, out var value)) { value = new ArmorQualityState(); ArmorQualities[equipment] = value; } value.ChestHash = GetItemHash(chest); value.ChestQuality = chest?.m_quality ?? 0; value.LegHash = GetItemHash(legs); value.LegQuality = legs?.m_quality ?? 0; value.HelmetHash = GetItemHash(helmet); value.HelmetQuality = helmet?.m_quality ?? 0; value.ShoulderHash = GetItemHash(shoulder); value.ShoulderQuality = shoulder?.m_quality ?? 0; value.UtilityHash = GetItemHash(utility); value.UtilityQuality = utility?.m_quality ?? 0; object? obj = VisEquipmentNetViewField?.GetValue(equipment); ZNetView val = (ZNetView)((obj is ZNetView) ? obj : null); ZDO val2 = ((val != null) ? val.GetZDO() : null); if (val2 != null && val.IsOwner()) { val2.Set("PotentialDraught_ChestQuality", value.ChestQuality); val2.Set("PotentialDraught_LegQuality", value.LegQuality); val2.Set("PotentialDraught_HelmetQuality", value.HelmetQuality); val2.Set("PotentialDraught_UtilityQuality", value.UtilityQuality); } } } private static int ResolveArmorQuality(VisEquipment equipment, int itemHash, int originalQuality) { if ((Object)(object)equipment == (Object)null || itemHash == 0) { return originalQuality; } int num = originalQuality; if (ArmorQualities.TryGetValue(equipment, out var value)) { if (value.ChestHash == itemHash) { num = Mathf.Max(num, value.ChestQuality); } if (value.LegHash == itemHash) { num = Mathf.Max(num, value.LegQuality); } if (value.HelmetHash == itemHash) { num = Mathf.Max(num, value.HelmetQuality); } if (value.ShoulderHash == itemHash) { num = Mathf.Max(num, value.ShoulderQuality); } if (value.UtilityHash == itemHash) { num = Mathf.Max(num, value.UtilityQuality); } } ZDO equipmentZdo = GetEquipmentZdo(equipment); if (equipmentZdo != null) { if (equipmentZdo.GetInt(ZDOVars.s_chestItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_ChestQuality", 0)); } if (equipmentZdo.GetInt(ZDOVars.s_legItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_LegQuality", 0)); } if (equipmentZdo.GetInt(ZDOVars.s_helmetItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_HelmetQuality", 0)); } if (equipmentZdo.GetInt(ZDOVars.s_shoulderItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt(ZDOVars.s_shoulderItemQuality, 0)); } if (equipmentZdo.GetInt(ZDOVars.s_utilityItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_UtilityQuality", 0)); } } return num; } private static void RecordHandQualities(VisEquipment equipment, ItemData rightHand, ItemData leftHand, ItemData leftBack, ItemData rightBack) { if (!((Object)(object)equipment == (Object)null)) { object? obj = VisEquipmentNetViewField?.GetValue(equipment); ZNetView val = (ZNetView)((obj is ZNetView) ? obj : null); ZDO val2 = ((val != null) ? val.GetZDO() : null); if (val2 != null && val.IsOwner()) { val2.Set("PotentialDraught_LeftHandQuality", leftHand?.m_quality ?? 0); val2.Set("PotentialDraught_RightHandQuality", rightHand?.m_quality ?? 0); val2.Set("PotentialDraught_LeftBackQuality", leftBack?.m_quality ?? 0); val2.Set("PotentialDraught_RightBackQuality", rightBack?.m_quality ?? 0); } } } private static int ResolveEquipmentQuality(VisEquipment equipment, int itemHash, int originalQuality) { int num = ResolveArmorQuality(equipment, itemHash, originalQuality); ZDO equipmentZdo = GetEquipmentZdo(equipment); if (equipmentZdo == null || itemHash == 0) { return num; } if (equipmentZdo.GetInt(ZDOVars.s_leftItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_LeftHandQuality", equipmentZdo.GetInt(ZDOVars.s_leftItemQuality, 0))); } if (equipmentZdo.GetInt(ZDOVars.s_rightItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_RightHandQuality", equipmentZdo.GetInt(ZDOVars.s_rightItemQuality, 0))); } if (equipmentZdo.GetInt(ZDOVars.s_leftBackItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_LeftBackQuality", equipmentZdo.GetInt(ZDOVars.s_leftBackItemQuality, 0))); } if (equipmentZdo.GetInt(ZDOVars.s_rightBackItem, 0) == itemHash) { num = Mathf.Max(num, equipmentZdo.GetInt("PotentialDraught_RightBackQuality", equipmentZdo.GetInt(ZDOVars.s_rightBackItemQuality, 0))); } return num; } private static bool HasPotionEffect(Player player) { if ((Object)(object)player != (Object)null) { CustomStatusEffect potentialStatusEffect = PotentialStatusEffect; if ((Object)(object)((potentialStatusEffect != null) ? potentialStatusEffect.StatusEffect : null) != (Object)null) { return ((Character)player).GetSEMan().HaveStatusEffect(PotentialStatusEffect.StatusEffect.NameHash()); } } return false; } private static bool HasAdminPotionEffect(Player player) { if ((Object)(object)player != (Object)null) { CustomStatusEffect adminPotentialStatusEffect = AdminPotentialStatusEffect; if ((Object)(object)((adminPotentialStatusEffect != null) ? adminPotentialStatusEffect.StatusEffect : null) != (Object)null) { return ((Character)player).GetSEMan().HaveStatusEffect(AdminPotentialStatusEffect.StatusEffect.NameHash()); } } return false; } private static bool IsAdminPotionItem(ItemData item) { if (item?.m_shared == null) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "PotionPotentialDraughtAdmin") { return true; } CustomStatusEffect adminPotentialStatusEffect = AdminPotentialStatusEffect; if ((Object)(object)((adminPotentialStatusEffect != null) ? adminPotentialStatusEffect.StatusEffect : null) != (Object)null) { return (Object)(object)item.m_shared.m_consumeStatusEffect == (Object)(object)AdminPotentialStatusEffect.StatusEffect; } return false; } private Sprite LoadEmbeddedIcon() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PotentialDraught.Assets.potential_draught_icon.png"); if (stream == null) { throw new FileNotFoundException("Embedded icon resource not found: PotentialDraught.Assets.potential_draught_icon.png"); } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num == 0) { break; } } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = "PotentialDraughtIcon", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(val, array, false)) { throw new InvalidDataException("Could not decode the embedded potion icon."); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } private static void RegisterAdminPotionRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _registeredAdminPotionRpcInstance) { instance.Register<long>("PotentialDraught_RequestAdminPotionPurge", (Action<long, long>)RPC_RequestAdminPotionPurge); instance.Register<long>("PotentialDraught_ExecuteAdminPotionPurge", (Action<long, long>)RPC_ExecuteAdminPotionPurge); instance.Register<long>("PotentialDraught_RequestAdminPotionPermission", (Action<long, long>)RPC_RequestAdminPotionPermission); instance.Register<long, string, bool>("PotentialDraught_SetAdminPotionPermission", (Action<long, long, string, bool>)RPC_SetAdminPotionPermission); instance.Register<long, bool>("PotentialDraught_SyncAdminPotionPermission", (Action<long, long, bool>)RPC_SyncAdminPotionPermission); instance.Register<long, string>("PotentialDraught_AdminPotionCommandResult", (Action<long, long, string>)RPC_AdminPotionCommandResult); _registeredAdminPotionRpcInstance = instance; } } private static IEnumerator AdminPotionPermissionServerReceive(long sender, ZPackage package) { if (package != null && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { byte b = package.ReadByte(); switch (b) { case 1: RPC_RequestAdminPotionPermission(sender, package.ReadLong()); break; case 2: RPC_SetAdminPotionPermission(sender, package.ReadLong(), package.ReadString(), package.ReadBool()); break; case 5: SetMaximumItemQualityOnServer(sender, package.ReadLong(), package.ReadInt()); break; case 7: ExecuteAdminPotionPurgeOnServer(sender, package.ReadLong()); break; default: ((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"Ignored unknown admin-potion server message {b} from {sender}."); break; } yield return null; } } private static IEnumerator AdminPotionPermissionClientReceive(long sender, ZPackage package) { if (package == null) { yield break; } byte b = package.ReadByte(); switch (b) { case 3: RPC_SyncAdminPotionPermission(sender, package.ReadLong(), package.ReadBool()); break; case 4: RPC_AdminPotionCommandResult(sender, package.ReadLong(), package.ReadString()); break; case 6: { long num = package.ReadLong(); int num2 = package.ReadInt(); if ((Object)(object)Player.m_localPlayer != (Object)null && (num == 0L || Player.m_localPlayer.GetPlayerID() == num)) { _synchronizedMaximumItemQuality = Mathf.Max(1, num2); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Synchronized Forge maximum item quality: {_synchronizedMaximumItemQuality}."); } break; } case 8: RemoveAdminPotionsFromLocalPlayer(package.ReadLong()); break; default: ((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"Ignored unknown admin-potion client message {b} from {sender}."); break; } yield return null; } private static void SendAdminPotionRequestToServer(ZPackage package) { if (_adminPotionPermissionRpc != null && ZRoutedRpc.instance != null) { long serverPeerUid = GetServerPeerUid(); ((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"Sending admin-potion request to routed server peer {serverPeerUid}."); _adminPotionPermissionRpc.SendPackage(serverPeerUid, package); } } private static void BroadcastAdminPotionPackage(ZPackage package) { if (_adminPotionPermissionRpc != null && !((Object)(object)ZNet.instance == (Object)null)) { _adminPotionPermissionRpc.SendPackage(new List<ZNetPeer>(ZNet.instance.GetConnectedPeers()), package); } } private static void SendAdminPotionPermissionSync(long playerId, bool allowed) { //IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write((byte)3); val.Write(playerId); val.Write(allowed); BroadcastAdminPotionPackage(val); if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerID() == playerId) { _localAdminPotionUseAllowed = allowed; } } private static void SendMaximumItemQualitySync(long targetPlayerId) { //IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write((byte)6); val.Write(targetPlayerId); val.Write(MaximumItemQuality); BroadcastAdminPotionPackage(val); } private static int RemoveAdminPotionsFromLocalPlayer(long requestingPlayerId) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.GetPlayerID() == requestingPlayerId) { return 0; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory == null) { return 0; } int num = RemoveAdminPotionItems(inventory); if (num > 0) { ((Character)localPlayer).Message((MessageType)2, $"An administrator removed {num} Absolute Potential potion" + ((num == 1) ? string.Empty : "s") + " from your inventory.", 0, (Sprite)null, false); ((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Removed {num} admin potion(s) from local player '{localPlayer.GetPlayerName()}'."); } return num; } private static int RemoveAdminPotionItems(Inventory inventory) { if (inventory == null) { return 0; } List<ItemData> list = new List<ItemData>(inventory.GetAllItems()); int num = 0; foreach (ItemData item in list) { if (IsAdminPotionItem(item)) { num += Mathf.Max(1, item.m_stack); inventory.RemoveItem(item); } } return num; } private static int PurgeAdminPotionsFromWorldStorage() { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown int num = 0; Container[] array = Object.FindObjectsOfType<Container>(); foreach (Container val in array) { int num2 = RemoveAdminPotionItems(val.GetInventory()); if (num2 > 0) { num += num2; ContainerSaveMethod?.Invoke(val, null); } } if (!(ZdoObjectsByIdField?.GetValue(ZDOMan.instance) is IDictionary dictionary)) { return num; } foreach (object value in dictionary.Values) { ZDO val2 = (ZDO)((value is ZDO) ? value : null); if (val2 == null) { continue; } string text = val2.GetString(ZDOVars.s_items, string.Empty); if (string.IsNullOrEmpty(text)) { continue; } try { Inventory val3 = new Inventory("PotentialDraught_Purge", (Sprite)null, 8, 100); val3.Load(new ZPackage(text)); int num3 = RemoveAdminPotionItems(val3); if (num3 > 0) { ZPackage val4 = new ZPackage(); val3.Save(val4); val2.Set(ZDOVars.s_items, val4.GetBase64()); num += num3; } } catch (Exception ex) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Could not inspect a stored world inventory during admin-potion purge: " + ex.Message)); } } return num; } private static void ExecuteAdminPotionPurgeOnServer(long sender, long requestingPlayerId) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } if (!IsAdminOrHostPeer(sender, requestingPlayerId)) { SendAdminPotionCommandResult(requestingPlayerId, "The server rejected the purge: host or administrator access is required."); return; } int num = 0; foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers()) { if (connectedPeer != null && connectedPeer.m_playerID != requestingPlayerId) { num++; } } if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerID() != requestingPlayerId) { num++; } RemoveAdminPotionsFromLocalPlayer(requestingPlayerId); int num2 = PurgeAdminPotionsFromWorldStorage(); ZPackage val = new ZPackage(); val.Write((byte)8); val.Write(requestingPlayerId); BroadcastAdminPotionPackage(val); SendAdminPotionCommandResult(requestingPlayerId, $"Purge complete: removed {num2} admin potion" + ((num2 == 1) ? string.Empty : "s") + " from world storage and delivered the inventory purge to " + string.Format("{0} other connected player{1}.", num, (num == 1) ? string.Empty : "s")); } private static void SetMaximumItemQualityOnServer(long sender, long requestingPlayerId, int requestedQuality) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { if (!IsAdminOrHostPeer(sender, requestingPlayerId)) { SendAdminPotionCommandResult(requestingPlayerId, "The server rejected the command: host or administrator access is required."); return; } if (requestedQuality < 1) { SendAdminPotionCommandResult(requestingPlayerId, "Maximum item quality must be a positive whole number."); return; } _maximumItemQualityConfig.Value = requestedQuality; ((BaseUnityPlugin)Instance).Config.Save(); SendMaximumItemQualitySync(0L); SendAdminPotionCommandResult(requestingPlayerId, $"Maximum item quality is now {requestedQuality}. Creature scaling will adjust automatically."); } } private static void LoadAllowedAdminPotionPlayerIdentities() { AllowedAdminPotionPlayerIdentities.Clear(); string text = _allowedAdminPotionPlayerIdentitiesConfig?.Value; if (string.IsNullOrWhiteSpace(text)) { return; } string[] array = text.Split('|'); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (!string.IsNullOrEmpty(text2)) { AllowedAdminPotionPlayerIdentities.Add(text2); } } } private static void SaveAllowedAdminPotionPlayerIdentities() { List<string> list = new List<string>(); foreach (string allowedAdminPotionPlayerIdentity in AllowedAdminPotionPlayerIdentities) { list.Add(allowedAdminPotionPlayerIdentity); } list.Sort(StringComparer.OrdinalIgnoreCase); _allowedAdminPotionPlayerIdentitiesConfig.Value = string.Join("|", list.ToArray()); ((BaseUnityPlugin)Instance).Config.Save(); } private unsafe static string GetPeerIdentity(ZNetPeer peer) { if (peer == null) { return string.Empty; } if (TryGetPeerPlatformUserId(peer, out var platformUserId)) { return ((object)(*(PlatformUserID*)(&platformUserId))/*cast due to .constrained prefix*/).ToString(); } object? obj = ZNetPeerSocketField?.GetValue(peer); object? obj2 = ((obj is ISocket) ? obj : null); string text = ((obj2 == null) ? null : ((ISocket)obj2).GetHostName()?.Trim()); if (!string.IsNullOrEmpty(text)) { return text; } if (!string.IsNullOrWhiteSpace(peer.m_playfabId)) { return "playfab:" + peer.m_playfabId.Trim(); } if (peer.m_uid == 0L) { return string.Empty; } return "peer:" + peer.m_uid; } private static bool TryGetPeerPlatformUserId(ZNetPeer peer, out PlatformUserID platformUserId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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) platformUserId = PlatformUserID.None; ISocket obj = peer?.m_socket; ZPlayFabSocket val = (ZPlayFabSocket)(object)((obj is ZPlayFabSocket) ? obj : null); if (val == null || PlayFabSocketPlatformUserIdField == null) { return false; } if (!(PlayFabSocketPlatformUserIdField.GetValue(val) is PlatformUserID val2) || !((PlatformUserID)(ref val2)).IsValid) { return false; } platformUserId = val2; return true; } private static long GetServerPeerUid() { if (ZRoutedRpc.instance != null && RoutedRpcGetServerPeerIdMethod != null && RoutedRpcGetServerPeerIdMethod.Invoke(ZRoutedRpc.instance, null) is long num && num != 0L) { return num; } if ((Object)(object)ZNet.instance == (Object)null) { return 0L; } if (ZNet.instance.IsServer()) { return ZNet.GetUID(); } return ZNet.instance.GetServerPeer()?.m_uid ?? 0; } private static ZNetPeer FindPeerByPlayerId(long playerId) { if ((Object)(object)ZNet.instance == (Object)null || playerId == 0L) { return null; } foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers()) { if (connectedPeer != null && connectedPeer.m_playerID == playerId) { return connectedPeer; } } return null; } private static bool IsAdminOrHostPeer(long sender, long playerId = 0L) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return false; } if (sender == ZNet.GetUID() || sender == GetServerPeerUid()) { return true; } if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerID() == playerId) { return true; } ZNetPeer val = ZNet.instance.GetPeer(sender) ?? FindPeerByPlayerId(playerId); if (TryGetPeerPlatformUserId(val, out var platformUserId) && ZNet.instance.PlayerIsAdmin(platformUserId)) { return true; } object? obj = ZNetPeerSocketField?.GetValue(val); ISocket val2 = (ISocket)((obj is ISocket) ? obj : null); if (val2 != null) { return ZNet.instance.IsAdmin(val2.GetHostName()); } return false; } private static bool IsAdminPotionAllowed(long sender, long playerId) { if (IsAdminOrHostPeer(sender, playerId)) { return true; } ZNet instance = ZNet.instance; string peerIdentity = GetPeerIdentity(((instance != null) ? instance.GetPeer(sender) : null) ?? FindPeerByPlayerId(playerId)); if (!string.IsNullOrEmpty(peerIdentity)) { return AllowedAdminPotionPlayerIdentities.Contains(peerIdentity); } return false; } private static void RPC_RequestAdminPotionPurge(long sender, long requestingPlayerId) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && ZRoutedRpc.instance != null) { if (!IsAdminOrHostPeer(sender, requestingPlayerId)) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"Rejected unauthorized admin-potion purge request from routed peer {sender}."); return; } ZRoutedRpc.instance.InvokeRoutedRPC(0L, "PotentialDr