Decompiled source of ReplayMod v1.0.1
Mods/ReplayMod.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
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