Decompiled source of PingVisualizer v1.0.1

Mods/PingVisualizer.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2Cpp;
using Il2CppExitGames.Client.Photon;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppLiv.Lck;
using Il2CppPhoton.Pun;
using Il2CppPhoton.Realtime;
using Il2CppRUMBLE.CharacterCreation.Interactable;
using Il2CppRUMBLE.Combat.ShiftStones;
using Il2CppRUMBLE.Input;
using Il2CppRUMBLE.Interactions.InteractionBase;
using Il2CppRUMBLE.Managers;
using Il2CppRUMBLE.MeshGeneration;
using Il2CppRUMBLE.Networking;
using Il2CppRUMBLE.Players;
using Il2CppRUMBLE.Players.Scaling;
using Il2CppRUMBLE.Players.Subsystems;
using Il2CppRUMBLE.Pools;
using Il2CppRUMBLE.Utilities;
using Il2CppSystem;
using MelonLoader;
using PingVisualizer;
using RumbleModUI;
using RumbleModdingAPI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.VFX;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "PingVisualizer", "1.0.1", "TacoSlayer36", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonColor(255, 255, 248, 231)]
[assembly: MelonAuthorColor(255, 255, 248, 231)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PingVisualizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d55961afffbcdf089ba639c3ea00483d3ae75fba")]
[assembly: AssemblyProduct("PingVisualizer")]
[assembly: AssemblyTitle("PingVisualizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace PingVisualizer
{
	public static class BuildInfo
	{
		public const string Name = "PingVisualizer";

		public const string Author = "TacoSlayer36";

		public const string Version = "1.0.1";

		public const string Description = "Visualizes ping with delayed clones";
	}
	public class Core : MelonMod
	{
		public static Core Instance;

		public bool GlobalInit = false;

		public List<Laggard> LaggardList = new List<Laggard>();

		public GameObject ParentGameObject;

		public string CurrentScene;

		public Material LaggardMaterial;

		public PooledVisualEffect LocalGuardVFX = null;

		public bool HasGuard = false;

		private int _hostPing = 150;

		private int _localPing = 70;

		public Mod Mod = new Mod();

		private Player host
		{
			get
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				return (currentRoom != null) ? currentRoom.players[PhotonNetwork.CurrentRoom.MasterClientId] : null;
			}
		}

		public bool NoHostExists => PhotonNetwork.IsMasterClient || host == null || CurrentScene == "Gym";

		private bool opponentHasLaggardsEnabled
		{
			get
			{
				Player obj = Singleton<PlayerManager>.Instance.AllPlayers[1];
				int result;
				if (obj != null)
				{
					PlayerController controller = obj.Controller;
					if (controller != null)
					{
						PhotonView component = ((Component)controller).GetComponent<PhotonView>();
						if (component != null)
						{
							Player owner = component.Owner;
							if (owner != null)
							{
								Object obj2 = owner.CustomProperties[Object.op_Implicit("PingVisualizer.LaggardsEnabled")];
								if (obj2 != null)
								{
									((Il2CppObjectBase)obj2).Unbox<bool>();
									if (0 == 0)
									{
										result = 1;
										goto IL_0063;
									}
								}
							}
						}
					}
				}
				result = 0;
				goto IL_0063;
				IL_0063:
				return (byte)result != 0;
			}
		}

		public int HostPing
		{
			get
			{
				if (ModUISettings.HostTestPing.HasValue)
				{
					return ModUISettings.HostTestPing.Value;
				}
				return _hostPing;
			}
			set
			{
				_hostPing = value;
			}
		}

		public int LocalPing
		{
			get
			{
				if (ModUISettings.LocalTestPing.HasValue)
				{
					return ModUISettings.LocalTestPing.Value;
				}
				return _localPing;
			}
			set
			{
				_localPing = value;
			}
		}

		public override void OnLateInitializeMelon()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			Instance = this;
			UI.instance.UI_Initialized += OnUIInit;
			Calls.onMapInitialized += sceneReady;
			MelonCoroutines.Start(C_SlowFixedUpdate());
			LaggardMaterial = new Material(Calls.LoadAssetFromStream<Material>((MelonMod)(object)this, "PingVisualizer.assets.pingvisualizer", "Laggard"));
			((Object)LaggardMaterial).hideFlags = (HideFlags)32;
		}

		public override void OnFixedUpdate()
		{
			List<Laggard> list = new List<Laggard>();
			foreach (Laggard laggard in LaggardList)
			{
				if ((Object)(object)laggard == (Object)null)
				{
					list.Add(laggard);
					continue;
				}
				laggard.AddPosition();
				laggard.PlayBackPosition();
			}
			foreach (Laggard item in list)
			{
				LaggardList.Remove(item);
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			CurrentScene = sceneName;
		}

		private void sceneReady()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if (CurrentScene != "Loader")
			{
				ParentGameObject = new GameObject("PingVisualizer");
				if (!GlobalInit)
				{
					MelonCoroutines.Start(C_SlowFixedUpdate());
					GlobalInit = true;
				}
			}
			if (CurrentScene == "Gym")
			{
				MelonCoroutines.Start(C_ListenForLandButton("FlatLand"));
				MelonCoroutines.Start(C_ListenForLandButton("VoidLand"));
			}
		}

		private IEnumerator C_ListenForLandButton(string landType)
		{
			yield return (object)new WaitForSeconds(1f);
			GameObject obj = GameObject.Find(landType);
			if (obj != null)
			{
				obj.GetComponentInChildren<InteractionButton>().onPressed.AddListener(UnityAction.op_Implicit((Action)delegate
				{
					MelonCoroutines.Start(C_OnLandEntered());
				}));
			}
		}

		private IEnumerator C_OnLandEntered()
		{
			CurrentScene = "Land";
			yield return (object)new WaitForSeconds(1.5f);
			ParentGameObject.SetActive(true);
		}

		public IEnumerator C_SlowFixedUpdate()
		{
			while (true)
			{
				yield return (object)new WaitForSeconds(1f);
				if (CurrentScene != "Loader")
				{
					FetchPings();
				}
			}
		}

		public void FetchPings()
		{
			try
			{
				LocalPing = PhotonNetwork.GetPing();
			}
			catch
			{
			}
			if (PhotonNetwork.InRoom && CurrentScene != "Gym")
			{
				try
				{
					if (NoHostExists)
					{
						HostPing = ModUISettings.AssumedHostPing;
					}
					else
					{
						HostPing = ((Il2CppObjectBase)host.CustomProperties[Object.op_Implicit("ping")]).Unbox<int>();
					}
					return;
				}
				catch
				{
					return;
				}
			}
			HostPing = ModUISettings.AssumedHostPing;
		}

		public void CreateAllLaggards(PlayerController player, float waitTime)
		{
			MelonCoroutines.Start(C_CreateAllLaggards(player, waitTime));
		}

		public IEnumerator C_CreateAllLaggards(PlayerController player, float waitTime)
		{
			if (PhotonNetwork.InRoom)
			{
				Hashtable ht = new Hashtable();
				ht[Object.op_Implicit("PingVisualizer.LaggardsEnabled")] = Object.op_Implicit(ModUISettings.RoundTripLaggard || ModUISettings.OneWayLaggard);
				PhotonNetwork.LocalPlayer.SetCustomProperties(ht, (Hashtable)null, (WebFlags)null);
			}
			yield return (object)new WaitForSeconds(waitTime);
			if (!CurrentScene.Contains("Map") || Singleton<PlayerManager>.Instance.AllPlayers.Count <= 1 || opponentHasLaggardsEnabled)
			{
				CreateLaggard(player, roundTrip: false);
				CreateLaggard(player, roundTrip: true);
				SetLaggardsVisibility();
			}
		}

		public void ClearAllLaggards()
		{
			MelonCoroutines.Start(C_ClearAllLaggards());
		}

		public IEnumerator C_ClearAllLaggards()
		{
			yield return (object)new WaitForSeconds(0.1f);
			foreach (Laggard laggard in LaggardList)
			{
				Object.Destroy((Object)(object)((Component)laggard).gameObject);
			}
			LaggardList.Clear();
		}

		public void CreateLaggard(PlayerController player, bool roundTrip)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)player).gameObject);
			val.transform.SetParent(ParentGameObject.transform);
			((Object)val).name = (roundTrip ? "Round-Trip Laggard" : "One-Way Laggard");
			Laggard laggard = val.AddComponent<Laggard>();
			laggard.RoundTrip = roundTrip;
			laggard.TrackedPlayer = player;
			try
			{
				laggard.Setup();
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Failed to create laggard: " + ex.Message);
				Object.Destroy((Object)(object)val);
				return;
			}
			LaggardList.Add(laggard);
		}

		public void SetLaggardsVisibility()
		{
			foreach (Laggard laggard in LaggardList)
			{
				if (laggard.RoundTrip)
				{
					((Component)laggard).gameObject.SetActive(ModUISettings.RoundTripLaggard);
				}
				else
				{
					((Component)laggard).gameObject.SetActive(ModUISettings.OneWayLaggard);
				}
				if (ModUISettings.AssumedHostPing < 0 && NoHostExists)
				{
					((Component)laggard).gameObject.SetActive(false);
				}
			}
		}

		public void OnUIInit()
		{
			//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_005b: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			Mod.ModName = "PingVisualizer";
			Mod.ModVersion = "1.0.1";
			Mod.SetFolder("PingVisualizer");
			Mod.AddDescription("Description", "", "Visualizes ping with delayed clones", new Tags
			{
				IsSummary = true
			});
			Mod.AddToList("<#F0F>Round-trip laggard", true, 0, "Enable a <#F0F>clone</color> to show your ping delay to the host and back\n(This is the position that can be hit/spawn structures)", new Tags());
			Mod.AddToList("<#FF0>One-way laggard", false, 0, "Enable a <#FF0>clone</color> to show your ping delay to the host\n(This has no affect on gameplay, but is the real-time location that the host is seeing you)", new Tags());
			Mod.AddToList("Assumed Host Ping", 70, "The ping to assume for the host when there is not one\nSet to -1 to auto-disable laggards on host", new Tags());
			Mod.AddToList("Test Pings", "", "Override actual pings with these values for testing\nLeave blank to ignore\n\nFormatted like: \"host, client\"\nEx: \"70, 150\"", new Tags());
			Mod.AddToList("Hide nearby laggards", 1, "The amount to hide laggards that are close to you\n0: None\n1: Hide heads only\n2: Hide entire bodies", new Tags());
			Mod.GetFromFile();
			Mod.ModSaved += OnUISave;
			UI.instance.AddMod(Mod);
		}

		public void OnUISave()
		{
			SetLaggardsVisibility();
		}
	}
	[RegisterTypeInIl2Cpp]
	public class Laggard : MonoBehaviour
	{
		public PlayerController TrackedPlayer;

		public PlayerController PlayerController;

		public Material MaterialInstance;

		public bool RoundTrip = false;

		public List<PlayerPosition> RecordedPositions = new List<PlayerPosition>();

		private PlayerMeasurement lastMeasurement;

		private Transform headBone;

		private Transform chestBone;

		private VisualEffect guardVFX = null;

		private bool hasGuardObject = false;

		private bool hadGuardLastFrame = false;

		private float delayTime => RoundTrip ? (Core.Instance.HostPing + Core.Instance.LocalPing) : ((Core.Instance.HostPing + Core.Instance.LocalPing) / 2);

		private int delayUpdates => Math.Clamp((int)(delayTime / 20f), 0, int.MaxValue);

		private int frame => Math.Clamp(RecordedPositions.Count - delayUpdates - 1, 0, RecordedPositions.Count);

		public PlayerPosition PlayerPosition => RecordedPositions[frame];

		public Transform vr => ((Component)this).gameObject.transform.GetChild(1);

		public Transform visuals => ((Component)this).gameObject.transform.GetChild(0);

		public Transform Head => ((Component)vr.GetChild(0).GetChild(0)).transform;

		public Transform LeftHand => ((Component)vr.GetChild(1)).transform;

		public Transform RightHand => ((Component)vr.GetChild(2)).transform;

		public void Setup()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Core.Instance.LaggardMaterial == (Object)null)
			{
				throw new Exception("Ghost material was null");
			}
			MaterialInstance = new Material(Core.Instance.LaggardMaterial);
			headBone = ((Component)this).transform.GetChild(1).GetChild(1).GetChild(0)
				.GetChild(4)
				.GetChild(0)
				.GetChild(0)
				.GetChild(0);
			chestBone = ((Component)this).transform.GetChild(1).GetChild(1).GetChild(0)
				.GetChild(4)
				.GetChild(0);
			Transform obj = ((Component)this).transform.GetChild(1).GetChild(1).GetChild(0)
				.GetChild(4)
				.GetChild(0)
				.Find("Guardstone_VFX");
			guardVFX = ((obj != null) ? ((Component)obj).GetComponent<VisualEffect>() : null);
			if ((Object)(object)guardVFX != (Object)null)
			{
				((Component)((Component)guardVFX).transform.GetChild(0)).gameObject.SetActive(false);
				((Component)guardVFX).gameObject.SetActive(true);
				guardVFX.Stop();
				hasGuardObject = true;
			}
			PlayerController = ((Component)this).GetComponent<PlayerController>();
			((Behaviour)PlayerController).enabled = false;
			foreach (Behaviour component2 in ((Component)this).GetComponents<Behaviour>())
			{
				component2.enabled = false;
			}
			((Behaviour)this).enabled = true;
			foreach (Renderer componentsInChild in ((Component)this).gameObject.GetComponentsInChildren<Renderer>())
			{
				if (((Object)componentsInChild).name != "FadeScreenRenderer" && ((Object)componentsInChild).name != "GuardShield")
				{
					componentsInChild.shadowCastingMode = (ShadowCastingMode)0;
					componentsInChild.sharedMaterial = MaterialInstance;
					componentsInChild.material.SetFloat("_Opacity", 0.1f);
					componentsInChild.material.SetColor("_Color", RoundTrip ? Color.magenta : Color.yellow);
					componentsInChild.material.SetFloat("_Inflate", 0.002f);
				}
			}
			PlayerShiftstoneSystem component = ((Component)this).GetComponent<PlayerShiftstoneSystem>();
			foreach (ShiftstoneSocket item in (Il2CppArrayBase<ShiftstoneSocket>)(object)component.shiftStoneSockets)
			{
				if (item.shiftstonePlacementTransform.childCount > 0)
				{
					Object.Destroy((Object)(object)((Component)item.shiftstonePlacementTransform.GetChild(0)).gameObject);
				}
			}
			((Behaviour)component).enabled = false;
			Transform child = ((Component)this).gameObject.transform.GetChild(10);
			((Behaviour)((Component)child.GetChild(1)).GetComponent<LckServiceHelper>()).enabled = false;
			((Component)child.GetChild(3)).gameObject.SetActive(false);
			Object.Destroy((Object)(object)((Component)child.GetChild(2)).gameObject, 0.25f);
			((Component)child.GetChild(0)).gameObject.SetActive(false);
			((Behaviour)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PlayerAnimator>()).enabled = false;
			((Behaviour)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PlayerVisuals>()).enabled = false;
			((Behaviour)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PlayerAudioPresence>()).enabled = false;
			((Behaviour)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PhotonAnimatorView>()).enabled = false;
			((Behaviour)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PhotonView>()).enabled = false;
			((PlayerControllerSubsystem)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PlayerHandPresence>()).Initialize(PlayerController);
			Object.Destroy((Object)(object)((Component)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PlayerHandPresence>().lefthand.Index.BoneC).GetComponent<SphereCollider>());
			Object.Destroy((Object)(object)((Component)((Component)((Component)this).gameObject.transform.GetChild(1)).GetComponent<PlayerHandPresence>().righthand.Index.BoneC).GetComponent<SphereCollider>());
			((Component)((Component)this).gameObject.transform.GetChild(1).GetChild(0)).gameObject.layer = 0;
			Transform child2 = ((Component)this).transform.GetChild(2).GetChild(0).GetChild(0);
			((Behaviour)((Component)child2).GetComponent<PlayerCamera>()).enabled = false;
			((Behaviour)((Component)child2).GetComponent<UniversalAdditionalCameraData>()).enabled = false;
			((Behaviour)((Component)child2).GetComponent<Volume>()).enabled = false;
			((Behaviour)((Component)child2).GetComponent<NetworkGameObject>()).enabled = false;
			((Behaviour)((Component)child2).GetComponent<LckAudioCapture>()).enabled = false;
			Object.Destroy((Object)(object)((Component)child2).GetComponent<Rigidbody>());
			Object.DestroyImmediate((Object)(object)((Component)child2.GetChild(4)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)child2.GetChild(3)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)child2.GetChild(2)).gameObject);
			((Component)child2.GetChild(1)).gameObject.SetActive(false);
			((Behaviour)((Component)((Component)this).transform.GetChild(2).GetChild(1)).GetComponent<InteractionHand>()).enabled = false;
			((Behaviour)((Component)((Component)this).transform.GetChild(2).GetChild(1)).GetComponent<NetworkGameObject>()).enabled = false;
			((Behaviour)((Component)((Component)this).transform.GetChild(2).GetChild(2)).GetComponent<InteractionHand>()).enabled = false;
			((Behaviour)((Component)((Component)this).transform.GetChild(2).GetChild(2)).GetComponent<NetworkGameObject>()).enabled = false;
			((Behaviour)((Component)((Component)this).gameObject.transform.GetChild(2)).GetComponent<NetworkGameObject>()).enabled = false;
			Object.Destroy((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(2)).GetComponent<Rigidbody>());
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(9)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(8)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(7)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(6)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(5)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(2).GetChild(1).GetChild(1)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(2).GetChild(2).GetChild(1)).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)((Component)this).gameObject.transform.GetChild(0)).gameObject);
		}

		public void AddPosition()
		{
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: 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_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: 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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			Il2CppStructArray<int> currentShiftStoneConfiguration = ((Component)TrackedPlayer).GetComponent<PlayerShiftstoneSystem>().GetCurrentShiftStoneConfiguration();
			Core.Instance.HasGuard = ((Il2CppArrayBase<int>)(object)currentShiftStoneConfiguration)[0] == 3 || ((Il2CppArrayBase<int>)(object)currentShiftStoneConfiguration)[1] == 3;
			if (!Core.Instance.HasGuard)
			{
				Core.Instance.LocalGuardVFX = null;
			}
			else if ((Object)(object)Core.Instance.LocalGuardVFX == (Object)null)
			{
				Core instance = Core.Instance;
				Transform obj = ((Component)TrackedPlayer).transform.GetChild(1).GetChild(1).GetChild(0)
					.GetChild(4)
					.GetChild(0)
					.Find("Guardstone_VFX");
				instance.LocalGuardVFX = ((obj != null) ? ((Component)obj).GetComponent<PooledVisualEffect>() : null);
			}
			if (!hadGuardLastFrame && Core.Instance.HasGuard && Time.timeSinceLevelLoad > 5f && (Object)(object)Core.Instance.LocalGuardVFX != (Object)null && (Object)(object)guardVFX == (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)Core.Instance.LocalGuardVFX).gameObject);
				((Component)val.transform.GetChild(0)).gameObject.SetActive(false);
				val.transform.SetParent(((Component)PlayerController).transform.GetChild(0).GetChild(1).GetChild(0)
					.GetChild(4)
					.GetChild(0), false);
				guardVFX = val.GetComponent<VisualEffect>();
			}
			hadGuardLastFrame = Core.Instance.HasGuard;
			HandPresenceInput val2 = default(HandPresenceInput);
			val2.indexInput = 1f;
			val2.gripInput = 1f;
			val2.thumbInput = 1f;
			HandPresenceInput val3 = val2;
			Vector3 position = TrackedPlayer.GetPlayerHead().transform.position;
			Quaternion rotation = TrackedPlayer.GetPlayerHead().transform.rotation;
			Vector3 position2 = TrackedPlayer.GetLeftHand().transform.position;
			Vector3 position3 = TrackedPlayer.GetRightHand().transform.position;
			Quaternion rotation2 = TrackedPlayer.GetLeftHand().transform.rotation;
			Quaternion rotation3 = TrackedPlayer.GetRightHand().transform.rotation;
			PlayerMeasurement playerMeasurement = TrackedPlayer.assignedPlayer.Data.PlayerMeasurement;
			Vector3 position4 = ((Component)TrackedPlayer).transform.GetChild(1).position;
			HandPresenceInput lHandInput = (TrackedPlayer.IsDoingPose() ? val3 : TrackedPlayer.GetHandPresence().GetHandPresenceInputForHand((Hand)1));
			HandPresenceInput rHandInput = (TrackedPlayer.IsDoingPose() ? val3 : TrackedPlayer.GetHandPresence().GetHandPresenceInputForHand((Hand)2));
			PooledVisualEffect localGuardVFX = Core.Instance.LocalGuardVFX;
			int num;
			if (localGuardVFX != null)
			{
				_ = localGuardVFX.isPlaying;
				if (true)
				{
					num = (Core.Instance.LocalGuardVFX.isPlaying ? 1 : 0);
					goto IL_02f1;
				}
			}
			num = 0;
			goto IL_02f1;
			IL_02f1:
			bool isGuarding = (byte)num != 0;
			PooledVisualEffect localGuardVFX2 = Core.Instance.LocalGuardVFX;
			Vector3? guardPos = ((localGuardVFX2 != null) ? new Vector3?(((Component)localGuardVFX2).transform.position) : null);
			PooledVisualEffect localGuardVFX3 = Core.Instance.LocalGuardVFX;
			float? guardYaw = ((localGuardVFX3 != null) ? new float?(((Component)localGuardVFX3).transform.eulerAngles.y) : null);
			PlayerPosition item = new PlayerPosition
			{
				HeadPos = position,
				HeadRot = rotation,
				LeftHandPos = position2,
				RightHandPos = position3,
				LeftHandRot = rotation2,
				RightHandRot = rotation3,
				Measurement = playerMeasurement,
				VisualsPos = position4,
				LHandInput = lHandInput,
				RHandInput = rHandInput,
				IsGuarding = isGuarding,
				GuardPos = guardPos,
				GuardYaw = guardYaw
			};
			if (RecordedPositions.Count > delayUpdates + 1000)
			{
				RecordedPositions.RemoveAt(0);
			}
			RecordedPositions.Add(item);
		}

		public void PlayBackPosition()
		{
			//IL_0044: 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_007c: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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)
			//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_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: 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_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			if (RecordedPositions.Count <= delayUpdates && RecordedPositions.Count > frame)
			{
				return;
			}
			((Component)Head).transform.position = PlayerPosition.HeadPos;
			((Component)LeftHand).transform.position = PlayerPosition.LeftHandPos;
			((Component)RightHand).transform.position = PlayerPosition.RightHandPos;
			((Component)Head).transform.rotation = PlayerPosition.HeadRot;
			((Component)LeftHand).transform.rotation = PlayerPosition.LeftHandRot;
			((Component)RightHand).transform.rotation = PlayerPosition.RightHandRot;
			((Component)Head).transform.rotation = PlayerPosition.HeadRot;
			if (lastMeasurement.Length != PlayerPosition.Measurement.Length || lastMeasurement.ArmSpan != PlayerPosition.Measurement.ArmSpan)
			{
				((Component)visuals).GetComponent<PlayerScaling>().ScaleController(PlayerPosition.Measurement);
			}
			lastMeasurement = PlayerPosition.Measurement;
			((Component)visuals).transform.position = PlayerPosition.VisualsPos;
			double num = Vector3.Distance(((Component)Head).transform.position, Singleton<PlayerManager>.Instance.LocalPlayer.Controller.GetPlayerHead().transform.position);
			float num2 = (float)Math.Round(Math.Clamp(num - 0.2, 0.0, 1.0), 3);
			if (PlayerPosition.GuardPos.HasValue && PlayerPosition.GuardYaw.HasValue)
			{
				((Component)guardVFX).transform.position = PlayerPosition.GuardPos.Value + Vector3.down * 0.4f;
				((Component)guardVFX).transform.rotation = Quaternion.Euler(0f, PlayerPosition.GuardYaw.Value, 0f);
			}
			if (ModUISettings.HideNearbyLaggards == 1)
			{
				((Renderer)((Component)visuals).GetComponentInChildren<SkinnedMeshRenderer>()).material.SetFloat("_HeadOpacity", num2);
			}
			else
			{
				((Renderer)((Component)visuals).GetComponentInChildren<SkinnedMeshRenderer>()).material.SetFloat("_HeadOpacity", 1f);
			}
			if (ModUISettings.HideNearbyLaggards == 2)
			{
				((Renderer)((Component)visuals).GetComponentInChildren<SkinnedMeshRenderer>()).material.SetFloat("_BodyOpacity", num2);
			}
			else
			{
				((Renderer)((Component)visuals).GetComponentInChildren<SkinnedMeshRenderer>()).material.SetFloat("_BodyOpacity", 1f);
			}
			if (PlayerPosition.IsGuarding)
			{
				VisualEffect obj = guardVFX;
				if (obj != null)
				{
					obj.Play();
				}
			}
			else
			{
				VisualEffect obj2 = guardVFX;
				if (obj2 != null)
				{
					obj2.Stop();
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerController), "Initialize", new Type[] { typeof(Player) })]
	public static class playerSpawnPatch
	{
		private static void Postfix(ref PlayerController __instance, ref Player player)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if ((int)player.Controller.controllerType == 1)
			{
				MelonCoroutines.Start(Core.Instance.C_CreateAllLaggards(player.Controller, 2f));
			}
		}
	}
	[HarmonyPatch(typeof(PlayerHandPresence), "UpdateHandPresenceAnimationStates")]
	public class handPresencePatch
	{
		private static void Prefix(PlayerHandPresence __instance, Hand hand, ref HandPresenceInput input)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (((PlayerControllerSubsystem)__instance).parentController.IsLaggard())
			{
				Laggard component = ((Component)((PlayerControllerSubsystem)__instance).parentController).GetComponent<Laggard>();
				if (!((Object)(object)component == (Object)null) && component.RecordedPositions.Count >= 1)
				{
					input = (((int)hand == 1) ? component.PlayerPosition.LHandInput : component.PlayerPosition.RHandInput);
				}
			}
		}
	}
	[HarmonyPatch(typeof(DressingRoom), "DelayedApplyData", new Type[] { typeof(GeneratedPlayerVisuals) })]
	public static class dressingRoomPatch
	{
		private static void Prefix(ref GeneratedPlayerVisuals generatedVisuals)
		{
			if (Time.timeSinceLevelLoad > 5f)
			{
				Core.Instance.ClearAllLaggards();
				MelonCoroutines.Start(Core.Instance.C_CreateAllLaggards(Singleton<PlayerManager>.Instance.LocalPlayer.Controller, 0.15f));
			}
		}
	}
	[HarmonyPatch(typeof(PlayerController), "DeActivate", new Type[] { })]
	public static class playerControllerPatch
	{
		private static bool Prefix(ref PlayerController __instance)
		{
			if (__instance.IsLaggard())
			{
				return false;
			}
			return true;
		}
	}
	public class PlayerPosition
	{
		public Vector3 LeftHandPos;

		public Vector3 RightHandPos;

		public Vector3 HeadPos;

		public Quaternion LeftHandRot;

		public Quaternion RightHandRot;

		public Quaternion HeadRot;

		public HandPresenceInput LHandInput;

		public HandPresenceInput RHandInput;

		public Vector3 VisualsPos;

		public PlayerMeasurement Measurement;

		public bool IsGuarding;

		public Vector3? GuardPos;

		public float? GuardYaw;
	}
	public static class Extensions
	{
		public static GameObject GetPlayerHead(this PlayerController player)
		{
			return ((Component)((Component)player).transform.GetChild(2).GetChild(0).GetChild(0)).gameObject;
		}

		public static GameObject GetLeftHand(this PlayerController player)
		{
			return ((Component)((Component)player).transform.GetChild(2).GetChild(1)).gameObject;
		}

		public static GameObject GetRightHand(this PlayerController player)
		{
			return ((Component)((Component)player).transform.GetChild(2).GetChild(2)).gameObject;
		}

		public static PlayerHandPresence GetHandPresence(this PlayerController player)
		{
			return player.GetSubsystem<PlayerHandPresence>();
		}

		public static bool IsDoingPose(this PlayerController player)
		{
			return player.GetSubsystem<PlayerPoseSystem>().IsDoingAnyPose();
		}

		public static bool IsLaggard(this PlayerController player)
		{
			return Core.Instance.LaggardList.Contains(((Component)player).GetComponent<Laggard>());
		}

		public static Transform GetChestBone(this PlayerController player)
		{
			return ((Component)((Component)player).transform).GetComponentInChildren<RigDefinition>().chestDefinition.Transform;
		}
	}
	public static class ModUISettings
	{
		public static bool RoundTripLaggard => (bool)Core.Instance.Mod.Settings[1].SavedValue;

		public static bool OneWayLaggard => (bool)Core.Instance.Mod.Settings[2].SavedValue;

		public static int AssumedHostPing => (int)Core.Instance.Mod.Settings[3].SavedValue;

		private static string _testPings => (string)Core.Instance.Mod.Settings[4].SavedValue;

		public static int? HostTestPing
		{
			get
			{
				string[] array = _testPings.Split(", ");
				int result = 0;
				if (array.Length >= 1 && int.TryParse(array[0], out result))
				{
					return result;
				}
				return null;
			}
		}

		public static int HideNearbyLaggards => (int)Core.Instance.Mod.Settings[5].SavedValue;

		public static int? LocalTestPing
		{
			get
			{
				string[] array = _testPings.Split(", ");
				int result = 0;
				if (array.Length == 2 && int.TryParse(array[1], out result))
				{
					return result;
				}
				return null;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}