Decompiled source of NO Music Replacer v0.32.1

NOMusicReplacer.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Xml;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using NOMusicReplacer.Patch;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("NOMusicReplacer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NOMusicReplacer")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("290b0796-69ec-4736-9a4b-951bee0793ca")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace NOMusicReplacer
{
	[BepInPlugin("Truffle.NOMusicReplacer", "Nuclear Option Music Replacer", "0.30.2.1")]
	public class MusicReplacerBase : BaseUnityPlugin
	{
		private const string modGUID = "Truffle.NOMusicReplacer";

		private const string modName = "Nuclear Option Music Replacer";

		private const string modVersion = "0.30.2.1";

		private readonly Harmony harmony = new Harmony("Truffle.NOMusicReplacer");

		internal static Dictionary<string, bool> BundleDict = new Dictionary<string, bool>();

		internal static Dictionary<string, List<AudioClip>> AudioDict = new Dictionary<string, List<AudioClip>>();

		internal static List<string> PackNames = new List<string>
		{
			"cricket", "compass", "chicane", "revoker", "tarantula", "ifrit", "medusa", "darkreach", "vortex", "ibis",
			"brawler", "win", "loss", "kill", "tactical", "strategic", "title", "pala", "bdf"
		};

		internal static List<string> PlanePacks = new List<string>
		{
			"cricket", "compass", "chicane", "revoker", "tarantula", "ifrit", "medusa", "darkreach", "vortex", "ibis",
			"brawler"
		};

		internal static List<string> EventPacks = new List<string> { "win", "loss", "kill", "tactical", "strategic", "title", "pala", "bdf" };

		internal static Dictionary<string, string> ConversionDict = new Dictionary<string, string>();

		internal static MusicReplacerBase Instance;

		internal static ManualLogSource mls;

		internal static Random rng = new Random();

		internal static bool LoopSetting = false;

		internal static string FolderPath;

		private XmlDocument settings = new XmlDocument();

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("Truffle.NOMusicReplacer");
			harmony.PatchAll(typeof(MusicReplacerBase));
			harmony.PatchAll(typeof(MusicPatch));
			mls.LogInfo((object)"Music Replacer Started");
			FolderPath = ((BaseUnityPlugin)Instance).Info.Location;
			FolderPath = FolderPath.TrimEnd("NOMusicReplacer.dll".ToCharArray());
			settings.Load(FolderPath + "settings.xml");
			XmlNode xmlNode = settings.DocumentElement.SelectSingleNode("/Settings");
			if (xmlNode != null)
			{
				string innerText = xmlNode.SelectSingleNode("LoopMusic").InnerText;
				bool.TryParse(innerText, out var result);
				LoopSetting = result;
			}
			else
			{
				mls.LogError((object)"settings.xml corrupted");
			}
			ConversionDict.Add("Ignition (UnityEngine.AudioClip)", "title");
			ConversionDict.Add("9. PALA (UnityEngine.AudioClip)", "pala");
			ConversionDict.Add("2. BDF (UnityEngine.AudioClip)", "bdf");
			ConversionDict.Add("CI-22 Cricket (UnityEngine.AudioClip)", "cricket");
			ConversionDict.Add("Compass_song1 (UnityEngine.AudioClip)", "compass");
			ConversionDict.Add("SAH46_Chicane (UnityEngine.AudioClip)", "chicane");
			ConversionDict.Add("Furball (UnityEngine.AudioClip)", "revoker");
			ConversionDict.Add("18. VL-49 Tarantula (UnityEngine.AudioClip)", "tarantula");
			ConversionDict.Add("KR-67_Ifrit_2 (UnityEngine.AudioClip)", "ifrit");
			ConversionDict.Add("EW-25_Medusa (UnityEngine.AudioClip)", "medusa");
			ConversionDict.Add("SFB81_Darkreach (UnityEngine.AudioClip)", "darkreach");
			ConversionDict.Add("FS-20 Vortex (UnityEngine.AudioClip)", "vortex");
			ConversionDict.Add("UH-90 Ibis (UnityEngine.AudioClip)", "ibis");
			ConversionDict.Add("CAS1 master (UnityEngine.AudioClip)", "brawler");
			ConversionDict.Add("Stratosphere_-_fadeout_ending (UnityEngine.AudioClip)", "win");
			ConversionDict.Add("Mission_Failed_extended (1) (UnityEngine.AudioClip)", "loss");
			ConversionDict.Add("12. Nuclear Escalation (UnityEngine.AudioClip)", "tactical");
			ConversionDict.Add("Ignus Balls (UnityEngine.AudioClip)", "tactical");
			ConversionDict.Add("3. Port Maris (UnityEngine.AudioClip)", "strategic");
			ConversionDict.Add("10. Agrapol (UnityEngine.AudioClip)", "strategic");
			ConversionDict.Add("BDF Island Theme 3 (UnityEngine.AudioClip)", "strategic");
			ConversionDict.Add("PALA Island theme 2 (UnityEngine.AudioClip)", "strategic");
			ConversionDict.Add("Kill_song (UnityEngine.AudioClip)", "kill");
			PreloadAudio(FolderPath);
		}

		internal static AudioClip GetReplacement(string input)
		{
			List<AudioClip> list = AudioDict[input];
			int index = rng.Next(list.Count);
			return list[index];
		}

		private void PreloadAudio(string path)
		{
			mls.LogInfo((object)("BASEPATH: " + path));
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			string text = path + "Aircraft" + directorySeparatorChar;
			directorySeparatorChar = Path.DirectorySeparatorChar;
			string text2 = path + "Events" + directorySeparatorChar;
			for (int i = 0; i < PlanePacks.Count; i++)
			{
				string[] files = Directory.GetFiles(text + PlanePacks[i]);
				if (files.Length == 0)
				{
					mls.LogInfo((object)(PlanePacks[i] + " music not found."));
					BundleDict.Add(PlanePacks[i], value: false);
					continue;
				}
				List<AudioClip> list = new List<AudioClip>();
				string[] array = files;
				foreach (string path2 in array)
				{
					AudioClip val = LoadSong(path2);
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
				}
				if (list.Count == 0)
				{
					mls.LogInfo((object)(PlanePacks[i] + " music not found."));
					BundleDict.Add(PlanePacks[i], value: false);
				}
				else
				{
					BundleDict.Add(PlanePacks[i], value: true);
					AudioDict.Add(PlanePacks[i], list);
					mls.LogInfo((object)(PlanePacks[i] + " asset bundle loaded"));
				}
			}
			for (int k = 0; k < EventPacks.Count; k++)
			{
				string[] files2 = Directory.GetFiles(text2 + EventPacks[k]);
				if (files2.Length == 0)
				{
					mls.LogInfo((object)(EventPacks[k] + " music not found."));
					BundleDict.Add(EventPacks[k], value: false);
					continue;
				}
				List<AudioClip> list2 = new List<AudioClip>();
				string[] array2 = files2;
				foreach (string path3 in array2)
				{
					AudioClip val2 = LoadSong(path3);
					if ((Object)(object)val2 != (Object)null)
					{
						list2.Add(val2);
					}
				}
				if (list2.Count == 0)
				{
					mls.LogInfo((object)(EventPacks[k] + " music not found."));
					BundleDict.Add(EventPacks[k], value: false);
				}
				else
				{
					BundleDict.Add(EventPacks[k], value: true);
					AudioDict.Add(EventPacks[k], list2);
					mls.LogInfo((object)(EventPacks[k] + " asset bundle loaded"));
				}
			}
		}

		private AudioClip LoadSong(string path)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			AudioType audioType = GetAudioType(path);
			if ((int)audioType == 0)
			{
				return null;
			}
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, audioType);
			audioClip.SendWebRequest();
			while (!audioClip.isDone)
			{
			}
			if (audioClip.error != null)
			{
				mls.LogError((object)audioClip.error);
				return null;
			}
			AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
			if (Object.op_Implicit((Object)(object)content) && (int)content.loadState == 2)
			{
				((Object)content).name = path.TrimStart(FolderPath.ToCharArray());
				return content;
			}
			mls.LogError((object)("Failed to load clip:" + path));
			return null;
		}

		private static AudioType GetAudioType(string path)
		{
			//IL_001e: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			switch (Path.GetExtension(path).ToLower())
			{
			case ".wav":
				return (AudioType)20;
			case ".ogg":
				return (AudioType)14;
			case ".mp3":
				return (AudioType)13;
			default:
				mls.LogError((object)("Unsupported extension: " + path));
				return (AudioType)0;
			}
		}
	}
}
namespace NOMusicReplacer.Patch
{
	[HarmonyPatch(typeof(MusicManager))]
	internal class MusicPatch
	{
		[HarmonyPatch("PlayMusic")]
		[HarmonyPrefix]
		private static void SwapTheme(ref AudioClip audioClip, ref bool repeat)
		{
			repeat = MusicReplacerBase.LoopSetting;
			string text = ((object)audioClip).ToString();
			AudioClip newSong = GetNewSong(text);
			if ((Object)(object)newSong != (Object)null)
			{
				audioClip = newSong;
				MusicReplacerBase.mls.LogInfo((object)("Replaced: " + text + " with: " + ((object)newSong).ToString()));
			}
			else
			{
				MusicReplacerBase.mls.LogError((object)(text + " resulted in a failed pull from an asset bundle"));
			}
		}

		[HarmonyPatch("CrossFadeMusic")]
		[HarmonyPrefix]
		private static void SwapCrossTheme(ref AudioClip audioClip, ref bool repeat)
		{
			repeat = MusicReplacerBase.LoopSetting;
			string text = ((object)audioClip).ToString();
			AudioClip newSong = GetNewSong(text);
			if ((Object)(object)newSong != (Object)null)
			{
				audioClip = newSong;
				MusicReplacerBase.mls.LogInfo((object)("Replaced: " + text + " with: " + ((object)newSong).ToString()));
			}
		}

		private static AudioClip GetNewSong(string song_title)
		{
			if (!MusicReplacerBase.ConversionDict.ContainsKey(song_title))
			{
				MusicReplacerBase.mls.LogError((object)(song_title + " resulted in a failed pull."));
				return null;
			}
			string text = MusicReplacerBase.ConversionDict[song_title];
			if (!MusicReplacerBase.BundleDict[text])
			{
				MusicReplacerBase.mls.LogInfo((object)("Asset Bundle not found, playing " + song_title));
				return null;
			}
			return MusicReplacerBase.GetReplacement(text);
		}
	}
}