using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; 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 ChatCommandAPI; using ChatCommandAPI.Old; using ChatCommandAPI.Utils; using GameNetcodeStuff; using HarmonyLib; using LethalModUtils; using Microsoft.CodeAnalysis; using SpectateEnemy; using Unity.Netcode; 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("2.4.2.0")] [assembly: AssemblyInformationalVersion("2.4.2+7ef5654f423fc153f3563e1d41e9ae1937b50ef1")] [assembly: AssemblyProduct("CustomBoomboxMusic")] [assembly: AssemblyTitle("baer1.CustomBoomboxMusic")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.4.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 int? VanillaId { get; } public uint? Crc { get; } public AudioClip AudioClip { get; } public string FilePath { get; } public string Name => Path.GetFileNameWithoutExtension(FilePath); public AudioFile(uint crc, AudioClip audioClip, string filePath) { Crc = crc; AudioClip = audioClip; FilePath = filePath; } public AudioFile(int vanillaId, AudioClip audioClip) { VanillaId = vanillaId; AudioClip = audioClip; FilePath = $"Boombox {vanillaId + 1} (Lethal Company)"; } public override string ToString() { return "{ VanillaId: " + a(VanillaId) + ", Crc: " + a(Crc) + ", AudioClip: " + b(AudioClip) + ", FilePath: " + c(FilePath) + ", Name: " + c(Name) + " }"; static string a(object? e) { return (e == null) ? "null" : e.ToString(); } static string b(AudioClip e) { return ((Object)(object)e == (Object)null || !Object.op_Implicit((Object)(object)e)) ? "null" : ((object)e).ToString(); } static string c(string? e) { return (e == null) ? "null" : ("\"" + e.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") + "\""); } } } public static class AudioManager { private static List audioClips = new List(); internal const string VANILLA_AUDIO_CLIP_NAME = "Boombox {0} (Lethal Company)"; public static IReadOnlyList AudioClips => audioClips; public static IReadOnlyList VanillaAudioClips(BoomboxItem boombox) { return boombox.musicAudios.Select((AudioClip clip, int i) => new AudioFile(i, clip)).ToList(); } internal static void Reload() { CollectionExtensions.Do((IEnumerable)audioClips, (Action)delegate(AudioFile f) { f.AudioClip.UnloadAudioData(); }); audioClips.Clear(); FS.IterateDirectories(new DirectoryInfo(Paths.BepInExRootPath), (Action)ProcessFile, (Func)((DirectoryInfo i) => (ProcessFilter)((!i.Name.Equals("CustomBoomboxMusic", StringComparison.CurrentCultureIgnoreCase)) ? 2 : 0))); audioClips = audioClips.OrderBy((AudioFile f) => f.Crc).ToList(); CustomBoomboxMusic.BoomboxPlayPatch.rng = new ConditionalWeakTable>(); } private static void ProcessFile(FileInfo file) { CustomBoomboxMusic.Logger.LogDebug((object)$">> ProcessFile(file: {file})"); try { UnityWebRequest val = default(UnityWebRequest); AudioClip audioClip = Audio.Load(new Uri(file.FullName), ref val, (TimeSpan?)CustomBoomboxMusic.Instance.LoadTimeOut); audioClips.Add(new AudioFile(Crc32.Calculate(val.downloadHandler.data), audioClip, file.FullName)); } catch (Exception arg) { CustomBoomboxMusic.Logger.LogWarning((object)$"Couldn't load file {file.FullName}: {arg}"); } } public static bool TryGetCrc(uint crc, out AudioFile audioClip) { return (audioClip = AudioClips.FirstOrDefault((AudioFile i) => i.Crc.HasValue && i.Crc.Value == crc)) != null; } public static bool TryGetVanillaId(BoomboxItem boombox, int vanillaId, out AudioFile audioClip) { return (audioClip = VanillaAudioClips(boombox).FirstOrDefault((AudioFile i) => i.VanillaId.HasValue && i.VanillaId.Value == vanillaId)) != null; } } internal static class ChatCommandIntegration { internal static void Init() { new BoomboxCommand(); } } public class BoomboxCommand : LegacyCommand { public override string Name => "Boombox"; public override string Description => "Various commands for the CustomBoomboxMusic mod"; public override string[] Commands => new string[6] { ((BaseCommand)this).Name.ToLower(), "boo", "boom", "boomb", "boombo", "boobs" }; public override string[] Syntax => new string[4] { "play ", "reload", "version", "list" }; public override bool Invoke(string[] args, out string? error) { error = null; switch ((args.Length != 0) ? args[0] : null) { case "reload": case "r": Chat.Print("Reloading...", (Color?)null); AudioManager.Reload(); Chat.Print("Done reloading, found " + a(AudioManager.AudioClips.Count), (Color?)null); break; case "version": case "v": case null: Chat.Print("CustomBoomboxMusic v2.4.2\n" + a(AudioManager.AudioClips.Count) + " loaded", (Color?)null); break; case "list": case "l": { List list = AudioManager.AudioClips.OrderBy((AudioFile i) => i.Name).ToList(); int count = list.Count; Chat.Print((count == 0) ? (a(count) + " loaded") : (a(count) + " loaded:\n> " + GeneralExtensions.Join((IEnumerable)list, (Func)((AudioFile i) => i.Name), "\n> ")), (Color?)null); CustomBoomboxMusic.Logger.LogInfo((object)$"Listing loaded tracks ({count}):"); foreach (AudioFile item in list) { CustomBoomboxMusic.Logger.LogInfo((object)$"> {item.Name} - {item.FilePath} (CRC32: {item.Crc})"); } break; } case "play": case "p": { error = "Invalid arguments"; if (args.Length < 2) { return false; } error = "You need to be holding a boombox"; GrabbableObject val; if ((Object)(object)(val = GameNetworkManager.Instance?.localPlayerController?.currentlyHeldObjectServer) == (Object)null) { return false; } BoomboxItem boombox = default(BoomboxItem); if (!((Component)val).gameObject.TryGetComponent(ref boombox)) { return false; } error = "Track could not be found"; return Play(GeneralExtensions.Join((IEnumerable)args[1..], (Func)null, " "), boombox); } default: Chat.PrintError("Invalid subcommand, use /help for usage information"); break; } return true; static string a(int num) { return (num == 0) ? "No tracks" : $"{num} track{b(num)}"; } static string b(int num) { return (num == 1) ? string.Empty : "s"; } } private static bool Play(string identifier, BoomboxItem boombox) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) IReadOnlyList readOnlyList = AudioManager.AudioClips; if (CustomBoomboxMusic.Instance.IncludeVanilla || readOnlyList.Count == 0) { readOnlyList = readOnlyList.Concat(AudioManager.VanillaAudioClips(boombox)).ToList(); } List list = new List(); if (uint.TryParse(identifier, out var result) && AudioManager.TryGetCrc(result, out AudioFile audioClip)) { list.Add(audioClip); } if (list.Count == 0) { list.AddRange(readOnlyList.Where((AudioFile i) => string.Equals(i.Name, identifier, StringComparison.CurrentCultureIgnoreCase))); } if (list.Count == 0) { list.AddRange(readOnlyList.Where((AudioFile i) => i.Name.StartsWith(identifier, StringComparison.CurrentCultureIgnoreCase))); } if (list.Count == 0) { return false; } foreach (AudioFile item in list) { if (item == null) { continue; } if ((Object)(object)ModNetworkBehaviour.Instance != (Object)null) { if (item.VanillaId.HasValue) { ModNetworkBehaviour.Instance.StartPlayingVanillaMusicServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)boombox).NetworkObject), item.VanillaId.Value); } else { if (!item.Crc.HasValue) { CustomBoomboxMusic.Logger.LogWarning((object)$"AudioFile doesn't have CRC nor VanillaID: {item}"); continue; } ModNetworkBehaviour.Instance.StartPlayingMusicServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)boombox).NetworkObject), item.Crc.Value, item.Name); } return true; } if (!((GrabbableObject)boombox).isBeingUsed) { ((GrabbableObject)boombox).ActivateItemServerRpc(true, true); } boombox.boomboxAudio.clip = item.AudioClip; boombox.boomboxAudio.pitch = 1f; boombox.boomboxAudio.Play(); ((GrabbableObject)boombox).isBeingUsed = (boombox.isPlayingMusic = true); CustomBoomboxMusic.AnnouncePlaying(item); return true; } return false; } } [BepInPlugin("baer1.CustomBoomboxMusic", "CustomBoomboxMusic", "2.4.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class CustomBoomboxMusic : BaseUnityPlugin { [HarmonyPatch(typeof(GameNetworkManager), "Start")] internal static class StartPatch { private static void Postfix() { Logger.LogDebug((object)$">> StartPatch() ClientSide:{Instance.ClientSide} networkPrefab:{a(networkPrefab)}"); if (!Instance.ClientSide && !((Object)(object)networkPrefab != (Object)null)) { AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty, "modnetworkmanager")); networkPrefab = val.LoadAsset("ModNetworkManager"); ((Object)networkPrefab).name = "baer1.CustomBoomboxMusic-ModNetworkManager"; networkPrefab.AddComponent(); NetworkManager.Singleton.AddNetworkPrefab(networkPrefab); Logger.LogDebug((object)(" Registered network prefab " + a(networkPrefab))); } } } [HarmonyPatch(typeof(StartOfRound), "Awake")] internal static class InitPatch { private static void Postfix() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) Logger.LogDebug((object)$">> InitPatch() ClientSide:{Instance.ClientSide} IsHost:{NetworkManager.Singleton.IsHost} IsServer:{NetworkManager.Singleton.IsServer} networkPrefab:{a(networkPrefab)}"); if (Instance.ClientSide || (!NetworkManager.Singleton.IsHost && !NetworkManager.Singleton.IsServer) || (Object)(object)networkPrefab == (Object)null) { Logger.LogDebug((object)"<< InitPatch false"); return; } GameObject val = Object.Instantiate(networkPrefab, Vector3.zero, Quaternion.identity); val.GetComponent().Spawn(true); Logger.LogDebug((object)"<< InitPatch true"); } } [HarmonyPatch(typeof(BoomboxItem), "StartMusic")] internal static class BoomboxPlayPatch { internal static ConditionalWeakTable> rng = new ConditionalWeakTable>(); private static IReadOnlyList GetClips(BoomboxItem __instance) { IReadOnlyList readOnlyList = AudioManager.AudioClips; if (Instance.IncludeVanilla || readOnlyList.Count == 0) { readOnlyList = readOnlyList.Concat(AudioManager.VanillaAudioClips(__instance)).ToList(); } return readOnlyList; } private static IEnumerator RNG(BoomboxItem __instance) { IReadOnlyList clips = GetClips(__instance); Logger.LogDebug((object)$">> RNG({__instance}) clips.Count: {clips.Count}"); List clipIds = Enumerable.Range(0, clips.Count).ToList(); while (clipIds.Count > 0) { int i = __instance.musicRandomizer.Next(clipIds.Count); int id = clipIds[i]; clipIds.RemoveAt(i); Logger.LogDebug((object)$"Requested new RNG Value for {__instance}: {id} ({clipIds.Count} remaining)"); yield return clips[id]; } } private static AudioFile OldRNG(BoomboxItem __instance) { IReadOnlyList clips = GetClips(__instance); Logger.LogDebug((object)$">> OldRNG({__instance}) clips.Count: {clips.Count}"); return clips[__instance.musicRandomizer.Next(clips.Count)]; } private static AudioFile GetNextClip(BoomboxItem __instance) { Logger.LogDebug((object)$">> GetNextClip({__instance})"); if (!Instance.NewRNG) { return OldRNG(__instance); } if (!rng.TryGetValue(__instance, out IEnumerator enumerator)) { Logger.LogDebug((object)" Failed to obtain enumerator, creating new..."); create(); } AudioFile current = enumerator.Current; Logger.LogDebug((object)$" Got clip: {current}"); if (!enumerator.MoveNext()) { Logger.LogDebug((object)" Failed to advance RNG, creating new..."); create(); } return current; void create() { rng.AddOrUpdate(__instance, enumerator = RNG(__instance)); enumerator.MoveNext(); } } private static bool Prefix(ref BoomboxItem __instance, ref bool startMusic, ref bool pitchDown) { //IL_0072: 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) if (!startMusic) { return true; } if (!Instance.ClientSide && !((NetworkBehaviour)__instance).IsOwner) { return false; } AudioFile nextClip = GetNextClip(__instance); if ((Object)(object)ModNetworkBehaviour.Instance != (Object)null) { if (nextClip.VanillaId.HasValue) { ModNetworkBehaviour.Instance.StartPlayingVanillaMusicServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)__instance).NetworkObject), nextClip.VanillaId.Value); } else if (nextClip.Crc.HasValue) { ModNetworkBehaviour.Instance.StartPlayingMusicServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)__instance).NetworkObject), nextClip.Crc.Value, nextClip.Name); } else { Logger.LogWarning((object)$"AudioFile doesn't have CRC nor VanillaID: {nextClip}"); } } else { __instance.boomboxAudio.clip = nextClip.AudioClip; __instance.boomboxAudio.pitch = 1f; __instance.boomboxAudio.Play(); BoomboxItem obj = __instance; BoomboxItem obj2 = __instance; bool num = startMusic; bool isBeingUsed = num; obj2.isPlayingMusic = num; ((GrabbableObject)obj).isBeingUsed = isBeingUsed; a(nextClip, __instance); } return false; } private static void a(AudioFile audioFile, BoomboxItem boombox) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) Logger.LogDebug((object)$">> BoomboxPlayPatch({audioFile}, {boombox}) IsOwner:{((NetworkBehaviour)boombox).IsOwner}"); if (!((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null) && (!GameNetworkManager.Instance.localPlayerController.isPlayerDead || GameNetworkManager.Instance.localPlayerController.hasBegunSpectating) && (Vector3.Distance(((Component)boombox.boomboxAudio).transform.position, GameNetworkManager.Instance.localPlayerController.isPlayerDead ? ((Component)GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript).transform.position : ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) <= boombox.boomboxAudio.maxDistance || ((NetworkBehaviour)boombox).IsOwner || ((NetworkBehaviour)boombox).OwnerClientId == GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript.actualClientId)) { AnnouncePlaying(audioFile); } } } public const string DIRECTORY_NAME = "CustomBoomboxMusic"; private ConfigEntry loadTimeOut = null; private ConfigEntry displayNowPlaying = null; private ConfigEntry includeVanilla = null; private ConfigEntry newRNG = null; private ConfigEntry clientSide = null; internal const string SPECTATE_ENEMIES = "SpectateEnemy"; private static GameObject networkPrefab; public static CustomBoomboxMusic Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } public TimeSpan LoadTimeOut => TimeSpan.FromSeconds(loadTimeOut.Value); public bool DisplayNowPlaying => displayNowPlaying.Value; public bool IncludeVanilla => includeVanilla.Value; public bool NewRNG => newRNG.Value; public bool ClientSide { get; private set; } private void Awake() { //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; Instance = this; loadTimeOut = ((BaseUnityPlugin)this).Config.Bind("General", "LoadTimeOut", 10f, "Maximum amount of time to wait for an audio file to load. Increase this value if you have giant files or are using a slow drive"); displayNowPlaying = ((BaseUnityPlugin)this).Config.Bind("General", "DisplayNowPlaying", true, "Whether to display a popup about which song is currently playing"); includeVanilla = ((BaseUnityPlugin)this).Config.Bind("General", "IncludeVanilla", true, "Includes vanilla music (forced true if no custom music is present)"); includeVanilla.SettingChanged += delegate { BoomboxPlayPatch.rng = new ConditionalWeakTable>(); }; newRNG = ((BaseUnityPlugin)this).Config.Bind("General", "NewRNG", true, "Enables an improved RNG which prevents repeats"); clientSide = ((BaseUnityPlugin)this).Config.Bind("General", "ClientSide", true, "Enables or disables custom networking to more accurately sync which song is currently playing"); ClientSide = clientSide.Value; clientSide.SettingChanged += delegate { Logger.LogWarning((object)"ClientSide requires a restart of the game to apply"); }; Logger.LogInfo((object)("Client-side mode " + (ClientSide ? "enabled" : "disabled"))); AudioManager.Reload(); if (Chainloader.PluginInfos.ContainsKey("baer1.ChatCommandAPI")) { ChatCommandIntegration.Init(); } if (Harmony == null) { Harmony = new Harmony("baer1.CustomBoomboxMusic"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); Logger.LogInfo((object)"baer1.CustomBoomboxMusic v2.4.2 has loaded!"); } private static string a(GameObject? e) { return ((Object)(object)e == (Object)null) ? "null" : ((object)e).ToString(); } internal static void AnnouncePlaying(AudioFile audioFile) { string name = audioFile.Name; Logger.LogInfo((object)("Now playing: " + name)); if (Instance.DisplayNowPlaying) { HUDManager.Instance.DisplayTip("Now playing:", name ?? "", false, false, "LC_Tip1"); } } internal static void AnnounceMissing(string missingName) { Logger.LogWarning((object)("Missing audio for " + missingName)); HUDManager.Instance.DisplayTip("Missing audio:", missingName + " could not be played", true, false, "LC_Tip1"); } } public class ModNetworkBehaviour : NetworkBehaviour { [CompilerGenerated] private static class <>O { public static RpcReceiveHandler <0>____rpc_handler_StartPlayingMusicServerRpc; public static RpcReceiveHandler <1>____rpc_handler_StartPlayingMusicClientRpc; public static RpcReceiveHandler <2>____rpc_handler_StartPlayingVanillaMusicServerRpc; public static RpcReceiveHandler <3>____rpc_handler_StartPlayingVanillaMusicClientRpc; } private const uint START_PLAYING_MUSIC_SERVER_RPC_ID = 2501615839u; private const uint START_PLAYING_MUSIC_CLIENT_RPC_ID = 636642922u; private const uint START_PLAYING_VANILLA_MUSIC_SERVER_RPC_ID = 2501615849u; private const uint START_PLAYING_VANILLA_MUSIC_CLIENT_RPC_ID = 636642923u; public static ModNetworkBehaviour? Instance { get; private set; } public override void OnNetworkSpawn() { CustomBoomboxMusic.Logger.LogDebug((object)(">> OnNetworkSpawn() Instance:" + (((object)Instance)?.ToString() ?? "null"))); if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { ModNetworkBehaviour? instance = Instance; if (instance != null) { NetworkObject component = ((Component)instance).gameObject.GetComponent(); if (component != null) { component.Despawn(true); } } } Instance = this; ((NetworkBehaviour)this).OnNetworkSpawn(); } public static bool IsInBoomboxRange(BoomboxItem? boombox) { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = StartOfRound.Instance?.localPlayerController; GameObject val2 = (Chainloader.PluginInfos.ContainsKey("SpectateEnemy") ? TryGetSpectatedEnemy() : null); CustomBoomboxMusic.Logger.LogDebug((object)($">> IsInBoomboxRange(boombox: {boombox}) localPlayer:{val} isPLayerDead:{val?.isPlayerDead} spectatedPlayerScript:{val?.spectatedPlayerScript}" + $" spectatedEnemy:{val2}")); bool flag = boombox != null && boombox.boomboxAudio != null; bool flag2 = flag; bool flag3; if (flag2) { if (val == null) { goto IL_00c9; } if (val.isPlayerDead) { PlayerControllerB spectatedPlayerScript = val.spectatedPlayerScript; if (spectatedPlayerScript == null) { goto IL_00c9; } } flag3 = true; goto IL_00cc; } goto IL_00dc; IL_00dc: return flag2 && (Vector3.Distance(((Component)boombox.boomboxAudio).transform.position, ((Object)(object)val2 != (Object)null) ? val2.transform.position : (val.isPlayerDead ? ((Component)val.spectatedPlayerScript).transform.position : ((Component)val).transform.position)) <= boombox.boomboxAudio.maxDistance || ((NetworkBehaviour)boombox).IsOwner || ((NetworkBehaviour)boombox).OwnerClientId == val.spectatedPlayerScript.actualClientId); IL_00cc: flag2 = flag3 || (Object)(object)val2 != (Object)null; goto IL_00dc; IL_00c9: flag3 = false; goto IL_00cc; static GameObject? TryGetSpectatedEnemy() { return (SpectateEnemiesAPI.IsLoaded && SpectateEnemiesAPI.IsSpectatingEnemies) ? SpectateEnemiesAPI.CurrentEnemySpectating() : null; } } public override void OnNetworkDespawn() { CustomBoomboxMusic.Logger.LogDebug((object)string.Format(">> OnNetworkDespawn() Instance:{0} ==this:{1}", ((object)Instance)?.ToString() ?? "null", (Object)(object)Instance == (Object)(object)this)); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } ((NetworkBehaviour)this).OnNetworkDespawn(); } private static void Play(BoomboxItem boombox, AudioFile clip) { CustomBoomboxMusic.Logger.LogDebug((object)$">> Play({boombox}, {clip}) IsOwner:{((NetworkBehaviour)boombox).IsOwner}"); boombox.boomboxAudio.clip = clip.AudioClip; boombox.boomboxAudio.pitch = 1f; boombox.boomboxAudio.Play(); ((GrabbableObject)boombox).isBeingUsed = (boombox.isPlayingMusic = true); if (!((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null) && (!GameNetworkManager.Instance.localPlayerController.isPlayerDead || GameNetworkManager.Instance.localPlayerController.hasBegunSpectating) && IsInBoomboxRange(boombox)) { CustomBoomboxMusic.AnnouncePlaying(clip); } } private static void PlayFallback(BoomboxItem boombox, string missingName) { CustomBoomboxMusic.Logger.LogDebug((object)$">> PlayFallback({boombox}, {missingName}) IsOwner:{((NetworkBehaviour)boombox).IsOwner}"); boombox.boomboxAudio.clip = boombox.musicAudios[boombox.musicRandomizer.Next(boombox.musicAudios.Length)]; boombox.boomboxAudio.pitch = 1f; boombox.boomboxAudio.Play(); ((GrabbableObject)boombox).isBeingUsed = (boombox.isPlayingMusic = true); if (!((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null) && (!GameNetworkManager.Instance.localPlayerController.isPlayerDead || GameNetworkManager.Instance.localPlayerController.hasBegunSpectating) && IsInBoomboxRange(boombox)) { CustomBoomboxMusic.AnnounceMissing(missingName); } } [ServerRpc(RequireOwnership = false)] public void StartPlayingMusicServerRpc(NetworkObjectReference boomboxObjectReference, uint crc, string? clipName = null) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2501615839u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); BytePacker.WriteValueBitPacked(val2, crc); bool flag = clipName == null; ((FastBufferWriter)(ref val2)).WriteValueSafe(ref flag, default(ForPrimitives)); if (!flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(clipName, false); } ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2501615839u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager == null || networkManager.IsServer || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; CustomBoomboxMusic.Logger.LogDebug((object)$">> StartPlayingMusicServerRpc({boomboxObjectReference}, {crc})"); NetworkObject val3 = default(NetworkObject); if (((NetworkObjectReference)(ref boomboxObjectReference)).TryGet(ref val3, (NetworkManager)null)) { StartPlayingMusicClientRpc(boomboxObjectReference, crc, clipName); } else { CustomBoomboxMusic.Logger.LogWarning((object)"[StartPlayingMusicServerRpc] Boombox object could not be found, dropping request"); } } } [ClientRpc] public void StartPlayingMusicClientRpc(NetworkObjectReference boomboxObjectReference, uint crc, string? clipName = null) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(636642922u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); BytePacker.WriteValueBitPacked(val2, crc); bool flag = clipName == null; ((FastBufferWriter)(ref val2)).WriteValueSafe(ref flag, default(ForPrimitives)); if (!flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(clipName, false); } ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 636642922u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (networkManager != null && !networkManager.IsClient && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; CustomBoomboxMusic.Logger.LogDebug((object)$">> StartPlayingMusicClientRpc({boomboxObjectReference}, {crc}, {clipName})"); NetworkObject val3 = default(NetworkObject); if (!((NetworkObjectReference)(ref boomboxObjectReference)).TryGet(ref val3, (NetworkManager)null)) { CustomBoomboxMusic.Logger.LogWarning((object)"[StartPlayingMusicClientRpc] Boombox object could not be found, dropping request"); return; } CustomBoomboxMusic.Logger.LogDebug((object)$" {val3}"); BoomboxItem val4 = default(BoomboxItem); if (!((Component)val3).TryGetComponent(ref val4)) { CustomBoomboxMusic.Logger.LogWarning((object)"[StartPlayingMusicClientRpc] Boombox component could not be found, dropping request"); return; } CustomBoomboxMusic.Logger.LogDebug((object)$" {val4}"); if (!AudioManager.TryGetCrc(crc, out AudioFile audioClip)) { CustomBoomboxMusic.Logger.LogWarning((object)$"Couldn't find AudioClip with crc32 {crc}, playing fallback"); PlayFallback(val4, $"{clipName} (CRC32: {crc})"); } else { CustomBoomboxMusic.Logger.LogDebug((object)$" {audioClip}"); Play(val4, audioClip); } } [ServerRpc(RequireOwnership = false)] public void StartPlayingVanillaMusicServerRpc(NetworkObjectReference boomboxObjectReference, int vanillaId) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2501615849u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); BytePacker.WriteValueBitPacked(val2, vanillaId); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2501615849u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager == null || networkManager.IsServer || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; CustomBoomboxMusic.Logger.LogDebug((object)$">> StartPlayingVanillaMusicServerRpc({boomboxObjectReference}, {vanillaId})"); NetworkObject val3 = default(NetworkObject); if (((NetworkObjectReference)(ref boomboxObjectReference)).TryGet(ref val3, (NetworkManager)null)) { StartPlayingVanillaMusicClientRpc(boomboxObjectReference, vanillaId); } else { CustomBoomboxMusic.Logger.LogWarning((object)"[StartPlayingVanillaMusicServerRpc] Boombox object could not be found, dropping request"); } } } [ClientRpc] public void StartPlayingVanillaMusicClientRpc(NetworkObjectReference boomboxObjectReference, int vanillaId) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(636642923u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); BytePacker.WriteValueBitPacked(val2, vanillaId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 636642923u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (networkManager != null && !networkManager.IsClient && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; CustomBoomboxMusic.Logger.LogDebug((object)$">> StartPlayingVanillaMusicClientRpc({boomboxObjectReference}, {vanillaId})"); NetworkObject val3 = default(NetworkObject); if (!((NetworkObjectReference)(ref boomboxObjectReference)).TryGet(ref val3, (NetworkManager)null)) { CustomBoomboxMusic.Logger.LogWarning((object)"[StartPlayingVanillaMusicClientRpc] Boombox object could not be found, dropping request"); return; } CustomBoomboxMusic.Logger.LogDebug((object)$" {val3}"); BoomboxItem val4 = default(BoomboxItem); if (!((Component)val3).TryGetComponent(ref val4)) { CustomBoomboxMusic.Logger.LogWarning((object)"[StartPlayingMusicClientRpc] Boombox component could not be found, dropping request"); return; } CustomBoomboxMusic.Logger.LogDebug((object)$" {val4}"); if (!AudioManager.TryGetVanillaId(val4, vanillaId, out AudioFile audioClip)) { CustomBoomboxMusic.Logger.LogWarning((object)$"Couldn't find AudioClip with vanillaId {vanillaId}, playing fallback"); PlayFallback(val4, $"Boombox {vanillaId + 1} (Lethal Company)"); } else { CustomBoomboxMusic.Logger.LogDebug((object)$" {audioClip}"); Play(val4, audioClip); } } protected override void __initializeRpcs() { //IL_0017: 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_0043: 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) //IL_004e: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown object obj = <>O.<0>____rpc_handler_StartPlayingMusicServerRpc; if (obj == null) { RpcReceiveHandler val = __rpc_handler_StartPlayingMusicServerRpc; <>O.<0>____rpc_handler_StartPlayingMusicServerRpc = val; obj = (object)val; } ((NetworkBehaviour)this).__registerRpc(2501615839u, (RpcReceiveHandler)obj, "StartPlayingMusicServerRpc"); object obj2 = <>O.<1>____rpc_handler_StartPlayingMusicClientRpc; if (obj2 == null) { RpcReceiveHandler val2 = __rpc_handler_StartPlayingMusicClientRpc; <>O.<1>____rpc_handler_StartPlayingMusicClientRpc = val2; obj2 = (object)val2; } ((NetworkBehaviour)this).__registerRpc(636642922u, (RpcReceiveHandler)obj2, "StartPlayingMusicClientRpc"); object obj3 = <>O.<2>____rpc_handler_StartPlayingVanillaMusicServerRpc; if (obj3 == null) { RpcReceiveHandler val3 = __rpc_handler_StartPlayingVanillaMusicServerRpc; <>O.<2>____rpc_handler_StartPlayingVanillaMusicServerRpc = val3; obj3 = (object)val3; } ((NetworkBehaviour)this).__registerRpc(2501615849u, (RpcReceiveHandler)obj3, "StartPlayingVanillaMusicServerRpc"); object obj4 = <>O.<3>____rpc_handler_StartPlayingVanillaMusicClientRpc; if (obj4 == null) { RpcReceiveHandler val4 = __rpc_handler_StartPlayingVanillaMusicClientRpc; <>O.<3>____rpc_handler_StartPlayingVanillaMusicClientRpc = val4; obj4 = (object)val4; } ((NetworkBehaviour)this).__registerRpc(636642923u, (RpcReceiveHandler)obj4, "StartPlayingVanillaMusicClientRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_StartPlayingMusicServerRpc(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) //IL_004e: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (!((Object)(object)networkManager == (Object)null) && networkManager.IsListening) { NetworkObjectReference boomboxObjectReference = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); uint crc = default(uint); ByteUnpacker.ReadValueBitPacked(reader, ref crc); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); string clipName = null; if (!flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref clipName, false); } ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)1; ((ModNetworkBehaviour)(object)target).StartPlayingMusicServerRpc(boomboxObjectReference, crc, clipName); ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_StartPlayingMusicClientRpc(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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) //IL_004e: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (!((Object)(object)networkManager == (Object)null) && networkManager.IsListening) { NetworkObjectReference boomboxObjectReference = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); uint crc = default(uint); ByteUnpacker.ReadValueBitPacked(reader, ref crc); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); string clipName = null; if (!flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref clipName, false); } ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)1; ((ModNetworkBehaviour)(object)target).StartPlayingMusicClientRpc(boomboxObjectReference, crc, clipName); ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_StartPlayingVanillaMusicServerRpc(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0052: 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) NetworkManager networkManager = target.NetworkManager; if (!((Object)(object)networkManager == (Object)null) && networkManager.IsListening) { NetworkObjectReference boomboxObjectReference = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); int vanillaId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref vanillaId); ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)1; ((ModNetworkBehaviour)(object)target).StartPlayingVanillaMusicServerRpc(boomboxObjectReference, vanillaId); ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_StartPlayingVanillaMusicClientRpc(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0052: 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) NetworkManager networkManager = target.NetworkManager; if (!((Object)(object)networkManager == (Object)null) && networkManager.IsListening) { NetworkObjectReference boomboxObjectReference = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadValueSafe(ref boomboxObjectReference, default(ForNetworkSerializable)); int vanillaId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref vanillaId); ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)1; ((ModNetworkBehaviour)(object)target).StartPlayingVanillaMusicClientRpc(boomboxObjectReference, vanillaId); ((NetworkBehaviour)(ModNetworkBehaviour)(object)target).__rpc_exec_stage = (__RpcExecStage)0; } } protected override string __getTypeName() { return ((object)this).GetType().Name; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "baer1.CustomBoomboxMusic"; public const string PLUGIN_NAME = "CustomBoomboxMusic"; public const string PLUGIN_VERSION = "2.4.2"; } }