Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Empress Replay System v1.0.1
BepInEx\plugins\Empress-Replays\EmpressReplays.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MenuLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Empress")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EmpressReplays")] [assembly: AssemblyTitle("EmpressReplays")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Empress.REPO.Replays { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.empress.repo.replays", "Empress Replays", "1.0.0")] public sealed class EmpressReplaysPlugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action <>9__23_1; public static BuilderDelegate <>9__23_0; internal void <RegisterMenu>b__23_0(Transform parent) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) MenuAPI.CreateREPOButton("Empress Replays", (Action)delegate { ReplayController.Instance?.OpenBrowserFromMenu(); }, parent, new Vector2(550f, 56f)); } internal void <RegisterMenu>b__23_1() { ReplayController.Instance?.OpenBrowserFromMenu(); } } public const string PluginGuid = "com.empress.repo.replays"; public const string PluginName = "Empress Replays"; public const string PluginVersion = "1.0.0"; private Harmony _harmony; internal static EmpressReplaysPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ReplaySettings Settings { get; private set; } internal static string ReplayFolder { get; private set; } internal static void DebugLog(string message) { if (Settings != null && Settings.DebugLogs.Value) { Log.LogInfo((object)message); } } internal static void DebugWarn(string message) { if (Settings != null && Settings.DebugLogs.Value) { Log.LogWarning((object)message); } } private void Awake() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Settings = new ReplaySettings(((BaseUnityPlugin)this).Config); ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); ReplayFolder = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty, "Replays"); Directory.CreateDirectory(ReplayFolder); _harmony = new Harmony("com.empress.repo.replays"); _harmony.PatchAll(typeof(EmpressReplaysPlugin).Assembly); ReplayController.EnsureHost(); RegisterMenu(); DebugLog("Empress Replays v1.0.0 loaded. Replays in " + ReplayFolder); } private void RegisterMenu() { //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) //IL_001f: Expected O, but got Unknown object obj = <>c.<>9__23_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) MenuAPI.CreateREPOButton("Empress Replays", (Action)delegate { ReplayController.Instance?.OpenBrowserFromMenu(); }, parent, new Vector2(550f, 56f)); }; <>c.<>9__23_0 = val; obj = (object)val; } MenuAPI.AddElementToMainMenu((BuilderDelegate)obj); } } internal sealed class ReplaySettings { public readonly ConfigEntry<bool> AutoRecord; public readonly ConfigEntry<bool> ShowRecordingIndicator; public readonly ConfigEntry<bool> DebugLogs; public readonly ConfigEntry<int> MaxReplays; public readonly ConfigEntry<float> TickInterval; public readonly ConfigEntry<float> CameraSpeed; public readonly ConfigEntry<float> LookSensitivity; public readonly ConfigEntry<KeyCode> ViewModeKey; public readonly ConfigEntry<KeyCode> NextTargetKey; public readonly ConfigEntry<KeyCode> ExitKey; public ReplaySettings(ConfigFile config) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown AutoRecord = config.Bind<bool>("Recording", "AutoRecord", true, "Automatically record every match and save it on level completion."); ShowRecordingIndicator = config.Bind<bool>("Recording", "ShowRecordingIndicator", false, "Show the blinking REC indicator in-game while a match is being recorded."); DebugLogs = config.Bind<bool>("Debug", "DebugLogs", false, "Write verbose diagnostic logs to the console (for troubleshooting only)."); MaxReplays = config.Bind<int>("Recording", "MaxReplays", 100, new ConfigDescription("Maximum saved replays before the oldest is overwritten.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 500), Array.Empty<object>())); TickInterval = config.Bind<float>("Recording", "TickInterval", 0.05f, new ConfigDescription("Seconds between recorded snapshots (lower = smoother, bigger files).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.25f), Array.Empty<object>())); CameraSpeed = config.Bind<float>("Playback", "CameraSpeed", 8f, new ConfigDescription("Free-camera move speed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f), Array.Empty<object>())); LookSensitivity = config.Bind<float>("Playback", "LookSensitivity", 2.2f, new ConfigDescription("Camera look sensitivity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 6f), Array.Empty<object>())); ViewModeKey = config.Bind<KeyCode>("Playback", "ViewModeKey", (KeyCode)118, "Cycles first-person / third-person orbit / free camera."); NextTargetKey = config.Bind<KeyCode>("Playback", "NextTargetKey", (KeyCode)9, "Switches which player you are spectating."); ExitKey = config.Bind<KeyCode>("Playback", "ExitKey", (KeyCode)27, "Exits playback back to the menu."); } } internal static class ReplayAccess { private static readonly FieldInfo PlayerAvatarNameField = AccessTools.Field(typeof(PlayerAvatar), "playerName"); private static readonly FieldInfo PlayerAvatarDeadSetField = AccessTools.Field(typeof(PlayerAvatar), "deadSet"); private static readonly FieldInfo PlayerAvatarVisualsField = AccessTools.Field(typeof(PlayerAvatar), "playerAvatarVisuals"); private static readonly FieldInfo PlayerAvatarVisualsMeshParentField = AccessTools.Field(typeof(PlayerAvatarVisuals), "meshParent"); private static readonly FieldInfo PlayerAvatarVisualsAnimatorField = AccessTools.Field(typeof(PlayerAvatarVisuals), "animator"); private static readonly FieldInfo PlayerControllerAvatarField = AccessTools.Field(typeof(PlayerController), "playerAvatarScript"); private static readonly FieldInfo EnemyParentNameField = AccessTools.Field(typeof(EnemyParent), "enemyName"); private static readonly FieldInfo EnemyParentEnemyField = AccessTools.Field(typeof(EnemyParent), "Enemy"); private static readonly FieldInfo EnemyDirectorInstanceField = AccessTools.Field(typeof(EnemyDirector), "instance"); private static readonly FieldInfo EnemyDirectorSpawnedField = AccessTools.Field(typeof(EnemyDirector), "enemiesSpawned"); private static readonly FieldInfo EnemyDirectorDifficulty1Field = AccessTools.Field(typeof(EnemyDirector), "enemiesDifficulty1"); private static readonly FieldInfo EnemyDirectorDifficulty2Field = AccessTools.Field(typeof(EnemyDirector), "enemiesDifficulty2"); private static readonly FieldInfo EnemyDirectorDifficulty3Field = AccessTools.Field(typeof(EnemyDirector), "enemiesDifficulty3"); private static readonly FieldInfo EnemyDirectorListField = AccessTools.Field(typeof(EnemyDirector), "enemyList"); private static readonly FieldInfo EnemyDirectorCurrentListField = AccessTools.Field(typeof(EnemyDirector), "enemyListCurrent"); private static readonly FieldInfo EnemySetupSpawnObjectsField = AccessTools.Field(typeof(EnemySetup), "spawnObjects"); private static readonly FieldInfo ValuableDollarField = AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent"); private static readonly FieldInfo RunManagerLevelCurrentField = AccessTools.Field(typeof(RunManager), "levelCurrent"); private static readonly FieldInfo GameDirectorCurrentStateField = AccessTools.Field(typeof(GameDirector), "currentState"); private static readonly FieldInfo GameDirectorPlayerListField = AccessTools.Field(typeof(GameDirector), "PlayerList"); private static readonly FieldInfo LevelGeneratorGeneratedField = AccessTools.Field(typeof(LevelGenerator), "Generated"); private static readonly FieldInfo LoadingUiAnimationCompletedField = AccessTools.Field(typeof(LoadingUI), "levelAnimationCompleted"); private static readonly FieldInfo LevelGeneratorLevelParentField = AccessTools.Field(typeof(LevelGenerator), "LevelParent"); private static readonly FieldInfo LevelConnectObjectField = AccessTools.Field(typeof(Level), "ConnectObject"); private static readonly FieldInfo LevelBlockObjectField = AccessTools.Field(typeof(Level), "BlockObject"); private static readonly FieldInfo LevelStartRoomsField = AccessTools.Field(typeof(Level), "StartRooms"); private static readonly FieldInfo LevelModulesNormal1Field = AccessTools.Field(typeof(Level), "ModulesNormal1"); private static readonly FieldInfo LevelModulesNormal2Field = AccessTools.Field(typeof(Level), "ModulesNormal2"); private static readonly FieldInfo LevelModulesNormal3Field = AccessTools.Field(typeof(Level), "ModulesNormal3"); private static readonly FieldInfo LevelModulesPassage1Field = AccessTools.Field(typeof(Level), "ModulesPassage1"); private static readonly FieldInfo LevelModulesPassage2Field = AccessTools.Field(typeof(Level), "ModulesPassage2"); private static readonly FieldInfo LevelModulesPassage3Field = AccessTools.Field(typeof(Level), "ModulesPassage3"); private static readonly FieldInfo LevelModulesDeadEnd1Field = AccessTools.Field(typeof(Level), "ModulesDeadEnd1"); private static readonly FieldInfo LevelModulesDeadEnd2Field = AccessTools.Field(typeof(Level), "ModulesDeadEnd2"); private static readonly FieldInfo LevelModulesDeadEnd3Field = AccessTools.Field(typeof(Level), "ModulesDeadEnd3"); private static readonly FieldInfo LevelModulesExtraction1Field = AccessTools.Field(typeof(Level), "ModulesExtraction1"); private static readonly FieldInfo LevelModulesExtraction2Field = AccessTools.Field(typeof(Level), "ModulesExtraction2"); private static readonly FieldInfo LevelModulesExtraction3Field = AccessTools.Field(typeof(Level), "ModulesExtraction3"); private static readonly FieldInfo LevelModulesSpecialField = AccessTools.Field(typeof(Level), "ModulesSpecial"); private static readonly FieldInfo TruckDoorMeshField = AccessTools.Field(typeof(TruckDoor), "doorMesh"); private static readonly FieldInfo RunManagerSingleplayerPoolField = AccessTools.Field(typeof(RunManager), "singleplayerPool"); private static readonly FieldInfo RunManagerMultiplayerPoolField = AccessTools.Field(typeof(RunManager), "multiplayerPool"); private static readonly FieldInfo MultiplayerPoolResourceCacheField = AccessTools.Field(AccessTools.TypeByName("MultiplayerPool"), "ResourceCache"); private static readonly FieldInfo RunManagerLevelsField = AccessTools.Field(typeof(RunManager), "levels"); private static readonly FieldInfo RunManagerDebugLevelField = AccessTools.Field(typeof(RunManager), "debugLevel"); private static readonly FieldInfo RunManagerLevelsCompletedField = AccessTools.Field(typeof(RunManager), "levelsCompleted"); private static readonly FieldInfo LevelValuablePresetsField = AccessTools.Field(typeof(Level), "ValuablePresets"); private static readonly FieldInfo LevelValuablesTinyField = AccessTools.Field(typeof(LevelValuables), "tiny"); private static readonly FieldInfo LevelValuablesSmallField = AccessTools.Field(typeof(LevelValuables), "small"); private static readonly FieldInfo LevelValuablesMediumField = AccessTools.Field(typeof(LevelValuables), "medium"); private static readonly FieldInfo LevelValuablesBigField = AccessTools.Field(typeof(LevelValuables), "big"); private static readonly FieldInfo LevelValuablesWideField = AccessTools.Field(typeof(LevelValuables), "wide"); private static readonly FieldInfo LevelValuablesTallField = AccessTools.Field(typeof(LevelValuables), "tall"); private static readonly FieldInfo LevelValuablesVeryTallField = AccessTools.Field(typeof(LevelValuables), "veryTall"); private static readonly FieldInfo ValuableDirectorTinyValuablesField = AccessTools.Field(typeof(ValuableDirector), "tinyValuables"); private static readonly FieldInfo ValuableDirectorSmallValuablesField = AccessTools.Field(typeof(ValuableDirector), "smallValuables"); private static readonly FieldInfo ValuableDirectorMediumValuablesField = AccessTools.Field(typeof(ValuableDirector), "mediumValuables"); private static readonly FieldInfo ValuableDirectorBigValuablesField = AccessTools.Field(typeof(ValuableDirector), "bigValuables"); private static readonly FieldInfo ValuableDirectorWideValuablesField = AccessTools.Field(typeof(ValuableDirector), "wideValuables"); private static readonly FieldInfo ValuableDirectorTallValuablesField = AccessTools.Field(typeof(ValuableDirector), "tallValuables"); private static readonly FieldInfo ValuableDirectorVeryTallValuablesField = AccessTools.Field(typeof(ValuableDirector), "veryTallValuables"); private static readonly MethodInfo PrefabRefPrefabNameGetter = AccessTools.PropertyGetter(typeof(PrefabRef), "PrefabName"); private static readonly MethodInfo PrefabRefResourcePathGetter = AccessTools.PropertyGetter(typeof(PrefabRef), "ResourcePath"); private static readonly MethodInfo PrefabRefPrefabGetter = AccessTools.PropertyGetter(typeof(PrefabRef), "Prefab"); private static GameObject[] EnemyResourcePrefabs; private static readonly FieldInfo GameDirectorDisableInputField = AccessTools.Field(typeof(GameDirector), "DisableInput"); private static readonly FieldInfo GameDirectorMainCameraField = AccessTools.Field(typeof(GameDirector), "MainCamera"); private static readonly FieldInfo MenuCursorMeshField = AccessTools.Field(typeof(MenuCursor), "mesh"); private static readonly FieldInfo MenuCursorShowTimerField = AccessTools.Field(typeof(MenuCursor), "showTimer"); private static readonly FieldInfo MenuCursorOverridePosTimerField = AccessTools.Field(typeof(MenuCursor), "overridePosTimer"); private static readonly FieldInfo CursorManagerUnlockTimerField = AccessTools.Field(typeof(CursorManager), "unlockTimer"); private static readonly FieldInfo ValuableDirectorListField = AccessTools.Field(typeof(ValuableDirector), "valuableList"); public static List<PlayerAvatar> GetPlayerList() { if (GameDirectorPlayerListField != null && (Object)(object)GameDirector.instance != (Object)null) { return GameDirectorPlayerListField.GetValue(GameDirector.instance) as List<PlayerAvatar>; } return null; } public static bool IsGameStateMain() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 if (GameDirectorCurrentStateField == null || (Object)(object)GameDirector.instance == (Object)null) { return false; } if (GameDirectorCurrentStateField.GetValue(GameDirector.instance) is gameState val) { return (int)val == 2; } return false; } public static bool IsLevelGenerated() { if (LevelGeneratorGeneratedField == null || (Object)(object)LevelGenerator.Instance == (Object)null) { return false; } object value = LevelGeneratorGeneratedField.GetValue(LevelGenerator.Instance); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } public static bool IsLoadingComplete() { if ((Object)(object)LoadingUI.instance == (Object)null) { return true; } if (!((Component)LoadingUI.instance).gameObject.activeInHierarchy) { return true; } if (LoadingUiAnimationCompletedField == null) { return true; } object value = LoadingUiAnimationCompletedField.GetValue(LoadingUI.instance); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } public static PlayerAvatar GetLocalAvatar() { if (PlayerControllerAvatarField != null && (Object)(object)PlayerController.instance != (Object)null) { object? value = PlayerControllerAvatarField.GetValue(PlayerController.instance); return (PlayerAvatar)((value is PlayerAvatar) ? value : null); } return null; } public static Level GetLevelCurrent() { if (RunManagerLevelCurrentField != null && (Object)(object)RunManager.instance != (Object)null) { object? value = RunManagerLevelCurrentField.GetValue(RunManager.instance); return (Level)((value is Level) ? value : null); } return null; } public static int GetLevelsCompleted() { if (RunManagerLevelsCompletedField != null && (Object)(object)RunManager.instance != (Object)null) { object value = RunManagerLevelsCompletedField.GetValue(RunManager.instance); if (value is int) { return (int)value; } return 0; } return 0; } public static void SetLevelCurrent(Level level) { if (RunManagerLevelCurrentField != null && (Object)(object)RunManager.instance != (Object)null) { RunManagerLevelCurrentField.SetValue(RunManager.instance, level); } } public static GameObject GetAvatarMeshParent(PlayerAvatar avatar) { if ((Object)(object)avatar == (Object)null || PlayerAvatarVisualsField == null || PlayerAvatarVisualsMeshParentField == null) { return null; } object value = PlayerAvatarVisualsField.GetValue(avatar); if (value == null) { return null; } object? value2 = PlayerAvatarVisualsMeshParentField.GetValue(value); return (GameObject)((value2 is GameObject) ? value2 : null); } public static GameObject GetAvatarVisualRoot(PlayerAvatar avatar) { if ((Object)(object)avatar == (Object)null || PlayerAvatarVisualsField == null) { return null; } object? value = PlayerAvatarVisualsField.GetValue(avatar); Component val = (Component)((value is Component) ? value : null); if (!((Object)(object)val != (Object)null)) { return GetAvatarMeshParent(avatar); } return val.gameObject; } public static Animator GetAvatarAnimator(PlayerAvatar avatar) { if ((Object)(object)avatar == (Object)null || PlayerAvatarVisualsField == null || PlayerAvatarVisualsAnimatorField == null) { return null; } object value = PlayerAvatarVisualsField.GetValue(avatar); if (value == null) { return null; } object? value2 = PlayerAvatarVisualsAnimatorField.GetValue(value); Animator val = (Animator)((value2 is Animator) ? value2 : null); if ((Object)(object)val != (Object)null) { return val; } GameObject avatarVisualRoot = GetAvatarVisualRoot(avatar); if (!((Object)(object)avatarVisualRoot != (Object)null)) { return null; } return avatarVisualRoot.GetComponentInChildren<Animator>(true); } public static Transform GetTruckDoorMesh(TruckDoor door) { if ((Object)(object)door == (Object)null || TruckDoorMeshField == null) { return null; } object? value = TruckDoorMeshField.GetValue(door); return (Transform)((value is Transform) ? value : null); } public static TruckDoor FindLiveTruckDoor() { return Object.FindObjectOfType<TruckDoor>(); } public static Animator GetEnemyAnimator(Transform enemyTransform) { if ((Object)(object)enemyTransform == (Object)null) { return null; } Animator[] componentsInChildren = ((Component)enemyTransform).GetComponentsInChildren<Animator>(true); foreach (Animator val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)val.runtimeAnimatorController != (Object)null) { return val; } } return null; } public static Level FindLevelByName(string resourceName) { if ((Object)(object)RunManager.instance == (Object)null || RunManagerLevelsField == null || string.IsNullOrEmpty(resourceName)) { return null; } if (RunManagerLevelsField.GetValue(RunManager.instance) is List<Level> list) { for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i] != (Object)null && ((Object)list[i]).name == resourceName) { return list[i]; } } } return null; } public static void SetDebugLevel(Level level) { if (RunManagerDebugLevelField != null && (Object)(object)RunManager.instance != (Object)null) { RunManagerDebugLevelField.SetValue(RunManager.instance, level); } } public static void SetLevelsCompleted(int value) { if (RunManagerLevelsCompletedField != null && (Object)(object)RunManager.instance != (Object)null) { RunManagerLevelsCompletedField.SetValue(RunManager.instance, value); } } public static void SetGameInputDisabled(bool value) { if (GameDirectorDisableInputField != null && (Object)(object)GameDirector.instance != (Object)null) { GameDirectorDisableInputField.SetValue(GameDirector.instance, value); } } public static Camera GetGameMainCamera() { if (GameDirectorMainCameraField != null && (Object)(object)GameDirector.instance != (Object)null) { object? value = GameDirectorMainCameraField.GetValue(GameDirector.instance); return (Camera)((value is Camera) ? value : null); } return null; } public static Quaternion GetLocalAimRotation() { //IL_0015: 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_002a: Unknown result type (might be due to invalid IL or missing references) Camera gameMainCamera = GetGameMainCamera(); if ((Object)(object)gameMainCamera != (Object)null) { return ((Component)gameMainCamera).transform.rotation; } PlayerAvatar localAvatar = GetLocalAvatar(); if (!((Object)(object)localAvatar != (Object)null)) { return Quaternion.identity; } return ((Component)localAvatar).transform.rotation; } public static GameObject LookupPooledModule(string key) { if (string.IsNullOrEmpty(key) || (Object)(object)RunManager.instance == (Object)null) { return null; } if (RunManagerSingleplayerPoolField != null && RunManagerSingleplayerPoolField.GetValue(RunManager.instance) is Dictionary<string, Object> dictionary && dictionary.TryGetValue(key, out var value)) { GameObject val = (GameObject)(object)((value is GameObject) ? value : null); if (val != null) { return val; } } object obj = ((RunManagerMultiplayerPoolField != null) ? RunManagerMultiplayerPoolField.GetValue(RunManager.instance) : null); if (obj != null && MultiplayerPoolResourceCacheField != null && MultiplayerPoolResourceCacheField.GetValue(obj) is Dictionary<string, GameObject> dictionary2 && dictionary2.TryGetValue(key, out var value2) && (Object)(object)value2 != (Object)null) { return value2; } return null; } public static GameObject FindPrefabByNameInPool(string rawName) { if (string.IsNullOrWhiteSpace(rawName) || (Object)(object)RunManager.instance == (Object)null) { return null; } string text = NormalizeReplayName(rawName, string.Empty); if (string.IsNullOrEmpty(text)) { return null; } if (RunManagerSingleplayerPoolField != null && RunManagerSingleplayerPoolField.GetValue(RunManager.instance) is Dictionary<string, Object> dictionary) { foreach (KeyValuePair<string, Object> item in dictionary) { Object value = item.Value; GameObject val = (GameObject)(object)((value is GameObject) ? value : null); if (val != null && NormalizeReplayName(((Object)val).name, string.Empty) == text) { return val; } } } object obj = ((RunManagerMultiplayerPoolField != null) ? RunManagerMultiplayerPoolField.GetValue(RunManager.instance) : null); if (obj != null && MultiplayerPoolResourceCacheField != null && MultiplayerPoolResourceCacheField.GetValue(obj) is Dictionary<string, GameObject> dictionary2) { foreach (KeyValuePair<string, GameObject> item2 in dictionary2) { if ((Object)(object)item2.Value != (Object)null && NormalizeReplayName(((Object)item2.Value).name, string.Empty) == text) { return item2.Value; } } } return null; } public static GameObject LookupReplayPrefab(string key) { if (string.IsNullOrEmpty(key)) { return null; } GameObject val = LookupPooledModule(key); if ((Object)(object)val != (Object)null) { return val; } if (!key.StartsWith("AssetBundles/")) { return Resources.Load<GameObject>(key); } return null; } public static void SuppressGameCursor() { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (CursorManagerUnlockTimerField != null && (Object)(object)CursorManager.instance != (Object)null) { CursorManagerUnlockTimerField.SetValue(CursorManager.instance, -1234f); } if (!((Object)(object)MenuCursor.instance == (Object)null)) { if (MenuCursorShowTimerField != null) { MenuCursorShowTimerField.SetValue(MenuCursor.instance, 0f); } if (MenuCursorOverridePosTimerField != null) { MenuCursorOverridePosTimerField.SetValue(MenuCursor.instance, 0f); } GameObject val = (GameObject)((MenuCursorMeshField != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null && val.activeSelf) { val.SetActive(false); } ((Component)MenuCursor.instance).transform.localScale = Vector3.zero; } } public static bool IsAvatarDead(PlayerAvatar avatar) { if ((Object)(object)avatar == (Object)null || PlayerAvatarDeadSetField == null) { return false; } object value = PlayerAvatarDeadSetField.GetValue(avatar); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } public static string GetPlayerName(PlayerAvatar avatar) { if ((Object)(object)avatar == (Object)null) { return "Player"; } string text = ((PlayerAvatarNameField != null) ? (PlayerAvatarNameField.GetValue(avatar) as string) : null); if (!string.IsNullOrWhiteSpace(text)) { return text; } return "Player"; } public static string GetEnemyName(EnemyParent parent) { if ((Object)(object)parent == (Object)null) { return "Monster"; } string text = ((EnemyParentNameField != null) ? (EnemyParentNameField.GetValue(parent) as string) : null); if (!string.IsNullOrWhiteSpace(text)) { return text; } return "Monster"; } public static Transform GetEnemyTransform(EnemyParent parent) { if ((Object)(object)parent == (Object)null || EnemyParentEnemyField == null) { if (!((Object)(object)parent != (Object)null)) { return null; } return ((Component)parent).transform; } object? value = EnemyParentEnemyField.GetValue(parent); Enemy val = (Enemy)((value is Enemy) ? value : null); if (!((Object)(object)val != (Object)null)) { return ((Component)parent).transform; } return ((Component)val).transform; } public static GameObject GetEnemyVisualObject(GameObject root) { return root; } public static List<EnemyParent> GetSpawnedEnemies() { EnemyDirector enemyDirector = GetEnemyDirector(); if ((Object)(object)enemyDirector == (Object)null || EnemyDirectorSpawnedField == null) { return null; } return EnemyDirectorSpawnedField.GetValue(enemyDirector) as List<EnemyParent>; } public static GameObject FindEnemyPrefab(string name) { if (string.IsNullOrWhiteSpace(name)) { return null; } GameObject val = FindEnemyPrefabInDirector(name); if ((Object)(object)val != (Object)null) { return val; } if (EnemyResourcePrefabs == null) { EnemyResourcePrefabs = Resources.LoadAll<GameObject>("Enemies"); } string text = NormalizeReplayName(name, "Enemy"); for (int i = 0; i < EnemyResourcePrefabs.Length; i++) { GameObject val2 = EnemyResourcePrefabs[i]; if ((Object)(object)val2 != (Object)null && NormalizeReplayName(((Object)val2).name, "Enemy") == text) { return val2; } } string text2 = CleanResourceName(name); if (!string.IsNullOrEmpty(text2)) { val = Resources.Load<GameObject>("Enemies/" + text2); if ((Object)(object)val != (Object)null) { return val; } val = Resources.Load<GameObject>("Enemies/Enemy - " + text2); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static GameObject FindEnemyPrefabInDirector(string name) { EnemyDirector enemyDirector = GetEnemyDirector(); if ((Object)(object)enemyDirector == (Object)null) { return null; } FieldInfo[] array = new FieldInfo[5] { EnemyDirectorCurrentListField, EnemyDirectorListField, EnemyDirectorDifficulty1Field, EnemyDirectorDifficulty2Field, EnemyDirectorDifficulty3Field }; for (int i = 0; i < array.Length; i++) { GameObject val = FindEnemyPrefabInSetups((array[i] != null) ? (array[i].GetValue(enemyDirector) as List<EnemySetup>) : null, name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static EnemyDirector GetEnemyDirector() { if (!(EnemyDirectorInstanceField != null)) { return null; } object? value = EnemyDirectorInstanceField.GetValue(null); return (EnemyDirector)((value is EnemyDirector) ? value : null); } private static GameObject FindEnemyPrefabInSetups(List<EnemySetup> setups, string name) { if (setups == null) { return null; } string text = NormalizeReplayName(name, "Enemy"); for (int i = 0; i < setups.Count; i++) { EnemySetup val = setups[i]; if (!((Object)(object)val == (Object)null)) { if (NormalizeReplayName(((Object)val).name, "Enemy") == text) { return FindFirstEnemyPrefab(val); } GameObject val2 = FindPrefabRefPrefabInList((EnemySetupSpawnObjectsField != null) ? (EnemySetupSpawnObjectsField.GetValue(val) as List<PrefabRef>) : null, text, "Enemy"); if ((Object)(object)val2 != (Object)null) { return val2; } } } return null; } private static GameObject FindFirstEnemyPrefab(EnemySetup setup) { if ((Object)(object)setup == (Object)null || EnemySetupSpawnObjectsField == null) { return null; } if (!(EnemySetupSpawnObjectsField.GetValue(setup) is List<PrefabRef> list)) { return null; } for (int i = 0; i < list.Count; i++) { GameObject prefabRefPrefab = GetPrefabRefPrefab(list[i]); if ((Object)(object)prefabRefPrefab != (Object)null) { return prefabRefPrefab; } } return null; } public static float GetValuableValue(ValuableObject valuable) { if ((Object)(object)valuable == (Object)null || ValuableDollarField == null) { return 0f; } object value = ValuableDollarField.GetValue(valuable); if (value is float) { return (float)value; } return 0f; } public static GameObject GetLevelParentObject() { if ((Object)(object)LevelGenerator.Instance == (Object)null || LevelGeneratorLevelParentField == null) { return null; } object? value = LevelGeneratorLevelParentField.GetValue(LevelGenerator.Instance); return (GameObject)((value is GameObject) ? value : null); } public static void CaptureGeneratedModules(List<ReplayModule> modules) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) if (modules == null) { return; } modules.Clear(); GameObject levelParentObject = GetLevelParentObject(); if ((Object)(object)levelParentObject == (Object)null) { return; } Level levelCurrent = GetLevelCurrent(); Dictionary<string, string> dictionary = (((Object)(object)levelCurrent != (Object)null) ? BuildLevelPrefabPathMap(levelCurrent) : new Dictionary<string, string>()); Transform transform = levelParentObject.transform; for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); if (!((Object)(object)child == (Object)null) && IsModuleChild(child)) { string prefabName = CleanResourceName(((Object)child).name); string key = NormalizeReplayName(((Object)child).name, string.Empty); string value; string resourcePath = (dictionary.TryGetValue(key, out value) ? value : string.Empty); ReplayModule replayModule = new ReplayModule { ResourcePath = resourcePath, PrefabName = prefabName, Position = child.position, Rotation = child.rotation }; CaptureRendererStates(child, replayModule); modules.Add(replayModule); } } } private static void CaptureRendererStates(Transform child, ReplayModule module) { Renderer[] componentsInChildren = ((Component)child).GetComponentsInChildren<Renderer>(true); bool[] array = new bool[componentsInChildren.Length]; int[] array2 = new int[componentsInChildren.Length]; for (int i = 0; i < componentsInChildren.Length; i++) { Renderer val = componentsInChildren[i]; array[i] = (Object)(object)val != (Object)null && val.enabled && ((Component)val).gameObject.activeInHierarchy; array2[i] = (((Object)(object)val != (Object)null) ? RendererPathHash(child, ((Component)val).transform) : 0); } module.RendererStates = array; module.RendererPathHashes = array2; } public static int RendererPathHash(Transform root, Transform target) { StringBuilder stringBuilder = new StringBuilder(); Transform val = target; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { stringBuilder.Insert(0, ((Object)val).name); stringBuilder.Insert(0, '/'); val = val.parent; } return Animator.StringToHash(stringBuilder.ToString()); } private static bool IsModuleChild(Transform child) { if (!((Object)(object)((Component)child).GetComponent<Module>() != (Object)null) && !((Object)(object)((Component)child).GetComponent<StartRoom>() != (Object)null) && !((Object)(object)((Component)child).GetComponent<ModuleConnectObject>() != (Object)null) && !((Object)(object)((Component)child).GetComponent<ModuleBlockObject>() != (Object)null)) { return (Object)(object)((Component)child).GetComponentInChildren<Renderer>(true) != (Object)null; } return true; } public static GameObject ResolveModulePrefab(string resourcePath, string prefabName, Dictionary<string, GameObject> levelPrefabs) { if (levelPrefabs != null && !string.IsNullOrEmpty(prefabName)) { string text = NormalizeReplayName(prefabName, string.Empty); if (!string.IsNullOrEmpty(text) && levelPrefabs.TryGetValue(text, out var value) && (Object)(object)value != (Object)null) { return value; } } GameObject val = LookupReplayPrefab(resourcePath); if ((Object)(object)val != (Object)null) { return val; } val = FindPrefabByNameInPool(prefabName); if ((Object)(object)val != (Object)null) { return val; } return FindPrefabByNameInPool(resourcePath); } public static Dictionary<string, GameObject> BuildLevelPrefabObjectMap(Level level) { Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); if ((Object)(object)level == (Object)null) { return dictionary; } AddPrefabObjectField(dictionary, level, LevelConnectObjectField); AddPrefabObjectField(dictionary, level, LevelBlockObjectField); AddPrefabObjectListField(dictionary, level, LevelStartRoomsField); AddPrefabObjectListField(dictionary, level, LevelModulesNormal1Field); AddPrefabObjectListField(dictionary, level, LevelModulesNormal2Field); AddPrefabObjectListField(dictionary, level, LevelModulesNormal3Field); AddPrefabObjectListField(dictionary, level, LevelModulesPassage1Field); AddPrefabObjectListField(dictionary, level, LevelModulesPassage2Field); AddPrefabObjectListField(dictionary, level, LevelModulesPassage3Field); AddPrefabObjectListField(dictionary, level, LevelModulesDeadEnd1Field); AddPrefabObjectListField(dictionary, level, LevelModulesDeadEnd2Field); AddPrefabObjectListField(dictionary, level, LevelModulesDeadEnd3Field); AddPrefabObjectListField(dictionary, level, LevelModulesExtraction1Field); AddPrefabObjectListField(dictionary, level, LevelModulesExtraction2Field); AddPrefabObjectListField(dictionary, level, LevelModulesExtraction3Field); AddPrefabObjectListField(dictionary, level, LevelModulesSpecialField); return dictionary; } private static void AddPrefabObjectField(Dictionary<string, GameObject> map, object owner, FieldInfo field) { if (map != null && owner != null && !(field == null)) { object? value = field.GetValue(owner); AddPrefabObject(map, (PrefabRef)((value is PrefabRef) ? value : null)); } } private static void AddPrefabObjectListField(Dictionary<string, GameObject> map, object owner, FieldInfo field) { if (map != null && owner != null && !(field == null) && field.GetValue(owner) is List<PrefabRef> list) { for (int i = 0; i < list.Count; i++) { AddPrefabObject(map, list[i]); } } } private static void AddPrefabObject(Dictionary<string, GameObject> map, PrefabRef prefabRef) { if (map == null || prefabRef == null) { return; } GameObject prefabRefPrefab = GetPrefabRefPrefab(prefabRef); if (!((Object)(object)prefabRefPrefab == (Object)null)) { string prefabRefString = GetPrefabRefString(PrefabRefPrefabNameGetter, prefabRef); string text = NormalizeReplayName(string.IsNullOrEmpty(prefabRefString) ? ((Object)prefabRefPrefab).name : prefabRefString, string.Empty); if (!string.IsNullOrEmpty(text) && !map.ContainsKey(text)) { map.Add(text, prefabRefPrefab); } } } private static Dictionary<string, string> BuildLevelPrefabPathMap(Level level) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); AddPrefabRefField(dictionary, level, LevelConnectObjectField); AddPrefabRefField(dictionary, level, LevelBlockObjectField); AddPrefabRefListField(dictionary, level, LevelStartRoomsField); AddPrefabRefListField(dictionary, level, LevelModulesNormal1Field); AddPrefabRefListField(dictionary, level, LevelModulesNormal2Field); AddPrefabRefListField(dictionary, level, LevelModulesNormal3Field); AddPrefabRefListField(dictionary, level, LevelModulesPassage1Field); AddPrefabRefListField(dictionary, level, LevelModulesPassage2Field); AddPrefabRefListField(dictionary, level, LevelModulesPassage3Field); AddPrefabRefListField(dictionary, level, LevelModulesDeadEnd1Field); AddPrefabRefListField(dictionary, level, LevelModulesDeadEnd2Field); AddPrefabRefListField(dictionary, level, LevelModulesDeadEnd3Field); AddPrefabRefListField(dictionary, level, LevelModulesExtraction1Field); AddPrefabRefListField(dictionary, level, LevelModulesExtraction2Field); AddPrefabRefListField(dictionary, level, LevelModulesExtraction3Field); AddPrefabRefListField(dictionary, level, LevelModulesSpecialField); return dictionary; } private static void AddPrefabRefField(Dictionary<string, string> map, object owner, FieldInfo field) { if (map != null && owner != null && !(field == null)) { object? value = field.GetValue(owner); AddPrefabRef(map, (PrefabRef)((value is PrefabRef) ? value : null)); } } private static void AddPrefabRefListField(Dictionary<string, string> map, object owner, FieldInfo field) { if (map != null && owner != null && !(field == null) && field.GetValue(owner) is List<PrefabRef> list) { for (int i = 0; i < list.Count; i++) { AddPrefabRef(map, list[i]); } } } private static void AddPrefabRef(Dictionary<string, string> map, PrefabRef prefabRef) { if (map == null || prefabRef == null) { return; } string prefabRefString = GetPrefabRefString(PrefabRefPrefabNameGetter, prefabRef); string prefabResourcePath = GetPrefabResourcePath(prefabRef); if (!string.IsNullOrEmpty(prefabRefString) && !string.IsNullOrEmpty(prefabResourcePath)) { string key = NormalizeReplayName(prefabRefString, string.Empty); if (!map.ContainsKey(key)) { map.Add(key, prefabResourcePath); } } } public static string GetPrefabResourcePath(PrefabRef prefabRef) { return GetPrefabRefString(PrefabRefResourcePathGetter, prefabRef); } public static GameObject FindValuablePrefab(string cleanedName) { if (string.IsNullOrEmpty(cleanedName)) { return null; } GameObject val = FindValuablePrefabInLevel(GetLevelCurrent(), cleanedName); if ((Object)(object)val != (Object)null) { return val; } val = FindValuablePrefabInDirector(cleanedName); if ((Object)(object)val != (Object)null) { return val; } if (RunManagerLevelsField != null && (Object)(object)RunManager.instance != (Object)null && RunManagerLevelsField.GetValue(RunManager.instance) is List<Level> list) { for (int i = 0; i < list.Count; i++) { val = FindValuablePrefabInLevel(list[i], cleanedName); if ((Object)(object)val != (Object)null) { return val; } } } if (ValuableDirectorListField == null || (Object)(object)ValuableDirector.instance == (Object)null) { return null; } if (!(ValuableDirectorListField.GetValue(ValuableDirector.instance) is IEnumerable enumerable)) { return null; } foreach (object item in enumerable) { ValuableObject val2 = (ValuableObject)((item is ValuableObject) ? item : null); if (!((Object)(object)val2 == (Object)null) && ((Object)val2).name.Replace("(Clone)", string.Empty).Replace("Valuable ", string.Empty).Trim() == cleanedName) { return ((Component)val2).gameObject; } } return null; } private static GameObject FindValuablePrefabInLevel(Level level, string cleanedName) { if ((Object)(object)level == (Object)null || LevelValuablePresetsField == null) { return null; } if (!(LevelValuablePresetsField.GetValue(level) is List<LevelValuables> list)) { return null; } for (int i = 0; i < list.Count; i++) { GameObject val = FindValuablePrefabInPreset(list[i], cleanedName); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static GameObject FindValuablePrefabInPreset(LevelValuables preset, string cleanedName) { if ((Object)(object)preset == (Object)null) { return null; } FieldInfo[] array = new FieldInfo[7] { LevelValuablesTinyField, LevelValuablesSmallField, LevelValuablesMediumField, LevelValuablesBigField, LevelValuablesWideField, LevelValuablesTallField, LevelValuablesVeryTallField }; for (int i = 0; i < array.Length; i++) { GameObject val = FindValuablePrefabInList((array[i] != null) ? (array[i].GetValue(preset) as List<PrefabRef>) : null, cleanedName); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static GameObject FindValuablePrefabInDirector(string cleanedName) { if ((Object)(object)ValuableDirector.instance == (Object)null) { return null; } FieldInfo[] array = new FieldInfo[7] { ValuableDirectorTinyValuablesField, ValuableDirectorSmallValuablesField, ValuableDirectorMediumValuablesField, ValuableDirectorBigValuablesField, ValuableDirectorWideValuablesField, ValuableDirectorTallValuablesField, ValuableDirectorVeryTallValuablesField }; for (int i = 0; i < array.Length; i++) { GameObject val = FindValuablePrefabInList((array[i] != null) ? (array[i].GetValue(ValuableDirector.instance) as List<PrefabRef>) : null, cleanedName); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static GameObject FindValuablePrefabInList(List<PrefabRef> prefabs, string cleanedName) { if (prefabs == null || prefabs.Count == 0) { return null; } string target = NormalizeValuableName(cleanedName); return FindPrefabRefPrefabInList(prefabs, target, "Valuable"); } private static bool PrefabRefMatches(PrefabRef prefabRef, string target) { return PrefabRefMatches(prefabRef, target, "Valuable"); } private static GameObject FindPrefabRefPrefabInList(List<PrefabRef> prefabs, string target, string prefix) { if (prefabs == null || prefabs.Count == 0) { return null; } for (int i = 0; i < prefabs.Count; i++) { PrefabRef val = prefabs[i]; if (val != null && PrefabRefMatches(val, target, prefix)) { GameObject prefabRefPrefab = GetPrefabRefPrefab(val); if ((Object)(object)prefabRefPrefab != (Object)null) { return prefabRefPrefab; } } } return null; } private static bool PrefabRefMatches(PrefabRef prefabRef, string target, string prefix) { if (string.IsNullOrEmpty(target)) { return false; } if (NormalizeReplayName(GetPrefabRefString(PrefabRefPrefabNameGetter, prefabRef), prefix) == target) { return true; } return NormalizeReplayName(GetPrefabRefString(PrefabRefResourcePathGetter, prefabRef), prefix) == target; } private static string GetPrefabRefString(MethodInfo getter, PrefabRef prefabRef) { if (getter == null || prefabRef == null) { return string.Empty; } try { return (getter.Invoke(prefabRef, null) as string) ?? string.Empty; } catch { return string.Empty; } } private static GameObject GetPrefabRefPrefab(PrefabRef prefabRef) { if (PrefabRefPrefabGetter == null || prefabRef == null) { return null; } try { object? obj = PrefabRefPrefabGetter.Invoke(prefabRef, null); return (GameObject)((obj is GameObject) ? obj : null); } catch { return null; } } private static string NormalizeValuableName(string raw) { return NormalizeReplayName(raw, "Valuable"); } private static string NormalizeReplayName(string raw, string prefix) { if (string.IsNullOrWhiteSpace(raw)) { return string.Empty; } string text = CleanResourceName(raw); text = text.Replace("(Clone)", string.Empty).Trim(); if (!string.IsNullOrWhiteSpace(prefix)) { text = text.Replace(prefix + " ", string.Empty).Replace(prefix + "_", string.Empty).Replace(prefix + "-", string.Empty) .Trim(); } text = text.Replace(" ", string.Empty).Replace("_", string.Empty).Replace("-", string.Empty); return text.ToLowerInvariant(); } private static string CleanResourceName(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return string.Empty; } string text = raw.Replace("\\", "/"); int num = text.LastIndexOf('/'); if (num >= 0 && num + 1 < text.Length) { text = text.Substring(num + 1); } int num2 = text.LastIndexOf('.'); if (num2 > 0) { text = text.Substring(0, num2); } return text.Replace("(Clone)", string.Empty).Trim(); } } internal enum ReplayAnimParamType : byte { Float, Int, Bool, Trigger } internal sealed class ReplayAnimParam { public string Name = string.Empty; public ReplayAnimParamType Type; public int Hash; } internal sealed class ReplayAnimBinding { public Animator Animator; public HashSet<int> ParamHashes; public bool DrivesSchema; } internal static class ReplayAnimation { private const float FloatEpsilon = 0.01f; private const float SpeedEpsilon = 0.02f; public static ReplayAnimParam[] BuildSchema(Animator animator) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)animator == (Object)null || (Object)(object)animator.runtimeAnimatorController == (Object)null) { return null; } AnimatorControllerParameter[] parameters; try { parameters = animator.parameters; } catch { return null; } if (parameters == null || parameters.Length == 0) { return null; } ReplayAnimParam[] array = new ReplayAnimParam[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { AnimatorControllerParameter val = parameters[i]; array[i] = new ReplayAnimParam { Name = val.name, Type = MapType(val.type), Hash = val.nameHash }; } return array; } public static float Snapshot(Animator animator, ReplayAnimParam[] schema, float[] destination) { if ((Object)(object)animator == (Object)null || schema == null || destination == null) { return 1f; } for (int i = 0; i < schema.Length && i < destination.Length; i++) { ReplayAnimParam replayAnimParam = schema[i]; switch (replayAnimParam.Type) { case ReplayAnimParamType.Float: destination[i] = animator.GetFloat(replayAnimParam.Hash); break; case ReplayAnimParamType.Int: destination[i] = animator.GetInteger(replayAnimParam.Hash); break; default: destination[i] = (animator.GetBool(replayAnimParam.Hash) ? 1f : 0f); break; } } return animator.speed; } public static bool Changed(ReplayAnimParam[] schema, float[] current, float[] last, float currentSpeed, float lastSpeed) { if (schema == null || current == null || last == null) { return false; } if (Mathf.Abs(currentSpeed - lastSpeed) > 0.02f) { return true; } for (int i = 0; i < schema.Length && i < current.Length && i < last.Length; i++) { if (schema[i].Type == ReplayAnimParamType.Float) { if (Mathf.Abs(current[i] - last[i]) > 0.01f) { return true; } } else if (!Mathf.Approximately(current[i], last[i])) { return true; } } return false; } public static ReplayAnimBinding[] BuildBindings(Animator[] animators, ReplayAnimParam[] schema) { if (animators == null || animators.Length == 0 || schema == null || schema.Length == 0) { return null; } List<ReplayAnimBinding> list = new List<ReplayAnimBinding>(); foreach (Animator val in animators) { if ((Object)(object)val == (Object)null || (Object)(object)val.runtimeAnimatorController == (Object)null) { continue; } AnimatorControllerParameter[] parameters; try { parameters = val.parameters; } catch { continue; } if (parameters == null || parameters.Length == 0) { continue; } HashSet<int> hashSet = new HashSet<int>(); for (int j = 0; j < parameters.Length; j++) { hashSet.Add(parameters[j].nameHash); } bool flag = false; for (int k = 0; k < schema.Length; k++) { if (hashSet.Contains(schema[k].Hash)) { flag = true; break; } } if (flag) { list.Add(new ReplayAnimBinding { Animator = val, ParamHashes = hashSet, DrivesSchema = true }); } } if (list.Count <= 0) { return null; } return list.ToArray(); } public static void Apply(ReplayAnimBinding[] bindings, ReplayAnimParam[] schema, float[] values, float speed, float[] triggerState) { if (bindings == null || schema == null || values == null) { return; } foreach (ReplayAnimBinding replayAnimBinding in bindings) { if (replayAnimBinding == null || (Object)(object)replayAnimBinding.Animator == (Object)null) { continue; } for (int j = 0; j < schema.Length && j < values.Length; j++) { ReplayAnimParam replayAnimParam = schema[j]; if (!replayAnimBinding.ParamHashes.Contains(replayAnimParam.Hash)) { continue; } switch (replayAnimParam.Type) { case ReplayAnimParamType.Float: replayAnimBinding.Animator.SetFloat(replayAnimParam.Hash, values[j]); break; case ReplayAnimParamType.Int: replayAnimBinding.Animator.SetInteger(replayAnimParam.Hash, Mathf.RoundToInt(values[j])); break; case ReplayAnimParamType.Bool: replayAnimBinding.Animator.SetBool(replayAnimParam.Hash, values[j] >= 0.5f); break; case ReplayAnimParamType.Trigger: if (triggerState != null && j < triggerState.Length && values[j] >= 0.5f && triggerState[j] < 0.5f) { replayAnimBinding.Animator.SetTrigger(replayAnimParam.Hash); } break; } } if (replayAnimBinding.DrivesSchema) { replayAnimBinding.Animator.speed = speed; } } if (triggerState == null) { return; } for (int k = 0; k < schema.Length && k < values.Length && k < triggerState.Length; k++) { if (schema[k].Type == ReplayAnimParamType.Trigger) { triggerState[k] = values[k]; } } } private static ReplayAnimParamType MapType(AnimatorControllerParameterType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)type != 1) { if ((int)type != 3) { if ((int)type == 9) { return ReplayAnimParamType.Trigger; } return ReplayAnimParamType.Bool; } return ReplayAnimParamType.Int; } return ReplayAnimParamType.Float; } } internal enum ReplayViewMode { FirstPerson, ThirdPerson, Free } internal sealed class ReplayCamera { private float _yaw; private float _pitch; private float _orbitDistance = 4.5f; private bool _active; private Vector3 _position; private Quaternion _rotation = Quaternion.identity; private bool _followAimValid; private Quaternion _followAim = Quaternion.identity; public bool Active => _active; public ReplayViewMode Mode { get; private set; } = ReplayViewMode.ThirdPerson; public Transform FollowTarget { get; set; } public Vector3 Position => _position; public Quaternion Rotation => _rotation; public void Begin(Vector3 startPosition, Quaternion startRotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) _position = startPosition; _rotation = startRotation; Vector3 eulerAngles = ((Quaternion)(ref startRotation)).eulerAngles; _pitch = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x); _yaw = eulerAngles.y; _active = true; } public void End() { _active = false; } public void SetMode(ReplayViewMode mode) { Mode = mode; } public void CycleMode() { Mode = (ReplayViewMode)((int)(Mode + 1) % 3); } public void SetFollowAim(bool valid, Quaternion aim) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) _followAimValid = valid; _followAim = aim; } public void Tick(float deltaTime, bool lookEnabled) { if (_active) { float value = EmpressReplaysPlugin.Settings.LookSensitivity.Value; if ((Mode == ReplayViewMode.Free || Mode == ReplayViewMode.ThirdPerson) && lookEnabled) { _yaw += Input.GetAxisRaw("Mouse X") * value; _pitch -= Input.GetAxisRaw("Mouse Y") * value; _pitch = Mathf.Clamp(_pitch, -85f, 85f); } float axis = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(axis) > 0.0001f && Mode == ReplayViewMode.ThirdPerson) { _orbitDistance = Mathf.Clamp(_orbitDistance - axis * 4f, 1.5f, 12f); } switch (Mode) { case ReplayViewMode.FirstPerson: TickFirstPerson(); break; case ReplayViewMode.ThirdPerson: TickThirdPerson(); break; default: TickFree(deltaTime); break; } } } private void TickFirstPerson() { //IL_002c: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)FollowTarget == (Object)null) { SetMode(ReplayViewMode.Free); return; } Quaternion rotation = (_followAimValid ? _followAim : FollowTarget.rotation); _position = FollowTarget.position + Vector3.up * 1.6f; _rotation = rotation; Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; _pitch = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x); _yaw = eulerAngles.y; } private void TickThirdPerson() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_0092: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)FollowTarget == (Object)null) { SetMode(ReplayViewMode.Free); return; } Quaternion val = Quaternion.Euler(_pitch, _yaw, 0f); Vector3 val2 = FollowTarget.position + Vector3.up * 1.4f; Vector3 val3 = val2 - val * Vector3.forward * _orbitDistance; RaycastHit val4 = default(RaycastHit); if (Physics.Linecast(val2, val3, ref val4, -1, (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<PlayerAvatar>() == (Object)null) { val3 = ((RaycastHit)(ref val4)).point + ((RaycastHit)(ref val4)).normal * 0.3f; } _position = val3; _rotation = val; } private void TickFree(float deltaTime) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_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_005d: 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_006c: 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_006e: 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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) Quaternion val = (_rotation = Quaternion.Euler(_pitch, _yaw, 0f)); float num = EmpressReplaysPlugin.Settings.CameraSpeed.Value; if (Input.GetKey((KeyCode)304)) { num *= 3f; } Vector3 val2 = Vector3.zero; if (Input.GetKey((KeyCode)119)) { val2 += val * Vector3.forward; } if (Input.GetKey((KeyCode)115)) { val2 += val * Vector3.back; } if (Input.GetKey((KeyCode)100)) { val2 += val * Vector3.right; } if (Input.GetKey((KeyCode)97)) { val2 += val * Vector3.left; } if (Input.GetKey((KeyCode)101)) { val2 += Vector3.up; } if (Input.GetKey((KeyCode)113)) { val2 += Vector3.down; } _position += val2 * num * deltaTime; } } internal enum ReplayMode { Idle, Recording, Playback } internal sealed class ReplayController : MonoBehaviour { private readonly ReplayRecorder _recorder = new ReplayRecorder(); private readonly ReplayPlayer _player = new ReplayPlayer(); private readonly ReplayCamera _camera = new ReplayCamera(); private readonly ReplayLevelOverlay _levelOverlay = new ReplayLevelOverlay(); private ReplayHud _hud; private ReplayMode _mode; private int _sceneHandle = -1; private bool _levelRecorded; private List<ReplayGhost> _playerTargets = new List<ReplayGhost>(); private int _targetIndex; private ReplayData _pendingReplay; private bool _awaitingPlaybackLevel; private bool _settling; private float _settleTimer; private float _rehideTimer; private bool _suppressRecording; private const float PlaybackSettleSeconds = 3.5f; public static ReplayController Instance { get; private set; } public static bool IsPlaybackBoot { get; private set; } public ReplayMode Mode => _mode; public ReplayPlayer Player => _player; public ReplayCamera Camera => _camera; public static ReplayController EnsureHost() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown if ((Object)(object)Instance != (Object)null) { return Instance; } GameObject val = new GameObject("Empress Replay Controller"); val.transform.parent = null; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent<ReplayController>(); return Instance; } private void Awake() { Instance = this; _hud = ReplayHud.Create(this); } private void Update() { HandleSceneChange(); float unscaledDeltaTime = Time.unscaledDeltaTime; if (_awaitingPlaybackLevel) { if (_pendingReplay != null && LevelFullyLoaded()) { if (!_settling) { _settling = true; _settleTimer = 3.5f; _hud.Toast("Level loaded, starting replay", 3.5f); } else { _settleTimer -= unscaledDeltaTime; if (_settleTimer <= 0f) { BeginPlaybackInLevel(); } } } _hud.UpdateState(_mode, _recorder.FrameCount, _player, _camera); return; } if (_mode == ReplayMode.Idle && !_levelRecorded && !_suppressRecording && EmpressReplaysPlugin.Settings.AutoRecord.Value && InLevel() && ReplayAccess.IsLevelGenerated()) { _levelRecorded = true; _recorder.Begin(); _mode = ReplayMode.Recording; _hud.Toast("● Recording match", 2.5f); EmpressReplaysPlugin.DebugLog("Empress Replays recording started for " + ReplayLayoutCapture.LevelName); } if (_mode == ReplayMode.Recording) { _recorder.Tick(Time.deltaTime); } if (_mode == ReplayMode.Playback) { if (Time.timeScale != 0f) { Time.timeScale = 0f; } ReplayEnvironment.Apply(); _player.Tick(unscaledDeltaTime); UpdateDeathFollow(); PushFollowAim(); ApplyFirstPersonHiding(); bool mouseButton = Input.GetMouseButton(1); _camera.Tick(unscaledDeltaTime, mouseButton); HandlePlaybackInput(); _rehideTimer -= unscaledDeltaTime; if (_rehideTimer <= 0f) { _rehideTimer = 1f; ReplayLiveSuppressor.RefreshHidden(); } } _hud.UpdateState(_mode, _recorder.FrameCount, _player, _camera); } private void LateUpdate() { if (_hud.WantsCursor() && (_mode != ReplayMode.Playback || !Input.GetMouseButton(1))) { ReplayAccess.SuppressGameCursor(); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } public void OnLevelGenerateStarting() { if (_mode == ReplayMode.Recording) { ReplayData data = _recorder.End(); _mode = ReplayMode.Idle; SaveReplay(data); } _levelRecorded = false; if (!IsPlaybackBoot) { _suppressRecording = false; } } public void OnLevelChanging(bool completed) { if (_mode == ReplayMode.Recording) { ReplayData data = _recorder.End(); _mode = ReplayMode.Idle; SaveReplay(data); } } private void SaveReplay(ReplayData data) { if (data == null || data.FrameCount < 4) { return; } try { string path = SafeName(data.LevelName) + "_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".emrly"; string text = Path.Combine(EmpressReplaysPlugin.ReplayFolder, path); ReplayFormat.Save(text, data); EnforceReplayCap(); _hud.Toast("Replay saved", 3f); EmpressReplaysPlugin.DebugLog("Saved replay: " + text); } catch (Exception ex) { EmpressReplaysPlugin.Log.LogError((object)("Replay save failed: " + ex)); } } private void EnforceReplayCap() { int value = EmpressReplaysPlugin.Settings.MaxReplays.Value; List<string> list = ListReplays(); if (list.Count <= value) { return; } list.Sort(CompareByWriteTimeAsc); int num = list.Count - value; for (int i = 0; i < num; i++) { try { File.Delete(list[i]); } catch { } } } public void OpenBrowserFromMenu() { _hud.OpenBrowser(ListReplaysNewestFirst()); } public void StartPlayback(string path) { try { ReplayData replayData = ReplayFormat.Load(path); if (replayData == null) { _hud.Toast("Invalid replay", 2.5f); return; } Level val = ReplayAccess.FindLevelByName(replayData.LevelResourceName); if ((Object)(object)val == (Object)null) { _hud.Toast("Level not found: " + replayData.LevelName, 3.5f); return; } if (_mode == ReplayMode.Recording) { _recorder.End(); _mode = ReplayMode.Idle; } _pendingReplay = replayData; _awaitingPlaybackLevel = true; _settling = false; _suppressRecording = true; IsPlaybackBoot = true; ReplaySeed.Activate(replayData.LevelSeed); _hud.CloseBrowser(); _hud.Toast("Loading replay: " + replayData.LevelName, 3f); BootPlaybackLevel(val, replayData.LevelsCompleted); } catch (Exception ex) { _hud.Toast("Load failed", 2.5f); EmpressReplaysPlugin.Log.LogError((object)("Replay load failed: " + ex)); IsPlaybackBoot = false; _awaitingPlaybackLevel = false; _suppressRecording = false; } } private void BootPlaybackLevel(Level level, int levelsCompleted) { GameManager instance = GameManager.instance; if (instance != null) { instance.SetConnectRandom(false); } GameManager instance2 = GameManager.instance; if (instance2 != null) { instance2.SetLobbyType((LobbyTypes)0); } RunManager.instance.ResetProgress(); ReplayAccess.SetLevelsCompleted(levelsCompleted); ReplayAccess.SetDebugLevel(level); ReplayAccess.SetLevelCurrent(level); RunManager.instance.ChangeLevel(true, false, (ChangeLevelType)1); } public void OnLevelGenerateDone() { if (!IsPlaybackBoot) { ReplaySeed.Deactivate(); } } private bool LevelFullyLoaded() { if (!ReplayAccess.IsGameStateMain()) { return false; } if (!ReplayAccess.IsLevelGenerated()) { return false; } if ((Object)(object)ReplayAccess.GetLocalAvatar() == (Object)null) { return false; } if (!ReplayAccess.IsLoadingComplete()) { return false; } return true; } private void BeginPlaybackInLevel() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) _awaitingPlaybackLevel = false; _settling = false; IsPlaybackBoot = false; ReplaySeed.Deactivate(); ReplayEnvironment.Capture(); HashSet<string> movedPropNames = CollectMovedPropNames(_pendingReplay); _levelOverlay.Build(_pendingReplay, movedPropNames); _player.Load(_pendingReplay); ReplayLiveSuppressor.SetMovedPropNames(movedPropNames); ReplayLiveSuppressor.Suppress(suppress: true); _mode = ReplayMode.Playback; _playerTargets = _player.PlayerGhosts; _targetIndex = LocalPlayerIndex(_playerTargets); _rehideTimer = 1f; Vector3 startPosition = FirstPlayerPosition(_pendingReplay) + new Vector3(0f, 4f, -6f); _camera.Begin(startPosition, Quaternion.Euler(20f, 0f, 0f)); _camera.SetMode(ReplayViewMode.FirstPerson); UpdateCameraTarget(); _player.Play(); Time.timeScale = 0f; _hud.Toast("Playing " + _pendingReplay.LevelName, 3f); } private void UpdateDeathFollow() { List<ReplayGhost> playerGhosts = _player.PlayerGhosts; if (playerGhosts.Count == 0) { return; } int index = Mathf.Clamp(_targetIndex, 0, playerGhosts.Count - 1); ReplayGhost replayGhost = playerGhosts[index]; if (!((Object)(object)replayGhost.Root == (Object)null) && ((Component)replayGhost.Root).gameObject.activeSelf) { if ((Object)(object)replayGhost.Root != (Object)null) { _camera.FollowTarget = replayGhost.Root; } return; } ReplayGhost deathHeadGhost = _player.GetDeathHeadGhost(); if (deathHeadGhost != null && !((Object)(object)deathHeadGhost.Root == (Object)null)) { _camera.FollowTarget = deathHeadGhost.Root; if (_camera.Mode == ReplayViewMode.FirstPerson) { _camera.SetMode(ReplayViewMode.ThirdPerson); } } } private void PushFollowAim() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) List<ReplayGhost> playerGhosts = _player.PlayerGhosts; if (playerGhosts.Count == 0) { _camera.SetFollowAim(valid: false, Quaternion.identity); return; } int index = Mathf.Clamp(_targetIndex, 0, playerGhosts.Count - 1); ReplayGhost replayGhost = playerGhosts[index]; _camera.SetFollowAim(replayGhost.HasAim, replayGhost.CurrentAim); } private static HashSet<string> CollectMovedPropNames(ReplayData data) { HashSet<string> hashSet = new HashSet<string>(); if (data == null) { return hashSet; } for (int i = 0; i < data.Actors.Count; i++) { ReplayActor replayActor = data.Actors[i]; if (replayActor.Kind == ReplayActorKind.Prop && ReplayPlayer.ActorMoved(replayActor)) { hashSet.Add(replayActor.DisplayName); } } return hashSet; } private static int LocalPlayerIndex(List<ReplayGhost> players) { for (int i = 0; i < players.Count; i++) { if (players[i].Actor != null && players[i].Actor.IsLocalPlayer) { return i; } } return 0; } private void ApplyFirstPersonHiding() { List<ReplayGhost> playerGhosts = _player.PlayerGhosts; if (playerGhosts.Count != 0) { bool flag = _camera.Mode == ReplayViewMode.FirstPerson; int num = Mathf.Clamp(_targetIndex, 0, playerGhosts.Count - 1); for (int i = 0; i < playerGhosts.Count; i++) { SetGhostRenderers(playerGhosts[i], !flag || i != num); } } } private static void SetGhostRenderers(ReplayGhost ghost, bool visible) { if (ghost == null || ghost.Renderers == null) { return; } for (int i = 0; i < ghost.Renderers.Length; i++) { Renderer val = ghost.Renderers[i]; if ((Object)(object)val != (Object)null && val.enabled != visible) { val.enabled = visible; } } } public void ApplyCameraPosition(CameraPosition cameraPosition) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (_mode == ReplayMode.Playback && _camera.Active && !((Object)(object)cameraPosition == (Object)null)) { ((Component)cameraPosition).transform.position = _camera.Position; } } public void ApplyCameraAim(CameraAim cameraAim) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (_mode == ReplayMode.Playback && _camera.Active && !((Object)(object)cameraAim == (Object)null)) { ((Component)cameraAim).transform.rotation = _camera.Rotation; } } public void StopPlayback() { if (_mode == ReplayMode.Playback) { Time.timeScale = 1f; ReplayEnvironment.Clear(); _player.Unload(); _levelOverlay.Clear(); _camera.End(); ReplayLiveSuppressor.Suppress(suppress: false); _mode = ReplayMode.Idle; _pendingReplay = null; _hud.Toast("Playback ended, leaving", 2f); if ((Object)(object)RunManager.instance != (Object)null) { ReplayAccess.SetDebugLevel(null); ((MonoBehaviour)this).StartCoroutine(LeaveAfterDelay()); } } } private IEnumerator LeaveAfterDelay() { yield return (object)new WaitForSecondsRealtime(0.5f); if ((Object)(object)RunManager.instance != (Object)null) { ((MonoBehaviour)this).StartCoroutine(RunManager.instance.LeaveToMainMenu()); } } public void DeleteReplay(string path) { try { File.Delete(path); } catch { } } public List<string> ListReplaysNewestFirst() { List<string> list = ListReplays(); list.Sort(CompareByWriteTimeDesc); return list; } private void HandlePlaybackInput() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(EmpressReplaysPlugin.Settings.ViewModeKey.Value)) { _camera.CycleMode(); UpdateCameraTarget(); _hud.Toast("View: " + _camera.Mode, 1.5f); } if (Input.GetKeyDown(EmpressReplaysPlugin.Settings.NextTargetKey.Value)) { CycleTarget(); } if (Input.GetKeyDown(EmpressReplaysPlugin.Settings.ExitKey.Value)) { StopPlayback(); } } private void CycleTarget() { _playerTargets = _player.PlayerGhosts; if (_playerTargets.Count != 0) { _targetIndex = (_targetIndex + 1) % _playerTargets.Count; UpdateCameraTarget(); _hud.Toast("Spectating " + _playerTargets[_targetIndex].Actor.DisplayName, 2f); } } private void UpdateCameraTarget() { _playerTargets = _player.PlayerGhosts; if (_playerTargets.Count == 0) { _camera.FollowTarget = null; if (_camera.Mode != ReplayViewMode.Free) { _camera.SetMode(ReplayViewMode.Free); } } else { _targetIndex = Mathf.Clamp(_targetIndex, 0, _playerTargets.Count - 1); _camera.FollowTarget = _playerTargets[_targetIndex].Root; } } private List<string> ListReplays() { List<string> list = new List<string>(); try { if (Directory.Exists(EmpressReplaysPlugin.ReplayFolder)) { list.AddRange(Directory.GetFiles(EmpressReplaysPlugin.ReplayFolder, "*.emrly")); } } catch { } return list; } private static int CompareByWriteTimeDesc(string a, string b) { return File.GetLastWriteTimeUtc(b).CompareTo(File.GetLastWriteTimeUtc(a)); } private static int CompareByWriteTimeAsc(string a, string b) { return File.GetLastWriteTimeUtc(a).CompareTo(File.GetLastWriteTimeUtc(b)); } private void HandleSceneChange() { //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(); int handle = ((Scene)(ref activeScene)).handle; if (handle != _sceneHandle) { _sceneHandle = handle; _levelOverlay.Clear(); if (_mode == ReplayMode.Playback) { StopPlayback(); } else if (_mode == ReplayMode.Recording) { ReplayData data = _recorder.End(); SaveReplay(data); } _mode = ReplayMode.Idle; _levelRecorded = false; } } private static bool InLevel() { if (ReplayAccess.IsGameStateMain() && (Object)(object)LevelGenerator.Instance != (Object)null) { return !SemiFunc.MenuLevel(); } return false; } private static Vector3 FirstPlayerPosition(ReplayData data) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < data.Actors.Count; i++) { ReplayActor replayActor = data.Actors[i]; if (replayActor.Kind == ReplayActorKind.Player && replayActor.Positions.Count > 0) { return replayActor.Positions[0]; } } return Vector3.zero; } private static string SafeName(string raw) { if (string.IsNullOrEmpty(raw)) { return "Level"; } char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); string text = raw; for (int i = 0; i < invalidFileNameChars.Length; i++) { text = text.Replace(invalidFileNameChars[i], '_'); } return text.Replace(' ', '_'); } } internal static class ReplayEnvironment { private static bool _captured; private static bool _fog; private static Color _fogColor; private static FogMode _fogMode; private static float _fogStart; private static float _fogEnd; private static float _fogDensity; private static AmbientMode _ambientMode; private static Color _ambientLight; private static Color _ambientSky; private static Color _ambientEquator; private static Color _ambientGround; private static float _ambientIntensity; public static void Capture() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_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) //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_0046: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) _fog = RenderSettings.fog; _fogColor = RenderSettings.fogColor; _fogMode = RenderSettings.fogMode; _fogStart = RenderSettings.fogStartDistance; _fogEnd = RenderSettings.fogEndDistance; _fogDensity = RenderSettings.fogDensity; _ambientMode = RenderSettings.ambientMode; _ambientLight = RenderSettings.ambientLight; _ambientSky = RenderSettings.ambientSkyColor; _ambientEquator = RenderSettings.ambientEquatorColor; _ambientGround = RenderSettings.ambientGroundColor; _ambientIntensity = RenderSettings.ambientIntensity; _captured = true; } public static void Apply() { //IL_0012: 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_0044: 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_0058: 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_006c: Unknown result type (might be due to invalid IL or missing references) if (_captured) { RenderSettings.fog = _fog; RenderSettings.fogColor = _fogColor; RenderSettings.fogMode = _fogMode; RenderSettings.fogStartDistance = _fogStart; RenderSettings.fogEndDistance = _fogEnd; RenderSettings.fogDensity = _fogDensity; RenderSettings.ambientMode = _ambientMode; RenderSettings.ambientLight = _ambientLight; RenderSettings.ambientSkyColor = _ambientSky; RenderSettings.ambientEquatorColor = _ambientEquator; RenderSettings.ambientGroundColor = _ambientGround; RenderSettings.ambientIntensity = _ambientIntensity; } } public static void Clear() { _captured = false; } } internal enum ReplayActorKind : byte { Player, Enemy, Valuable, Prop } internal sealed class ReplayModule { public string ResourcePath; public string PrefabName = string.Empty; public Vector3 Position; public Quaternion Rotation; public bool[] RendererStates; public int[] RendererPathHashes; } internal sealed class ReplayActor { public int ActorId; public ReplayActorKind Kind; public string DisplayName; public string PrefabPath = string.Empty; public Vector3 BaseScale = Vector3.one; public bool IsLocalPlayer; public readonly List<int> FrameIndices = new List<int>(); public readonly List<Vector3> Positions = new List<Vector3>(); public readonly List<Quaternion> Rotations = new List<Quaternion>(); public readonly List<bool> Active = new List<bool>(); public readonly List<Quaternion> AimRotations = new List<Quaternion>(); public bool HasAnim; public readonly List<ReplayAnimParam> AnimParams = new List<ReplayAnimParam>(); public readonly List<float[]> AnimSamples = new List<float[]>(); public readonly List<float> AnimSpeeds = new List<float>(); } internal sealed class ReplayData { public string LevelName = string.Empty; public string LevelResourceName = string.Empty; public int LevelSeed; public int LevelsCompleted; public float TickInterval = 0.05f; public int FrameCount; public float Duration; public DateTime RecordedAt = DateTime.Now; public readonly List<ReplayModule> Modules = new List<ReplayModule>(); public readonly List<ReplayActor> Actors = new List<ReplayActor>(); } internal static class ReplayFormat { private static readonly char[] Magic = new char[8] { 'E', 'M', 'P', 'R', 'P', 'L', 'Y', '3' }; public const string Extension = ".emrly"; public static void Save(string path, ReplayData data) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) using FileStream output = File.Create(path); using BinaryWriter binaryWriter = new BinaryWriter(output); binaryWriter.Write(Magic); binaryWriter.Write((byte)8); binaryWriter.Write(data.LevelName ?? string.Empty); binaryWriter.Write(data.LevelResourceName ?? string.Empty); binaryWriter.Write(data.LevelSeed); binaryWriter.Write(data.LevelsCompleted); binaryWriter.Write(data.TickInterval); binaryWriter.Write(data.FrameCount); binaryWriter.Write(data.Duration); binaryWriter.Write(data.RecordedAt.ToBinary()); binaryWriter.Write(data.Modules.Count); for (int i = 0; i < data.Modules.Count; i++) { ReplayModule replayModule = data.Modules[i]; binaryWriter.Write(replayModule.ResourcePath ?? string.Empty); binaryWriter.Write(replayModule.PrefabName ?? string.Empty); WriteVector(binaryWriter, replayModule.Position); WriteQuaternion(binaryWriter, replayModule.Rotation); int num = ((replayModule.RendererStates != null) ? replayModule.RendererStates.Length : 0); binaryWriter.Write(num); for (int j = 0; j < num; j++) { binaryWriter.Write(replayModule.RendererStates[j]); } for (int k = 0; k < num; k++) { binaryWriter.Write((replayModule.RendererPathHashes != null && k < replayModule.RendererPathHashes.Length) ? replayModule.RendererPathHashes[k] : 0); } } binaryWriter.Write(data.Actors.Count); for (int l = 0; l < data.Actors.Count; l++) { ReplayActor replayActor = data.Actors[l]; binaryWriter.Write(replayActor.ActorId); binaryWriter.Write((byte)replayActor.Kind); binaryWriter.Write(replayActor.DisplayName ?? string.Empty); binaryWriter.Write(replayActor.PrefabPath ?? string.Empty); WriteVector(binaryWriter, replayActor.BaseScale); binaryWriter.Write(replayActor.IsLocalPlayer); int count = replayActor.FrameIndices.Count; binaryWriter.Write(count); for (int m = 0; m < count; m++) { binaryWriter.Write(replayActor.FrameIndices[m]); WriteVector(binaryWriter, replayActor.Positions[m]); WriteQuaternion(binaryWriter, replayActor.Rotations[m]); binaryWriter.Write(replayActor.Active[m]); } int count2 = replayActor.AimRotations.Count; binaryWriter.Write(count2); for (int n = 0; n < count2; n++) { WriteQuaternion(binaryWriter, replayActor.AimRotations[n]); } bool flag = replayActor.HasAnim && replayActor.AnimParams.Count > 0 && replayActor.AnimSamples.Count == count; binaryWriter.Write(flag); if (!flag) { continue; } binaryWriter.Write(replayActor.AnimParams.Count); for (int num2 = 0; num2 < replayActor.AnimParams.Count; num2++) { ReplayAnimParam replayAnimParam = replayActor.AnimParams[num2]; binaryWriter.Write(replayAnimParam.Name ?? string.Empty); binaryWriter.Write((byte)replayAnimParam.Type); } binaryWriter.Write(replayActor.AnimSamples.Count); for (int num3 = 0; num3 < replayActor.AnimSamples.Count; num3++) { float[] array = replayActor.AnimSamples[num3]; for (int num4 = 0; num4 < replayActor.AnimParams.Count; num4++) { binaryWriter.Write((array != null && num4 < array.Length) ? array[num4] : 0f); } binaryWriter.Write((num3 < replayActor.AnimSpeeds.Count) ? replayActor.AnimSpeeds[num3] : 1f); } } } public static ReplayData Load(string path) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) using FileStream input = File.OpenRead(path); using BinaryReader binaryReader = new BinaryReader(input); char[] array = binaryReader.ReadChars(Magic.Length); for (int i = 0; i < Magic.Length; i++) { if (array[i] != Magic[i]) { return null; } } byte b = binaryReader.ReadByte(); ReplayData replayData = new ReplayData { LevelName = binaryReader.ReadString(), LevelResourceName = binaryReader.ReadString(), LevelSeed = binaryReader.ReadInt32(), LevelsCompleted = binaryReader.ReadInt32(), TickInterval = binaryReader.ReadSingle(), FrameCount = binaryReader.ReadInt32(), Duration = binaryReader.ReadSingle(), RecordedAt = DateTime.FromBinary(binaryReader.ReadInt64()) }; int num = binaryReader.ReadInt32(); for (int j = 0; j < num; j++) { ReplayModule replayModule = new ReplayModule { ResourcePath = binaryReader.ReadString() }; if (b >= 6) { replayModule.PrefabName = binaryReader.ReadString(); } replayModule.Position = ReadVector(binaryReader); replayModule.Rotation = ReadQuaternion(binaryReader); if (b >= 7) { int num2 = binaryReader.ReadInt32(); if (num2 > 0) { replayModule.RendererStates = new bool[num2]; for (int k = 0; k < num2; k++) { replayModule.RendererStates[k] = binaryReader.ReadBoolean(); } if (b >= 8) { replayModule.RendererPathHashes = new int[num2]; for (int l = 0; l < num2; l++) { replayModule.RendererPathHashes[l] = binaryReader.ReadInt32(); } } } } replayData.Modules.Add(replayModule); } int num3 = binaryReader.ReadInt32(); for (int m = 0; m < num3; m++) { ReplayActor replayActor = new ReplayActor { ActorId = binaryReader.ReadInt32(), Kind = (ReplayActorKind)binaryReader.ReadByte(), DisplayName = binaryReader.ReadString(), PrefabPath = binaryReader.ReadString(), BaseScale = ReadVector(binaryReader) }; if (b >= 4) { replayActor.IsLocalPlayer = binaryReader.ReadBoolean(); } int num4 = binaryReader.ReadInt32(); for (int n = 0; n < num4; n++) { replayActor.FrameIndices.Add(binaryReader.ReadInt32()); replayActor.Positions.Add(ReadVector(binaryReader)); replayActor.Rotations.Add(ReadQuaternion(binaryReader)); replayActor.Active.Add(binaryReader.ReadBoolean()); } if (b >= 4) { int num5 = binaryReader.ReadInt32(); for (int num6 = 0; num6 < num5; num6++) { replayActor.AimRotations.Add(ReadQuaternion(binaryReader)); } } if (b >= 5) { replayActor.HasAnim = binaryReader.ReadBoolean(); if (replayActor.HasAnim) { int num7 = binaryReader.ReadInt32(); for (int num8 = 0; num8 < num7; num8++) { string text = binaryReader.ReadString(); replayActor.AnimParams.Add(new ReplayAnimParam { Name = text, Type = (ReplayAnimParamType)binaryReader.ReadByte(), Hash = Animator.StringToHash(text) }); } int num9 = binaryReader.ReadInt32(); for (int num10 = 0; num10 < num9; num10++) { float[] array2 = new float[num7]; for (int num11 = 0; num11 < num7; num11++) { array2[num11] = binaryReader.ReadSingle(); } replayActor.AnimSamples.Add(array2); replayActor.AnimSpeeds.Add(binaryReader.ReadSingle()); } } } replayData.Actors.Add(replayActor); } return replayData; } public static string PeekLevelName(string path) { try { using FileStream input = File.OpenRead(path); using BinaryReader binaryReader = new BinaryReader(input); char[] array = binaryReader.ReadChars(Magic.Length); for (int i = 0; i < Magic.Length; i++) { if (array[i] != Magic[i]) { return null; } } binaryReader.ReadByte(); return binaryReader.ReadString(); } catch { return null; } } private static void WriteVector(BinaryWriter writer, Vector3 value) { //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) writer.Write(value.x); writer.Write(value.y); writer.Write(value.z); } private static Vector3 ReadVector(BinaryReader reader) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } private static void WriteQuaternion(BinaryWriter writer, Quaternion value) { //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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) writer.Write(value.x); writer.Write(value.y); writer.Write(value.z); writer.Write(value.w); } private static Quaternion ReadQuaternion(BinaryReader reader) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } } internal sealed class ReplayHud : MonoBehaviour { private ReplayController _controller; private ReplayMode _mode; private int _recordFrames; private ReplayPlayer _player; private ReplayCamera _camera; private bool _browserVisible; private readonly List<string> _files = new List<string>(); private Vector2 _scroll; private string _toast = string.Empty; private float _toastUntil; private Texture2D _panel; private GUIStyle _title; private GUIStyle _item; private GUIStyle _small; private GUIStyle _badge; private bool _stylesReady; public static ReplayHud Create(ReplayController controller) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: