Decompiled source of TimeStopSounds v1.9.0

TimeStopSounds.dll

Decompiled a day ago
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 BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("TimeStopSounds")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TimeStopSounds")]
[assembly: AssemblyTitle("TimeStopSounds")]
[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 TimeStopSounds
{
	[BepInPlugin("com.yourname.timestopsounds", "Time Stop Sounds", "1.0.0")]
	public class TimeStopSounds : BaseUnityPlugin
	{
		private static readonly string[] FileNames = new string[3] { "sound1.mp3", "sound2.mp3", "sound3.mp3" };

		private static TimeStopSounds instance;

		private static readonly List<AudioClip> clips = new List<AudioClip>();

		private AudioSource source;

		private ConfigEntry<float> volume;

		private ConfigEntry<bool> freezeGame;

		private ConfigEntry<bool> invertColors;

		private int nextIndex;

		private readonly HashSet<int> knownIds = new HashSet<int>();

		private float pollTimer;

		private int lastCount = -1;

		private float lastPlayTime = -100f;

		private bool frozen;

		private float freezeRemaining;

		private float savedTimeScale = 1f;

		private Material invertMat;

		private bool invertFailedLogged;

		private void Awake()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			instance = this;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			volume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 1f, new ConfigDescription("Volume of the time stop sound (0 to 1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			freezeGame = ((BaseUnityPlugin)this).Config.Bind<bool>("Effect", "FreezeGame", true, "Freeze the game while the clip plays");
			invertColors = ((BaseUnityPlugin)this).Config.Bind<bool>("Effect", "InvertColors", true, "Invert the screen colors while the clip plays");
			EnsureSource();
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			string[] fileNames = FileNames;
			foreach (string path in fileNames)
			{
				string text = Path.Combine(directoryName, path);
				if (File.Exists(text))
				{
					((MonoBehaviour)this).StartCoroutine(LoadClip(text));
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Missing sound file: " + text));
				}
			}
			try
			{
				new Harmony("com.yourname.timestopsounds").Patch((MethodBase)AccessTools.Method(typeof(TimeStop), "Init", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(TimeStopSounds), "OnTimeStopInit", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched TimeStop.Init");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to patch TimeStop.Init: " + ex));
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Time Stop Sounds plugin object was destroyed");
			if (frozen)
			{
				EndFreeze();
			}
		}

		private void EnsureSource()
		{
			if (!((Object)(object)source != (Object)null))
			{
				source = ((Component)this).gameObject.AddComponent<AudioSource>();
				source.playOnAwake = false;
				source.spatialBlend = 0f;
				source.ignoreListenerPause = true;
				source.ignoreListenerVolume = true;
			}
		}

		private void Update()
		{
			if (frozen)
			{
				Time.timeScale = 0f;
				freezeRemaining -= Time.unscaledDeltaTime;
				if (freezeRemaining <= 0f)
				{
					EndFreeze();
				}
			}
			pollTimer += Time.unscaledDeltaTime;
			if (pollTimer < 0.1f)
			{
				return;
			}
			pollTimer = 0f;
			try
			{
				Object[] array = Object.FindObjectsOfType(typeof(TimeStop));
				if (array.Length != lastCount)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("TimeStop object count: " + array.Length));
					lastCount = array.Length;
				}
				bool flag = false;
				HashSet<int> hashSet = new HashSet<int>();
				Object[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					int instanceID = array2[i].GetInstanceID();
					hashSet.Add(instanceID);
					if (!knownIds.Contains(instanceID))
					{
						flag = true;
					}
				}
				knownIds.Clear();
				foreach (int item in hashSet)
				{
					knownIds.Add(item);
				}
				if (flag)
				{
					PlayNext("new TimeStop object");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("TimeStop polling failed: " + ex.Message));
			}
		}

		private void LateUpdate()
		{
			if (frozen)
			{
				Time.timeScale = 0f;
			}
		}

		private void StartFreeze(float duration)
		{
			if (!frozen)
			{
				savedTimeScale = ((Time.timeScale > 0f) ? Time.timeScale : 1f);
				freezeRemaining = duration + 0.5f;
				frozen = true;
				if (freezeGame.Value)
				{
					Time.timeScale = 0f;
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Freeze started for " + freezeRemaining.ToString("F2") + "s (saved timeScale " + savedTimeScale.ToString("F2") + ")"));
			}
		}

		private void EndFreeze()
		{
			frozen = false;
			Time.timeScale = savedTimeScale;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Freeze ended, timeScale restored to " + savedTimeScale.ToString("F2")));
		}

		private void OnGUI()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			if (!frozen || !invertColors.Value || (int)Event.current.type != 7)
			{
				return;
			}
			if ((Object)(object)invertMat == (Object)null)
			{
				Shader val = Shader.Find("Hidden/Internal-Colored");
				if ((Object)(object)val == (Object)null)
				{
					if (!invertFailedLogged)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find shader for color inversion");
						invertFailedLogged = true;
					}
					return;
				}
				invertMat = new Material(val);
				((Object)invertMat).hideFlags = (HideFlags)61;
				invertMat.SetInt("_SrcBlend", 4);
				invertMat.SetInt("_DstBlend", 0);
				invertMat.SetInt("_Cull", 0);
				invertMat.SetInt("_ZWrite", 0);
				invertMat.SetInt("_ZTest", 8);
			}
			GL.PushMatrix();
			invertMat.SetPass(0);
			GL.LoadOrtho();
			GL.Begin(7);
			GL.Color(Color.white);
			GL.Vertex3(0f, 0f, 0f);
			GL.Vertex3(0f, 1f, 0f);
			GL.Vertex3(1f, 1f, 0f);
			GL.Vertex3(1f, 0f, 0f);
			GL.End();
			GL.PopMatrix();
		}

		private IEnumerator LoadClip(string path)
		{
			string absoluteUri = new Uri(path).AbsoluteUri;
			UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, (AudioType)13);
			try
			{
				yield return req.SendWebRequest();
				if ((int)req.result != 1)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Could not load " + path + ": " + req.error));
					yield break;
				}
				AudioClip content = DownloadHandlerAudioClip.GetContent(req);
				((Object)content).name = Path.GetFileName(path);
				clips.Add(content);
				clips.Sort((AudioClip a, AudioClip b) => string.Compare(((Object)a).name, ((Object)b).name, StringComparison.OrdinalIgnoreCase));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded " + ((Object)content).name + " (" + content.length.ToString("F2") + "s)"));
			}
			finally
			{
				((IDisposable)req)?.Dispose();
			}
		}

		private void PlayNext(string reason)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Time stop trigger: " + reason));
			if (clips.Count == 0)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"No clips are loaded");
			}
			else if (!(Time.realtimeSinceStartup - lastPlayTime < 0.5f) && !frozen)
			{
				lastPlayTime = Time.realtimeSinceStartup;
				try
				{
					EnsureSource();
					AudioClip val = clips[nextIndex % clips.Count];
					nextIndex = (nextIndex + 1) % clips.Count;
					source.PlayOneShot(val, volume.Value);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Playing " + ((Object)val).name + " (listener volume " + AudioListener.volume.ToString("F2") + ", source volume " + volume.Value.ToString("F2") + ")"));
					StartFreeze(val.length);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to play sound: " + ex));
				}
			}
		}

		private static void OnTimeStopInit()
		{
			if (!((Object)(object)instance == (Object)null))
			{
				instance.PlayNext("TimeStop.Init");
			}
		}
	}
}