Decompiled source of panacheOriginalSoundTrack v1.2.0

OriginalSoundTrack.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Xml;
using BepInEx;
using EntityStates.Missions.BrotherEncounter;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using On.EntityStates.Missions.BrotherEncounter;
using On.RoR2;
using On.RoR2.UI;
using RoR2;
using RoR2.ConVar;
using RoR2.UI;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("OriginalSoundTrack")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OriginalSoundTrack")]
[assembly: AssemblyTitle("OriginalSoundTrack")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OriginalSoundTrack;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.kylepaulsen.originalsoundtrack", "OriginalSoundTrack", "1.2.0")]
public class OriginalSoundTrack : BaseUnityPlugin
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static Func<string, string> <>9__14_7;

		public static hook_OnEnter <>9__14_5;

		public static Func<FileInfo, bool> <>9__15_0;

		internal string <Awake>b__14_7(string str)
		{
			return str.Trim();
		}

		internal void <Awake>b__14_5(orig_OnEnter orig, EncounterFinished self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== FINAL BOSS FIGHT DONE ======================");
		}

		internal bool <SearchForAudioFiles>b__15_0(FileInfo f)
		{
			if (!(Path.GetExtension(f.Name) == ".mp3"))
			{
				return Path.GetExtension(f.Name) == ".wav";
			}
			return true;
		}
	}

	private FadeInOutSampleProvider fader;

	private WaveOutEvent outputDevice;

	private FileInfo[] soundFiles;

	private List<Music> musics = new List<Music>();

	private AudioFileReader currentSong;

	private string currentSongFullName = "";

	private bool startedTeleporterEvent;

	private bool songPaused;

	private float globalMusicVolume = 0.5f;

	private bool shouldLoop = true;

	private string oldMusicVolume = "";

	private string currentScene = "";

	private Random rnd = new Random();

	private XmlElement settings;

	public void Awake()
	{
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Expected O, but got Unknown
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Expected O, but got Unknown
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Expected O, but got Unknown
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Expected O, but got Unknown
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f4: Expected O, but got Unknown
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Expected O, but got Unknown
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		//IL_030d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0313: Expected O, but got Unknown
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string text = directoryName;
		try
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(directoryName + "/settings.xml");
			settings = xmlDocument["settings"];
			globalMusicVolume = float.Parse(settings["volume"].InnerText, CultureInfo.InvariantCulture);
			shouldLoop = settings["loop"].InnerText.ToLower() == "true";
			if (settings["music-path"] != null)
			{
				text = settings["music-path"].InnerText;
			}
			soundFiles = SearchForAudioFiles(text);
			foreach (XmlNode childNode in settings["music"].ChildNodes)
			{
				if (childNode.NodeType == XmlNodeType.Comment)
				{
					continue;
				}
				Music music = new Music();
				music.name = GetAttribute(childNode, "name");
				music.scenes = (from str in GetAttribute(childNode, "scenes").Split(new char[1] { ',' })
					select str.Trim()).ToArray();
				music.boss = GetAttribute(childNode, "boss").ToLower() == "true";
				music.volume = 1f;
				string attribute = GetAttribute(childNode, "volume");
				if (attribute != "")
				{
					music.volume = float.Parse(attribute, CultureInfo.InvariantCulture);
				}
				FileInfo[] array = soundFiles;
				foreach (FileInfo fileInfo in array)
				{
					if (fileInfo.Name == music.name)
					{
						music.fullName = fileInfo.FullName;
						break;
					}
				}
				musics.Add(music);
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)"!!!!! OriginalSoundTrack Mod: Failed to parse settings.xml !!!!!");
			Debug.Log((object)"OriginalSoundTrack Mod: Music will be randomly selected from what is found in the plugin dir.");
			Debug.Log((object)ex);
		}
		if (soundFiles == null)
		{
			text = directoryName;
			soundFiles = SearchForAudioFiles(text);
		}
		if (soundFiles.Length == 0)
		{
			Debug.LogError((object)"!!!!! OriginalSoundTrack Mod: No audio files found. Exiting. !!!!!");
			Debug.LogError((object)("OriginalSoundTrack Mod: Looked for .mp3 and .wav files in: " + text));
			return;
		}
		if (outputDevice == null)
		{
			outputDevice = new WaveOutEvent();
		}
		TeleporterInteraction.OnInteractionBegin += (hook_OnInteractionBegin)delegate(orig_OnInteractionBegin orig, TeleporterInteraction self, Interactor activator)
		{
			orig.Invoke(self, activator);
			if (!startedTeleporterEvent)
			{
				startedTeleporterEvent = true;
				PickOutMusic(isForTeleporter: true);
			}
		};
		TeleporterInteraction.RpcClientOnActivated += (hook_RpcClientOnActivated)delegate(orig_RpcClientOnActivated orig, TeleporterInteraction self, GameObject activator)
		{
			orig.Invoke(self, activator);
			if (!startedTeleporterEvent)
			{
				startedTeleporterEvent = true;
				PickOutMusic(isForTeleporter: true);
			}
		};
		PauseScreenController.OnEnable += (hook_OnEnable)delegate(orig_OnEnable orig, PauseScreenController self)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			orig.Invoke(self);
			if (outputDevice != null && (int)outputDevice.PlaybackState == 1)
			{
				outputDevice.Pause();
				songPaused = true;
			}
		};
		PauseScreenController.OnDisable += (hook_OnDisable)delegate(orig_OnDisable orig, PauseScreenController self)
		{
			orig.Invoke(self);
			if (outputDevice != null && songPaused)
			{
				outputDevice.Play();
				songPaused = false;
			}
		};
		Phase1.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Phase1 self)
		{
			orig.Invoke(self);
			Debug.Log((object)"====================== FINAL BOSS FIGHT START ======================");
			PickOutMusic(isForTeleporter: true);
		};
		object obj = <>c.<>9__14_5;
		if (obj == null)
		{
			hook_OnEnter val = delegate(orig_OnEnter orig, EncounterFinished self)
			{
				orig.Invoke(self);
				Debug.Log((object)"====================== FINAL BOSS FIGHT DONE ======================");
			};
			<>c.<>9__14_5 = val;
			obj = (object)val;
		}
		EncounterFinished.OnEnter += (hook_OnEnter)obj;
		SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
		{
			if (currentScene != ((Scene)(ref scene)).name)
			{
				currentScene = ((Scene)(ref scene)).name;
				startedTeleporterEvent = false;
				PickOutMusic();
			}
		};
	}

	private FileInfo[] SearchForAudioFiles(string path)
	{
		DirectoryInfo directoryInfo = new DirectoryInfo(path);
		if (directoryInfo.Exists)
		{
			return (from f in directoryInfo.GetFiles()
				where Path.GetExtension(f.Name) == ".mp3" || Path.GetExtension(f.Name) == ".wav"
				select f).ToArray();
		}
		return new FileInfo[0];
	}

	private string GetAttribute(XmlNode node, string attribute)
	{
		if (node.Attributes != null)
		{
			XmlNode namedItem = node.Attributes.GetNamedItem(attribute);
			if (namedItem != null)
			{
				return namedItem.Value;
			}
		}
		return "";
	}

	private bool sceneMostlyMatches(string[] scenes)
	{
		foreach (string value in scenes)
		{
			if (currentScene.Contains(value))
			{
				return true;
			}
		}
		return false;
	}

	private void PickOutMusic(bool isForTeleporter = false)
	{
		Music[] array = musics.Where(delegate(Music music)
		{
			bool flag = isForTeleporter == music.boss;
			return music.fullName != null && flag && sceneMostlyMatches(music.scenes);
		}).ToArray();
		string fullName = currentSongFullName;
		Music music2 = null;
		int num = 0;
		if (array.Length != 0)
		{
			while (fullName == currentSongFullName && num < 10)
			{
				music2 = array[rnd.Next(array.Length)];
				fullName = music2.fullName;
				num++;
			}
			((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName, music2.volume));
		}
		else
		{
			num = 0;
			while (fullName == currentSongFullName && num < 10)
			{
				fullName = soundFiles[rnd.Next(soundFiles.Length)].FullName;
				num++;
			}
			((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName));
		}
	}

	private IEnumerator<WaitForSeconds> PlayMusic(string file, float volume = 1f)
	{
		if (file != currentSongFullName)
		{
			currentSongFullName = file;
			if ((int)outputDevice.PlaybackState == 1)
			{
				fader.BeginFadeOut(1500.0);
				yield return new WaitForSeconds(1.5f);
				outputDevice.Stop();
				currentSong = null;
			}
			currentSong = new AudioFileReader(file);
			currentSong.Volume = volume * globalMusicVolume;
			LoopStream loopStream = new LoopStream((WaveStream)(object)currentSong, shouldLoop);
			fader = new FadeInOutSampleProvider((ISampleProvider)new WaveToSampleProvider((IWaveProvider)(object)loopStream), false);
			WaveExtensionMethods.Init((IWavePlayer)(object)outputDevice, (ISampleProvider)(object)fader, false);
			outputDevice.Play();
			songPaused = false;
		}
	}

	public void Update()
	{
		if (oldMusicVolume == "" && (Object)(object)Console.instance != (Object)null)
		{
			BaseConVar val = Console.instance.FindConVar("volume_music");
			if (val != null)
			{
				oldMusicVolume = val.GetString();
				val.SetString("0");
			}
		}
	}

	private void FixedUpdate()
	{
		if (currentSong != null && ((Stream)(object)currentSong).Position >= ((Stream)(object)currentSong).Length && !shouldLoop)
		{
			outputDevice.Stop();
			((Stream)(object)currentSong).Position = ((Stream)(object)currentSong).Length - 1;
			PickOutMusic(startedTeleporterEvent);
		}
	}

	private void OnDestroy()
	{
		BaseConVar val = Console.instance.FindConVar("volume_music");
		if (val != null)
		{
			val.SetString(oldMusicVolume);
		}
	}
}
public class Music
{
	public string name;

	public string fullName;

	public string[] scenes;

	public bool boss;

	public float volume = 1f;
}
public class LoopStream : WaveStream
{
	private WaveStream sourceStream;

	private bool EnableLooping = true;

	public override WaveFormat WaveFormat => sourceStream.WaveFormat;

	public override long Position
	{
		get
		{
			return ((Stream)(object)sourceStream).Position;
		}
		set
		{
			((Stream)(object)sourceStream).Position = value;
		}
	}

	public override long Length => ((Stream)(object)sourceStream).Length;

	public LoopStream(WaveStream sourceStream, bool shouldLoop)
	{
		this.sourceStream = sourceStream;
		EnableLooping = shouldLoop;
	}

	public override int Read(byte[] buffer, int offset, int count)
	{
		int i;
		int num2;
		for (i = 0; i < count; i += num2)
		{
			int num = count - i;
			num2 = ((Stream)(object)sourceStream).Read(buffer, offset + i, num);
			if (num2 < num || ((Stream)(object)sourceStream).Position >= ((Stream)(object)sourceStream).Length)
			{
				if (!EnableLooping)
				{
					break;
				}
				((Stream)(object)sourceStream).Position = 0L;
			}
		}
		return i;
	}
}