Decompiled source of OpenSaysMe v1.2.0

OpenSaysMe.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using OpenSaysMe.Utils;
using ServerSync;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("OpenSaysMe")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("OpenSaysMe")]
[assembly: AssemblyTitle("OpenSaysMe")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 OpenSaysMe
{
	public enum AutoUseType
	{
		Disabled,
		OpenClose,
		Close
	}
	public class InvertedDoorConfig
	{
		public string ModGUID;

		public List<string> InvertedDoorNames;
	}
	[BepInPlugin("OpenSaysMe", "OpenSaysMe", "1.2.0")]
	public class OpenSaysMePlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <RPC_SetDoorAutoUseType>d__24 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZPackage package;

			public long sender;

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

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

			[DebuggerHidden]
			public <RPC_SetDoorAutoUseType>d__24(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				if (!ZNet.instance.IsServer())
				{
					return false;
				}
				ZDOID val = package.ReadZDOID();
				int num = package.ReadInt();
				ZDO zDO = ZDOMan.instance.GetZDO(val);
				if (zDO != null)
				{
					zDO.Set(AutoUseTypeZDO, num);
					Logger.LogInfo((object)$"RPC_SetDoorAutoUseType: sender={sender}, doorZDOID={val}, autoUseType={num}");
				}
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <RPC_SetDoorAutoUseTypeClient>d__25 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

			[DebuggerHidden]
			public <RPC_SetDoorAutoUseTypeClient>d__25(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				return false;
			}

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

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

		public static readonly string IgnoreAutoUseZDO_DEPRECATED = "OpenSaysMe_ignoreAutoUse";

		public static readonly string AutoUseTypeZDO = "OpenSaysMe_AutoUseType";

		private static ConfigSync configSync;

		private static ConfigEntry<bool> _configLocked;

		private static ConfigEntry<bool> _enableAutoUse;

		private static ConfigEntry<float> _autoUseRadius;

		private static ConfigEntry<AutoUseType> _defaultAutoUseType;

		private static ConfigEntry<string> _invertedDoorsRaw;

		public static CustomRPC Rpc_SetDoorAutoUseType;

		public static CustomRPC Rpc_SyncInvertedDoors;

		internal static ManualLogSource Logger;

		private readonly Harmony _harmony = new Harmony("OpenSaysMe");

		public static bool EnableAutoUse => _enableAutoUse.Value;

		public static float AutoUseRadius => _autoUseRadius.Value;

		public static AutoUseType DefaultAutoUseType => _defaultAutoUseType.Value;

		public static List<InvertedDoorConfig> InvertedDoorsData { get; private set; }

		private void Awake()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0066: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			_setupConfig();
			LoadInvertedDoorsFromConfig();
			_invertedDoorsRaw.SettingChanged += delegate
			{
				LoadInvertedDoorsFromConfig();
			};
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			Rpc_SetDoorAutoUseType = NetworkManager.Instance.AddRPC("SetDoorAutoUseType", new CoroutineHandler(RPC_SetDoorAutoUseType), new CoroutineHandler(RPC_SetDoorAutoUseTypeClient));
			Logger.LogInfo((object)"Plugin OpenSaysMe is loaded!");
		}

		private void LoadInvertedDoorsFromConfig()
		{
			InvertedDoorsData = new List<InvertedDoorConfig>();
			if (string.IsNullOrWhiteSpace(_invertedDoorsRaw.Value))
			{
				Logger.LogWarning((object)"No inverted doors configured.");
				return;
			}
			string[] array = _invertedDoorsRaw.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string[] array2 = text.Split(new char[1] { '=' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length != 2)
				{
					Logger.LogWarning((object)("Invalid inverted door entry: " + text));
					continue;
				}
				string modGUID = array2[0].Trim();
				string[] collection = array2[1].Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				InvertedDoorsData.Add(new InvertedDoorConfig
				{
					ModGUID = modGUID,
					InvertedDoorNames = new List<string>(collection)
				});
			}
			Logger.LogInfo((object)$"Loaded {InvertedDoorsData.Count} inverted door config entries from cfg.");
		}

		[IteratorStateMachine(typeof(<RPC_SetDoorAutoUseType>d__24))]
		private IEnumerator RPC_SetDoorAutoUseType(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RPC_SetDoorAutoUseType>d__24(0)
			{
				sender = sender,
				package = package
			};
		}

		[IteratorStateMachine(typeof(<RPC_SetDoorAutoUseTypeClient>d__25))]
		private IEnumerator RPC_SetDoorAutoUseTypeClient(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RPC_SetDoorAutoUseTypeClient>d__25(0);
		}

		private void _setupConfig()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			configSync = new ConfigSync("OpenSaysMe")
			{
				DisplayName = "OpenSaysMe",
				CurrentVersion = "1.2.0",
				MinimumRequiredVersion = "1.2.0"
			};
			_configLocked = config("General", "Lock Configuration", value: true, "If on, the configuration is locked and can be changed by server admins only.");
			configSync.AddLockingConfigEntry<bool>(_configLocked);
			_enableAutoUse = config("Settings", "Enable Auto Use", value: true, "Enable automatic door interaction. Server-synced.");
			_autoUseRadius = config("Settings", "Auto Use Radius", 5f, new ConfigDescription("The distance a player needs to be at to activate auto use. Server-synced.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			_defaultAutoUseType = config("Settings", "Default Auto Use Type", AutoUseType.OpenClose, "Default auto use type for newly created doors. Server-synced.");
			_invertedDoorsRaw = config("Inverted Doors", "Inverted Door Prefabs", "odinplus.plugins.odinskingdom=$GB_Stone_RoundWall_Door,$GB_Wood_RoundWall_Door", "Format: ModGUID=Prefab1,Prefab2;ModGUID2=PrefabA. Server-synced.");
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
			((OwnConfigEntryBase)configSync.AddConfigEntry<T>(val)).SynchronizedConfig = synchronizedSetting;
			return val;
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "OpenSaysMe";

		public const string PLUGIN_NAME = "OpenSaysMe";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}
namespace OpenSaysMe.Utils
{
	public static class DoorUtil
	{
		private static readonly MethodInfo CanInteractMethod = AccessTools.Method(typeof(Door), "CanInteract", (Type[])null, (Type[])null);

		public static bool CanInteract(Door door)
		{
			if (!Object.op_Implicit((Object)(object)door))
			{
				return false;
			}
			return (bool)CanInteractMethod.Invoke(door, null);
		}

		public static bool IsOpen(Door door)
		{
			int @int = ((Component)door).GetComponent<ZNetView>().GetZDO().GetInt(ZDOVars.s_state, 0);
			if (!door.m_invertedOpenClosedText)
			{
				return @int == 0;
			}
			return @int != 0;
		}
	}
	public static class PlayerUtil
	{
		private static readonly MethodInfo TakeInputMethod = AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null);

		public static bool TakeInput(Player player)
		{
			return (bool)TakeInputMethod.Invoke(player, null);
		}
	}
	public static class PrivateAreaUtil
	{
		private static readonly MethodInfo IsEnabledMethod = AccessTools.Method(typeof(PrivateArea), "IsEnabled", (Type[])null, (Type[])null);

		private static readonly MethodInfo IsInsideMethod = AccessTools.Method(typeof(PrivateArea), "IsInside", (Type[])null, (Type[])null);

		private static readonly MethodInfo IsPermittedMethod = AccessTools.Method(typeof(PrivateArea), "IsPermitted", (Type[])null, (Type[])null);

		private static readonly FieldInfo m_allAreasField = AccessTools.Field(typeof(PrivateArea), "m_allAreas");

		private static readonly FieldInfo m_piece = AccessTools.Field(typeof(PrivateArea), "m_piece");

		private static List<PrivateArea> AllAreas => m_allAreasField.GetValue(null) as List<PrivateArea>;

		public static bool CanAccess(Player player, Vector3 point)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			foreach (PrivateArea allArea in AllAreas)
			{
				if (IsEnabled(allArea) && IsInside(allArea, point) && !HaveAccess(allArea, player))
				{
					return false;
				}
			}
			return true;
		}

		public static bool IsEnabled(PrivateArea area)
		{
			return (bool)IsEnabledMethod.Invoke(area, null);
		}

		public static bool IsInside(PrivateArea area, Vector3 point)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return (bool)IsInsideMethod.Invoke(area, new object[2] { point, 0 });
		}

		public static bool IsPermitted(PrivateArea area, Player player)
		{
			return (bool)IsPermittedMethod.Invoke(area, new object[1] { player.GetPlayerID() });
		}

		public static bool HaveAccess(PrivateArea area, Player player)
		{
			if (player.GetPlayerID() != GetPiece(area).GetCreator())
			{
				return IsPermitted(area, player);
			}
			return true;
		}

		public static Piece GetPiece(PrivateArea area)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (Piece)m_piece.GetValue(area);
		}
	}
}
namespace OpenSaysMe.Patches
{
	[HarmonyPatch(typeof(Door))]
	public static class DoorPatch
	{
		private static readonly HashSet<Door> Doors = new HashSet<Door>();

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		public static void GetHoverTextPostfix(Door __instance, ref string __result)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			ZNetView val = default(ZNetView);
			if (OpenSaysMePlugin.EnableAutoUse && ((Component)__instance).TryGetComponent<ZNetView>(ref val) && DoorUtil.CanInteract(__instance) && (!__instance.m_checkGuardStone || PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false)))
			{
				string text = (AutoUseType)val.GetZDO().GetInt(OpenSaysMePlugin.AutoUseTypeZDO, 0) switch
				{
					AutoUseType.Disabled => "Enable auto open and close", 
					AutoUseType.OpenClose => "Enable auto close only", 
					AutoUseType.Close => "Disable auto use", 
					_ => "", 
				};
				__result = __result + "\n" + Localization.instance.Localize("[<color=yellow><b>$KEY_Run</b></color> + <color=yellow><b>$KEY_Use</b></color>]") + " " + text;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void AwakePostfix(Door __instance)
		{
			ZNetView val = default(ZNetView);
			if (OpenSaysMePlugin.EnableAutoUse && ((Component)__instance).TryGetComponent<ZNetView>(ref val) && val.IsValid())
			{
				bool @bool = val.GetZDO().GetBool(OpenSaysMePlugin.IgnoreAutoUseZDO_DEPRECATED, false);
				bool num = val.GetZDO().RemoveInt(OpenSaysMePlugin.IgnoreAutoUseZDO_DEPRECATED);
				AutoUseType autoUseType = (AutoUseType)val.GetZDO().GetInt(OpenSaysMePlugin.AutoUseTypeZDO, (int)OpenSaysMePlugin.DefaultAutoUseType);
				if (num && @bool)
				{
					autoUseType = AutoUseType.Disabled;
				}
				val.GetZDO().Set(OpenSaysMePlugin.AutoUseTypeZDO, (int)autoUseType);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdateState")]
		public static void UpdateStatePostfix(Door __instance)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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)
			if (!OpenSaysMePlugin.EnableAutoUse || !Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return;
			}
			float autoUseRadius = OpenSaysMePlugin.AutoUseRadius;
			Player closestPlayer = Player.GetClosestPlayer(((Component)__instance).transform.position, autoUseRadius + 1f);
			if (Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)__instance).transform.position) > autoUseRadius && !Doors.Contains(__instance))
			{
				return;
			}
			ZNetView val = default(ZNetView);
			if ((Object)(object)closestPlayer != (Object)null && (Object)(object)closestPlayer != (Object)(object)Player.m_localPlayer && PrivateAreaUtil.CanAccess(closestPlayer, ((Component)__instance).transform.position))
			{
				if (Doors.Contains(__instance))
				{
					OpenSaysMePlugin.Logger.LogDebug((object)("Not the closest permitted player, removing " + _getDoorID(__instance)));
					Doors.Remove(__instance);
				}
			}
			else if (((Component)__instance).TryGetComponent<ZNetView>(ref val) && val.IsValid())
			{
				Doors.Add(__instance);
				bool flag = DoorUtil.CanInteract(__instance);
				AutoUseType @int = (AutoUseType)val.GetZDO().GetInt(OpenSaysMePlugin.AutoUseTypeZDO, 0);
				if (@int != 0 && flag && (!__instance.m_checkGuardStone || PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false)))
				{
					int int2 = val.GetZDO().GetInt(ZDOVars.s_state, 0);
					float num = Vector3.Distance(((Component)__instance).transform.position, ((Component)Player.m_localPlayer).transform.position);
					bool flag2 = (__instance.m_invertedOpenClosedText ? (int2 != 0) : (int2 == 0));
					bool flag3 = (__instance.m_invertedOpenClosedText ? (int2 == 0) : (int2 != 0));
					bool flag4 = num <= autoUseRadius;
					bool flag5 = num >= autoUseRadius;
					if (flag4 && flag2 && @int == AutoUseType.OpenClose)
					{
						__instance.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
					}
					else if (flag5 && flag3 && Doors.Contains(__instance))
					{
						OpenSaysMePlugin.Logger.LogDebug((object)("Closing door " + _getDoorID(__instance)));
						__instance.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
						Doors.Remove(__instance);
					}
				}
			}
			else
			{
				OpenSaysMePlugin.Logger.LogDebug((object)("No ZNetView " + _getDoorID(__instance)));
				Doors.Remove(__instance);
			}
		}

		private static string _getDoorID(Door door)
		{
			return $"{((door != null) ? new int?(((Object)((Component)door).gameObject).GetInstanceID()) : null)}";
		}
	}
	[HarmonyPatch(typeof(Door), "Awake")]
	[HarmonyPriority(0)]
	public static class DoorPatch_InvertedDoorFix
	{
		[HarmonyPostfix]
		public static void AwakePostfix(Door __instance)
		{
			foreach (InvertedDoorConfig invertedDoorsDatum in OpenSaysMePlugin.InvertedDoorsData)
			{
				if (Chainloader.PluginInfos.ContainsKey(invertedDoorsDatum.ModGUID) && invertedDoorsDatum.InvertedDoorNames.Contains(__instance.m_name))
				{
					__instance.m_invertedOpenClosedText = true;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	public static class PlayerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Interact")]
		public static bool InteractPrefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			if (!OpenSaysMePlugin.EnableAutoUse)
			{
				return true;
			}
			Door componentInParent = go.GetComponentInParent<Door>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return true;
			}
			ZNetView val = default(ZNetView);
			if (PlayerUtil.TakeInput(__instance) && !Hud.InRadial() && (!componentInParent.m_checkGuardStone || PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false)) && ((Component)componentInParent).TryGetComponent<ZNetView>(ref val))
			{
				AutoUseType @int = (AutoUseType)val.GetZDO().GetInt(OpenSaysMePlugin.AutoUseTypeZDO, 0);
				bool num = ZInput.GetButton("Run") && ZInput.GetButtonDown("Use");
				bool flag = ZInput.GetButton("Use") && ZInput.GetButtonDown("Use");
				if (num)
				{
					ZPackage val2 = new ZPackage();
					val2.Write(val.GetZDO().m_uid);
					val2.Write((int)((@int != AutoUseType.Close) ? (@int + 1) : AutoUseType.Disabled));
					OpenSaysMePlugin.Rpc_SetDoorAutoUseType.SendPackage(ZNet.instance.GetServerPeer().m_uid, val2);
					return false;
				}
				if (flag)
				{
					bool flag2 = DoorUtil.IsOpen(componentInParent);
					if (@int != 0 && ((@int == AutoUseType.Close && !flag2) || @int != AutoUseType.Close))
					{
						ZPackage val3 = new ZPackage();
						val3.Write(val.GetZDO().m_uid);
						val3.Write(0);
						OpenSaysMePlugin.Rpc_SetDoorAutoUseType.SendPackage(ZNet.instance.GetServerPeer().m_uid, val3);
					}
				}
			}
			return true;
		}
	}
}