Decompiled source of TimeFreeze v1.0.0

TimeFreezeMod.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AudioImportLib;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using Microsoft.CodeAnalysis;
using TimeFreezeMod;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonColor(255, 0, 150, 255)]
[assembly: MelonInfo(typeof(TimeFreezeController), "TimeFreeze", "1.0.0", "VoidIndustries", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonPlatform(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.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 TimeFreezeMod
{
	public class TimeFreezeController : MelonMod
	{
		private struct FrozenRigidbody
		{
			public Rigidbody Rb;

			public bool WasKinematic;

			public Vector3 Velocity;

			public Vector3 AngularVelocity;
		}

		private struct SavedLight
		{
			public Light Light;

			public float OrigIntensity;

			public Color OrigColor;
		}

		private volatile bool _modEnabled = true;

		private volatile bool _pendingToggleMod;

		private bool _isFrozen;

		private readonly List<FrozenRigidbody> _frozenObjects = new List<FrozenRigidbody>(256);

		private readonly List<Rigidbody> _playerRbs = new List<Rigidbody>(32);

		private bool _playerRbsCached;

		private float _lastCacheTime = -999f;

		private const float PlayerRbsCacheInterval = 2f;

		private AudioClip _stopSound;

		private AudioClip _resumeSound;

		private bool _origFogEnabled;

		private Color _origFogColor;

		private float _origFogDensity;

		private readonly List<SavedLight> _savedLights = new List<SavedLight>(32);

		private GameObject _audioObj;

		private AudioSource _audioSource;

		private Page _boneMenuPage;

		public override void OnInitializeMelon()
		{
			LoadSounds();
			MelonLogger.Msg("[TimeFreeze] Initialized. Right thumbstick to toggle freeze.");
		}

		public override void OnLateInitializeMelon()
		{
			SetupBoneMenu();
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			_frozenObjects.Clear();
			_playerRbs.Clear();
			_playerRbsCached = false;
			_lastCacheTime = -999f;
			if (_isFrozen)
			{
				UnfreezeAll();
			}
		}

		public override void OnUpdate()
		{
			if (_pendingToggleMod)
			{
				_pendingToggleMod = false;
				_modEnabled = !_modEnabled;
				MelonLogger.Msg("[TimeFreeze] " + (_modEnabled ? "MOD: ON" : "MOD: OFF"));
				if (!_modEnabled && _isFrozen)
				{
					UnfreezeAll();
				}
				RebuildBoneMenu();
			}
			if (_modEnabled && (Object)(object)Player.RightController != (Object)null && Player.RightController.GetThumbStickDown())
			{
				ToggleFreeze();
			}
		}

		public void ToggleFreeze()
		{
			if (_isFrozen)
			{
				UnfreezeAll();
			}
			else
			{
				FreezeAll();
			}
		}

		private void FreezeAll()
		{
			//IL_0077: 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_0084: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			RefreshPlayerRbs();
			Rigidbody[] array = Il2CppArrayBase<Rigidbody>.op_Implicit(Resources.FindObjectsOfTypeAll<Rigidbody>());
			int num = array.Length;
			for (int i = 0; i < num; i++)
			{
				Rigidbody val = array[i];
				if (!((Object)(object)val == (Object)null) && !val.isKinematic && !_playerRbs.Contains(val))
				{
					_frozenObjects.Add(new FrozenRigidbody
					{
						Rb = val,
						WasKinematic = val.isKinematic,
						Velocity = val.velocity,
						AngularVelocity = val.angularVelocity
					});
					val.isKinematic = true;
					val.velocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
				}
			}
			_isFrozen = true;
			ApplyGreyVisuals();
			PlaySound(_stopSound);
			MelonLogger.Msg("[TimeFreeze] Frozen " + _frozenObjects.Count + " rigidbodies");
		}

		private void UnfreezeAll()
		{
			//IL_0044: 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)
			int count = _frozenObjects.Count;
			for (int i = 0; i < count; i++)
			{
				FrozenRigidbody frozenRigidbody = _frozenObjects[i];
				Rigidbody rb = frozenRigidbody.Rb;
				if (!((Object)(object)rb == (Object)null))
				{
					rb.isKinematic = frozenRigidbody.WasKinematic;
					rb.velocity = frozenRigidbody.Velocity;
					rb.angularVelocity = frozenRigidbody.AngularVelocity;
				}
			}
			_frozenObjects.Clear();
			_isFrozen = false;
			RemoveGreyVisuals();
			PlaySound(_resumeSound);
			MelonLogger.Msg("[TimeFreeze] Unfrozen " + count + " rigidbodies");
		}

		private void RefreshPlayerRbs()
		{
			float unscaledTime = Time.unscaledTime;
			if (_playerRbsCached && unscaledTime - _lastCacheTime < 2f)
			{
				return;
			}
			_playerRbs.Clear();
			_lastCacheTime = unscaledTime;
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.physicsRig == (Object)null)
			{
				return;
			}
			HashSet<Rigidbody> selfRbs = rigManager.physicsRig.selfRbs;
			if (selfRbs == null)
			{
				return;
			}
			Enumerator<Rigidbody> enumerator = selfRbs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Rigidbody current = enumerator.Current;
					if ((Object)(object)current != (Object)null)
					{
						_playerRbs.Add(current);
					}
				}
			}
			finally
			{
				enumerator.Dispose();
			}
			_playerRbsCached = true;
		}

		private void ApplyGreyVisuals()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Invalid comparison between Unknown and I4
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_origFogEnabled = RenderSettings.fog;
				_origFogColor = RenderSettings.fogColor;
				_origFogDensity = RenderSettings.fogDensity;
				RenderSettings.fog = true;
				RenderSettings.fogMode = (FogMode)3;
				RenderSettings.fogColor = new Color(0.12f, 0.12f, 0.12f, 1f);
				RenderSettings.fogDensity = 0.25f;
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[TimeFreeze] Failed to set fog: " + ex.Message);
			}
			try
			{
				RenderSettings.ambientLight = new Color(0.08f, 0.08f, 0.08f);
				RenderSettings.reflectionIntensity = 0.05f;
			}
			catch (Exception ex2)
			{
				MelonLogger.Warning("[TimeFreeze] Failed to set ambient: " + ex2.Message);
			}
			_savedLights.Clear();
			try
			{
				Light[] array = Il2CppArrayBase<Light>.op_Implicit(Resources.FindObjectsOfTypeAll<Light>());
				int num = array.Length;
				for (int i = 0; i < num; i++)
				{
					Light val = array[i];
					if (!((Object)(object)val == (Object)null) && (int)val.type != 1)
					{
						_savedLights.Add(new SavedLight
						{
							Light = val,
							OrigIntensity = val.intensity,
							OrigColor = val.color
						});
						val.intensity *= 0.15f;
						val.color = new Color(val.color.r + (0.15f - val.color.r) * 0.7f, val.color.g + (0.15f - val.color.g) * 0.7f, val.color.b + (0.15f - val.color.b) * 0.7f);
					}
				}
			}
			catch (Exception ex3)
			{
				MelonLogger.Warning("[TimeFreeze] Failed to dim lights: " + ex3.Message);
			}
		}

		private void RemoveGreyVisuals()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RenderSettings.fog = _origFogEnabled;
				RenderSettings.fogColor = _origFogColor;
				RenderSettings.fogDensity = _origFogDensity;
			}
			catch
			{
			}
			try
			{
				RenderSettings.reflectionIntensity = 1f;
			}
			catch
			{
			}
			try
			{
				int count = _savedLights.Count;
				for (int i = 0; i < count; i++)
				{
					SavedLight savedLight = _savedLights[i];
					if ((Object)(object)savedLight.Light != (Object)null)
					{
						savedLight.Light.intensity = savedLight.OrigIntensity;
						savedLight.Light.color = savedLight.OrigColor;
					}
				}
				_savedLights.Clear();
			}
			catch
			{
			}
		}

		private void LoadSounds()
		{
			PropertyInfo property = typeof(MelonUtils).GetProperty("GameDirectory", BindingFlags.Static | BindingFlags.Public);
			string text = Path.Combine((string)property.GetValue(null), "UserData", "TimeFreeze", "Sounds");
			if (!Directory.Exists(text))
			{
				MelonLogger.Warning("[TimeFreeze] Sounds directory not found: " + text);
				return;
			}
			string text2 = Path.Combine(text, "time stop.mp3");
			string text3 = Path.Combine(text, "time resume.mp3");
			if (File.Exists(text2))
			{
				try
				{
					_stopSound = API.LoadAudioClip(text2, true);
				}
				catch (Exception ex)
				{
					MelonLogger.Warning("[TimeFreeze] Failed to load stop sound: " + ex.Message);
				}
			}
			if (!File.Exists(text3))
			{
				return;
			}
			try
			{
				_resumeSound = API.LoadAudioClip(text3, true);
			}
			catch (Exception ex2)
			{
				MelonLogger.Warning("[TimeFreeze] Failed to load resume sound: " + ex2.Message);
			}
		}

		private void EnsureAudioSource()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			if (!((Object)(object)_audioObj != (Object)null) || !((Object)(object)_audioSource != (Object)null))
			{
				_audioObj = new GameObject("TimeFreezeAudio");
				Object.DontDestroyOnLoad((Object)(object)_audioObj);
				_audioSource = _audioObj.AddComponent<AudioSource>();
				_audioSource.playOnAwake = false;
				_audioSource.loop = false;
				_audioSource.spatialBlend = 0f;
				_audioSource.volume = 1f;
			}
		}

		private void PlaySound(AudioClip clip)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)clip == (Object)null))
			{
				EnsureAudioSource();
				RigManager rigManager = Player.RigManager;
				_audioObj.transform.position = (((Object)(object)rigManager != (Object)null) ? ((Component)rigManager).transform.position : Vector3.zero);
				_audioSource.Stop();
				_audioSource.clip = clip;
				_audioSource.Play();
			}
		}

		private void SetupBoneMenu()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_boneMenuPage = Page.Root.CreatePage("TimeFreeze", new Color(0f, 0.6f, 1f), 0, true);
				RebuildBoneMenu();
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[TimeFreeze] Failed to setup BoneMenu: " + ex.Message);
			}
		}

		private void RebuildBoneMenu()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			if (_boneMenuPage != null)
			{
				_boneMenuPage.RemoveAll();
				Color val = (_modEnabled ? Color.green : Color.red);
				string text = (_modEnabled ? "MOD: ON" : "MOD: OFF");
				_boneMenuPage.CreateFunction(text, val, (Action)delegate
				{
					_pendingToggleMod = true;
				});
			}
		}
	}
}