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;
}
}