Decompiled source of SoulOut v1.0.0

SoulOut.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SoulOut")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SoulOut")]
[assembly: AssemblyTitle("SoulOut")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SoulOut;

internal static class ReflectionHelper
{
	public static Type FindTypeByName(string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return null;
		}
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			Type[] types;
			try
			{
				types = assembly.GetTypes();
			}
			catch
			{
				continue;
			}
			for (int j = 0; j < types.Length; j++)
			{
				if (types[j] != null && types[j].Name == name)
				{
					return types[j];
				}
			}
		}
		return null;
	}

	public static FieldInfo FindFieldRecursive(Type t, string name, BindingFlags flags)
	{
		Type type = t;
		int num = 0;
		while (type != null && num++ < 12)
		{
			FieldInfo field = type.GetField(name, flags);
			if (field != null)
			{
				return field;
			}
			type = type.BaseType;
		}
		return null;
	}
}
[BepInPlugin("SoulOut", "SoulOut", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Logger;

	internal static KeyCode SoulOutKey = (KeyCode)103;

	internal static KeyCode LastPlayerKey = (KeyCode)49;

	internal static KeyCode NextPlayerKey = (KeyCode)50;

	private void Awake()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Expected O, but got Unknown
		Logger = ((BaseUnityPlugin)this).Logger;
		Logger.LogInfo((object)"[SoulOut] v1.0.0");
		Harmony val = new Harmony("SoulOut");
		try
		{
			val.PatchAll();
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("[SoulOut] PatchAll 失败: " + ex.Message));
		}
		VanillaSyncBridge.TryInstall(val);
		ConfigFile config = ((BaseUnityPlugin)this).Config;
		ConfigEntry<KeyCode> val2 = config.Bind<KeyCode>("热键/Controls", "灵魂出窍/SoulOut", (KeyCode)103, "灵魂出窍/SoulOut。");
		ConfigEntry<KeyCode> val3 = config.Bind<KeyCode>("热键/Controls", "上个玩家/LastPlayer", (KeyCode)49, "观战上个玩家/Spectate the last player。");
		ConfigEntry<KeyCode> val4 = config.Bind<KeyCode>("热键/Controls", "下个玩家/NextPlayer", (KeyCode)50, "观战下个玩家/Spectate the next player。");
		SoulOutKey = val2.Value;
		LastPlayerKey = val3.Value;
		NextPlayerKey = val4.Value;
		GameObject val5 = new GameObject("SoulOut_Input");
		Object.DontDestroyOnLoad((Object)(object)val5);
		val5.AddComponent<SoulOutInputHandler>();
	}
}
public static class GhostPositionCodec
{
	public struct GhostEncoding
	{
		public Vector2 LookValues;

		public float Zoom;

		public Vector3 DecodedPosition;

		public float Error;
	}

	public const float GhostUpOffset = 0.5f;

	private const float DegToRad = MathF.PI / 180f;

	private const float RadToDeg = 180f / MathF.PI;

	public static bool IsFinite(float v)
	{
		return !float.IsNaN(v) && !float.IsInfinity(v);
	}

	public static bool IsFinite(Vector2 v)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		return IsFinite(v.x) && IsFinite(v.y);
	}

	public static bool IsFinite(Vector3 v)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		return IsFinite(v.x) && IsFinite(v.y) && IsFinite(v.z);
	}

	public static float Quantize(float value)
	{
		return HalfToFloat(FloatToHalf(value));
	}

	private static ushort FloatToHalf(float value)
	{
		int num = BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
		int num2 = (num >> 16) & 0x8000;
		int num3 = (num >> 23) & 0xFF;
		int num4 = num & 0x7FFFFF;
		switch (num3)
		{
		case 0:
			return (ushort)num2;
		case 255:
			if (num4 == 0)
			{
				return (ushort)(num2 | 0x7C00);
			}
			return (ushort)(num2 | 0x7C00 | (num4 >> 13) | 1);
		default:
		{
			int num5 = num3 - 127 + 15;
			if (num5 >= 31)
			{
				return (ushort)(num2 | 0x7C00);
			}
			if (num5 <= 0)
			{
				if (num5 < -10)
				{
					return (ushort)num2;
				}
				int num6 = num4 | 0x800000;
				int num7 = 14 - num5;
				int num8 = num6 >> num7;
				int num9 = num6 & ((1 << num7) - 1);
				int num10 = 1 << num7 - 1;
				if (num9 > num10 || (num9 == num10 && (num8 & 1) == 1))
				{
					num8++;
				}
				return (ushort)(num2 | num8);
			}
			int num11 = num4 >> 13;
			int num12 = num4 & 0x1FFF;
			if (num12 > 4096 || (num12 == 4096 && (num11 & 1) == 1))
			{
				num11++;
				if (num11 > 1023)
				{
					num11 = 0;
					num5++;
					if (num5 >= 31)
					{
						return (ushort)(num2 | 0x7C00);
					}
				}
			}
			return (ushort)(num2 | (num5 << 10) | num11);
		}
		}
	}

	private static float HalfToFloat(ushort half)
	{
		int num = (half & 0x8000) << 16;
		int num2 = (half >> 10) & 0x1F;
		int num3 = half & 0x3FF;
		switch (num2)
		{
		case 0:
		{
			if (num3 == 0)
			{
				return BitConverter.ToSingle(BitConverter.GetBytes(num), 0);
			}
			int num4 = 113;
			while ((num3 & 0x400) == 0)
			{
				num3 <<= 1;
				num4--;
			}
			num3 &= -1025;
			int value3 = num | (num4 << 23) | (num3 << 13);
			return BitConverter.ToSingle(BitConverter.GetBytes(value3), 0);
		}
		case 31:
		{
			int value2 = num | 0x7F800000 | (num3 << 13);
			return BitConverter.ToSingle(BitConverter.GetBytes(value2), 0);
		}
		default:
		{
			int value = num | (num2 + 127 - 15 << 23) | (num3 << 13);
			return BitConverter.ToSingle(BitConverter.GetBytes(value), 0);
		}
		}
	}

	public static Vector3 DirectionFromLook(Vector2 lookValues)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		float num = lookValues.x * (MathF.PI / 180f);
		float num2 = lookValues.y * (MathF.PI / 180f);
		float num3 = Mathf.Cos(num2);
		Vector3 value = default(Vector3);
		((Vector3)(ref value))..ctor(Mathf.Sin(num) * num3, Mathf.Sin(num2), Mathf.Cos(num) * num3);
		Vector3 normalized;
		return TryNormalize(value, out normalized) ? normalized : Vector3.forward;
	}

	public static Vector2 DirectionToLook(Vector3 direction)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		if (!TryNormalize(direction, out var normalized))
		{
			return Vector2.zero;
		}
		float num = Mathf.Atan2(normalized.x, normalized.z) * (180f / MathF.PI);
		float num2 = Mathf.Asin(Mathf.Clamp(normalized.y, -1f, 1f)) * (180f / MathF.PI);
		return new Vector2(num, num2);
	}

	public static float UnwrapYaw(float yaw, float reference)
	{
		if (!IsFinite(yaw) || !IsFinite(reference))
		{
			return yaw;
		}
		return yaw + 360f * Mathf.Round((reference - yaw) / 360f);
	}

	public static bool TrySolveDirection(Vector3 targetCenter, Vector3 desiredPosition, out Vector3 direction)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: 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_0043: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		direction = Vector3.zero;
		if (!IsFinite(targetCenter) || !IsFinite(desiredPosition))
		{
			return false;
		}
		Vector3 val = desiredPosition - targetCenter - Vector3.up * 0.5f;
		if (!TryNormalize(-val, out direction))
		{
			direction = Vector3.forward;
		}
		return IsFinite(direction);
	}

	public static bool TryEncodeLook(Vector3 targetCenter, Vector3 desiredPosition, Vector2 seedLook, bool hasPrevious, Vector2 previousLook, out GhostEncoding encoding)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		encoding = default(GhostEncoding);
		if (!IsFinite(targetCenter) || !IsFinite(desiredPosition) || !IsFinite(seedLook))
		{
			return false;
		}
		if (hasPrevious)
		{
			seedLook.x = UnwrapYaw(seedLook.x, previousLook.x);
		}
		seedLook.y = Mathf.Clamp(seedLook.y, -90f, 90f);
		return TryEvaluateQuantizedLook(targetCenter, desiredPosition, seedLook, out encoding);
	}

	private static bool TryEvaluateQuantizedLook(Vector3 targetCenter, Vector3 desiredPosition, Vector2 lookValues, out GhostEncoding encoding)
	{
		//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_0025: 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_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_0043: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		encoding = default(GhostEncoding);
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(Quantize(lookValues.x), Quantize(lookValues.y));
		if (!IsFinite(val))
		{
			return false;
		}
		Vector3 val2 = DirectionFromLook(val);
		Vector3 val3 = desiredPosition - targetCenter - Vector3.up * 0.5f;
		float num = Quantize(Mathf.Max(0f, 0f - Vector3.Dot(val3, val2)));
		if (!IsFinite(val2) || !IsFinite(num))
		{
			return false;
		}
		Vector3 val4 = targetCenter - val2 * num + Vector3.up * 0.5f;
		float num2 = Vector3.Distance(val4, desiredPosition);
		if (!IsFinite(val4) || !IsFinite(num2))
		{
			return false;
		}
		encoding.LookValues = val;
		encoding.Zoom = num;
		encoding.DecodedPosition = val4;
		encoding.Error = num2;
		return true;
	}

	public static bool TryNormalize(Vector3 value, out Vector3 normalized)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		float sqrMagnitude = ((Vector3)(ref value)).sqrMagnitude;
		if (!IsFinite(sqrMagnitude) || sqrMagnitude <= 1E-16f)
		{
			normalized = Vector3.zero;
			return false;
		}
		normalized = value / Mathf.Sqrt(sqrMagnitude);
		return IsFinite(normalized);
	}
}
public static class VanillaSyncBridge
{
	public static bool Enabled = true;

	public static float MaxDistance = 1000f;

	private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static MethodInfo _getDataToWrite;

	private static FieldInfo _mCharacterField;

	private static FieldInfo _lookField;

	private static FieldInfo _zoomField;

	private static MethodInfo _gameDirectionToLook;

	private static bool _converterResolved;

	private static object _pendingData;

	private static object _pendingLook;

	private static object _pendingZoom;

	private static bool _hasPending;

	private static bool _hasLastEncodedLook;

	private static Vector2 _lastEncodedLook;

	public static bool Installed { get; private set; }

	public static bool TryInstall(Harmony harmony)
	{
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Expected O, but got Unknown
		//IL_0149: Expected O, but got Unknown
		if (Installed)
		{
			return true;
		}
		if (harmony == null)
		{
			return false;
		}
		try
		{
			Type type = ReflectionHelper.FindTypeByName("CharacterSyncer");
			if (type == null)
			{
				return false;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (!(methodInfo.Name != "GetDataToWrite") && methodInfo.GetParameters().Length == 0)
				{
					_getDataToWrite = methodInfo;
					break;
				}
			}
			if (_getDataToWrite == null)
			{
				return false;
			}
			_mCharacterField = ReflectionHelper.FindFieldRecursive(type, "m_character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (_mCharacterField == null)
			{
				return false;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(VanillaSyncBridge), "SyncPrefix", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(VanillaSyncBridge), "SyncPostfix", (Type[])null, (Type[])null);
			if (methodInfo2 == null || methodInfo3 == null)
			{
				return false;
			}
			harmony.Patch((MethodBase)_getDataToWrite, new HarmonyMethod(methodInfo2), new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			bool flag = false;
			foreach (MethodBase patchedMethod in harmony.GetPatchedMethods())
			{
				if (patchedMethod == _getDataToWrite)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return false;
			}
			Installed = true;
			ResolveDirectionConverter();
			Plugin.Logger.LogInfo((object)"[SoulOut] ✓ 原版可见性桥接已挂载");
			return true;
		}
		catch (Exception ex)
		{
			Plugin.Logger.LogError((object)("[SoulOut] ✗ 原版可见性桥接安装失败: " + ex.GetBaseException().Message));
			return false;
		}
	}

	private static void ResolveDirectionConverter()
	{
		if (_converterResolved)
		{
			return;
		}
		_converterResolved = true;
		try
		{
			Type type = ReflectionHelper.FindTypeByName("HelperFunctions");
			if (type == null)
			{
				return;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (!(methodInfo.Name != "DirectionToLook"))
				{
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if (parameters.Length == 1 && parameters[0].ParameterType == typeof(Vector3) && methodInfo.ReturnType == typeof(Vector3))
					{
						_gameDirectionToLook = methodInfo;
						break;
					}
				}
			}
		}
		catch
		{
		}
	}

	private static Vector3 DirectionToLook(Vector3 dir)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: 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_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: 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_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if (_gameDirectionToLook != null)
		{
			try
			{
				if (_gameDirectionToLook.Invoke(null, new object[1] { dir }) is Vector3 val && GhostPositionCodec.IsFinite(val))
				{
					return val;
				}
			}
			catch
			{
				_gameDirectionToLook = null;
			}
		}
		return Vector2.op_Implicit(GhostPositionCodec.DirectionToLook(dir));
	}

	private static void SyncPrefix(object __instance)
	{
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		_hasPending = false;
		if (!Enabled || !Installed || !SoulOutInputHandler.IsGhostMode || __instance == null)
		{
			return;
		}
		try
		{
			object? value = _mCharacterField.GetValue(__instance);
			Character val = (Character)((value is Character) ? value : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Character.localCharacter) && !((Object)(object)val.data == (Object)null))
			{
				object data = val.data;
				if (EnsureDataFields(data) && TryEncodeForLocalGhost(val, out var encoding))
				{
					_pendingData = data;
					_pendingLook = _lookField.GetValue(data);
					_pendingZoom = _zoomField.GetValue(data);
					_hasPending = true;
					WriteLook(data, encoding.LookValues);
					WriteFloat(data, _zoomField, encoding.Zoom);
					_lastEncodedLook = encoding.LookValues;
					_hasLastEncodedLook = true;
				}
			}
		}
		catch
		{
			_hasPending = false;
		}
	}

	private static void SyncPostfix(object __instance)
	{
		RestorePending();
	}

	private static void RestorePending()
	{
		if (!_hasPending)
		{
			return;
		}
		try
		{
			if (_pendingData != null && _lookField != null && _zoomField != null)
			{
				if (_pendingLook != null)
				{
					_lookField.SetValue(_pendingData, _pendingLook);
				}
				if (_pendingZoom != null)
				{
					_zoomField.SetValue(_pendingData, _pendingZoom);
				}
			}
		}
		catch
		{
		}
		finally
		{
			_hasPending = false;
			_pendingData = (_pendingLook = (_pendingZoom = null));
		}
	}

	public static void EnsureNoPendingRestore()
	{
		if (_hasPending)
		{
			RestorePending();
		}
	}

	public static void ResetSession()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		RestorePending();
		_hasLastEncodedLook = false;
		_lastEncodedLook = Vector2.zero;
	}

	private static bool TryEncodeForLocalGhost(Character character, out GhostPositionCodec.GhostEncoding encoding)
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		encoding = default(GhostPositionCodec.GhostEncoding);
		SoulOutInputHandler instance = SoulOutInputHandler.Instance;
		GameObject localGhostObj = SoulOutInputHandler.LocalGhostObj;
		if ((Object)(object)instance == (Object)null || (Object)(object)localGhostObj == (Object)null)
		{
			return false;
		}
		PlayerGhost component = localGhostObj.GetComponent<PlayerGhost>();
		if ((Object)(object)component == (Object)null)
		{
			return false;
		}
		Character val = (((Object)(object)component.m_target != (Object)null) ? component.m_target : character);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		Vector3 center = val.Center;
		Vector3 val2 = instance.GhostPos;
		if (!GhostPositionCodec.IsFinite(center) || !GhostPositionCodec.IsFinite(val2))
		{
			return false;
		}
		Vector3 val3 = val2 - center - Vector3.up * 0.5f;
		float magnitude = ((Vector3)(ref val3)).magnitude;
		float num = Mathf.Max(1f, MaxDistance);
		if (magnitude > num)
		{
			val2 = center + Vector3.up * 0.5f + val3 * (num / magnitude);
		}
		if (!GhostPositionCodec.TrySolveDirection(center, val2, out var direction))
		{
			return false;
		}
		Vector3 val4 = DirectionToLook(direction);
		Vector2 seedLook = default(Vector2);
		((Vector2)(ref seedLook))..ctor(val4.x, val4.y);
		return GhostPositionCodec.TryEncodeLook(center, val2, seedLook, _hasLastEncodedLook, _lastEncodedLook, out encoding);
	}

	private static bool EnsureDataFields(object data)
	{
		if (_lookField != null && _zoomField != null)
		{
			return true;
		}
		if (data == null)
		{
			return false;
		}
		try
		{
			Type type = data.GetType();
			_lookField = ReflectionHelper.FindFieldRecursive(type, "lookValues", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_zoomField = ReflectionHelper.FindFieldRecursive(type, "spectateZoom", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return _lookField != null && _zoomField != null;
		}
		catch
		{
			return false;
		}
	}

	private static void WriteLook(object data, Vector2 value)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		object obj = _lookField.GetValue(data);
		if (obj == null)
		{
			obj = Activator.CreateInstance(_lookField.FieldType);
		}
		Type fieldType = _lookField.FieldType;
		FieldInfo field = fieldType.GetField("x", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		FieldInfo field2 = fieldType.GetField("y", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null && field2 != null)
		{
			field.SetValue(obj, value.x);
			field2.SetValue(obj, value.y);
			_lookField.SetValue(data, obj);
		}
		else if (fieldType == typeof(Vector2))
		{
			_lookField.SetValue(data, value);
		}
	}

	private static void WriteFloat(object data, FieldInfo field, float value)
	{
		if (field != null && field.FieldType == typeof(float))
		{
			field.SetValue(data, value);
		}
	}
}
public class GhostTakeover
{
	private PlayerGhost _pg;

	private bool _hasState = false;

	private bool _wasActive;

	private Transform _origParent;

	private Vector3 _origLocalPos;

	private Quaternion _origLocalRot;

	private Renderer[] _renderers;

	private bool[] _rendererEnabled;

	private GameObject[] _childObjs;

	private bool[] _childActive;

	private Rigidbody _rb;

	private bool _wasKinematic;

	private bool _hadRb = false;

	private static readonly string[] LinearVelocityNames = new string[2] { "linearVelocity", "velocity" };

	private static PropertyInfo _linearVelProp = null;

	private static bool _linearVelResolved = false;

	public void TakeOver(PlayerGhost pg)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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)
		_pg = pg;
		_hasState = false;
		if ((Object)(object)pg == (Object)null)
		{
			return;
		}
		try
		{
			GameObject gameObject = ((Component)pg).gameObject;
			Transform transform = gameObject.transform;
			_wasActive = gameObject.activeSelf;
			_origParent = transform.parent;
			_origLocalPos = transform.localPosition;
			_origLocalRot = transform.localRotation;
			_renderers = gameObject.GetComponentsInChildren<Renderer>(true);
			_rendererEnabled = new bool[_renderers.Length];
			for (int i = 0; i < _renderers.Length; i++)
			{
				_rendererEnabled[i] = (Object)(object)_renderers[i] != (Object)null && _renderers[i].enabled;
			}
			Transform[] componentsInChildren = gameObject.GetComponentsInChildren<Transform>(true);
			List<GameObject> list = new List<GameObject>();
			List<bool> list2 = new List<bool>();
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if (!((Object)(object)((Component)componentsInChildren[j]).gameObject == (Object)(object)gameObject))
				{
					list.Add(((Component)componentsInChildren[j]).gameObject);
					list2.Add(((Component)componentsInChildren[j]).gameObject.activeSelf);
				}
			}
			_childObjs = list.ToArray();
			_childActive = list2.ToArray();
			_rb = gameObject.GetComponent<Rigidbody>();
			if ((Object)(object)_rb != (Object)null)
			{
				_hadRb = true;
				_wasKinematic = _rb.isKinematic;
				_rb.isKinematic = true;
				ZeroRigidbodyVelocity(_rb);
			}
			_hasState = true;
		}
		catch
		{
		}
	}

	private static void ZeroRigidbodyVelocity(Rigidbody rb)
	{
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)rb == (Object)null)
		{
			return;
		}
		try
		{
			if (!_linearVelResolved)
			{
				_linearVelResolved = true;
				for (int i = 0; i < LinearVelocityNames.Length; i++)
				{
					PropertyInfo property = typeof(Rigidbody).GetProperty(LinearVelocityNames[i], BindingFlags.Instance | BindingFlags.Public);
					if (property != null && property.CanWrite && property.PropertyType == typeof(Vector3))
					{
						_linearVelProp = property;
						break;
					}
				}
			}
			if (_linearVelProp != null)
			{
				_linearVelProp.SetValue(rb, Vector3.zero, null);
			}
			rb.angularVelocity = Vector3.zero;
		}
		catch
		{
		}
	}

	public void Restore()
	{
		//IL_0082: 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)
		if (!_hasState || (Object)(object)_pg == (Object)null)
		{
			_hasState = false;
			_pg = null;
			return;
		}
		try
		{
			GameObject gameObject = ((Component)_pg).gameObject;
			Transform transform = gameObject.transform;
			if (_hadRb && (Object)(object)_rb != (Object)null)
			{
				_rb.isKinematic = _wasKinematic;
			}
			transform.SetParent(_origParent, false);
			transform.localPosition = _origLocalPos;
			transform.localRotation = _origLocalRot;
			for (int i = 0; i < _renderers.Length; i++)
			{
				if ((Object)(object)_renderers[i] != (Object)null)
				{
					_renderers[i].enabled = _rendererEnabled[i];
				}
			}
			for (int num = _childObjs.Length - 1; num >= 0; num--)
			{
				if ((Object)(object)_childObjs[num] != (Object)null)
				{
					_childObjs[num].SetActive(_childActive[num]);
				}
			}
			if (gameObject.activeSelf != _wasActive)
			{
				gameObject.SetActive(_wasActive);
			}
		}
		catch
		{
		}
		finally
		{
			_hasState = false;
			_pg = null;
		}
	}
}
public class SoulOutInputHandler : MonoBehaviourPunCallbacks
{
	public static bool IsGhostMode = false;

	public static GameObject LocalGhostObj = null;

	public static bool UsingNativeGhost = false;

	public static bool HideThirdEye = true;

	private Character _localChar = null;

	private readonly GhostTakeover _takeover = new GhostTakeover();

	private bool _weCreatedGhost = false;

	[SerializeField]
	private float _ghostSpeed = 8f;

	[SerializeField]
	private float _mouseSensitivity = 3f;

	[SerializeField]
	private float _ghostSprintMultiplier = 2.2f;

	private const KeyCode FallbackSprintKey = (KeyCode)304;

	internal static bool SprintHeldThisFrame = false;

	private int _lastInputFrame = -1;

	private Vector3 _ghostPos;

	private float _ghostPitch;

	private float _ghostYaw;

	private const float PitchLimit = 89.5f;

	private bool _spectating = false;

	private Character _spectateTarget = null;

	private int _spectateIndex = -1;

	private float _spectateDistance = 6f;

	internal static int EscMenuSuppressFrame = -1;

	public static SoulOutInputHandler Instance { get; private set; }

	internal Vector3 GhostPos => _ghostPos;

	internal Quaternion GhostRot => GhostRotation;

	private Quaternion GhostRotation => Quaternion.Euler(_ghostPitch, _ghostYaw, 0f);

	private static float NormalizePitch(float p)
	{
		p %= 360f;
		if (p > 180f)
		{
			p -= 360f;
		}
		else if (p < -180f)
		{
			p += 360f;
		}
		return Mathf.Clamp(p, -89.5f, 89.5f);
	}

	private void Awake()
	{
		Instance = this;
	}

	private void OnDestroy()
	{
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	private void Update()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		VanillaSyncBridge.EnsureNoPendingRestore();
		if (Input.GetKeyDown(Plugin.SoulOutKey) && CanUseInput())
		{
			try
			{
				if (!EnsureLocalChar())
				{
					return;
				}
				if (IsGhostMode)
				{
					if (_spectating)
					{
						EnterSpectate(null);
					}
					else
					{
						SwitchBack();
					}
				}
				else
				{
					SwitchToGhost();
				}
			}
			catch
			{
			}
		}
		if (!IsGhostMode)
		{
			return;
		}
		if (Input.GetKeyDown((KeyCode)27))
		{
			try
			{
				EscMenuSuppressFrame = Time.frameCount;
				SwitchBack();
			}
			catch
			{
			}
		}
		else if (Input.GetKeyDown(Plugin.LastPlayerKey) || Input.GetKeyDown(Plugin.NextPlayerKey))
		{
			bool keyDown = Input.GetKeyDown(Plugin.NextPlayerKey);
			try
			{
				CycleSpectateTarget(keyDown);
			}
			catch
			{
			}
		}
		AccumulateGhostInput();
	}

	private void LateUpdate()
	{
		if (IsGhostMode && !((Object)(object)LocalGhostObj == (Object)null))
		{
			WriteGhostTransform(LocalGhostObj.transform);
		}
	}

	private bool CanUseInput()
	{
		try
		{
			if ((Object)(object)GUIManager.instance == (Object)null)
			{
				return true;
			}
			if (GUIManager.instance.windowBlockingInput)
			{
				return false;
			}
			if (GUIManager.instance.wheelActive)
			{
				return false;
			}
		}
		catch
		{
		}
		return true;
	}

	private bool EnsureLocalChar()
	{
		if ((Object)(object)_localChar != (Object)null)
		{
			return true;
		}
		_localChar = Character.localCharacter;
		if ((Object)(object)_localChar == (Object)null)
		{
			Character val = Object.FindFirstObjectByType<Character>((FindObjectsInactive)1);
			if ((Object)(object)val != (Object)null)
			{
				_localChar = val;
			}
			else
			{
				Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
				if (array.Length != 0)
				{
					_localChar = array[0];
				}
			}
		}
		return (Object)(object)_localChar != (Object)null;
	}

	public static void AccumulateGhostInput()
	{
		//IL_0103: 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_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		if (!IsGhostMode)
		{
			return;
		}
		SoulOutInputHandler instance = Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		int frameCount = Time.frameCount;
		if (instance._lastInputFrame == frameCount)
		{
			return;
		}
		instance._lastInputFrame = frameCount;
		try
		{
			float num = Input.GetAxis("Mouse X") * instance._mouseSensitivity;
			float num2 = Input.GetAxis("Mouse Y") * instance._mouseSensitivity;
			instance._ghostYaw += num;
			instance._ghostPitch = Mathf.Clamp(instance._ghostPitch - num2, -89.5f, 89.5f);
			if (instance._ghostYaw > 360f)
			{
				instance._ghostYaw -= 360f;
			}
			else if (instance._ghostYaw < -360f)
			{
				instance._ghostYaw += 360f;
			}
			if (instance._spectating)
			{
				instance.UpdateSpectatePose();
				return;
			}
			Quaternion ghostRotation = instance.GhostRotation;
			Vector3 val = ghostRotation * Vector3.forward;
			Vector3 val2 = ghostRotation * Vector3.right;
			Vector3 val3 = Vector3.zero;
			if (Input.GetKey((KeyCode)119))
			{
				val3 += val;
			}
			if (Input.GetKey((KeyCode)115))
			{
				val3 -= val;
			}
			if (Input.GetKey((KeyCode)97))
			{
				val3 -= val2;
			}
			if (Input.GetKey((KeyCode)100))
			{
				val3 += val2;
			}
			if (Input.GetKey((KeyCode)32))
			{
				val3 += Vector3.up;
			}
			if (Input.GetKey((KeyCode)306))
			{
				val3 -= Vector3.up;
			}
			if (val3 != Vector3.zero)
			{
				bool flag = SprintHeldThisFrame || Input.GetKey((KeyCode)304);
				float num3 = instance._ghostSpeed * (flag ? instance._ghostSprintMultiplier : 1f);
				instance._ghostPos += ((Vector3)(ref val3)).normalized * num3 * Time.deltaTime;
			}
		}
		catch
		{
		}
	}

	public static void WriteGhostTransform(Transform t)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		if (IsGhostMode && !((Object)(object)t == (Object)null))
		{
			SoulOutInputHandler instance = Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				t.SetPositionAndRotation(instance._ghostPos, instance.GhostRotation);
			}
		}
	}

	private void CycleSpectateTarget(bool forward)
	{
		List<Character> list = new List<Character>();
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)_localChar) && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.data.dead)
			{
				list.Add(allCharacter);
			}
		}
		if (list.Count == 0)
		{
			EnterSpectate(null);
			return;
		}
		int num = (forward ? (_spectateIndex + 1) : (_spectateIndex - 1));
		if (num >= list.Count)
		{
			num = 0;
		}
		if (num < 0)
		{
			num = list.Count - 1;
		}
		_spectateIndex = num;
		EnterSpectate(list[num]);
	}

	private void EnterSpectate(Character target)
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		_spectateTarget = target;
		_spectating = (Object)(object)target != (Object)null;
		if ((Object)(object)LocalGhostObj != (Object)null)
		{
			PlayerGhost component = LocalGhostObj.GetComponent<PlayerGhost>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_view != (Object)null)
			{
				component.m_view.RPC("RPCA_SetTarget", (RpcTarget)3, new object[1] { ((Object)(object)target != (Object)null) ? ((MonoBehaviourPun)target).photonView : ((MonoBehaviourPun)_localChar).photonView });
			}
		}
		if ((Object)(object)target != (Object)null)
		{
			_ghostPos = target.Center + GhostRotation * (Vector3.back * _spectateDistance) + Vector3.up * 1.5f;
		}
	}

	private void UpdateSpectatePose()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		if (_spectating && !((Object)(object)_spectateTarget == (Object)null))
		{
			Character spectateTarget = _spectateTarget;
			if ((Object)(object)spectateTarget.data != (Object)null && spectateTarget.data.dead)
			{
				EnterSpectate(null);
			}
			else
			{
				_ghostPos = spectateTarget.Center + GhostRotation * (Vector3.back * _spectateDistance) + Vector3.up * 1.5f;
			}
		}
	}

	internal void InitGhostPose(Vector3 pos, Quaternion rot)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: 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)
		_ghostPos = pos;
		Vector3 eulerAngles = ((Quaternion)(ref rot)).eulerAngles;
		_ghostPitch = NormalizePitch(eulerAngles.x);
		_ghostYaw = eulerAngles.y;
		_lastInputFrame = -1;
	}

	public override void OnLeftRoom()
	{
		LocalGhostObj = null;
		UsingNativeGhost = false;
		_weCreatedGhost = false;
		IsGhostMode = false;
		_spectating = false;
		_spectateTarget = null;
		_spectateIndex = -1;
		VanillaSyncBridge.ResetSession();
	}

	public override void OnDisconnected(DisconnectCause cause)
	{
		((MonoBehaviourPunCallbacks)this).OnLeftRoom();
	}

	private void SwitchToGhost()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_007b: 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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_0038: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Camera main = Camera.main;
			Quaternion rotation;
			Quaternion val;
			if ((Object)(object)main != (Object)null)
			{
				rotation = ((Component)main).transform.rotation;
				Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
				val = Quaternion.Euler(NormalizePitch(eulerAngles.x), eulerAngles.y, 0f);
			}
			else
			{
				rotation = ((Component)_localChar).transform.rotation;
				val = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f);
			}
			Vector3 val2 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.position : ((_localChar.Head != Vector3.zero) ? (_localChar.Head + Vector3.up * 0.5f) : (_localChar.Center + Vector3.up * 2f)));
			PlayerGhost ghost = _localChar.Ghost;
			if ((Object)(object)ghost != (Object)null)
			{
				LocalGhostObj = ((Component)ghost).gameObject;
				UsingNativeGhost = true;
				_weCreatedGhost = false;
				_takeover.TakeOver(ghost);
				LocalGhostObj.SetActive(true);
			}
			else
			{
				GameObject val3 = (LocalGhostObj = PhotonNetwork.Instantiate("PlayerGhost", val2, val, (byte)0, (object[])null));
				UsingNativeGhost = false;
				_weCreatedGhost = true;
				PhotonView component = val3.GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && _localChar.refs != null)
				{
					component.RPC("RPCA_InitGhost", (RpcTarget)3, new object[2]
					{
						_localChar.refs.view,
						_localChar.refs.view
					});
				}
			}
			LocalGhostObj.transform.SetPositionAndRotation(val2, val);
			ForceEnableGhostRenderers();
			InitGhostPose(val2, val);
			IsGhostMode = true;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}
		catch (Exception)
		{
			IsGhostMode = false;
			if (UsingNativeGhost)
			{
				_takeover.Restore();
			}
		}
	}

	private void ForceEnableGhostRenderers()
	{
		if ((Object)(object)LocalGhostObj == (Object)null)
		{
			return;
		}
		try
		{
			PlayerGhost component = LocalGhostObj.GetComponent<PlayerGhost>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			if (component.PlayerRenderers != null)
			{
				Renderer[] playerRenderers = component.PlayerRenderers;
				foreach (Renderer val in playerRenderers)
				{
					if (Object.op_Implicit((Object)(object)val))
					{
						val.enabled = true;
					}
				}
			}
			if (component.EyeRenderers != null)
			{
				Renderer[] eyeRenderers = component.EyeRenderers;
				foreach (Renderer val2 in eyeRenderers)
				{
					if (Object.op_Implicit((Object)(object)val2))
					{
						val2.enabled = true;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)component.mouthRenderer))
			{
				component.mouthRenderer.enabled = true;
			}
			if (Object.op_Implicit((Object)(object)component.accessoryRenderer))
			{
				component.accessoryRenderer.enabled = true;
			}
			if (Object.op_Implicit((Object)(object)component.thirdEye) && HideThirdEye)
			{
				component.thirdEye.SetActive(false);
			}
		}
		catch
		{
		}
	}

	private void SwitchBack()
	{
		IsGhostMode = false;
		_spectating = false;
		_spectateTarget = null;
		_spectateIndex = -1;
		VanillaSyncBridge.ResetSession();
		if (UsingNativeGhost)
		{
			_takeover.Restore();
		}
		else if (_weCreatedGhost && (Object)(object)LocalGhostObj != (Object)null)
		{
			try
			{
				PhotonNetwork.Destroy(LocalGhostObj);
			}
			catch (Exception)
			{
				try
				{
					Object.Destroy((Object)(object)LocalGhostObj);
				}
				catch
				{
				}
			}
		}
		LocalGhostObj = null;
		UsingNativeGhost = false;
		_weCreatedGhost = false;
		Cursor.lockState = (CursorLockMode)1;
		Cursor.visible = false;
	}
}
[HarmonyPatch(typeof(CharacterInput), "Sample")]
public static class Patch_BlockInputAtSource
{
	private static void Postfix(CharacterInput __instance)
	{
		//IL_0055: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		if (SoulOutInputHandler.IsGhostMode && !((Object)(object)__instance == (Object)null))
		{
			Character component = ((Component)__instance).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component != (Object)(object)Character.localCharacter))
			{
				SoulOutInputHandler.SprintHeldThisFrame = __instance.sprintIsPressed;
				__instance.movementInput = Vector2.zero;
				__instance.lookInput = Vector2.zero;
				__instance.scrollInput = 0f;
				__instance.jumpWasPressed = false;
				__instance.jumpIsPressed = false;
				__instance.sprintWasPressed = false;
				__instance.sprintIsPressed = false;
				__instance.crouchWasPressed = false;
				__instance.crouchIsPressed = false;
				__instance.interactWasPressed = false;
				__instance.interactIsPressed = false;
				__instance.dropWasPressed = false;
				__instance.dropIsPressed = false;
				__instance.usePrimaryWasPressed = false;
				__instance.usePrimaryIsPressed = false;
				__instance.useSecondaryWasPressed = false;
				__instance.useSecondaryIsPressed = false;
				__instance.emoteIsPressed = false;
				__instance.pauseWasPressed = false;
				__instance.selectSlotForwardWasPressed = false;
				__instance.selectSlotBackwardWasPressed = false;
				__instance.unselectSlotWasPressed = false;
				__instance.selectBackpackWasPressed = false;
				__instance.scrollBackwardWasPressed = false;
				__instance.scrollForwardWasPressed = false;
				__instance.spectateLeftWasPressed = false;
				__instance.spectateRightWasPressed = false;
			}
		}
	}
}
[HarmonyPatch(typeof(MainCameraMovement), "LateUpdate")]
public static class Patch_Camera_GhostFollow
{
	private static void Postfix()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		if (!SoulOutInputHandler.IsGhostMode)
		{
			return;
		}
		GameObject localGhostObj = SoulOutInputHandler.LocalGhostObj;
		if ((Object)(object)localGhostObj == (Object)null)
		{
			return;
		}
		Camera main = Camera.main;
		if (!((Object)(object)main == (Object)null))
		{
			SoulOutInputHandler instance = SoulOutInputHandler.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				SoulOutInputHandler.WriteGhostTransform(localGhostObj.transform);
				((Component)main).transform.SetPositionAndRotation(instance.GhostPos, instance.GhostRot);
			}
		}
	}
}
[HarmonyPatch(typeof(CharacterItems), "DoSwitching")]
public static class Patch_BlockItemSwitching
{
	private static readonly FieldInfo _characterField = typeof(CharacterItems).GetField("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static bool Prefix(CharacterItems __instance)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		if (!SoulOutInputHandler.IsGhostMode)
		{
			return true;
		}
		if (_characterField == null)
		{
			return true;
		}
		Character val = (Character)_characterField.GetValue(__instance);
		if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Character.localCharacter)
		{
			return true;
		}
		return false;
	}
}
[HarmonyPatch(typeof(GUIManager), "UpdatePaused")]
public static class Patch_BlockPauseMenu
{
	private static bool Prefix()
	{
		if (!SoulOutInputHandler.IsGhostMode)
		{
			return Time.frameCount > SoulOutInputHandler.EscMenuSuppressFrame;
		}
		return false;
	}
}
[HarmonyPatch(typeof(CharacterInput), "Sample")]
public static class Patch_ClearResidualPause
{
	private static void Postfix(CharacterInput __instance)
	{
		if (!((Object)(object)__instance == (Object)null))
		{
			Character component = ((Component)__instance).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component != (Object)(object)Character.localCharacter) && (SoulOutInputHandler.IsGhostMode || Time.frameCount <= SoulOutInputHandler.EscMenuSuppressFrame))
			{
				__instance.pauseWasPressed = false;
			}
		}
	}
}
[HarmonyPatch(typeof(Character), "SetRotation")]
public static class Patch_LockBodyDirWhenGhosted
{
	private static readonly Dictionary<Character, Quaternion> _locked = new Dictionary<Character, Quaternion>();

	private static void Prefix(Character __instance)
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance == (Object)(object)Character.localCharacter) && __instance.refs != null && !((Object)(object)__instance.refs.rigCreator == (Object)null))
		{
			PlayerGhost ghost = __instance.Ghost;
			if (!((Object)(object)ghost != (Object)null) || !((Object)(object)((Component)ghost).gameObject != (Object)null) || !((Component)ghost).gameObject.activeInHierarchy)
			{
				_locked.Remove(__instance);
			}
			else if (!_locked.ContainsKey(__instance))
			{
				_locked[__instance] = ((Component)__instance.refs.rigCreator).transform.rotation;
			}
		}
	}

	private static void Postfix(Character __instance)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (_locked.TryGetValue(__instance, out var value))
		{
			((Component)__instance.refs.rigCreator).transform.rotation = value;
		}
	}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public static class Patch_PingAllowWhenGhosted
{
	private static readonly FieldInfo _lastPingedField = typeof(PointPinger).GetField("_timeLastPinged", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo _characterField = typeof(PointPinger).GetField("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static bool Prefix(PointPinger __instance, ref bool __result)
	{
		if (!SoulOutInputHandler.IsGhostMode)
		{
			return true;
		}
		if ((Object)(object)__instance == (Object)null)
		{
			return true;
		}
		Character val = (Character)((_characterField != null) ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)((Component)__instance).GetComponent<Character>()));
		if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Character.localCharacter)
		{
			return true;
		}
		float num = 0f;
		if (_lastPingedField != null)
		{
			try
			{
				num = (float)_lastPingedField.GetValue(__instance);
			}
			catch
			{
			}
		}
		__result = Time.time - num >= __instance.coolDown;
		return false;
	}
}
[HarmonyPatch(typeof(PointPinger), "DoPing")]
public static class Patch_PingOffsetFromGhost
{
	public static bool Enabled = true;

	public static float OffsetDistance = 1f;

	private static readonly FieldInfo _lastPingedField = typeof(PointPinger).GetField("_timeLastPinged", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo _characterField = typeof(PointPinger).GetField("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo _photonViewField = typeof(PointPinger).GetField("photonView", BindingFlags.Instance | BindingFlags.NonPublic);

	private static bool Prefix(PointPinger __instance)
	{
		//IL_00dd: 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_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: 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_01e7: 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_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		if (!Enabled)
		{
			return true;
		}
		if (!SoulOutInputHandler.IsGhostMode)
		{
			return true;
		}
		if ((Object)(object)__instance == (Object)null)
		{
			return true;
		}
		try
		{
			Character val = (Character)((_characterField != null) ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)((Component)__instance).GetComponent<Character>()));
			if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Character.localCharacter)
			{
				return true;
			}
			SoulOutInputHandler instance = SoulOutInputHandler.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			MethodInfo methodInfo = null;
			try
			{
				methodInfo = typeof(PointPinger).GetMethod("TryGetPingHit", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			catch
			{
			}
			if (methodInfo == null)
			{
				return true;
			}
			Vector3 mousePosition = Input.mousePosition;
			if (TryGetGamepadScheme())
			{
				((Vector3)(ref mousePosition))..ctor((float)(Screen.width / 2), (float)(Screen.height / 2));
			}
			object[] array = new object[2]
			{
				(object)default(RaycastHit),
				mousePosition
			};
			bool flag;
			try
			{
				flag = (bool)methodInfo.Invoke(null, array);
			}
			catch
			{
				return true;
			}
			if (!flag)
			{
				return false;
			}
			RaycastHit val2 = (RaycastHit)array[0];
			if (_lastPingedField != null)
			{
				_lastPingedField.SetValue(__instance, Time.time);
			}
			Vector3 ghostPos = instance.GhostPos;
			Vector3 val3 = ghostPos - ((RaycastHit)(ref val2)).point;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			Vector3 val4 = ((RaycastHit)(ref val2)).point;
			if (magnitude > 0.001f)
			{
				float num = Mathf.Min(OffsetDistance, Mathf.Max(0f, magnitude - 0.5f));
				val4 = ((RaycastHit)(ref val2)).point + ((Vector3)(ref val3)).normalized * num;
			}
			PhotonView val5 = null;
			try
			{
				if (_photonViewField != null)
				{
					object? value = _photonViewField.GetValue(__instance);
					val5 = (PhotonView)((value is PhotonView) ? value : null);
				}
				if ((Object)(object)val5 == (Object)null)
				{
					val5 = ((Component)__instance).GetComponent<PhotonView>();
				}
				if (!((Object)(object)val5 != (Object)null))
				{
					return true;
				}
				val5.RPC("ReceivePoint_Rpc", (RpcTarget)0, new object[2]
				{
					val4,
					((RaycastHit)(ref val2)).normal
				});
			}
			catch
			{
				return true;
			}
			return false;
		}
		catch
		{
			return true;
		}
	}

	private static bool TryGetGamepadScheme()
	{
		try
		{
			Type type = ReflectionHelper.FindTypeByName("InputHandler");
			if (type == null)
			{
				return false;
			}
			MethodInfo method = type.GetMethod("GetCurrentUsedInputScheme", BindingFlags.Static | BindingFlags.Public);
			if (method == null || method.ReturnType == null)
			{
				return false;
			}
			object obj = method.Invoke(null, null);
			if (obj == null || !method.ReturnType.IsEnum)
			{
				return false;
			}
			return obj.ToString() == "Gamepad";
		}
		catch
		{
			return false;
		}
	}
}
[HarmonyPatch(typeof(PointPing), "Go")]
public static class Patch_PointPingPerpendicular
{
	public static bool Enabled = true;

	private static readonly FieldInfo _cameraField = typeof(PointPing).GetField("camera", BindingFlags.Instance | BindingFlags.NonPublic);

	private static void Postfix(PointPing __instance)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: 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_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		if (!Enabled || (Object)(object)__instance == (Object)null)
		{
			return;
		}
		try
		{
			Vector3 hitNormal = __instance.hitNormal;
			if (hitNormal == Vector3.zero || float.IsNaN(hitNormal.x) || float.IsNaN(hitNormal.y) || float.IsNaN(hitNormal.z))
			{
				return;
			}
			((Vector3)(ref hitNormal)).Normalize();
			if (Mathf.Abs(hitNormal.y) > 0.95f)
			{
				return;
			}
			Camera val = (Camera)((_cameraField != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null)
			{
				val = Camera.main;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Vector3 val2 = ((Component)__instance).transform.position - ((Component)val).transform.position;
			if (!(val2 == Vector3.zero))
			{
				Vector3 val3 = -hitNormal;
				float num = __instance.angleThing;
				if (num <= 0f)
				{
					num = 90f;
				}
				float num2 = Mathf.Clamp01(Vector3.Angle(val3, val2) / num);
				Vector3 val4 = Vector3.Lerp(-Vector3.up, val3, num2);
				if (!(val4 == Vector3.zero))
				{
					((Component)__instance).transform.rotation = Quaternion.LookRotation(val4, Vector3.up);
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(PointPing), "Go")]
public static class Patch_PingNoPointAnim
{
	private static void Postfix(PointPing __instance)
	{
		if ((Object)(object)__instance == (Object)null)
		{
			return;
		}
		try
		{
			Character val = (((Object)(object)__instance.pointPinger != (Object)null) ? __instance.pointPinger.character : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			PlayerGhost ghost = val.Ghost;
			if (!((Object)(object)ghost == (Object)null))
			{
				GameObject gameObject = ((Component)ghost).gameObject;
				if (!((Object)(object)gameObject == (Object)null) && gameObject.activeInHierarchy && val.refs != null && (Object)(object)val.refs.animations != (Object)null)
				{
					val.refs.animations.point = null;
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(PointPinger), "ReceivePoint_Rpc")]
public static class Patch_PingRestorePoint
{
	private static readonly FieldInfo _pingInstanceField = typeof(PointPinger).GetField("pingInstance", BindingFlags.Instance | BindingFlags.NonPublic);

	private static void Postfix(PointPinger __instance, Vector3 point)
	{
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)null)
		{
			return;
		}
		Character character = __instance.character;
		if ((Object)(object)character == (Object)null)
		{
			return;
		}
		try
		{
			PlayerGhost ghost = character.Ghost;
			if ((Object)(object)ghost == (Object)null)
			{
				return;
			}
			GameObject gameObject = ((Component)ghost).gameObject;
			if ((Object)(object)gameObject == (Object)null || !gameObject.activeInHierarchy)
			{
				return;
			}
			float offsetDistance = Patch_PingOffsetFromGhost.OffsetDistance;
			if (offsetDistance <= 0f)
			{
				return;
			}
			Vector3 position = ((Component)ghost).transform.position;
			Vector3 val = point - position;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return;
			}
			Vector3 position2 = point + ((Vector3)(ref val)).normalized * offsetDistance;
			GameObject val2 = null;
			if (_pingInstanceField != null)
			{
				try
				{
					object? value = _pingInstanceField.GetValue(__instance);
					val2 = (GameObject)((value is GameObject) ? value : null);
				}
				catch
				{
				}
			}
			if (!((Object)(object)val2 == (Object)null))
			{
				val2.transform.position = position2;
			}
		}
		catch
		{
		}
	}
}