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 BepInEx.Configuration; using EntityStates.Missions.BrotherEncounter; using NAudio.Wave; using NAudio.Wave.SampleProviders; using On.EntityStates.Missions.BrotherEncounter; using On.RoR2; using On.RoR2.UI; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.ConVar; using RoR2.UI; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("OriginalSoundTrack")] [assembly: AssemblyConfiguration("Debug")] [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; internal class NetworkCompatibilityAttribute : Attribute { private CompatibilityLevel noNeedForSync; private VersionStrictness differentModVersionsAreOk; public NetworkCompatibilityAttribute(CompatibilityLevel noNeedForSync, VersionStrictness differentModVersionsAreOk) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0011: Unknown result type (might be due to invalid IL or missing references) this.noNeedForSync = noNeedForSync; this.differentModVersionsAreOk = differentModVersionsAreOk; } } [BepInPlugin("com.mrcountermax.moreostsmod", "MoreOSTsMod", "2.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class OriginalSoundTrack : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__16_8; public static hook_OnEnter <>9__16_6; public static Func <>9__18_0; internal string b__16_8(string str) { return str.Trim(); } internal void b__16_6(orig_OnEnter orig, EncounterFinished self) { orig.Invoke(self); Debug.Log((object)"====================== FINAL BOSS FIGHT DONE ======================"); } internal bool b__18_0(FileInfo f) { return Path.GetExtension(f.Name) == ".mp3" || Path.GetExtension(f.Name) == ".wav"; } } private FadeInOutSampleProvider fader; private WaveOutEvent outputDevice; private FileInfo[] soundFiles; private List musics = new List(); private AudioFileReader currentSong; private string currentSongFullName = ""; private bool startedTeleporterEvent = false; private bool songPaused = false; private float currentMusicVolume; private ConfigEntry globalMusicVolume; private bool shouldLoop = true; private string oldMusicVolume = ""; private string currentScene = ""; private Random rnd = new Random(); private XmlElement settings; private Texture2D modIconTexture; public void Awake() { //IL_0024: 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: Expected O, but got Unknown //IL_0051: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Expected O, but got Unknown //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Expected O, but got Unknown //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Expected O, but got Unknown //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Expected O, but got Unknown //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Expected O, but got Unknown //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Expected O, but got Unknown //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Expected O, but got Unknown string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = directoryName; globalMusicVolume = ((BaseUnityPlugin)this).Config.Bind(new ConfigDefinition("General", "Volume"), 40f, new ConfigDescription("The volume of the More OSTs Mod music. KEEP THE GAME'S MUSIC VOLUME AT 0!!!", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(globalMusicVolume, new StepSliderConfig { min = 0f, max = 100f, increment = 1f, formatString = "{0:0}%" })); globalMusicVolume.SettingChanged += delegate { UpdateVolume(); }; modIconTexture = new Texture2D(0, 0); using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("OriginalSoundTrack.ror2_more_osts_mod_clean.png")) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); byte[] array = memoryStream.ToArray(); ImageConversion.LoadImage(modIconTexture, array); } Sprite modIcon = Sprite.Create(modIconTexture, new Rect(0f, 0f, (float)((Texture)modIconTexture).width, (float)((Texture)modIconTexture).height), new Vector2(0f, 0f)); ModSettingsManager.SetModIcon(modIcon); try { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(directoryName + "/settings.xml"); settings = xmlDocument["settings"]; 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[] array2 = soundFiles; foreach (FileInfo fileInfo in array2) { 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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__16_6; if (obj == null) { hook_OnEnter val = delegate(orig_OnEnter orig, EncounterFinished self) { orig.Invoke(self); Debug.Log((object)"====================== FINAL BOSS FIGHT DONE ======================"); }; <>c.<>9__16_6 = val; obj = (object)val; } EncounterFinished.OnEnter += (hook_OnEnter)obj; SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode) { Debug.Log((object)"====================== CHANGE SCENE ========================"); Debug.Log((object)((Scene)(ref scene)).name); if (currentScene != ((Scene)(ref scene)).name) { currentScene = ((Scene)(ref scene)).name; startedTeleporterEvent = false; PickOutMusic(); } }; } private void UpdateVolume() { currentSong.Volume = currentMusicVolume * globalMusicVolume.Value / 100f; } 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(); Debug.Log((object)"====== Selecting Music ======"); Debug.Log((object)("Current Scene: " + currentScene)); Debug.Log((object)("Is For Teleporter: " + isForTeleporter)); Debug.Log((object)"Choices: "); Music[] array2 = array; foreach (Music music2 in array2) { Debug.Log((object)music2.name); } Debug.Log((object)""); string fullName = currentSongFullName; Music music3 = null; int num = 0; if (array.Length != 0) { while (fullName == currentSongFullName && num < 10) { music3 = array[rnd.Next(array.Length)]; fullName = music3.fullName; num++; } ((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName, music3.volume)); return; } Debug.Log((object)"======= MUSIC PICK FAILED! ======="); Debug.Log((object)"choosing random song..."); num = 0; while (fullName == currentSongFullName && num < 10) { fullName = soundFiles[rnd.Next(soundFiles.Length)].FullName; num++; } ((MonoBehaviour)this).StartCoroutine((IEnumerator)PlayMusic(fullName)); } private IEnumerator PlayMusic(string file, float volume = 1f) { currentMusicVolume = volume; 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); UpdateVolume(); LoopStream looper = new LoopStream((WaveStream)(object)currentSong, shouldLoop); fader = new FadeInOutSampleProvider((ISampleProvider)new WaveToSampleProvider((IWaveProvider)(object)looper), false); WaveExtensionMethods.Init((IWavePlayer)(object)outputDevice, (ISampleProvider)(object)fader, false); Debug.Log((object)("====== Now Playing: " + file)); outputDevice.Play(); songPaused = false; } else { Debug.Log((object)("PlayMusic: Already playing: " + file)); } } 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 = false; 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; } }