Decompiled source of CustomBoomboxMusic v1.0.0

baer1.CustomBoomboxMusic.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("baer1.CustomBoomboxMusic")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ede45e31856d3e44483464215eda5236e514a4bc")]
[assembly: AssemblyProduct("CustomBoomboxMusic")]
[assembly: AssemblyTitle("baer1.CustomBoomboxMusic")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 CustomBoomboxMusic
{
	public sealed class AudioFile
	{
		public uint Crc { get; }

		public AudioClip AudioClip { get; }

		public string FilePath { get; }

		public AudioFile(uint crc, AudioClip audioClip, string filePath)
		{
			Crc = crc;
			AudioClip = audioClip;
			FilePath = filePath;
			base..ctor();
		}
	}
	public static class AudioManager
	{
		private static List<AudioFile> audioClips = new List<AudioFile>();

		internal static AudioClip[]? vanilla = null;

		public static IReadOnlyList<AudioClip> AudioClips => ((CustomBoomboxMusic.Instance.IncludeVanilla || audioClips.Count == 0) && vanilla != null) ? audioClips.Select((AudioFile f) => f.AudioClip).Concat(vanilla).ToList() : audioClips.Select((AudioFile f) => f.AudioClip).ToList();

		public static IReadOnlyList<AudioFile> AudioFiles => ((CustomBoomboxMusic.Instance.IncludeVanilla || audioClips.Count == 0) && vanilla != null) ? ((IReadOnlyList<AudioFile>)audioClips.Concat(vanilla.Select((AudioClip f, int i) => new AudioFile(0u, f, $"Boombox {i + 1} (Lethal Company).ogg"))).ToList()) : ((IReadOnlyList<AudioFile>)audioClips);

		internal static void Reload()
		{
			CollectionExtensions.Do<AudioFile>((IEnumerable<AudioFile>)audioClips, (Action<AudioFile>)delegate(AudioFile f)
			{
				f.AudioClip.UnloadAudioData();
			});
			audioClips.Clear();
			ProcessDirectory(Paths.BepInExRootPath);
			audioClips = audioClips.OrderBy((AudioFile f) => f.Crc).ToList();
		}

		private static int ProcessDirectory(string path)
		{
			if (!Directory.Exists(path))
			{
				return 0;
			}
			CustomBoomboxMusic.Logger.LogDebug((object)(">> ProcessDirectory(" + Path.GetFullPath(path) + ")"));
			int num = ((IEnumerable<string>)Directory.GetDirectories(path)).Sum((Func<string, int>)ProcessDirectory);
			if (Path.GetFileName(path).Equals("CustomBoomboxMusic", StringComparison.CurrentCultureIgnoreCase))
			{
				num += Directory.GetFiles(path).Count(ProcessFile);
			}
			return num;
		}

		private static bool ProcessFile(string path)
		{
			//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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Invalid comparison between Unknown and I4
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetExtension(path).ToLower();
			if (1 == 0)
			{
			}
			AudioType val = (AudioType)(text switch
			{
				".ogg" => 14, 
				".mp3" => 13, 
				".wav" => 20, 
				".m4a" => 1, 
				".aiff" => 2, 
				_ => 0, 
			});
			if (1 == 0)
			{
			}
			AudioType val2 = val;
			CustomBoomboxMusic.Logger.LogDebug((object)$">> ProcessFile({Path.GetFullPath(path)}) audioType:{val2}");
			if ((int)val2 == 0)
			{
				return false;
			}
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, val2);
			((DownloadHandlerAudioClip)audioClip.downloadHandler).streamAudio = !CustomBoomboxMusic.Instance.LoadIntoRAM;
			audioClip.SendWebRequest();
			while (!audioClip.isDone)
			{
			}
			if (audioClip.error != null)
			{
				CustomBoomboxMusic.Logger.LogError((object)("Error loading " + Path.GetFullPath(path) + ": " + audioClip.error));
				return false;
			}
			AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
			if (Object.op_Implicit((Object)(object)content) && (int)content.loadState == 2)
			{
				CustomBoomboxMusic.Logger.LogInfo((object)("Loaded " + Path.GetFileName(path)));
				audioClips.Add(new AudioFile(Crc32.Calculate(audioClip.downloadHandler.data), content, Path.GetFullPath(path)));
				return true;
			}
			CustomBoomboxMusic.Logger.LogWarning((object)$"Error loading {Path.GetFullPath(path)}: {content.loadState}");
			return false;
		}
	}
	internal static class Crc32
	{
		private static readonly uint[] table = new uint[256]
		{
			0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, 249268274u, 2044508324u,
			3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, 498536548u, 1789927666u, 4089016648u, 2227061214u,
			450548861u, 1843258603u, 4107580753u, 2211677639u, 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u,
			4195302755u, 2366115317u, 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u,
			901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, 651767980u, 1373503546u,
			3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, 671266974u, 1594198024u, 3322730930u, 2970347812u,
			795835527u, 1483230225u, 3244367275u, 3060149565u, 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u,
			2680153253u, 3904427059u, 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u,
			1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, 1706088902u, 314042704u,
			2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, 1303535960u, 984961486u, 2747007092u, 3569037538u,
			1256170817u, 1037604311u, 2765210733u, 3554079995u, 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u,
			2852801631u, 3708648649u, 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u,
			1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, 3988292384u, 2596254646u,
			62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, 3814918930u, 2489596804u, 225274430u, 2053790376u,
			3826175755u, 2466906013u, 167816743u, 2097651377u, 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u,
			426522225u, 1852507879u, 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u,
			3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, 3624741850u, 2936675148u,
			906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, 3412177804u, 3160834842u, 628085408u, 1382605366u,
			3423369109u, 3138078467u, 570562233u, 1426400815u, 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u,
			752459403u, 1541320221u, 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u,
			2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, 2262029012u, 4057260610u,
			1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, 2282248934u, 4279200368u, 1711684554u, 285281116u,
			2405801727u, 4167216745u, 1634467795u, 376229701u, 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u,
			1231636301u, 1047427035u, 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u,
			3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, 3009837614u, 3294710456u,
			1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u
		};

		public static uint Calculate(byte[] bytes)
		{
			return bytes.Aggregate(uint.MaxValue, (uint current, byte b) => (current >> 8) ^ table[(current ^ b) & 0xFF]) ^ 0xFFFFFFFFu;
		}
	}
	internal static class CSync
	{
		internal static bool IncludeVanilla => CSync_instance.Instance == null || CSync_instance.Instance.includeVanilla.Value;

		internal static void Initialize(CustomBoomboxMusic plugin)
		{
			CSync_instance.Instance = new CSync_instance
			{
				includeVanilla = SyncedBindingExtensions.BindSyncedEntry<bool>(((BaseUnityPlugin)plugin).Config, "General", "IncludeVanilla", true, "Includes vanilla music (synced to host, forced true if no custom music is present)")
			};
		}
	}
	internal class CSync_instance
	{
		internal SyncedEntry<bool> includeVanilla = null;

		internal static CSync_instance? Instance { get; set; }
	}
	[BepInPlugin("baer1.CustomBoomboxMusic", "CustomBoomboxMusic", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class CustomBoomboxMusic : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(BoomboxItem), "ItemActivate")]
		internal class BoomboxUsePatch
		{
			private static void Prefix(ref BoomboxItem __instance)
			{
				if (AudioManager.vanilla == null)
				{
					AudioManager.vanilla = (AudioClip[])__instance.musicAudios.Clone();
				}
				__instance.musicAudios = AudioManager.AudioClips.ToArray();
			}
		}

		[HarmonyPatch(typeof(BoomboxItem), "StartMusic")]
		internal class BoomboxPlayPatch
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldelem_Ref, (object)null, (string)null)
				}).Insert((CodeInstruction[])(object)new CodeInstruction[3]
				{
					new CodeInstruction(OpCodes.Dup, (object)null),
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(BoomboxPlayPatch), "a", (Type[])null, (Type[])null))
				}).InstructionEnumeration();
			}

			internal static void a(int songId, BoomboxItem boombox)
			{
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController) && !GameNetworkManager.Instance.localPlayerController.isPlayerDead && GameNetworkManager.Instance.localPlayerController.isPlayerControlled)
				{
					Logger.LogDebug((object)$">> BoomboxPlayPatch(#{songId}, {boombox})");
					if (Vector3.Distance(((Component)boombox.boomboxAudio).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) <= boombox.boomboxAudio.maxDistance)
					{
						AnnouncePlaying(songId);
					}
				}
			}
		}

		public const string DIRECTORY_NAME = "CustomBoomboxMusic";

		internal ConfigEntry<bool> loadIntoRAM = null;

		internal ConfigEntry<bool> displayNowPlaying = null;

		internal ConfigEntry<bool> includeVanilla = null;

		public static CustomBoomboxMusic Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		internal bool LoadIntoRAM => loadIntoRAM.Value;

		internal bool DisplayNowPlaying => displayNowPlaying.Value;

		internal bool IncludeVanilla => ClientSide ? includeVanilla.Value : CSync.IncludeVanilla;

		internal static bool ClientSide => !Chainloader.PluginInfos.ContainsKey("com.sigurd.csync");

		private void Awake()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			loadIntoRAM = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LoadIntoRAM", true, "Loads music into RAM, recommended if you use an HDD, not recommended if you have 8GB of RAM or less");
			displayNowPlaying = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisplayNowPlaying", true, "Whether to display a popup about which song is currently playing");
			if (!ClientSide)
			{
				CSync.Initialize(this);
			}
			else
			{
				includeVanilla = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludeVanilla", true, "Includes vanilla music (forced true if no custom music is present)");
			}
			AudioManager.Reload();
			if (Harmony == null)
			{
				Harmony = new Harmony("baer1.CustomBoomboxMusic");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
			Logger.LogInfo((object)"baer1.CustomBoomboxMusic v1.0.0 has loaded!");
		}

		internal static void AnnouncePlaying(int songId)
		{
			if (Instance.DisplayNowPlaying)
			{
				IReadOnlyList<AudioFile> audioFiles = AudioManager.AudioFiles;
				if (songId < audioFiles.Count && songId >= 0)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(audioFiles[songId].FilePath);
					Logger.LogInfo((object)("Now playing: " + fileNameWithoutExtension));
					HUDManager.Instance.DisplayTip("Now playing:", fileNameWithoutExtension ?? "", false, false, "LC_Tip1");
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "baer1.CustomBoomboxMusic";

		public const string PLUGIN_NAME = "CustomBoomboxMusic";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}