Decompiled source of ReplayMod v1.0.1

Mods/ReplayMod.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using HarmonyLib;
using Il2Cpp;
using Il2CppAudio;
using Il2CppCinemachine;
using Il2CppCoreNet.Components.Client;
using Il2CppCoreNet.Contexts;
using Il2CppCoreNet.Messaging.Messages;
using Il2CppCoreNet.Model;
using Il2CppCoreNet.Objects;
using Il2CppCoreNet.StateSync.Syncs;
using Il2CppCostumes;
using Il2CppFemur;
using Il2CppGB;
using Il2CppGB.Config;
using Il2CppGB.Core;
using Il2CppGB.Core.Loading;
using Il2CppGB.Data.Loading;
using Il2CppGB.Game;
using Il2CppGB.Game.Critters;
using Il2CppGB.Gamemodes;
using Il2CppGB.Networking.Objects;
using Il2CppGB.Networking.Utils;
using Il2CppGB.Platform.Lobby;
using Il2CppGB.Stages.Train;
using Il2CppGB.Stages.Vents;
using Il2CppGB.UI.Beasts;
using Il2CppGB.UI.Menu;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSuperGenius.Lib.Burst.Easing;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using PengooinLabs.ReplayMod;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Replay), "ReplayMod", "1.0.1", "PengooinLabs", null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ReplayMod")]
[assembly: AssemblyConfiguration("release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ReplayMod")]
[assembly: AssemblyTitle("ReplayMod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace PengooinLabs.ReplayMod
{
	public class PositionLoop
	{
		public Vector3 current = Vector3.zero;

		public Vector3 target = Vector3.zero;

		public float speed = 3f;

		public float minThreshold = 0.2f;

		public void tick(float deltaTime)
		{
			if (target.x == current.x && target.y == current.y && target.z == current.z)
			{
				return;
			}
			float num = speed * deltaTime;
			float num2 = current.x;
			float num3 = current.y;
			float num4 = current.z;
			float x = target.x;
			float y = target.y;
			float z = target.z;
			float num5 = x - num2;
			float num6 = y - num3;
			float num7 = z - num4;
			if (num5 < 0f)
			{
				if (num5 > 0f - minThreshold)
				{
					num5 = 0f - minThreshold;
				}
			}
			else if (num5 > 0f && num5 < minThreshold)
			{
				num5 = minThreshold;
			}
			if (num6 < 0f)
			{
				if (num6 > 0f - minThreshold)
				{
					num6 = 0f - minThreshold;
				}
			}
			else if (num6 > 0f && num6 < minThreshold)
			{
				num6 = minThreshold;
			}
			if (num7 < 0f)
			{
				if (num7 > 0f - minThreshold)
				{
					num7 = 0f - minThreshold;
				}
			}
			else if (num7 > 0f && num7 < minThreshold)
			{
				num7 = minThreshold;
			}
			if (num2 != x)
			{
				bool num8 = num2 < x;
				num2 += num5 * num;
				if (num8)
				{
					if (num2 > x)
					{
						num2 = x;
					}
				}
				else if (num2 < x)
				{
					num2 = x;
				}
			}
			if (num3 != y)
			{
				bool num9 = num3 < y;
				num3 += num6 * num;
				if (num9)
				{
					if (num3 > y)
					{
						num3 = y;
					}
				}
				else if (num3 < y)
				{
					num3 = y;
				}
			}
			if (num4 != z)
			{
				bool num10 = num4 < z;
				num4 += num7 * num;
				if (num10)
				{
					if (num4 > z)
					{
						num4 = z;
					}
				}
				else if (num4 < z)
				{
					num4 = z;
				}
			}
			current.x = num2;
			current.y = num3;
			current.z = num4;
		}
	}
	public class RotationLoop
	{
		public Vector3 currentEulers = Vector3.zero;

		public Vector3 targetEulers = Vector3.zero;

		public float speed = 90f;

		private float clampAngle(float angle)
		{
			angle %= 360f;
			if (angle < 0f)
			{
				angle += 360f;
			}
			return angle;
		}

		private float getShortRotation(float from, float to)
		{
			from = clampAngle(from);
			to = clampAngle(to);
			if (to > from)
			{
				if (to - from <= 180f)
				{
					return to - from;
				}
				return 0f - (360f - to + from);
			}
			if (from - to <= 180f)
			{
				return 0f - (from - to);
			}
			return 360f - from + to;
		}

		public void tick(float deltaT)
		{
			if (currentEulers.x == targetEulers.x && currentEulers.y == targetEulers.y && currentEulers.z == targetEulers.z)
			{
				return;
			}
			float num = currentEulers.x;
			float num2 = currentEulers.y;
			float num3 = currentEulers.z;
			float x = targetEulers.x;
			float y = targetEulers.y;
			float z = targetEulers.z;
			float shortRotation = getShortRotation(num, x);
			float shortRotation2 = getShortRotation(num2, y);
			float shortRotation3 = getShortRotation(num3, z);
			float num4 = speed * deltaT;
			if (num != x)
			{
				bool num5 = num < x;
				num += shortRotation * num4;
				if (num5)
				{
					if (num > x)
					{
						num = x;
					}
				}
				else if (num < x)
				{
					num = x;
				}
			}
			if (num2 != y)
			{
				bool num6 = num2 < y;
				num2 += shortRotation2 * num4;
				if (num6)
				{
					if (num2 > y)
					{
						num2 = y;
					}
				}
				else if (num2 < y)
				{
					num2 = y;
				}
			}
			if (num3 != z)
			{
				bool num7 = num3 < z;
				num3 += shortRotation3 * num4;
				if (num7)
				{
					if (num3 > z)
					{
						num3 = z;
					}
				}
				else if (num3 < z)
				{
					num3 = z;
				}
			}
			currentEulers.x = clampAngle(num);
			currentEulers.y = clampAngle(num2);
			currentEulers.z = clampAngle(num3);
		}
	}
	public class Binary
	{
		public static void WriteVector3(BinaryWriter binaryWriter, Vector3 vector3)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			binaryWriter.Write(vector3.x);
			binaryWriter.Write(vector3.y);
			binaryWriter.Write(vector3.z);
		}

		public static void WriteVector2(BinaryWriter binaryWriter, Vector2 vector2)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			binaryWriter.Write(vector2.x);
			binaryWriter.Write(vector2.y);
		}

		public static Vector3 ReadVector3(BinaryReader binaryReader)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
		}

		public static Types._2dAudioClip ReadSound2d(BinaryReader r, string clipName)
		{
			return new Types._2dAudioClip
			{
				time = r.ReadSingle(),
				name = clipName,
				soundType = r.ReadInt32(),
				loop = r.ReadBoolean(),
				volume = r.ReadSingle(),
				pitch = r.ReadSingle(),
				delay = r.ReadSingle()
			};
		}

		public static void WriteSound2d(BinaryWriter w, Types._2dAudioClip clp)
		{
			w.Write(clp.time);
			w.Write(clp.soundType);
			w.Write(clp.loop);
			w.Write(clp.volume);
			w.Write(clp.pitch);
			w.Write(clp.delay);
		}

		public static Types._3dAudioClip ReadSound3d(BinaryReader binaryReader, string clipName)
		{
			return new Types._3dAudioClip
			{
				name = clipName,
				time = binaryReader.ReadSingle(),
				posX = binaryReader.ReadSingle(),
				posY = binaryReader.ReadSingle(),
				posZ = binaryReader.ReadSingle(),
				soundType = binaryReader.ReadInt32(),
				loop = binaryReader.ReadBoolean(),
				volume = binaryReader.ReadSingle(),
				pitch = binaryReader.ReadSingle(),
				delay = binaryReader.ReadSingle(),
				minDistance = binaryReader.ReadSingle(),
				maxDistance = binaryReader.ReadSingle(),
				dopplerLevel = binaryReader.ReadSingle(),
				spatialBlendOverride = binaryReader.ReadSingle()
			};
		}

		public static void WriteSound3d(BinaryWriter w, Types._3dAudioClip clp)
		{
			w.Write(clp.time);
			w.Write(clp.posX);
			w.Write(clp.posY);
			w.Write(clp.posZ);
			w.Write(clp.soundType);
			w.Write(clp.loop);
			w.Write(clp.volume);
			w.Write(clp.pitch);
			w.Write(clp.delay);
			w.Write(clp.minDistance);
			w.Write(clp.maxDistance);
			w.Write(clp.dopplerLevel);
			w.Write(clp.spatialBlendOverride);
		}

		public static Vector3 ReadVector2(BinaryReader binaryReader)
		{
			//IL_000c: 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)
			return Vector2.op_Implicit(new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()));
		}

		public static Glass.ShardContainerData ReadShardContainer(BinaryReader r)
		{
			Glass.ShardContainerData shardContainerData = new Glass.ShardContainerData();
			shardContainerData.key = r.ReadString();
			int num = r.ReadInt32();
			shardContainerData.meshData = new Glass.MeshData[num];
			for (int i = 0; i < num; i++)
			{
				shardContainerData.meshData[i] = ReadShard(r);
			}
			return shardContainerData;
		}

		public static Glass.MeshData ReadShard(BinaryReader r)
		{
			//IL_0017: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)
			int num = r.ReadInt32();
			Vector3[] array = (Vector3[])(object)new Vector3[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = ReadVector3(r);
			}
			int num2 = r.ReadInt32();
			Vector3[] array2 = (Vector3[])(object)new Vector3[num2];
			for (int j = 0; j < num2; j++)
			{
				array2[j] = ReadVector3(r);
			}
			int num3 = r.ReadInt32();
			Vector2[] array3 = (Vector2[])(object)new Vector2[num3];
			for (int k = 0; k < num3; k++)
			{
				array3[k] = Vector2.op_Implicit(ReadVector2(r));
			}
			int num4 = r.ReadInt32();
			int[] array4 = new int[num4];
			for (int l = 0; l < num4; l++)
			{
				array4[l] = r.ReadInt32();
			}
			int num5 = r.ReadInt32();
			int[][] array5 = new int[num5][];
			for (int m = 0; m < num5; m++)
			{
				int num6 = r.ReadInt32();
				array5[m] = new int[num6];
				for (int n = 0; n < num6; n++)
				{
					array5[m][n] = r.ReadInt32();
				}
			}
			return new Glass.MeshData
			{
				triangles = array4,
				submeshIndices = array5,
				uv = array3,
				normals = array,
				vertices = array2
			};
		}
	}
	public class Controls
	{
		public static Vector2 getMouseWheel()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return ((InputControl<Vector2>)(object)Mouse.current.scroll).ReadValue();
		}

		public static bool wasToggleCameraTargetButtonPressed()
		{
			if (Gamepad.current != null && Gamepad.current.buttonEast.wasPressedThisFrame)
			{
				return true;
			}
			if (Keyboard.current != null && !Replay.cfg_disableKeys.Value && ((ButtonControl)Keyboard.current.cKey).wasPressedThisFrame)
			{
				return true;
			}
			return false;
		}

		public static bool wasPrevActorButtonPressed()
		{
			if (Gamepad.current != null && Gamepad.current.leftShoulder.wasPressedThisFrame)
			{
				return true;
			}
			if (Keyboard.current != null && !Replay.cfg_disableKeys.Value && ((ButtonControl)Keyboard.current.aKey).wasPressedThisFrame)
			{
				return true;
			}
			return false;
		}

		public static bool wasNextActorButtonPressed()
		{
			if (Gamepad.current != null && Gamepad.current.rightShoulder.wasPressedThisFrame)
			{
				return true;
			}
			if (Keyboard.current != null && !Replay.cfg_disableKeys.Value && ((ButtonControl)Keyboard.current.dKey).wasPressedThisFrame)
			{
				return true;
			}
			return false;
		}

		public static bool wasPauseButtonPressed()
		{
			if (Gamepad.current != null && Gamepad.current.buttonWest.wasPressedThisFrame)
			{
				return true;
			}
			if (Keyboard.current != null && !Replay.cfg_disableKeys.Value && ((ButtonControl)Keyboard.current.spaceKey).wasPressedThisFrame)
			{
				return true;
			}
			return false;
		}

		public static bool wasSpeedIncreaseKeyPressed()
		{
			if (Keyboard.current != null && !Replay.cfg_disableKeys.Value)
			{
				return ((ButtonControl)Keyboard.current.wKey).wasPressedThisFrame;
			}
			return false;
		}

		public static bool wasSpeedDecreaseKeyPressed()
		{
			if (Keyboard.current != null && !Replay.cfg_disableKeys.Value)
			{
				return ((ButtonControl)Keyboard.current.sKey).wasPressedThisFrame;
			}
			return false;
		}

		public static bool isSpeedControlButtonDown()
		{
			return isLeftTriggerPressed();
		}

		public static bool isFasterSpeedButtonDown()
		{
			return isRightTriggerPressed();
		}

		public static bool isRightTriggerPressed()
		{
			if (Gamepad.current == null)
			{
				return false;
			}
			if (Gamepad.current.rightTrigger.isPressed)
			{
				return true;
			}
			return false;
		}

		public static bool isLeftTriggerPressed()
		{
			if (Gamepad.current == null)
			{
				return false;
			}
			if (Gamepad.current.leftTrigger.isPressed)
			{
				return true;
			}
			return false;
		}
	}
	public class Game
	{
		public enum SceneType
		{
			Menu,
			Loading,
			Fight
		}

		public class SpawnActorOpt
		{
			public string name = "Actor";

			public Color primaryColor = Color.gray;

			public Color costumeColor = Color.gray;

			public ushort[] costumeIdsWithColors = new ushort[0];

			public int controllerId = 10;

			public Vector3 position = Vector3.zero;

			public Quaternion rotation = Quaternion.identity;

			public bool active = true;
		}

		private static SceneType _sceneType = SceneType.Loading;

		public static SceneType sceneType => _sceneType;

		public static void init()
		{
			LoadingHooks.onShowLoadingScreen += delegate
			{
				_sceneType = SceneType.Loading;
			};
			LoadingHooks.onHideLoadingScreen += delegate(string sceneName)
			{
				updateSceneType(sceneName);
			};
			updateSceneType(getSceneName());
		}

		private static void updateSceneType(string sceneName)
		{
			if (sceneName == Global.MENU_SCENE_NAME.ToLower())
			{
				_sceneType = SceneType.Menu;
			}
			else if (sceneName == "_bootscene")
			{
				_sceneType = SceneType.Loading;
			}
			else
			{
				_sceneType = SceneType.Fight;
			}
		}

		public static string getSceneName()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			return ((Scene)(ref activeScene)).name.ToLower();
		}

		public static void startGame(string mapName)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			RotationConfig rotationConfig = GBConfigLoader.CreateRotationConfig(new Il2CppStringArray(new string[1] { mapName }), (GameModeEnum)1, 1, false, 108000, 0);
			LobbyManager instance = LobbyManager.Instance;
			instance.LobbyStates.CurrentState = (State)3;
			instance.LobbyStates.UpdateLobbyState();
			instance.LocalBeasts.SetupNetMemberContext(false);
			NetMemberContext.LocalHostedGame = true;
			MonoSingleton<Global>.Instance.LevelLoadSystem.ShowLoadingScreen(1f, Action.op_Implicit((Action)delegate
			{
				MonoSingleton<Global>.Instance.UNetManager.LaunchHost();
				GameManagerNew.Instance.ChangeRotationConfig(rotationConfig, 0);
			}), -1f, false);
		}

		public static ushort[] getActorCostumeIdsWithColors(Actor actor)
		{
			return Il2CppArrayBase<ushort>.op_Implicit((Il2CppArrayBase<ushort>)(object)actor.CostumeCompRef.SaveEntry.ExtractCostumeItemIDs(true));
		}

		public static Actor spawnActor(SpawnActorOpt opt)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001a: 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_0035: 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_0043: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			NetCostume val = new NetCostume(new CostumeSaveEntry(Il2CppStructArray<ushort>.op_Implicit(opt.costumeIdsWithColors), true));
			val.Voice = Actor.GetRandomVoice(false, true);
			int num = 10;
			NetBeast val2 = new NetBeast(opt.controllerId, val, opt.primaryColor, opt.costumeColor, num, (PlayerType)1, true);
			((NetPlayer)val2).Alive = true;
			GameObject val3 = Object.Instantiate<GameObject>(((Il2CppArrayBase<SpawnInfo>)(object)MonoSingleton<Global>.Instance.SceneLoader.SpawnList.Spawnables)[8].Item, opt.position, opt.rotation);
			((Object)val3).name = opt.name;
			((NetPlayer)val2).Instance = val3;
			Actor component = val3.GetComponent<Actor>();
			component.ControlledBy = (ControlledTypes)1;
			component.playerID = -1;
			component.IsAI = true;
			component.controllerID = ((NetPlayer)val2).ControllerId;
			component.gangID = num;
			Object.FindObjectOfType<NetModel>().Add<NetBeast>("NET_PLAYERS", val2);
			component.DressBeast();
			NetworkServer.Spawn(val3);
			GBNetUtils.SetBeastsGang(val2);
			return component;
		}

		public static bool paused()
		{
			return PauseManager.Instance.IsPaused;
		}

		public static List<TransformCache.TransformInfo> getSubwayLoopAudioSourceTransforms()
		{
			AudioController instance = AudioController.Instance;
			List<TransformCache.TransformInfo> list = new List<TransformCache.TransformInfo>();
			int num = -1;
			for (int i = 0; i < ((Il2CppArrayBase<PooledAudioSource>)(object)instance._pooledSources).Count; i++)
			{
				PooledAudioSource val = ((Il2CppArrayBase<PooledAudioSource>)(object)instance._pooledSources)[i];
				if (val != null && (Object)(object)val.audioSource != (Object)null && (Object)(object)val.audioSource.clip != (Object)null && ((Object)val.audioSource.clip).name == "Subway Loop")
				{
					num++;
					string key = "audioclip:Subway Loop:" + num;
					TransformCache.TransformInfo item = Replay.tc.addTransformWithKey(((Component)val.audioSource).transform, key);
					list.Add(item);
				}
			}
			return list;
		}

		public static byte getActorBlink(Actor actor)
		{
			return (byte)(int)actor.effectsHandeler.blink;
		}

		public static void setActorBlink(Actor actor, float blink)
		{
			if ((Object)(object)actor.effectsHandeler != (Object)null && (Object)(object)actor.effectsHandeler.headMesh != (Object)null)
			{
				actor.effectsHandeler.headMesh.SetBlendShapeWeight(3, blink);
			}
		}

		public static void setBirdBlink(BirdActor bird, byte blink)
		{
			if ((Object)(object)bird.skinnedMeshRenderer != (Object)null)
			{
				float num = (((float)(int)blink > 100f) ? 100f : ((float)(int)blink));
				try
				{
					bird.skinnedMeshRenderer.SetBlendShapeWeight(0, num);
				}
				catch
				{
					Replay.logError("exception setting weight " + num);
				}
			}
		}

		public static string getVersion()
		{
			return GBConfigResourceLoader.ConfigData.GameVersion;
		}

		public static bool isInLocalGameMenu()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			if (sceneType != SceneType.Menu)
			{
				return false;
			}
			return (int)LobbyManager.Instance.LobbyStates.SelfState == 2;
		}

		public static bool isInOnlineGameMenu()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			if (sceneType != SceneType.Menu)
			{
				return false;
			}
			return (int)LobbyManager.Instance.LobbyStates.SelfState == 3;
		}

		public static bool isLobbyCountdownActive()
		{
			return false;
		}

		public static bool isSinglePlayerSelected()
		{
			int num = LobbyManager.Instance.LocalBeasts.TotalInState((PlayerState)1);
			int num2 = LobbyManager.Instance.LocalBeasts.TotalInState((PlayerState)2);
			return num + num2 == 1;
		}

		public static void returnToMenu()
		{
			PauseManager.instance.OnReturnToMenu();
		}
	}
	public class Glass
	{
		public class MeshData
		{
			public int[] triangles;

			public int[][] submeshIndices;

			public Vector2[] uv;

			public Vector3[] normals;

			public Vector3[] vertices;
		}

		public class ShardContainerData
		{
			public string key = "";

			public MeshData[] meshData;
		}

		public static List<GameObject> getShardContainers()
		{
			Dictionary<GameObject, bool> dictionary = new Dictionary<GameObject, bool>();
			Il2CppArrayBase<FractureShard> val = Resources.FindObjectsOfTypeAll<FractureShard>();
			for (int i = 0; i < val.Length; i++)
			{
				Transform parent = ((Component)val[i]).gameObject.transform.parent;
				if ((Object)(object)parent != (Object)null)
				{
					dictionary[((Component)parent).gameObject] = true;
				}
			}
			if (Game.getSceneName() == "incinerator")
			{
				foreach (Transform transform in Tools.getTransforms(new List<string> { "Scene/Geometry/Door (Windowed)/door_windowed (1)/door_frame_200cm/door_windowed/door_windowed_glassLower_fractured", "Scene/Geometry/Door (Windowed)/door_windowed (1)/door_frame_200cm/door_windowed/door_windowed_glassUpper_fractured", "Scene/Geometry/Door (Windowed)/door_windowed (2)/door_frame_200cm/door_windowed/door_windowed_glassLower_fractured", "Scene/Geometry/Door (Windowed)/door_windowed (2)/door_frame_200cm/door_windowed/door_windowed_glassUpper_fractured" }, withChildren: false))
				{
					if (!dictionary.ContainsKey(((Component)transform).gameObject))
					{
						dictionary[((Component)transform).gameObject] = true;
					}
				}
			}
			return dictionary.Keys.ToList();
		}

		public static void indexGlass()
		{
			foreach (GameObject shardContainer in getShardContainers())
			{
				int num = 0;
				foreach (Transform transformChild in Tools.getTransformChildren(shardContainer.transform))
				{
					Replay.tc.setFixedSingleTransformKey(transformChild, "Shard#" + num++);
				}
			}
		}

		private static void synchronizeShardMeshData(GameObject shardObject, MeshData data)
		{
			MeshFilter component = shardObject.GetComponent<MeshFilter>();
			Mesh mesh = component.mesh;
			mesh.normals = Il2CppStructArray<Vector3>.op_Implicit(data.normals);
			mesh.triangles = Il2CppStructArray<int>.op_Implicit(data.triangles);
			mesh.uv = Il2CppStructArray<Vector2>.op_Implicit(data.uv);
			mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(data.vertices);
			mesh.subMeshCount = data.submeshIndices.Length;
			for (int i = 0; i < data.submeshIndices.Length; i++)
			{
				mesh.SetTriangles(Il2CppStructArray<int>.op_Implicit(data.submeshIndices[i]), i);
			}
			component.mesh.RecalculateNormals();
			component.mesh.RecalculateBounds();
			component.mesh.RecalculateTangents();
		}

		private static void synchronizeGlassContainer(GameObject shardContainer, int count, GameObject? cloneShard)
		{
			while (shardContainer.transform.childCount > count)
			{
				Object.DestroyImmediate((Object)(object)((Component)shardContainer.transform.GetChild(0)).gameObject);
			}
			while (shardContainer.transform.childCount < count)
			{
				if ((Object)(object)cloneShard == (Object)null)
				{
					return;
				}
				GameObject obj = Object.Instantiate<GameObject>(cloneShard);
				obj.transform.SetParent(shardContainer.transform, false);
				obj.SetActive(true);
			}
			List<Transform> transformChildren = Tools.getTransformChildren(shardContainer.transform);
			for (int i = 0; i < transformChildren.Count; i++)
			{
				((Object)transformChildren[i]).name = "Shard#" + i;
			}
		}

		public static void synchronizeGlass(ShardContainerData data, GameObject? cloneShard)
		{
			string transformKey = data.key;
			GameObject val = getShardContainers().Find((GameObject c) => Replay.tc.getTransformInfo(c.transform).key == transformKey);
			if ((Object)(object)val == (Object)null)
			{
				Replay.logError("failed to find shard container " + data.key + "!");
				return;
			}
			int count = data.meshData.Length;
			synchronizeGlassContainer(val, count, cloneShard);
			for (int num = 0; num < val.transform.childCount; num++)
			{
				GameObject gameObject = ((Component)val.transform.GetChild(num)).gameObject;
				synchronizeShardMeshData(gameObject, data.meshData[num]);
				((Object)gameObject).name = "Shard#" + num;
			}
		}
	}
	public class Loader
	{
		public static class LoaderPatch
		{
			[HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object) })]
			[HarmonyPrefix]
			public static bool Object_Destroy(Object obj)
			{
				if (!Replay.loader.preventDestruction)
				{
					return true;
				}
				if (obj != (Object)null && (obj.name.StartsWith("trafficCone") || obj.name.StartsWith("puddle")))
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(Actor), "set_actorState")]
			[HarmonyPrefix]
			public static bool Actor_set_actorState(Actor __instance, ref ActorState value)
			{
				if (Replay.modState == Replay.ModState.LoadingReplay)
				{
					return false;
				}
				return true;
			}
		}

		private string mapName = "";

		private Dictionary<Types.CaptureGroupId, List<Types.Frame>> frameGroups = new Dictionary<Types.CaptureGroupId, List<Types.Frame>>();

		private List<Actor> spawnedActors = new List<Actor>();

		private List<Types.ActorInfo> lateActors = new List<Types.ActorInfo>();

		private List<Types.ActorInfo> actorInfos = new List<Types.ActorInfo>();

		private Dictionary<Actor, string> actorNames = new Dictionary<Actor, string>();

		private List<BirdActor> replayBirds = new List<BirdActor>();

		private List<Glass.ShardContainerData> shardContainersData = new List<Glass.ShardContainerData>();

		private Dictionary<string, Types.ItemState> staticItemStates = new Dictionary<string, Types.ItemState>();

		public float waitForActorsReadyTimeout;

		private Harmony? harmony;

		private bool preventDestruction = true;

		public Loader()
		{
			patch();
		}

		public Dictionary<string, Types.ItemState> getStaticItemStates()
		{
			return staticItemStates;
		}

		public string getMapName()
		{
			return mapName;
		}

		public List<Actor> getActors()
		{
			return spawnedActors;
		}

		public Dictionary<Types.CaptureGroupId, List<Types.Frame>> getFrameGroups()
		{
			return frameGroups;
		}

		public Dictionary<Actor, string> getActorNames()
		{
			return actorNames;
		}

		public List<BirdActor> getBirds()
		{
			return replayBirds;
		}

		public bool loadFromFile(string absFilePath)
		{
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				using MemoryStream input = new MemoryStream(File.ReadAllBytes(absFilePath));
				BinaryReader binaryReader = new BinaryReader(input);
				actorInfos.Clear();
				int contentFlags;
				try
				{
					contentFlags = binaryReader.ReadInt32();
					mapName = binaryReader.ReadString();
					actorInfos.Clear();
					shardContainersData.Clear();
					lateActors.Clear();
					binaryReader.ReadInt32();
					while (binaryReader.PeekChar() == 0)
					{
						binaryReader.ReadByte();
						Types.ActorInfo item = binaryReadActorInfo(binaryReader, contentFlags);
						actorInfos.Add(item);
					}
				}
				catch (Exception ex)
				{
					Replay.logError("Exception loading replay (block 1): " + ex);
					return false;
				}
				Dictionary<int, string> dictionary = new Dictionary<int, string>();
				Dictionary<int, string> dictionary2 = new Dictionary<int, string>();
				Dictionary<string, Vector3> dictionary3 = new Dictionary<string, Vector3>();
				bool flag = false;
				frameGroups.Clear();
				Types.Frame frame = null;
				Types.Frame frame2 = null;
				Types.Frame frame3 = null;
				try
				{
					while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length)
					{
						byte b = binaryReader.ReadByte();
						if (b != 1 && b != 4 && b != 0)
						{
							Replay.logError("expected a frame or shardcontainer indicator, but datatype is " + b);
							flag = true;
							throw new Exception("Invalid Data");
						}
						switch (b)
						{
						case 4:
						{
							Glass.ShardContainerData item4 = Binary.ReadShardContainer(binaryReader);
							shardContainersData.Add(item4);
							break;
						}
						case 0:
						{
							Types.ActorInfo item5 = binaryReadActorInfo(binaryReader, contentFlags);
							lateActors.Add(item5);
							break;
						}
						case 1:
						{
							Types.Frame frame4 = new Types.Frame();
							frame4.groupId = (Types.CaptureGroupId)binaryReader.ReadByte();
							if (!frameGroups.ContainsKey(frame4.groupId))
							{
								frameGroups[frame4.groupId] = new List<Types.Frame>();
							}
							frame4.index = frameGroups[frame4.groupId].Count;
							frame4.time = binaryReader.ReadSingle();
							if (frame4.groupId == Types.CaptureGroupId.Environment)
							{
								byte b2 = binaryReader.ReadByte();
								if (b2 > 0)
								{
									frame4.actorStates = new List<byte>();
									for (int i = 0; i < b2; i++)
									{
										frame4.actorStates.Add(binaryReader.ReadByte());
									}
									frame3 = frame4;
								}
								else
								{
									if (frame3 == null)
									{
										throw new Exception("Can't link actorStates because there's no lastFrameWithActorStates");
									}
									frame4.actorStates = frame3.actorStates;
								}
								byte b3 = binaryReader.ReadByte();
								if (b3 > 0)
								{
									frame4.actorBlinks = new List<byte>();
									for (int j = 0; j < b3; j++)
									{
										frame4.actorBlinks.Add(binaryReader.ReadByte());
									}
									frame = frame4;
								}
								else
								{
									if (frame == null)
									{
										throw new Exception("Can't link actorBlinks because there's no lastFrameWithActorBlinks");
									}
									frame4.actorBlinks = frame.actorBlinks;
								}
								byte b4 = binaryReader.ReadByte();
								if (b4 > 0)
								{
									frame4.birdBlinks = new List<byte>();
									for (int k = 0; k < b4; k++)
									{
										frame4.birdBlinks.Add(binaryReader.ReadByte());
									}
									frame2 = frame4;
								}
								else if (frame2 != null)
								{
									frame4.birdBlinks = frame2.birdBlinks;
								}
							}
							while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length)
							{
								int num = binaryReader.PeekChar();
								if (num != 3 && num != 5 && num != 2 && num != 7 && num != 6)
								{
									break;
								}
								byte b5 = binaryReader.ReadByte();
								switch (b5)
								{
								case 3:
								{
									int key5 = binaryReader.ReadInt32();
									string value2 = binaryReader.ReadString();
									dictionary[key5] = value2;
									break;
								}
								case 5:
								{
									int key3 = binaryReader.ReadInt32();
									string value = binaryReader.ReadString();
									dictionary2[key3] = value;
									break;
								}
								case 7:
								{
									int key4 = binaryReader.ReadInt32();
									string clipName2 = dictionary2[key4];
									Types._3dAudioClip item3 = Binary.ReadSound3d(binaryReader, clipName2);
									if (frame4.sounds3d == null)
									{
										frame4.sounds3d = new List<Types._3dAudioClip>();
									}
									frame4.sounds3d.Add(item3);
									break;
								}
								case 6:
								{
									int key2 = binaryReader.ReadInt32();
									string clipName = dictionary2[key2];
									Types._2dAudioClip item2 = Binary.ReadSound2d(binaryReader, clipName);
									if (frame4.sounds2d == null)
									{
										frame4.sounds2d = new List<Types._2dAudioClip>();
									}
									frame4.sounds2d.Add(item2);
									break;
								}
								case 2:
								{
									int key = binaryReader.ReadInt32();
									if (!dictionary.ContainsKey(key))
									{
										throw new Exception("Missing key name of keyIndex " + key);
									}
									string text = dictionary[key];
									Types.ItemState itemState = new Types.ItemState();
									ushort num2 = binaryReader.ReadUInt16();
									itemState.active = (num2 & 2) > 0;
									if ((num2 & 1) > 0)
									{
										itemState.pos = Binary.ReadVector3(binaryReader);
										dictionary3[text + "_position"] = itemState.pos;
									}
									else
									{
										itemState.pos = dictionary3[text + "_position"];
									}
									if ((num2 & 4) > 0)
									{
										itemState.lscale = Binary.ReadVector3(binaryReader);
										dictionary3[text + "_localScale"] = itemState.lscale;
									}
									else
									{
										itemState.lscale = dictionary3[text + "_localScale"];
									}
									if ((num2 & 8) > 0)
									{
										itemState.rot = Binary.ReadVector3(binaryReader);
										dictionary3[text + "_rotation"] = itemState.rot;
									}
									else
									{
										itemState.rot = dictionary3[text + "_rotation"];
									}
									frame4.states[text] = itemState;
									break;
								}
								default:
									Replay.logError("invalid datatype read, expected keymap or itemstate. datatype value is " + b5);
									flag = true;
									throw new Exception("Invalid Data");
								}
							}
							frameGroups[frame4.groupId].Add(frame4);
							break;
						}
						}
					}
				}
				catch (Exception ex2)
				{
					Replay.logError("Exception reading frames: " + ex2);
				}
				if (flag)
				{
					throw new Exception("Invalid Data");
				}
				foreach (Types.CaptureGroupId item6 in frameGroups.Keys.Where((Types.CaptureGroupId key6) => frameGroups[key6].Count == 0).ToList())
				{
					frameGroups.Remove(item6);
				}
				if (frameGroups.Count == 0)
				{
					Replay.logError("no complete frames in replay file (incomplete data?), aborting load");
					return false;
				}
				if (actorInfos.Count == 0)
				{
					Replay.logError("replay contains no actors (incomplete data?), aborting load");
					return false;
				}
				fixDeathBug(frameGroups[Types.CaptureGroupId.Actor]);
				fixLateActors(frameGroups[Types.CaptureGroupId.Actor]);
				staticItemStates.Clear();
				foreach (KeyValuePair<Types.CaptureGroupId, List<Types.Frame>> frameGroup in frameGroups)
				{
					_ = frameGroup.Key;
					List<Types.Frame> value3 = frameGroup.Value;
					extractStaticItems(value3);
				}
				foreach (List<Types.Frame> value4 in frameGroups.Values)
				{
					padFrameData(value4);
				}
			}
			catch (Exception ex3)
			{
				Replay.logError("exception in loadReplay: " + ex3);
				return false;
			}
			return true;
		}

		private void extractStaticItems(List<Types.Frame> frames)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			Dictionary<string, Dictionary<string, Types.ItemState>> dictionary2 = new Dictionary<string, Dictionary<string, Types.ItemState>>();
			foreach (Types.Frame frame in frames)
			{
				foreach (KeyValuePair<string, Types.ItemState> state in frame.states)
				{
					string key = state.Key;
					if (!dictionary.ContainsKey(key))
					{
						dictionary[key] = 0;
					}
					dictionary[key]++;
					dictionary2[key] = frame.states;
				}
			}
			foreach (KeyValuePair<string, int> item in dictionary)
			{
				string key2 = item.Key;
				if (item.Value == 1)
				{
					staticItemStates[key2] = dictionary2[key2][key2];
					dictionary2[key2].Remove(key2);
				}
			}
		}

		private void fixLateActors(List<Types.Frame> actorFrames)
		{
			//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_0062: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<string, bool> allTransformKeysInFrame in getAllTransformKeysInFrames(actorFrames))
			{
				string key = allTransformKeysInFrame.Key;
				if (key.StartsWith("Actor#") && !actorFrames[0].states.ContainsKey(key))
				{
					Types.ItemState firstState = getFirstState(actorFrames, key);
					Types.ItemState itemState = new Types.ItemState();
					itemState.pos = firstState.pos;
					itemState.rot = firstState.rot;
					itemState.lscale = firstState.lscale;
					itemState.active = false;
					actorFrames[0].states[key] = itemState;
				}
			}
		}

		private static Dictionary<string, bool> getAllTransformKeysInFrames(List<Types.Frame> frames)
		{
			Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
			for (int i = 0; i < frames.Count; i++)
			{
				foreach (KeyValuePair<string, Types.ItemState> state in frames[i].states)
				{
					dictionary[state.Key] = true;
				}
			}
			return dictionary;
		}

		private Types.ItemState? getFirstState(List<Types.Frame> inFrames, string key)
		{
			for (int i = 0; i < inFrames.Count; i++)
			{
				Types.Frame frame = inFrames[i];
				if (frame.states.ContainsKey(key))
				{
					return frame.states[key];
				}
			}
			return null;
		}

		public void setupMapForReplay()
		{
			try
			{
				setupMapForReplayImpl();
			}
			catch (Exception ex)
			{
				Replay.logError("Exception in setupMapForReplay (incomplete replay data?): " + ex);
				Replay.abortLoading();
			}
		}

		private void setupMapForReplayImpl()
		{
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_0194: 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_01af: Unknown result type (might be due to invalid IL or missing references)
			Replay.setTimeScale(0f);
			replayBirds = Replay.indexBirds(playing: true);
			float[] array = new float[3] { 65f, 0f, 12f };
			string sceneName = Game.getSceneName();
			if (sceneName == "ring")
			{
				array[1] = 180f;
			}
			else if (sceneName == "billboard")
			{
				array[1] = 90f;
			}
			Replay.camera.setUD(array[0], immediate: true);
			Replay.camera.setLR(array[1], immediate: true);
			Replay.camera.setDistance(array[2], immediate: true);
			destroyExistingActors();
			int aI_CONTROLLER_STARTIDEX = GameMode_Waves.AI_CONTROLLER_STARTIDEX;
			List<Types.ActorInfo> list = new List<Types.ActorInfo>(actorInfos);
			list.AddRange(lateActors);
			actorNames.Clear();
			for (int i = 0; i < list.Count; i++)
			{
				Types.ActorInfo actorInfo = list[i];
				string text = "Actor#" + i;
				Types.ItemState itemState = null;
				itemState = ((!staticItemStates.ContainsKey(text)) ? getFirstState(frameGroups[Types.CaptureGroupId.Actor], text) : staticItemStates[text]);
				if (itemState == null)
				{
					throw new Exception("Failed to find first state of " + text);
				}
				Actor val = Game.spawnActor(new Game.SpawnActorOpt
				{
					name = "Actor#" + i,
					primaryColor = actorInfo.primaryColor,
					costumeColor = actorInfo.CostumeColor,
					costumeIdsWithColors = actorInfo.costumeIdsWithColors,
					controllerId = aI_CONTROLLER_STARTIDEX++,
					position = itemState.pos,
					rotation = Quaternion.Euler(itemState.rot)
				});
				actorNames[val] = Types.getSpeakingNameOfColor(actorInfo.primaryColor);
				spawnedActors.Add(val);
				((Component)val).gameObject.SetActive(true);
			}
			if (spawnedActors.Count == 0)
			{
				Replay.logError("no actors in replay (incomplete data?), aborting");
				Replay.abortLoading();
			}
			else
			{
				waitForActorsReadyTimeout = 5f;
				Replay.nextSetupStep = replaySetup_waitForActorsReady;
			}
		}

		private void replaySetup_waitForActorsReady()
		{
			try
			{
				replaySetup_waitForActorsReadyImpl();
			}
			catch (Exception ex)
			{
				Replay.logError("Exception in replaySetup_waitForActorsReady (incomplete replay data?): " + ex);
				Replay.abortLoading();
			}
		}

		private void replaySetup_waitForActorsReadyImpl()
		{
			if ((Object)(object)spawnedActors.Find((Actor actor) => Tools.isGrayColor(actor.primaryColor)) != (Object)null)
			{
				waitForActorsReadyTimeout -= Time.unscaledDeltaTime;
				if (waitForActorsReadyTimeout <= 0f)
				{
					Replay.abortLoading();
				}
				return;
			}
			for (int num = 0; num < spawnedActors.Count; num++)
			{
				Actor val = spawnedActors[num];
				string name = ((Object)((Component)val).gameObject).name;
				if (!frameGroups[Types.CaptureGroupId.Actor][0].states.ContainsKey(name))
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
			if (mapName == "alley")
			{
				spawnBall();
			}
			preventDestruction = false;
			synchronizeMap();
			fixStickyness();
			Replay.disableInterferences();
			Replay.tc.refresh();
			if (mapName == "subway")
			{
				Game.getSubwayLoopAudioSourceTransforms();
			}
			Replay.replaySetup_createPlayer();
		}

		private Types.ActorInfo binaryReadActorInfo(BinaryReader reader, int contentFlags)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			Types.ActorInfo actorInfo = new Types.ActorInfo();
			actorInfo.primaryColor = new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
			actorInfo.CostumeColor = new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
			int num = reader.ReadInt32();
			ushort[] array = new ushort[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = reader.ReadUInt16();
			}
			actorInfo.costumeIdsWithColors = array;
			return actorInfo;
		}

		private void destroyExistingActors()
		{
			List<Actor> list = new List<Actor>();
			Enumerator<Actor> enumerator = Actor._ActorCache.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Actor current = enumerator.Current;
				list.Add(current);
			}
			foreach (Actor item in list)
			{
				Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
			}
		}

		private void padFrameData(List<Types.Frame> frames)
		{
			Dictionary<string, Types.ItemState> dictionary = new Dictionary<string, Types.ItemState>();
			for (int i = 0; i < frames.Count; i++)
			{
				Types.Frame frame = frames[i];
				foreach (KeyValuePair<string, Types.ItemState> state in frame.states)
				{
					string key = state.Key;
					Types.ItemState value = state.Value;
					dictionary[key] = value;
				}
				foreach (KeyValuePair<string, Types.ItemState> item in dictionary)
				{
					if (!frame.states.ContainsKey(item.Key))
					{
						frame.states[item.Key] = item.Value;
					}
				}
			}
		}

		private void fixDeathBug(List<Types.Frame> actorFrames)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0053: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < actorFrames.Count; i++)
			{
				foreach (string key in actorFrames[i].states.Keys)
				{
					Types.ItemState itemState = actorFrames[i].states[key];
					if (itemState.pos == Vector3.zero)
					{
						Vector3 rot = itemState.rot;
						Quaternion identity = Quaternion.identity;
						if (rot == ((Quaternion)(ref identity)).eulerAngles && !itemState.active && key.StartsWith("Actor#"))
						{
							actorFrames[i].states.Remove(key);
						}
					}
				}
			}
		}

		private void synchronizeMap()
		{
			string sceneName = Game.getSceneName();
			if (sceneName == "buoy")
			{
				foreach (Transform item in ((IEnumerable<Transform>)Object.FindObjectsByType<Transform>((FindObjectsInactive)1, (FindObjectsSortMode)0)).Where((Transform t) => ((Object)t).name.StartsWith("IceChunk_")))
				{
					((Component)item).gameObject.SetActive(false);
				}
			}
			else if (sceneName == "subway")
			{
				Dictionary<string, bool> allTransformKeysInFrames = getAllTransformKeysInFrames(frameGroups[Types.CaptureGroupId.Environment]);
				List<GameObject> source = ((IEnumerable<GameObject>)Object.FindObjectsByType<GameObject>((FindObjectsInactive)1, (FindObjectsSortMode)0)).Where((GameObject go) => ((Object)go).name.StartsWith("trafficCone (")).ToList();
				int i;
				for (i = 0; i < 5; i++)
				{
					GameObject val = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => ((Object)go).name == "trafficCone (" + i + ")"));
					if ((Object)(object)val != (Object)null)
					{
						string key = Replay.tc.getTransformInfo(val.transform).key;
						if (!allTransformKeysInFrames.ContainsKey(key))
						{
							val.SetActive(false);
						}
						else
						{
							val.SetActive(true);
						}
					}
				}
				GameObject val2 = GameObject.Find("PuddleGroup/drip");
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetActive(false);
				}
				GameObject val3 = GameObject.Find("PuddleGroup/puddle");
				if ((Object)(object)val3 != (Object)null)
				{
					if (!allTransformKeysInFrames.ContainsKey(Replay.tc.getTransformInfo(val3.transform).key))
					{
						val3.SetActive(false);
					}
					else
					{
						val3.SetActive(true);
					}
				}
			}
			if (shardContainersData.Count <= 0)
			{
				return;
			}
			FractureShard obj = Object.FindObjectOfType<FractureShard>(true);
			GameObject cloneShard = ((obj != null) ? ((Component)obj).gameObject : null);
			foreach (Glass.ShardContainerData shardContainersDatum in shardContainersData)
			{
				Glass.synchronizeGlass(shardContainersDatum, cloneShard);
			}
		}

		private void fixStickyness()
		{
			string sceneName = Game.getSceneName();
			if (sceneName == "crane")
			{
				GameObject obj = GameObject.Find("/Crane");
				obj.SetActive(false);
				obj.SetActive(true);
			}
			else if (sceneName == "containers")
			{
				GameObject obj2 = GameObject.Find("/Crane A");
				obj2.SetActive(false);
				obj2.SetActive(true);
				GameObject obj3 = GameObject.Find("/Crane B");
				obj3.SetActive(false);
				obj3.SetActive(true);
			}
		}

		private void spawnBall()
		{
			//IL_0014: 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)
			NetworkServer.Spawn(Object.Instantiate<GameObject>(MonoSingleton<Global>.Instance.SceneLoader.FootballData.Football, Vector3.zero, Quaternion.identity));
		}

		public void patch()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if (harmony == null)
			{
				harmony = Harmony.CreateAndPatchAll(typeof(LoaderPatch), (string)null);
				MethodInfo methodInfo = (from m in typeof(AudioController).GetMethods()
					where m.Name == "Play3DAt" && m.GetParameters().Length == 15
					select m).ToList().First();
				HarmonyMethod val = new HarmonyMethod(typeof(Loader).GetMethod("handlePlay3DAt"));
				if (harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null) == null)
				{
					Replay.logError("failed to patch Play3DAt");
				}
			}
		}

		public static bool handlePlay3DAt(AudioController __instance, AudioClip clip, Vector3 location, Transform? target = null, SoundType soundType = (SoundType)1, Action? onComplete = null, bool loop = false, float volume = 1f, float pitch = 1f, float delay = 0f, float minDistance = 1f, float maxDistance = 500f, float dopplerLevel = 0f, AudioMixerGroup? mixerGroup = null, PooledAudioSource? pooledSource = null, float spatialBlendOverride = 1f)
		{
			if (Replay.modState == Replay.ModState.LoadingReplay && ((Object)clip).name.StartsWith("Final KO "))
			{
				return false;
			}
			return true;
		}

		public void unpatch()
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
				harmony = null;
			}
		}

		public void destroy()
		{
			unpatch();
		}
	}
	public class LoadingHooks
	{
		public class LoadingPatch
		{
			[HarmonyPatch(typeof(LoadScreenSystem), "HideLoadingScreen")]
			[HarmonyPostfix]
			public static void LoadScreenSystem_HideLoadingScreen(LoadScreenSystem __instance)
			{
				string sceneName = Game.getSceneName();
				if (LoadingHooks.onHideLoadingScreen != null)
				{
					LoadingHooks.onHideLoadingScreen(sceneName);
				}
				__instance.internalOnHideCompleted += Action.op_Implicit((Action)delegate
				{
					if (LoadingHooks.onLoadingScreenHidden != null)
					{
						LoadingHooks.onLoadingScreenHidden(sceneName);
					}
				});
			}

			[HarmonyPatch(typeof(LoadScreenSystem), "ShowLoadingScreen")]
			[HarmonyPostfix]
			public static void LoadScreenSystem_ShowLoadingScreen(LoadScreenSystem __instance)
			{
				if (LoadingHooks.onShowLoadingScreen != null)
				{
					LoadingHooks.onShowLoadingScreen();
				}
			}
		}

		public static Harmony? harmony;

		public static event Action? onShowLoadingScreen;

		public static event Action<string>? onHideLoadingScreen;

		public static event Action<string>? onLoadingScreenHidden;

		public static void init()
		{
			harmony = Harmony.CreateAndPatchAll(typeof(LoadingPatch), (string)null);
		}
	}
	public class Menus
	{
		private static int lastReplayCount = 0;

		public static int pageIndex = -1;

		public static Rect replayOptionsMenuRect = default(Rect);

		private static GUIStyle? _projectLinkStyle = null;

		private static float replayItemHeight = 0f;

		private static float navButtonHeight = 0f;

		private static float closeButtonHeight = 0f;

		public static Rect fileListRect = default(Rect);

		private static GUIStyle? _helpTextStyle = null;

		public static Rect helpRect = default(Rect);

		public static GUIStyle projectLinkStyle
		{
			get
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Expected O, but got Unknown
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: 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_0077: Expected O, but got Unknown
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				if (_projectLinkStyle == null)
				{
					_projectLinkStyle = new GUIStyle(GUI.skin.button);
					_projectLinkStyle.fontSize = Vars.projectLinkFontSize;
					_projectLinkStyle.normal.textColor = Colors.projectLinkTextColor;
					_projectLinkStyle.hover.textColor = Colors.projectLinkHoverColor;
					_projectLinkStyle.alignment = (TextAnchor)4;
					_projectLinkStyle.padding = new RectOffset(10, 10, 10, 10);
					_projectLinkStyle.normal.background = null;
					_projectLinkStyle.hover.background = null;
					_projectLinkStyle.active.background = null;
				}
				if (UI.isRepaintStep())
				{
					GUIStyleState normal = _projectLinkStyle.normal;
					if (normal.background == null)
					{
						Texture2D val = (normal.background = UI.getTexture2D(Colors.transparent));
					}
					normal = _projectLinkStyle.hover;
					if (normal.background == null)
					{
						Texture2D val = (normal.background = UI.getTexture2D(Colors.transparent));
					}
				}
				return _projectLinkStyle;
			}
		}

		public static GUIStyle helpTextStyle
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				//IL_001b: 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_0056: Expected O, but got Unknown
				if (_helpTextStyle == null)
				{
					_helpTextStyle = new GUIStyle();
					_helpTextStyle.normal.textColor = Color.gray;
					_helpTextStyle.fontSize = Vars.menuFontSize;
					_helpTextStyle.wordWrap = true;
					_helpTextStyle.padding = new RectOffset(10, 10, 10, 10);
				}
				return _helpTextStyle;
			}
		}

		public static void drawReplayOptions()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginArea(new Rect((float)Vars.menuOffsetLeft, (float)(Screen.height - Replay.bottomBarHeight) - ((Rect)(ref replayOptionsMenuRect)).height - (float)Vars.menuOffsetBottom, ((Rect)(ref replayOptionsMenuRect)).width, ((Rect)(ref replayOptionsMenuRect)).height));
			GUILayout.BeginVertical(UI.backgroundStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Vars.menuWidth) });
			UI.section("Replay options");
			int num = (int)UI.SliderOption("Mousewheel speed step (ct)", Replay.cfg_mousewheel_speed_step.Value, 5f, 20f, 0);
			if (num != Replay.cfg_mousewheel_speed_step.Value)
			{
				Replay.cfg_mousewheel_speed_step.Value = num;
			}
			if (UI.Option("Hide UI when screenshotting via F12", Replay.cfg_hideUiOnScreenShot.Value ? "Yes" : "No"))
			{
				Replay.cfg_hideUiOnScreenShot.Value = !Replay.cfg_hideUiOnScreenShot.Value;
			}
			string valueText = ((Replay.cfg_cameraMode.Value == Types.CameraMode.SURROUND) ? "360°" : "Disabled");
			if (UI.Option("Camera mode:", valueText))
			{
				Replay.cfg_cameraMode.Value = Tools.cycleOption(new List<Types.CameraMode>
				{
					Types.CameraMode.SURROUND,
					Types.CameraMode.IGNORE
				}, Replay.cfg_cameraMode.Value);
			}
			if (Replay.cfg_cameraMode.Value == Types.CameraMode.SURROUND)
			{
				string valueText2 = ((Replay.cfg_camera_target.Value == ReplayCamera.CameraTarget.Chest) ? "Chest" : ((Replay.cfg_camera_target.Value == ReplayCamera.CameraTarget.Head) ? "Head" : "Smooth"));
				if (UI.Option("Camera targeting:", valueText2))
				{
					Replay.toggleCameraTargeting();
				}
				if (UI.Option("Switch camera target when player dies:", Replay.cfg_switchCameraOnActorDeath.Value ? "Yes" : "No"))
				{
					Replay.cfg_switchCameraOnActorDeath.Value = !Replay.cfg_switchCameraOnActorDeath.Value;
				}
				string valueText3 = ((Replay.cfg_invertMouseAxes.Value == Types.AXIS_INVERSION.NO) ? "None" : ((Replay.cfg_invertMouseAxes.Value == Types.AXIS_INVERSION.X) ? "X-Axis" : ((Replay.cfg_invertMouseAxes.Value == Types.AXIS_INVERSION.Y) ? "Y-Axis" : "Both")));
				if (UI.Option("Invert mouse rotation axes:", valueText3))
				{
					Replay.cfg_invertMouseAxes.Value = Tools.cycleOption(new List<Types.AXIS_INVERSION>
					{
						Types.AXIS_INVERSION.NO,
						Types.AXIS_INVERSION.X,
						Types.AXIS_INVERSION.Y,
						Types.AXIS_INVERSION.XY
					}, Replay.cfg_invertMouseAxes.Value);
				}
				int num2 = (int)UI.SliderOption("Mouse rotation sensitivity (X)", Replay.cfg_mouse_sensitivity_x.Value, Replay.cfg_mouse_sensitivity_x_min.Value, Replay.cfg_mouse_sensitivity_x_max.Value, 0);
				if (num2 != Replay.cfg_mouse_sensitivity_x.Value)
				{
					Replay.cfg_mouse_sensitivity_x.Value = num2;
				}
				int value = (int)UI.SliderOption("Mouse rotation sensitivity (Y)", Replay.cfg_mouse_sensitivity_y.Value, Replay.cfg_mouse_sensitivity_y_min.Value, Replay.cfg_mouse_sensitivity_y_max.Value, 0);
				if (num2 != Replay.cfg_mouse_sensitivity_y.Value)
				{
					Replay.cfg_mouse_sensitivity_y.Value = value;
				}
				int num3 = (int)UI.SliderOption("Mousewheel zoom sensitivity", Replay.cfg_mousewheel_zoom_sensitivity.Value, 20f, 140f, 0);
				if (num3 != Replay.cfg_mousewheel_zoom_sensitivity.Value)
				{
					Replay.cfg_mousewheel_zoom_sensitivity.Value = num3;
				}
				string valueText4 = ((Replay.cfg_invertGamepadAxes.Value == Types.AXIS_INVERSION.NO) ? "None" : ((Replay.cfg_invertGamepadAxes.Value == Types.AXIS_INVERSION.X) ? "X-Axis" : ((Replay.cfg_invertGamepadAxes.Value == Types.AXIS_INVERSION.Y) ? "Y-Axis" : "Both")));
				if (UI.Option("Invert gamepad rotation axes:", valueText4))
				{
					Replay.cfg_invertGamepadAxes.Value = Tools.cycleOption(new List<Types.AXIS_INVERSION>
					{
						Types.AXIS_INVERSION.NO,
						Types.AXIS_INVERSION.X,
						Types.AXIS_INVERSION.Y,
						Types.AXIS_INVERSION.XY
					}, Replay.cfg_invertGamepadAxes.Value);
				}
				int num4 = (int)UI.SliderOption("Gamepad left/right max rotation (°/s)", Replay.cfg_camLrSpeed.Value, Replay.cfg_camLrSpeed_min.Value, Replay.cfg_camLrSpeed_max.Value, 0);
				if (num4 != Replay.cfg_camLrSpeed.Value)
				{
					Replay.cfg_camLrSpeed.Value = num4;
				}
				int num5 = (int)UI.SliderOption("Gamepad up/down max rotation (°/s)", Replay.cfg_camUdSpeed.Value, Replay.cfg_camUdSpeed_min.Value, Replay.cfg_camUdSpeed_max.Value, 0);
				if (num5 != Replay.cfg_camUdSpeed.Value)
				{
					Replay.cfg_camUdSpeed.Value = num5;
				}
				int num6 = (int)UI.SliderOption("Gamepad max zoom speed (m/s)", Replay.cfg_camDistSpeed.Value, 5f, 70f, 0);
				if (num6 != Replay.cfg_camDistSpeed.Value)
				{
					Replay.cfg_camDistSpeed.Value = num6;
				}
			}
			UI.section("Unity Explorer compatibility options");
			if (UI.Option("Disable active-state enforcement:", Replay.cfg_disableActiveStateEnforcement.Value ? "Yes" : "No"))
			{
				Replay.cfg_disableActiveStateEnforcement.Value = !Replay.cfg_disableActiveStateEnforcement.Value;
			}
			string valueText5 = (Replay.cfg_disableRightDrag.Value ? "Yes" : "No");
			if (UI.Option("Disable right click/drag:", valueText5))
			{
				Replay.cfg_disableRightDrag.Value = !Replay.cfg_disableRightDrag.Value;
			}
			string valueText6 = (Replay.cfg_leftMouseAltMode.Value ? "Yes" : "No");
			if (UI.Option("Left mouse/wheel alt mode (hold ctrl/only when rotating):", valueText6))
			{
				Replay.cfg_leftMouseAltMode.Value = !Replay.cfg_leftMouseAltMode.Value;
			}
			string valueText7 = (Replay.cfg_disableKeys.Value ? "Yes" : "No");
			if (UI.Option("Disable keyboard key handling (except Ctrl key):", valueText7))
			{
				Replay.cfg_disableKeys.Value = !Replay.cfg_disableKeys.Value;
			}
			UI.projectLink("Visit project page for more info");
			if (UI.closeButton())
			{
				Replay.toggleWantMenuOpen(Types.Menu.ReplayOptions, false);
			}
			GUILayout.EndVertical();
			if (UI.isRepaintStep())
			{
				Rect? lastGuiRect = Tools.getLastGuiRect();
				if (lastGuiRect.HasValue)
				{
					replayOptionsMenuRect = lastGuiRect.Value;
				}
			}
			GUILayout.EndArea();
		}

		public static void drawFileList(Types.Menu menu)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: 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_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: 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_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			if (replayItemHeight == 0f)
			{
				replayItemHeight = Tools.getStyleLineHeight(UI.replayItemStyle) + 4f;
			}
			if (navButtonHeight == 0f)
			{
				navButtonHeight = Tools.getStyleLineHeight(UI.navButtonStyle) + 16f;
			}
			if (closeButtonHeight == 0f)
			{
				closeButtonHeight = Tools.getStyleLineHeight(UI.closeButtonStyle) + 20f;
			}
			if (Replay.modState != Replay.ModState.PlayingReplay && Game.isLobbyCountdownActive())
			{
				return;
			}
			float num = Screen.height - Replay.bottomBarHeight - Vars.menuOffsetTop - Vars.menuOffsetBottom;
			num -= closeButtonHeight;
			GUILayout.BeginArea(new Rect((float)Vars.menuOffsetLeft, (float)(Screen.height - Replay.bottomBarHeight) - ((Rect)(ref fileListRect)).height - (float)Vars.menuOffsetBottom, Vars.menuWidth, ((Rect)(ref fileListRect)).height));
			GUILayout.BeginVertical(UI.backgroundStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Vars.menuWidth) });
			UI.section("Replay files");
			num -= UI.sectionHeight;
			if (Replay.modState != Replay.ModState.PlayingReplay && !Game.isSinglePlayerSelected())
			{
				GUILayout.Label("Select a single player to show recorded matches", UI.hintStyle, (Il2CppReferenceArray<GUILayoutOption>)null);
				if (UI.closeButton())
				{
					Replay.toggleWantMenuOpen(menu, false);
				}
			}
			else if (Replay.replayFilenames.Count == 0)
			{
				GUILayout.Label("There are no recorded matches yet.", UI.hintStyle, (Il2CppReferenceArray<GUILayoutOption>)null);
				if (UI.closeButton())
				{
					Replay.toggleWantMenuOpen(menu, false);
				}
			}
			else
			{
				if (Replay.replayFilenames.Count != lastReplayCount)
				{
					lastReplayCount = Replay.replayFilenames.Count;
					pageIndex = -1;
				}
				bool flag = false;
				if ((float)Replay.replayFilenames.Count * replayItemHeight > num)
				{
					flag = true;
					num -= navButtonHeight;
				}
				int num2 = (int)(num / replayItemHeight);
				int num3 = (int)Math.Ceiling((float)Replay.replayFilenames.Count / (float)num2);
				if (pageIndex == -1)
				{
					pageIndex = num3 - 1;
				}
				else if (pageIndex > num3 - 1)
				{
					pageIndex = num3 - 1;
				}
				else if (pageIndex < 0)
				{
					pageIndex = 0;
				}
				int num4 = Replay.replayFilenames.Count - (num3 - pageIndex) * num2;
				int num5 = num4 + num2;
				if (num4 < 0)
				{
					num4 = 0;
				}
				bool flag2 = false;
				for (int i = num4; i < num5 && i < Replay.replayFilenames.Count; i++)
				{
					flag2 = true;
					if (Replay.replayFilenames[i] == Replay.lastLoadedReplay)
					{
						UI.replayItemStyle.normal.textColor = Color.white;
					}
					else
					{
						UI.replayItemStyle.normal.textColor = Color.gray;
					}
					if (GUILayout.Button(Replay.replayFilenames[i], UI.replayItemStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(replayItemHeight) }))
					{
						string replayName = Replay.replayFilenames[i];
						Tools.setTimeout("loadReplay", 0f, delegate
						{
							Replay.loadReplay(replayName);
						});
						return;
					}
					num -= replayItemHeight;
				}
				if (!flag2 && Replay.replayFilenames.Count > 0)
				{
					pageIndex--;
				}
				if (flag)
				{
					GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
					if (pageIndex == 0)
					{
						UI.navButtonStyle.normal.textColor = Colors.transparent;
						UI.navButtonStyle.hover.textColor = Colors.transparent;
					}
					else
					{
						UI.navButtonStyle.normal.textColor = Color.gray;
						UI.navButtonStyle.hover.textColor = Colors.gold;
					}
					if (GUILayout.Button("◀ Previous page", UI.navButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(navButtonHeight) }) && pageIndex > 0)
					{
						pageIndex--;
					}
					bool flag3 = pageIndex < num3 - 1;
					if (flag3)
					{
						UI.navButtonStyle.normal.textColor = Color.gray;
						UI.navButtonStyle.hover.textColor = Colors.gold;
					}
					else
					{
						UI.navButtonStyle.normal.textColor = Colors.transparent;
						UI.navButtonStyle.hover.textColor = Colors.transparent;
					}
					if (GUILayout.Button("Next page ▶", UI.navButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(navButtonHeight) }) && flag3)
					{
						pageIndex++;
					}
					GUILayout.EndHorizontal();
				}
				if (UI.closeButton())
				{
					Replay.toggleWantMenuOpen(menu, false);
				}
			}
			GUILayout.EndVertical();
			if (UI.isRepaintStep())
			{
				Rect? lastGuiRect = Tools.getLastGuiRect();
				if (lastGuiRect.HasValue)
				{
					fileListRect = lastGuiRect.Value;
				}
			}
			GUILayout.EndArea();
		}

		public static void drawHelp(Types.Menu whatMenu, string title, string helpText, string? projectLinkText, bool withBottomOffset)
		{
			//IL_0043: 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)
			GUILayout.BeginArea(new Rect((float)Vars.menuOffsetLeft, (float)(Screen.height - Replay.bottomBarHeight) - ((Rect)(ref helpRect)).height - (float)(withBottomOffset ? Vars.menuOffsetBottom : 0), (float)(Screen.width - Vars.menuOffsetLeft * 2), ((Rect)(ref helpRect)).height));
			GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
			GUILayout.BeginVertical(UI.backgroundStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) });
			UI.section(title);
			GUILayout.Label(helpText, helpTextStyle, (Il2CppReferenceArray<GUILayoutOption>)null);
			if (projectLinkText != null)
			{
				UI.projectLink(projectLinkText);
			}
			if (UI.closeButton())
			{
				Replay.toggleWantMenuOpen(whatMenu, false);
			}
			GUILayout.EndVertical();
			if (UI.isRepaintStep())
			{
				Rect? lastGuiRect = Tools.getLastGuiRect();
				if (lastGuiRect.HasValue)
				{
					helpRect = lastGuiRect.Value;
				}
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.EndArea();
		}
	}
	public class Player
	{
		public enum MouseAction
		{
			None,
			LeftClick,
			TimeControl,
			RotationControl
		}

		public class SortableNextActor
		{
			public Actor actor;

			public float screenDistanceX;
		}

		public class SortableNextClosestActor
		{
			public Actor actor;

			public float distance;
		}

		public static class PlayerPatch
		{
			[HarmonyPatch(typeof(GameMode), "UseGameTimer")]
			[HarmonyPrefix]
			public static bool GameMode_UseGameTimer(GameMode __instance)
			{
				return false;
			}

			[HarmonyPatch(typeof(CinemachineBrain), "LateUpdate")]
			[HarmonyPrefix]
			public static bool CinemachineBrain_LateUpdate(CinemachineBrain __instance)
			{
				if (Replay.modState == Replay.ModState.PlayingReplay && Replay.cfg_cameraMode.Value != Types.CameraMode.IGNORE)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(AudioController), "Update")]
			[HarmonyPostfix]
			public static void AudioController_Update(AudioController __instance)
			{
				Replay.player.setAudioClipsPosition();
			}

			[HarmonyPatch(typeof(PauseManager), "OnRestartRound")]
			[HarmonyPrefix]
			public static bool PauseManager_OnRestartRound(PauseManager __instance)
			{
				Replay.player.returnToStart();
				__instance.SetPaused(false);
				return false;
			}

			[HarmonyPatch(typeof(EffectsHandeler), "UpdateFaceState")]
			[HarmonyPrefix]
			public static bool EffectsHandeler_UpdateFaceState()
			{
				return false;
			}

			[HarmonyPatch(typeof(Actor), "set_actorState")]
			[HarmonyPrefix]
			public static bool Actor_set_actorState(Actor __instance, ref ActorState value)
			{
				return false;
			}

			[HarmonyPatch(typeof(TimeManager), "Update")]
			[HarmonyPrefix]
			public static bool TimeManager_Update()
			{
				if (Replay.forceTimeScale.HasValue)
				{
					Time.timeScale = Replay.forceTimeScale.Value;
					return false;
				}
				return true;
			}
		}

		private Dictionary<string, Types.ItemState> staticItemStates;

		public bool started;

		private Harmony? harmony;

		private bool stopped;

		public float totalCursorXDelta;

		private float fixedDeltaTime = 1f / 30f;

		private int? _stickSpeed = 0;

		public float innerDeadzone = 0.05f;

		public float outerDeadzone = 0.05f;

		public MouseAction mouseAction;

		public MouseAction lastMouseAction;

		public float dragThreshold = 5f;

		private bool cursorLocked;

		private int _lastEffectivePlaySpeed;

		private int idlePlaySpeed = 100;

		private int lastSliderSpeed = 100;

		private List<Actor> replayActors = new List<Actor>();

		private List<BirdActor> replayBirds = new List<BirdActor>();

		private Dictionary<Actor, string> actorNames = new Dictionary<Actor, string>();

		private Dictionary<Types.CaptureGroupId, List<Types.Frame>> frameGroups = new Dictionary<Types.CaptureGroupId, List<Types.Frame>>();

		private Types.Frame? currentKeyframe;

		private float playSoundGraceTime = 0.5f;

		private float virtualTime = -1f;

		private Dictionary<Transform, Vector3> audioclipPositions = new Dictionary<Transform, Vector3>();

		private Types.Frame? lastIntermediateFrame;

		private Dictionary<Types.CaptureGroupId, Types.Frame> lastLookedUpFrames = new Dictionary<Types.CaptureGroupId, Types.Frame>();

		private float tLastFocusAnotherActor;

		private List<Actor> lastFocusableActors = new List<Actor>();

		public bool useRealDeltaTime;

		public static Dictionary<string, AudioClip?>? cachedAudioClips;

		private int hideButtonWidth = 16;

		private GUIStyle? _playerLabelStyle;

		private static GUIStyle? _hideButtonStyle;

		private static GUIStyle? _playerButtonStyle;

		private float qmWidth;

		private float burgerWidth;

		private float speedWidth;

		private float playWidth;

		private float positionWidth;

		private float footerWidth;

		private float loadWidth;

		private string footerString = "ReplayMod " + Replay.VERSION;

		private string loadString = "Load";

		public Dictionary<Types.DragButton, bool> mouseDown = new Dictionary<Types.DragButton, bool>
		{
			{
				Types.DragButton.Left,
				true
			},
			{
				Types.DragButton.Right,
				true
			}
		};

		public Dictionary<Types.DragButton, Vector2?> dragStartPosition = new Dictionary<Types.DragButton, Vector2?>
		{
			{
				Types.DragButton.Left,
				null
			},
			{
				Types.DragButton.Right,
				null
			}
		};

		public Dictionary<Types.DragButton, Vector2?> dragEndPosition = new Dictionary<Types.DragButton, Vector2?>
		{
			{
				Types.DragButton.Left,
				null
			},
			{
				Types.DragButton.Right,
				null
			}
		};

		public Dictionary<Types.DragButton, bool> mouseButtonDown = new Dictionary<Types.DragButton, bool>
		{
			{
				Types.DragButton.Left,
				false
			},
			{
				Types.DragButton.Right,
				false
			}
		};

		public Dictionary<Types.DragButton, Vector2> mouseStart = new Dictionary<Types.DragButton, Vector2>
		{
			{
				Types.DragButton.Left,
				Vector2.zero
			},
			{
				Types.DragButton.Right,
				Vector2.zero
			}
		};

		private Dictionary<Types.DragButton, bool> mouseCrossedThreshold = new Dictionary<Types.DragButton, bool>
		{
			{
				Types.DragButton.Left,
				false
			},
			{
				Types.DragButton.Right,
				false
			}
		};

		public int? stickSpeed => _stickSpeed;

		private int lastEffectivePlaySpeed => _lastEffectivePlaySpeed;

		public GUIStyle playerLabelStyle
		{
			get
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected O, but got Unknown
				if (_playerLabelStyle == null)
				{
					_playerLabelStyle = new GUIStyle(Replay.labelStyle);
					_playerLabelStyle.alignment = (TextAnchor)3;
				}
				return _playerLabelStyle;
			}
		}

		private static GUIStyle hideButtonStyle
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Expected O, but got Unknown
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				if (_hideButtonStyle == null)
				{
					_hideButtonStyle = new GUIStyle();
					_hideButtonStyle.alignment = (TextAnchor)4;
					_hideButtonStyle.fontStyle = (FontStyle)1;
					_hideButtonStyle.normal.textColor = Color.gray;
					_hideButtonStyle.hover.textColor = Color.white;
					_hideButtonStyle.active.textColor = Color.white;
					_hideButtonStyle.normal.background = null;
					_hideButtonStyle.hover.background = null;
					_hideButtonStyle.active.background = null;
					_hideButtonStyle.fontStyle = (FontStyle)1;
					_hideButtonStyle.padding = Replay.zeroRectOffset;
					_hideButtonStyle.border = Replay.zeroRectOffset;
					_hideButtonStyle.margin = Replay.zeroRectOffset;
				}
				if (UI.isRepaintStep())
				{
					GUIStyleState hover = _hideButtonStyle.hover;
					if (hover.background == null)
					{
						Texture2D val = (hover.background = UI.getTexture2D(Color.black));
					}
					hover = _hideButtonStyle.active;
					if (hover.background == null)
					{
						Texture2D val = (hover.background = UI.getTexture2D(Color.black));
					}
				}
				return _hideButtonStyle;
			}
		}

		private static GUIStyle playerButtonStyle
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Expected O, but got Unknown
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				if (_playerButtonStyle == null)
				{
					_playerButtonStyle = new GUIStyle();
					_playerButtonStyle.fontSize = Vars.playerButtonsFontSize;
					_playerButtonStyle.alignment = (TextAnchor)4;
					_playerButtonStyle.fontStyle = (FontStyle)1;
					_playerButtonStyle.normal.textColor = Color.gray;
					_playerButtonStyle.hover.textColor = Color.white;
					_playerButtonStyle.active.textColor = Color.white;
					_playerButtonStyle.normal.background = null;
					_playerButtonStyle.hover.background = null;
					_playerButtonStyle.active.background = null;
					_playerButtonStyle.border = Replay.zeroRectOffset;
					_playerButtonStyle.margin = Replay.zeroRectOffset;
					_playerButtonStyle.padding = Replay.zeroRectOffset;
				}
				if (UI.isRepaintStep())
				{
					GUIStyleState hover = _playerButtonStyle.hover;
					if (hover.background == null)
					{
						Texture2D val = (hover.background = UI.getTexture2D(Colors.transparent));
					}
					hover = _playerButtonStyle.active;
					if (hover.background == null)
					{
						Texture2D val = (hover.background = _playerButtonStyle.hover.background);
					}
				}
				return _playerButtonStyle;
			}
		}

		private event Action<float, Types.Frame, Types.Frame>? afterPlayOurFrame;

		public Player(Dictionary<Types.CaptureGroupId, List<Types.Frame>> frameGroups, List<Actor> replayActors, Dictionary<Actor, string> actorNames, List<BirdActor> birds, Dictionary<string, Types.ItemState> staticItemStates)
		{
			//IL_0167: 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)
			this.frameGroups = frameGroups;
			this.replayActors = replayActors;
			this.actorNames = actorNames;
			replayBirds = birds;
			this.staticItemStates = staticItemStates;
		}

		public void start()
		{
			started = true;
			setPlaySpeed(idlePlaySpeed);
			if (Replay.cfg_isFirstStart_player.Value)
			{
				Replay.cfg_isFirstStart_player.Value = false;
				Replay.toggleWantMenuOpen(Types.Menu.ReplayHelp, true);
			}
		}

		private void unpatch()
		{
			harmony.UnpatchSelf();
			harmony = null;
		}

		public void stop()
		{
			if (!stopped)
			{
				stopped = true;
				unpatch();
			}
		}

		public void update_checkUserInput()
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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_0227: 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_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			update_drag(Types.DragButton.Left, handleDragStart, handleDragMove, handleDragEnd);
			update_drag(Types.DragButton.Right, handleDragStart, handleDragMove, handleDragEnd);
			if (Replay.cfg_cameraMode.Value == Types.CameraMode.SURROUND)
			{
				if (Controls.wasPrevActorButtonPressed())
				{
					focusPrevActor();
				}
				if (Controls.wasNextActorButtonPressed())
				{
					focusNextActor();
				}
				if (Controls.wasToggleCameraTargetButtonPressed())
				{
					Replay.toggleCameraTargeting();
				}
			}
			if (!Replay.cfg_disableKeys.Value)
			{
				if (Controls.wasSpeedIncreaseKeyPressed())
				{
					increasePlaySpeed();
				}
				else if (Controls.wasSpeedDecreaseKeyPressed())
				{
					decreasePlaySpeed();
				}
			}
			if (Controls.wasPauseButtonPressed())
			{
				if (idlePlaySpeed == 0 && lastSliderSpeed == 0)
				{
					lastSliderSpeed = 100;
				}
				idlePlaySpeed = ((idlePlaySpeed == 0) ? lastSliderSpeed : 0);
			}
			if (mouseAction == MouseAction.RotationControl)
			{
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue();
				totalCursorXDelta += val.x;
				if (val.x != 0f)
				{
					float num = (float)Replay.cfg_mouse_sensitivity_x.Value / -1000f;
					if (isMouseXInverted())
					{
						num *= -1f;
					}
					float num2 = val.x * num;
					Replay.camera.setLR(Replay.camera.getLR() + num2, immediate: false);
				}
				if (val.y != 0f && !Mouse.current.leftButton.isPressed)
				{
					float num3 = (float)Replay.cfg_mouse_sensitivity_y.Value / -1000f;
					if (isMouseYInverted())
					{
						num3 *= -1f;
					}
					float num4 = val.y * num3;
					Replay.camera.setUD(Replay.camera.getUD() + num4, immediate: false);
				}
			}
			else if (mouseAction == MouseAction.TimeControl)
			{
				Vector2 val2 = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue();
				totalCursorXDelta += val2.x;
				float num5 = (Mouse.current.rightButton.isPressed ? 5f : 1f);
				virtualTime += val2.x * num5 / 200f;
			}
			Vector2 mouseWheel = Controls.getMouseWheel();
			if (mouseWheel.y == 0f)
			{
				return;
			}
			if (Keyboard.current != null && Keyboard.current.ctrlKey.isPressed)
			{
				if (mouseWheel.y > 0f)
				{
					increasePlaySpeed();
				}
				else
				{
					decreasePlaySpeed();
				}
			}
			else if (!Replay.cfg_leftMouseAltMode.Value || mouseAction == MouseAction.RotationControl)
			{
				float num6 = mouseWheel.y / (float)(Replay.cfg_mousewheel_zoom_sensitivity.Value * -1);
				Replay.camera.setDistance(Replay.camera.getDistance() + num6, immediate: false);
			}
		}

		public void increasePlaySpeed()
		{
			idlePlaySpeed += Replay.cfg_mousewheel_speed_step.Value;
			if (idlePlaySpeed > 100)
			{
				idlePlaySpeed = 100;
			}
			if (idlePlaySpeed > 0 && idlePlaySpeed < Replay.cfg_mousewheel_speed_step.Value)
			{
				idlePlaySpeed = 0;
			}
			lastSliderSpeed = idlePlaySpeed;
		}

		public void decreasePlaySpeed()
		{
			idlePlaySpeed -= Replay.cfg_mousewheel_speed_step.Value;
			if (idlePlaySpeed < -100)
			{
				idlePlaySpeed = -100;
			}
			if (idlePlaySpeed < 0 && idlePlaySpeed > -Replay.cfg_mousewheel_speed_step.Value)
			{
				idlePlaySpeed = 0;
			}
			lastSliderSpeed = idlePlaySpeed;
		}

		public void fixedUpdate()
		{
			if (started && !stopped)
			{
				fixedUpdate_checkUserInput_setSpeed();
			}
		}

		public void fixedUpdate_checkUserInput_setSpeed()
		{
			//IL_0033: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0098: 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)
			if (Game.paused())
			{
				setPlaySpeed(0);
				return;
			}
			if (Gamepad.current != null && Replay.cfg_cameraMode.Value == Types.CameraMode.SURROUND)
			{
				Vector2 val = ((InputControl<Vector2>)(object)Gamepad.current.rightStick).ReadValue();
				if (val.x != 0f)
				{
					float x = val.x;
					float num = (isGamepadXInverted() ? (0f - fixedDeltaTime) : fixedDeltaTime);
					Replay.camera.setLR(Replay.camera.getLR() + (float)Replay.cfg_camLrSpeed.Value * (0f - x) * num, immediate: false);
				}
				if (val.y != 0f)
				{
					float y = val.y;
					float num2 = (isGamepadYInverted() ? (0f - fixedDeltaTime) : fixedDeltaTime);
					Replay.camera.setUD(Replay.camera.getUD() + (float)Replay.cfg_camUdSpeed.Value * (0f - y) * num2, immediate: false);
				}
			}
			if (mouseAction == MouseAction.TimeControl)
			{
				setPlaySpeed(0);
				return;
			}
			_stickSpeed = getAnalogStickPlaySpeed();
			if (Gamepad.current != null)
			{
				if (stickSpeed.HasValue)
				{
					setPlaySpeed(stickSpeed.Value);
					return;
				}
				Vector2 val2 = ((InputControl<Vector2>)(object)Gamepad.current.leftStick).ReadValue();
				if (Math.Abs(val2.y) > 0.2f)
				{
					float num3 = (float)Replay.cfg_camDistSpeed.Value * val2.y * fixedDeltaTime;
					Replay.camera.setDistance(Replay.camera.getDistance() - num3, immediate: false);
				}
			}
			setPlaySpeed(idlePlaySpeed);
		}

		public void setPlaySpeed(int effectiveSpeed)
		{
			if (effectiveSpeed != lastEffectivePlaySpeed)
			{
				_lastEffectivePlaySpeed = effectiveSpeed;
				Replay.setTimeScale((effectiveSpeed >= 0) ? ((float)effectiveSpeed / 100f) : 0f);
			}
		}

		public int? getAnalogStickPlaySpeed()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (Gamepad.current == null)
			{
				return null;
			}
			if (!Controls.isSpeedControlButtonDown())
			{
				return null;
			}
			float x = ((InputControl<Vector2>)(object)Gamepad.current.leftStick).ReadValue().x;
			if (Math.Abs(x) > innerDeadzone)
			{
				x /= 1f - outerDeadzone;
				if (x > 1f)
				{
					x = 1f;
				}
				else if (x < -1f)
				{
					x = -1f;
				}
				if (Controls.isFasterSpeedButtonDown())
				{
					x *= Replay.fasterSpeedMultiplier;
				}
				return (int)(x * 100f);
			}
			return 0;
		}

		public bool isInSliderArea(Vector2 position)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0082: 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_002d: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			Rect val;
			if (Replay.cfg_hideReplayControls_Value)
			{
				val = new Rect(0f, (float)(Screen.height - Replay.bottomBarHeight), (float)hideButtonWidth, (float)Replay.bottomBarHeight);
				return ((Rect)(ref val)).Contains(new Vector2(position.x, (float)Screen.height - position.y));
			}
			val = new Rect(0f, 0f, (float)Screen.width, (float)(Screen.height - Replay.bottomBarHeight));
			return !((Rect)(ref val)).Contains(new Vector2(position.x, (float)Screen.height - position.y));
		}

		public bool isInMenuArea(Vector2 position)
		{
			//IL_000d: 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_0024: 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)
			if (Replay.wantMenuOpen(Types.Menu.ReplayHelp) && ((Rect)(ref Menus.helpRect)).Contains(position))
			{
				return true;
			}
			if (Replay.wantMenuOpen(Types.Menu.ReplayOptions) && ((Rect)(ref Menus.replayOptionsMenuRect)).Contains(position))
			{
				return true;
			}
			if (isInSliderArea(position))
			{
				return true;
			}
			if (Replay.wantMenuOpen(Types.Menu.ReplayFilelist) && ((Rect)(ref Menus.fileListRect)).Contains(position))
			{
				return true;
			}
			return false;
		}

		public void handleDragStart(Types.DragButton button, Vector2 position)
		{
			//IL_0009: 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)
			if (Game.paused() || isInMenuArea(position) || mouseButtonDown[button])
			{
				return;
			}
			mouseButtonDown[button] = true;
			mouseCrossedThreshold[button] = false;
			dragStartPosition[button] = position;
			if (button == Types.DragButton.Right && mouseAction == MouseAction.LeftClick)
			{
				mouseAction = MouseAction.TimeControl;
				lastMouseAction = mouseAction;
			}
			if (mouseAction != MouseAction.None)
			{
				return;
			}
			switch (button)
			{
			case Types.DragButton.Left:
				if (!Replay.cfg_leftMouseAltMode.Value || (Keyboard.current != null && Keyboard.current.ctrlKey.isPressed))
				{
					mouseAction = MouseAction.LeftClick;
					lastMouseAction = mouseAction;
					totalCursorXDelta = 0f;
				}
				break;
			case Types.DragButton.Right:
				if (!Replay.cfg_disableRightDrag.Value && Replay.cfg_cameraMode.Value == Types.CameraMode.SURROUND)
				{
					mouseAction = MouseAction.RotationControl;
					lastMouseAction = mouseAction;
				}
				break;
			}
		}

		public void handleDragMove(Types.DragButton button, Vector2 position, Vector2 delta)
		{
		}

		public void handleDragEnd(Types.DragButton button, Vector2 position, Vector2 delta)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			mouseButtonDown[button] = false;
			dragEndPosition[button] = position;
			switch (button)
			{
			case Types.DragButton.Left:
				if (mouseAction == MouseAction.LeftClick)
				{
					focusActorAtScreenPosition(position);
					mouseAction = MouseAction.None;
				}
				else if (mouseAction == MouseAction.TimeControl)
				{
					mouseAction = MouseAction.None;
				}
				break;
			case Types.DragButton.Right:
				if (mouseAction == MouseAction.RotationControl)
				{
					mouseAction = MouseAction.None;
				}
				break;
			}
		}

		public void focusActorAtScreenPosition(Vector2 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Actor actorAtScreenPosition = getActorAtScreenPosition(position, nearestFallback: true);
			if ((Object)(object)actorAtScreenPosition != (Object)null)
			{
				Replay.camera.setFocusedActor(actorAtScreenPosition);
			}
		}

		public void togglePlayPause()
		{
			if (idlePlaySpeed == 0 && lastSliderSpeed == 0)
			{
				lastSliderSpeed = 100;
			}
			idlePlaySpeed = ((idlePlaySpeed == 0) ? lastSliderSpeed : 0);
		}

		public void update(float deltaTime, bool playFrame)
		{
			if (stopped || !started)
			{
				return;
			}
			if (!Game.paused())
			{
				update_checkUserInput();
			}
			if (playFrame)
			{
				playOurFrame(deltaTime);
				if (Replay.cfg_cameraMode.Value == Types.CameraMode.SURROUND)
				{
					Replay.camera.update(deltaTime);
				}
			}
		}

		public void lateUpdate(float deltaTime, bool playFrame)
		{
			//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_009c: 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_00c1: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (playFrame)
			{
				playOurFrame(deltaTime);
				if (Replay.cfg_cameraMode.Value == Types.CameraMode.SURROUND)
				{
					Replay.camera.update(deltaTime);
				}
			}
			bool flag = false;
			bool flag2 = false;
			if (!Game.paused() && (mouseAction == MouseAction.TimeControl || mouseAction == MouseAction.RotationControl))
			{
				flag2 = true;
			}
			if (flag2 != cursorLocked)
			{
				cursorLocked = flag2;
				if (!cursorLocked)
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
					flag = true;
				}
			}
			if (flag2)
			{
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
			if (flag)
			{
				if (lastMouseAction == MouseAction.RotationControl)
				{
					Vector2 value = dragStartPosition[Types.DragButton.Right].Value;
					Mouse.current.WarpCursorPosition(value);
				}
				else if (lastMouseAction == MouseAction.TimeControl)
				{
					Vector2 value2 = dragStartPosition[Types.DragButton.Left].Value;
					value2 += new Vector2(totalCursorXDelta, 0f);
					Mouse.current.WarpCursorPosition(value2);
				}
			}
			if (!MonoSingleton<Global>.Instance.UIDirector.ShowNameBars)
			{
				return;
			}
			foreach (Actor replayActor in replayActors)
			{
				try
				{
					((TMP_Text)replayActor.NameBar.CachedNameText).text = getNamebarNameForActor(replayActor);
				}
				catch
				{
				}
			}
		}

		public List<Actor> getActors()
		{
			return replayActors;
		}

		public void returnToStart()
		{
			virtualTime = 0f;
		}

		private void playOurFrame(float realDeltaTime)
		{
			if (virtualTime == -1f)
			{
				virtualTime = 0f;
			}
			else if (!Game.paused())
			{
				virtualTime += realDeltaTime * (float)lastEffectivePlaySpeed / 100f;
			}
			List<Types.Frame> list = frameGroups[Types.CaptureGroupId.Actor];
			if (list.Count == 0 || virtualTime < 0f)
			{
				virtualTime = 0f;
			}
			if (list.Count > 0)
			{
				if (virtualTime > list[list.Count - 1].time)
				{
					virtualTime = list[list.Count - 1].time;
				}
			}
			Types.Frame frameAtTime = getFrameAtTime(frameGroups[Types.CaptureGroupId.Actor], virtualTime);
			if (frameAtTime == null)
			{
				return;
			}
			Types.Frame frame = currentKeyframe;
			bool flag = false;
			if (currentKeyframe != frameAtTime)
			{
				flag = true;
				currentKeyframe = frameAtTime;
			}
			if (flag)
			{
				bool flag2 = false;
				if (frame != null)
				{
					float num = frameAtTime.time - frame.time;
					flag2 = num > 0f && num < playSoundGraceTime;
				}
				if (flag2)
				{
					for (int i = frame.index + 1; i <= frameAtTime.index; i++)
					{
						Types.Frame frame2 = frameGroups[Types.CaptureGroupId.Actor][i];
						playFrameSounds(frame2);
					}
				}
				else if (frame == null || frameAtTime.index > frame.index)
				{
					playFrameSounds(frameAtTime);
				}
			}
			Types.Frame intermediateFrame = getIntermediateFrame(virtualTime);
			if (intermediateFrame == null)
			{
				if (lastIntermediateFrame == null)
				{
					return;
				}
				intermediateFrame = lastIntermediateFrame;
				virtualTime = intermediateFrame.time;
			}
			lastIntermediateFrame = intermediateFrame;
			playFrame(intermediateFrame);
			if (this.afterPlayOurFrame != null)
			{
				this.afterPlayOurFrame(virtualTime, intermediateFrame, frameAtTime);
			}
		}

		private void playFrameSounds(Types.Frame frame)
		{
			if (frame.sounds3d != null)
			{
				foreach (Types._3dAudioClip item in frame.sounds3d)
				{
					item.loop = false;
					play3dAudioclip(item);
				}
			}
			if (frame.sounds2d == null)
			{
				return;
			}
			foreach (Types._2dAudioClip item2 in frame.sounds2d)
			{
				item2.loop = false;
				play2dAudioclip(item2);
			}
		}

		private void playFrame(Types.Frame intermediateFrame)
		{
			if (intermediateFrame.actorBlinks != null)
			{
				setActorBlinks(intermediateFrame.actorBlinks);
			}
			if (intermediateFrame.birdBlinks != null)
			{
				setBirdBlinks(intermediateFrame.birdBlinks);
			}
			setItemStates(intermediateFrame);
			if (intermediateFrame.actorStates != null)
			{
				setActorStates(intermediateFrame.actorStates);
			}
		}

		private void setActorBlinks(List<byte> blinks)
		{
			for (int i = 0; i < blinks.Count; i++)
			{
				Game.setActorBlink(replayActors[i], (int)blinks[i]);
			}
		}

		private void setBirdBlinks(List<byte> blinks)
		{
			for (int i = 0; i < blinks.Count && i <= replayBirds.Count - 1; i++)
			{
				Game.setBirdBlink(replayBirds[i], blinks[i]);
			}
		}

		private void setItemStates(Types.Frame intermediateFrame)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<string, Types.ItemState> state in intermediateFrame.states)
			{
				Types.ItemState value = state.Value;
				TransformCache.TransformInfo transformInfo = Replay.tc.query(state.Key);
				if (transformInfo != null)
				{
					if (transformInfo.key.StartsWith("audioclip:"))
					{
						audioclipPositions[transformInfo.transform] = value.pos;
					}
					Replay.setTransformState(transformInfo.transform, value, intermediateFrame.aIndex == 0);
				}
			}
			foreach (KeyValuePair<string, Types.ItemState> staticItemState in staticItemStates)
			{
				TransformCache.TransformInfo transformInfo2 = Replay.tc.query(staticItemState.Key);
				if (transformInfo2 != null)
				{
					string key = transformInfo2.key;
					Replay.setTransformState(transformInfo2.transform, staticItemStates[key], intermediateFrame.aIndex == 0);
				}
			}
		}

		public void setAudioClipsPosition()
		{
			//IL_001f: 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)
			foreach (KeyValuePair<Transform, Vector3> audioclipPosition in audioclipPositions)
			{
				Transform key = audioclipPosition.Key;
				Vector3 value = audioclipPosition.Value;
				key.position = value;
			}
		}

		private Types.Frame? getIntermediateFrame(float virtualTime)
		{
			if (lastIntermediateFrame != null && lastIntermediateFrame.time == virtualTime)
			{
				return lastIntermediateFrame;
			}
			List<Types.Frame> list = frameGroups[Types.CaptureGroupId.Actor];
			Types.Frame frameAtTime = getFrameAtTime(list, virtualTime);
			if (frameAtTime == null)
			{
				return null;
			}
			Types.Frame frame = ((frameAtTime.index == list.Count - 1) ? null : list[frameAtTime.index + 1]);
			if (frame == null)
			{
				return null;
			}
			Types.Frame partialIntermediateFrame = getPartialIntermediateFrame(frameAtTime, frame, virtualTime, null);
			List<Types.Frame> list2 = frameGroups[Types.CaptureGroupId.Environment];
			Types.Frame frameAtTime2 = getFrameAtTime(list2, virtualTime);
			if (frameAtTime2 == null)
			{
				return null;
			}
			Types.Frame frame2 = ((frameAtTime2.index == list2.Count - 1) ? null : list2[frameAtTime2.index + 1]);
			if (frame2 == null)
			{
				return null;
			}
			getPartialIntermediateFrame(frameAtTime2, frame2, virtualTime, partialIntermediateFrame);
			lastIntermediateFrame = partialIntermediateFrame;
			return partialIntermediateFrame;
		}

		private Types.Frame? getPartialIntermediateFrame(Types.Frame a, Types.Frame b, float virtualTime, Types.Frame? intermediate)
		{
			//IL_0106: 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_0132: 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_013f: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_015f: Unknown result type (mi