Decompiled source of Observe v1.0.0

plugins/Marioalexsan.Observe.dll

Decompiled 3 hours ago
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Compression;
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 CodeTalker;
using CodeTalker.Networking;
using CodeTalker.Packets;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Nessie.ATLYSS.EasySettings;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Marioalexsan.Observe")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+54c297f074d346d0806ff7bfec988dda2bd7964d")]
[assembly: AssemblyProduct("Observe")]
[assembly: AssemblyTitle("Marioalexsan.Observe")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 Marioalexsan.Observe
{
	internal class LookPacket : BinaryPacketBase
	{
		private const string Signature = "Marioalexsan.Observe.LookPacket";

		public Quaternion CameraRotation;

		public uint TargetNetId;

		public bool IgnoreCamera;

		public bool IsValid = true;

		public static readonly LookPacket Instance = new LookPacket();

		public override string PacketSignature => "Marioalexsan.Observe.LookPacket";

		public override byte[] Serialize()
		{
			byte[] array = new byte[32];
			Span<byte> destination = array.AsSpan();
			BinaryPrimitives.TryWriteInt32LittleEndian(destination, BitConverter.SingleToInt32Bits(CameraRotation.x));
			ref Span<byte> reference = ref destination;
			BinaryPrimitives.TryWriteInt32LittleEndian(reference.Slice(4, reference.Length - 4), BitConverter.SingleToInt32Bits(CameraRotation.y));
			reference = ref destination;
			BinaryPrimitives.TryWriteInt32LittleEndian(reference.Slice(8, reference.Length - 8), BitConverter.SingleToInt32Bits(CameraRotation.z));
			reference = ref destination;
			BinaryPrimitives.TryWriteInt32LittleEndian(reference.Slice(12, reference.Length - 12), BitConverter.SingleToInt32Bits(CameraRotation.w));
			reference = ref destination;
			BinaryPrimitives.TryWriteUInt32LittleEndian(reference.Slice(16, reference.Length - 16), TargetNetId);
			reference = ref destination;
			BitConverter.TryWriteBytes(reference.Slice(17, reference.Length - 17), IgnoreCamera);
			return array;
		}

		public override void Deserialize(byte[] data)
		{
			if (data.Length < 32)
			{
				IsValid = false;
				return;
			}
			Span<byte> span = data.AsSpan();
			CameraRotation.x = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(span));
			ref Quaternion cameraRotation = ref CameraRotation;
			ref Span<byte> reference = ref span;
			cameraRotation.y = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(reference.Slice(4, reference.Length - 4)));
			ref Quaternion cameraRotation2 = ref CameraRotation;
			reference = ref span;
			cameraRotation2.z = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(reference.Slice(8, reference.Length - 8)));
			ref Quaternion cameraRotation3 = ref CameraRotation;
			reference = ref span;
			cameraRotation3.w = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(reference.Slice(12, reference.Length - 12)));
			reference = ref span;
			TargetNetId = BinaryPrimitives.ReadUInt32LittleEndian(reference.Slice(16, reference.Length - 16));
			reference = ref span;
			IgnoreCamera = BitConverter.ToBoolean(reference.Slice(17, reference.Length - 17));
		}
	}
	[BepInPlugin("Marioalexsan.Observe", "Observe", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ObservePlugin : BaseUnityPlugin
	{
		private struct PlayerLookInfo
		{
			public Quaternion CameraRotation;

			public PlayerRaceModel RaceModel;

			public Transform Head;

			public Quaternion LastHeadRotation;

			public bool IgnoreCamera;
		}

		private struct SentPlayerInfo
		{
			public Quaternion CameraRotation;

			public bool IgnoreCamera;

			public DateTime Timestamp;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__17_0;

			public static Predicate<Player> <>9__20_0;

			internal void <RegisterEasySettings>b__17_0()
			{
				Settings.ModTab.AddHeader("Observe");
				Settings.ModTab.AddToggle("Enabled", Enabled);
				Settings.ModTab.AddToggle("Ignore Camera (self)", IgnoreCameraSetting);
				Settings.ModTab.AddToggle("Enable Networking", EnableNetworking);
			}

			internal bool <HandlePlayerCleanup>b__20_0(Player player)
			{
				return !Object.op_Implicit((Object)(object)player);
			}
		}

		private readonly Harmony _harmony = new Harmony("Marioalexsan.Observe");

		private readonly Dictionary<Player, PlayerLookInfo> _cachedPlayerData = new Dictionary<Player, PlayerLookInfo>();

		private readonly Dictionary<ulong, SentPlayerInfo> MultiplayerData = new Dictionary<ulong, SentPlayerInfo>();

		private static ConfigEntry<bool> Enabled = null;

		private static ConfigEntry<bool> IgnoreCameraSetting = null;

		private static ConfigEntry<bool> EnableNetworking = null;

		private bool _lastSendEnableState = false;

		private bool _shouldSendCurrentState = false;

		private static TimeSpan RefreshDirectionAccumulator = TimeSpan.Zero;

		private static TimeSpan PacketSendCooldown = TimeSpan.Zero;

		internal static HashSet<Player> Players { get; } = new HashSet<Player>();


		public ObservePlugin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable mod functionality completely.");
			IgnoreCameraSetting = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IgnoreCamera", false, "While active, makes your player look forward instead of using the camera direction.");
			EnableNetworking = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableNetworking", true, "Enable sending/receiving camera directions to/from people with the mod installed.");
		}

		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			_harmony.PatchAll();
			if (Chainloader.PluginInfos.ContainsKey("EasySettings"))
			{
				RegisterEasySettings();
			}
			CodeTalkerNetwork.RegisterBinaryListener<LookPacket>(new BinaryPacketListener(HandleNetworkSyncFromOthers));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private void RegisterEasySettings()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			UnityEvent onInitialized = Settings.OnInitialized;
			object obj = <>c.<>9__17_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					Settings.ModTab.AddHeader("Observe");
					Settings.ModTab.AddToggle("Enabled", Enabled);
					Settings.ModTab.AddToggle("Ignore Camera (self)", IgnoreCameraSetting);
					Settings.ModTab.AddToggle("Enable Networking", EnableNetworking);
				};
				<>c.<>9__17_0 = val;
				obj = (object)val;
			}
			onInitialized.AddListener((UnityAction)obj);
			Settings.OnApplySettings.AddListener((UnityAction)delegate
			{
				((BaseUnityPlugin)this).Config.Save();
			});
		}

		private void HandleNetworkSyncFromOthers(PacketHeader header, BinaryPacketBase packet)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (!EnableNetworking.Value || !(packet is LookPacket lookPacket) || !lookPacket.IsValid)
			{
				return;
			}
			bool flag = false;
			foreach (Player player in Players)
			{
				if (!Object.op_Implicit((Object)(object)player) || ((NetworkBehaviour)player).netId != lookPacket.TargetNetId || !(player._steamID == header.SenderID.ToString()))
				{
					continue;
				}
				flag = true;
				break;
			}
			if (flag)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Received packet");
				MultiplayerData[lookPacket.TargetNetId] = new SentPlayerInfo
				{
					CameraRotation = lookPacket.CameraRotation,
					IgnoreCamera = lookPacket.IgnoreCamera,
					Timestamp = DateTime.UtcNow
				};
			}
		}

		private void LateUpdate()
		{
			HandlePlayerCleanup();
			HandleNetworkSyncToOthers();
			HandleLocalPlayers();
		}

		private void HandlePlayerCleanup()
		{
			foreach (Player player in Players)
			{
				if (!Object.op_Implicit((Object)(object)player))
				{
					MultiplayerData.Remove(((NetworkBehaviour)player).netId);
					_cachedPlayerData.Remove(player);
				}
			}
			Players.RemoveWhere((Player player) => !Object.op_Implicit((Object)(object)player));
		}

		private void HandleNetworkSyncToOthers()
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Player._mainPlayer) && _cachedPlayerData.TryGetValue(Player._mainPlayer, out var value))
			{
				if (_lastSendEnableState || EnableNetworking.Value)
				{
					bool flag = value.IgnoreCamera != IgnoreCameraSetting.Value;
					if (IgnoreCameraSetting.Value)
					{
						RefreshDirectionAccumulator -= TimeSpan.FromSeconds(Time.deltaTime);
					}
					else
					{
						float num = Quaternion.Angle(value.CameraRotation, ((Component)CameraFunction._current).transform.rotation);
						RefreshDirectionAccumulator -= TimeSpan.FromSeconds((double)Time.deltaTime + (double)num * 3.0 / 30.0);
					}
					if (flag || RefreshDirectionAccumulator <= TimeSpan.Zero)
					{
						RefreshDirectionAccumulator = TimeSpan.FromSeconds(3.0);
						_shouldSendCurrentState = true;
					}
				}
				else
				{
					RefreshDirectionAccumulator = TimeSpan.Zero;
				}
				value.CameraRotation = ((Component)CameraFunction._current).transform.rotation;
				value.IgnoreCamera = IgnoreCameraSetting.Value;
				_cachedPlayerData[Player._mainPlayer] = value;
			}
			_lastSendEnableState = EnableNetworking.Value;
			PacketSendCooldown -= TimeSpan.FromSeconds(Time.deltaTime);
			if (PacketSendCooldown < TimeSpan.Zero)
			{
				PacketSendCooldown = TimeSpan.Zero;
			}
			if (!_shouldSendCurrentState || !(PacketSendCooldown <= TimeSpan.Zero))
			{
				return;
			}
			_shouldSendCurrentState = false;
			PacketSendCooldown = TimeSpan.FromMilliseconds(250.0);
			foreach (Player player in Players)
			{
				if ((Object)(object)player != (Object)(object)Player._mainPlayer)
				{
					LookPacket.Instance.CameraRotation = (IgnoreCameraSetting.Value ? Quaternion.identity : ((Component)CameraFunction._current).transform.rotation);
					LookPacket.Instance.TargetNetId = ((NetworkBehaviour)Player._mainPlayer).netId;
					LookPacket.Instance.IgnoreCamera = IgnoreCameraSetting.Value;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Sent packet");
					CodeTalkerNetwork.SendNetworkPacket(player, (BinaryPacketBase)(object)LookPacket.Instance, (CompressionType)0, CompressionLevel.Fastest);
				}
			}
		}

		private void HandleLocalPlayers()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			foreach (Player player in Players)
			{
				if (_cachedPlayerData.TryGetValue(player, out var value) && MultiplayerData.TryGetValue(((NetworkBehaviour)player).netId, out var value2))
				{
					if (value2.Timestamp + TimeSpan.FromSeconds(6.0) < DateTime.UtcNow)
					{
						value2.IgnoreCamera = true;
						MultiplayerData[((NetworkBehaviour)player).netId] = value2;
					}
					value.CameraRotation = value2.CameraRotation;
					value.IgnoreCamera = value2.IgnoreCamera;
					_cachedPlayerData[player] = value;
				}
				ProcessPlayerHeadRotation(player);
			}
		}

		private void ProcessPlayerHeadRotation(Player player)
		{
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: 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_02bc: Invalid comparison between Unknown and I4
			//IL_02c6: 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_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled.Value || !Object.op_Implicit((Object)(object)player) || (!((Object)(object)player == (Object)(object)Player._mainPlayer) && !MultiplayerData.ContainsKey(((NetworkBehaviour)player).netId)))
			{
				return;
			}
			if (!_cachedPlayerData.TryGetValue(player, out var value))
			{
				PlayerRaceModel componentInChildren = ((Component)player).GetComponentInChildren<PlayerRaceModel>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Transform armatureTransform = componentInChildren._armatureTransform;
					object obj;
					if (armatureTransform == null)
					{
						obj = null;
					}
					else
					{
						Transform obj2 = armatureTransform.Find("Armature_character");
						if (obj2 == null)
						{
							obj = null;
						}
						else
						{
							Transform obj3 = obj2.Find("masterBone");
							if (obj3 == null)
							{
								obj = null;
							}
							else
							{
								Transform obj4 = obj3.Find("hipCtrl");
								if (obj4 == null)
								{
									obj = null;
								}
								else
								{
									Transform obj5 = obj4.Find("hip");
									if (obj5 == null)
									{
										obj = null;
									}
									else
									{
										Transform obj6 = obj5.Find("lowBody");
										if (obj6 == null)
										{
											obj = null;
										}
										else
										{
											Transform obj7 = obj6.Find("midBody");
											if (obj7 == null)
											{
												obj = null;
											}
											else
											{
												Transform obj8 = obj7.Find("torso");
												if (obj8 == null)
												{
													obj = null;
												}
												else
												{
													Transform obj9 = obj8.Find("neck");
													obj = ((obj9 != null) ? obj9.Find("head") : null);
												}
											}
										}
									}
								}
							}
						}
					}
					Transform val = (Transform)obj;
					if ((Object)(object)val != (Object)null)
					{
						value = (_cachedPlayerData[player] = new PlayerLookInfo
						{
							CameraRotation = ((Component)player).transform.rotation,
							RaceModel = componentInChildren,
							Head = val,
							LastHeadRotation = Quaternion.identity,
							IgnoreCamera = false
						});
					}
				}
			}
			if ((Object)(object)value.Head == (Object)null)
			{
				return;
			}
			if (value.IgnoreCamera)
			{
				value.LastHeadRotation = Quaternion.identity;
				value.CameraRotation = ((Component)player).transform.rotation;
				_cachedPlayerData[player] = value;
				return;
			}
			Transform transform = ((Component)player).transform;
			Quaternion cameraRotation = value.CameraRotation;
			float num = Quaternion.Angle(transform.rotation, cameraRotation);
			bool flag = num >= 105f;
			Quaternion val2 = ((!(num >= 160f)) ? cameraRotation : Quaternion.LookRotation(transform.right, transform.up));
			Quaternion val3 = Quaternion.RotateTowards(value.Head.parent.rotation, val2, 70f);
			Quaternion val4 = Quaternion.Slerp(value.LastHeadRotation, val3, Time.deltaTime * 3.5f);
			val4 = Quaternion.RotateTowards(value.Head.parent.rotation, val4, 70f);
			value.Head.rotation = val4;
			value.LastHeadRotation = value.Head.rotation;
			if (flag && (int)value.RaceModel._currentEyeCondition == 0)
			{
				float num2 = Quaternion.Angle(Quaternion.LookRotation(transform.right * -1f, transform.up), val2);
				value.RaceModel.Set_EyeCondition((EyeCondition)((num2 <= 90f) ? 4 : 3), 0.15f);
			}
			_cachedPlayerData[player] = value;
		}
	}
	internal static class ModInfo
	{
		public const string GUID = "Marioalexsan.Observe";

		public const string NAME = "Observe";

		public const string VERSION = "1.0.0";
	}
}
namespace Marioalexsan.Observe.HarmonyPatches
{
	[HarmonyPatch(typeof(Player), "Update")]
	internal static class Trackplayers
	{
		private static void Postfix(Player __instance)
		{
			ObservePlugin.Players.Add(__instance);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}