Decompiled source of Boombox Controller v1.2.6
BepInEx/plugins/BoomboxController.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.IO.Compression; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BoomboxController.Audio; using BoomboxController.Boombox; using BoomboxController.Commands; using BoomboxController.Multiplayer; using BoomboxController.Options; using BoomboxController.Save; using BoomboxController.Startups; using BoomboxController.Vision; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: AssemblyCompany("MonoGame Team")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("BoomboxController")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BoomboxController")] [assembly: AssemblyTitle("BoomboxController")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MonoGame/MonoGame")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BoomboxController { public class BoomboxController : Variables { public static SaveManager saveManager; public void InitializationBoombox() { saveManager = new SaveManager(); Plugin.HarmonyLib.PatchAll(typeof(AudioManager)); Plugin.HarmonyLib.PatchAll(typeof(BoomboxManager)); Plugin.HarmonyLib.PatchAll(typeof(CommandManager)); Plugin.HarmonyLib.PatchAll(typeof(MenuManager)); Plugin.HarmonyLib.PatchAll(typeof(OptionManager)); Plugin.HarmonyLib.PatchAll(typeof(SaveManager)); Plugin.HarmonyLib.PatchAll(typeof(StartupManager)); Plugin.HarmonyLib.PatchAll(typeof(VisionManager)); Plugin.HarmonyLib.PatchAll(typeof(MultiplayerManager)); } public static void DrawString(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped, string? name) { if (!(Variables.LastMessage == chatMessage)) { Variables.LastMessage = chatMessage; Variables.LastnameOfUserWhoTyped = name; __instance.PingHUDElement(__instance.Chat, 4f, 1f, 0.2f); if (__instance.ChatMessageHistory.Count >= 4) { ((TMP_Text)__instance.chatText).text.Remove(0, __instance.ChatMessageHistory[0].Length); __instance.ChatMessageHistory.Remove(__instance.ChatMessageHistory[0]); } StringBuilder stringBuilder = new StringBuilder(chatMessage); stringBuilder.Replace("[playerNum0]", StartOfRound.Instance.allPlayerScripts[0].playerUsername); stringBuilder.Replace("[playerNum1]", StartOfRound.Instance.allPlayerScripts[1].playerUsername); stringBuilder.Replace("[playerNum2]", StartOfRound.Instance.allPlayerScripts[2].playerUsername); stringBuilder.Replace("[playerNum3]", StartOfRound.Instance.allPlayerScripts[3].playerUsername); chatMessage = stringBuilder.ToString(); string item = ((!string.IsNullOrEmpty(nameOfUserWhoTyped)) ? ("<color=#FF0000>" + nameOfUserWhoTyped + "</color>: <color=#FFFF00>'" + chatMessage + "'</color>") : ("<color=#7069ff>" + chatMessage + "</color>")); __instance.ChatMessageHistory.Add(item); ((TMP_Text)__instance.chatText).text = ""; for (int i = 0; i < __instance.ChatMessageHistory.Count; i++) { TextMeshProUGUI chatText = __instance.chatText; ((TMP_Text)chatText).text = ((TMP_Text)chatText).text + "\n" + __instance.ChatMessageHistory[i]; } } } } public class GrabbleBoombox { } public class VisualBoombox : MonoBehaviour { private static VisualBoombox _instance; public Coroutine Start(IEnumerator routine) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { _instance = new GameObject("VisualBoombox").AddComponent<VisualBoombox>(); Object.DontDestroyOnLoad((Object)_instance); } return ((MonoBehaviour)_instance).StartCoroutine(routine); } public IEnumerator GetTexture(string url, BoomboxItem boombox) { UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url); try { yield return uwr.SendWebRequest(); if ((int)uwr.result != 1) { Plugin.instance.Log(uwr.error); yield break; } Texture2D texture = DownloadHandlerTexture.GetContent(uwr); GameObject cube = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)cube).name = "QuadBoombox"; cube.transform.localScale = new Vector3(0.8f, 0.38f, 0.001f); Quaternion localRotation = cube.transform.localRotation; Vector3 rot = ((Quaternion)(ref localRotation)).eulerAngles; ((Vector3)(ref rot)).Set(0f, -90f, 0f); cube.transform.localRotation = Quaternion.Euler(rot); cube.transform.position = new Vector3(((Component)boombox).transform.position.x - 0.179f, ((Component)boombox).transform.position.y, ((Component)boombox).transform.position.z); cube.transform.parent = ((Component)boombox).transform; ((Collider)cube.GetComponent<BoxCollider>()).enabled = false; ((Renderer)cube.GetComponent<MeshRenderer>()).material = new Material(Shader.Find("HDRP/Lit")); ((Renderer)cube.GetComponent<MeshRenderer>()).material.mainTexture = (Texture)(object)texture; rot = default(Vector3); } finally { ((IDisposable)uwr)?.Dispose(); } } } public class Configs { public class Lang { public ConfigEntry<string> main_1; public ConfigEntry<string> main_2; public ConfigEntry<string> main_3; public ConfigEntry<string> main_4; public ConfigEntry<string> main_5; public ConfigEntry<string> main_6; public ConfigEntry<string> main_7; public ConfigEntry<string> main_8; public ConfigEntry<string> main_9; public ConfigEntry<string> main_10; public ConfigEntry<string> main_11; public ConfigEntry<string> main_12; public ConfigEntry<string> main_13; public ConfigEntry<string> main_14; public void GetConfigRU() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown ConfigFile val = new ConfigFile("BoomboxController\\lang\\boombox_ru.cfg", true); main_1 = val.Bind<string>("General", "Main_1", "Пожалуйста, подождите, загружаются дополнительные библиотеки, чтобы модификация заработала.", (ConfigDescription)null); main_2 = val.Bind<string>("General", "Main_2", "Взять BoomBox[1.2.6] : [E]\n@2 - @3\n@1 громкость\nСейчас играет: @4\nДоступных треков: @5", (ConfigDescription)null); main_3 = val.Bind<string>("General", "Main_3", "Все дополнительные библиотеки загружены, теперь вы можете использовать команды для бумбокса.", (ConfigDescription)null); main_4 = val.Bind<string>("General", "Main_4", "Подождите, трек еще загружается!", (ConfigDescription)null); main_5 = val.Bind<string>("General", "Main_5", "Команды:\n/bplay - Проиграть музыку\n/btime - Изменить позицию песни\n/bvolume - Изменить громкость трека", (ConfigDescription)null); main_6 = val.Bind<string>("General", "Main_6", "Введите правильный URL-адрес!", (ConfigDescription)null); main_7 = val.Bind<string>("General", "Main_7", "Пожалуйста подождите...", (ConfigDescription)null); main_8 = val.Bind<string>("General", "Main_8", "Трек был загружен в бумбокс", (ConfigDescription)null); main_9 = val.Bind<string>("General", "Main_9", "@1 изменил громкость трека @2", (ConfigDescription)null); main_10 = val.Bind<string>("General", "Main_10", "Введите правильную громкость трека (пример: 0, 10, 20, 30...)!", (ConfigDescription)null); main_11 = val.Bind<string>("General", "Main_11", "Ссылка недействительная!", (ConfigDescription)null); main_12 = val.Bind<string>("General", "Main_12", "Позиция трека изменена на @1!", (ConfigDescription)null); main_13 = val.Bind<string>("General", "Main_13", "Загрузка трека отменена!", (ConfigDescription)null); main_14 = val.Bind<string>("General", "Main_14", "Текущий трек был переключен на: @1!", (ConfigDescription)null); } public void GetConfigEN() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown ConfigFile val = new ConfigFile("BoomboxController\\lang\\boombox_en.cfg", true); main_1 = val.Bind<string>("General", "Main_1", "Please wait, additional libraries are being loaded for the modification to work.", (ConfigDescription)null); main_2 = val.Bind<string>("General", "Main_2", "Pickup BoomBox[1.2.6] : [E]\n@2 - @3\n@1 volume\nNow playing: @4\nAvailable tracks: @5", (ConfigDescription)null); main_3 = val.Bind<string>("General", "Main_3", "All libraries have loaded, now you can use the boombox commands.", (ConfigDescription)null); main_4 = val.Bind<string>("General", "Main_4", "Another track is being uploaded to the boombox!", (ConfigDescription)null); main_5 = val.Bind<string>("General", "Main_5", "Commands:\n/bplay - Play music\n/btime - Change the position of the song\n/bvolume - Change Boombox volume", (ConfigDescription)null); main_6 = val.Bind<string>("General", "Main_6", "Enter the correct URL!", (ConfigDescription)null); main_7 = val.Bind<string>("General", "Main_7", "Please wait...", (ConfigDescription)null); main_8 = val.Bind<string>("General", "Main_8", "The track was uploaded to the boombox", (ConfigDescription)null); main_9 = val.Bind<string>("General", "Main_9", "@1 changed the volume @2 of the boombox.", (ConfigDescription)null); main_10 = val.Bind<string>("General", "Main_10", "Enter the correct Volume (example: 0, 10, 20, 30...)!", (ConfigDescription)null); main_11 = val.Bind<string>("General", "Main_11", "Link is invalid!", (ConfigDescription)null); main_12 = val.Bind<string>("General", "Main_12", "Track position changed to @1!", (ConfigDescription)null); main_13 = val.Bind<string>("General", "Main_13", "Track download canceled!", (ConfigDescription)null); main_14 = val.Bind<string>("General", "Main_14", "The current track has been switched to: @1!", (ConfigDescription)null); } } public ConfigEntry<bool> requstbattery; public ConfigEntry<bool> pocketitem; public ConfigEntry<bool> radiuscheck; public ConfigEntry<string> languages; public ConfigEntry<bool> visual; public ConfigEntry<string> body; public ConfigEntry<string> otherelem; public static Lang lang = new Lang(); public Configs() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown ConfigFile val = new ConfigFile("BoomboxController\\boombox_controller.cfg", true); requstbattery = val.Bind<bool>("General.Toggles", "RequestBattery", false, "Enable/disable boombox battery (true = Enable; false = Disable)"); pocketitem = val.Bind<bool>("General.Toggles", "PocketItem", true, "Enable/disable music in your pocket. (true = Enable; false = Disable)"); radiuscheck = val.Bind<bool>("General.Toggles", "RadiusUse", true, "Enable/disable the command radius of the boombox. (true = Radius greater than 25; false = Standard radius 25)"); languages = val.Bind<string>("General", "Languages", "en", "EN/RU"); visual = val.Bind<bool>("Visual", "Visual", false, "Enable/Disable Visual Elements of Boombox"); body = val.Bind<string>("Visual", "Body", "#FFFFFF", "Color body Boombox"); otherelem = val.Bind<string>("Visual", "Other", "#000000", "Color Other Elements Boombox"); } public Lang GetLang() { return lang; } } public class Downloader { public static void DownloadFilesToUnpacking(Uri uri, string filename) { WebClient webClient = new WebClient(); webClient.DownloadFileCompleted += Web_DownloadFileCompletedToUnpacking; webClient.DownloadFileAsync(uri, filename); } public static void DownloadFiles(Uri uri, string filename) { WebClient webClient = new WebClient(); webClient.DownloadFileCompleted += Web_DownloadFileCompleted; webClient.DownloadFileAsync(uri, filename); } private static void Web_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { Thread.CurrentThread.Abort(); } private static void Web_DownloadFileCompletedToUnpacking(object sender, AsyncCompletedEventArgs e) { Unpacking(); if (!File.Exists("BoomboxController\\other\\yt-dlp.exe")) { Thread thread = new Thread((ThreadStart)delegate { DownloadFiles(new Uri("https://github.com/yt-dlp/yt-dlp/releases/download/2024.08.06/yt-dlp.exe"), "BoomboxController\\other\\yt-dlp.exe"); }); thread.Start(); } Thread.CurrentThread.Abort(); } public static bool Unpacking() { try { using (ZipArchive zipArchive = ZipFile.OpenRead("BoomboxController\\other\\ffmpeg-master-latest-win64-gpl.zip")) { foreach (ZipArchiveEntry entry in zipArchive.Entries) { if (entry.Name.Equals("ffmpeg.exe")) { entry.ExtractToFile(Path.Combine("BoomboxController\\other", entry.Name)); } } } File.Delete("BoomboxController\\other\\ffmpeg-master-latest-win64-gpl.zip"); return true; } catch (InvalidDataException) { Plugin.instance.Log("Zip файл поврежден, потому что он не был загружен должным образом. Сложно ли не закрывать игру и просто позволить загрузке файлов завершиться?"); Plugin.instance.Log("Zip is broken because it wasn't downloaded properly. Is it difficult to not close the game and just let the downloading of files to finish?"); File.Delete("BoomboxController\\other\\ffmpeg-master-latest-win64-gpl.zip"); return false; } } } public class QuitManager : MonoBehaviour { private void OnApplicationQuit() { DeleteFile(); } public void DeleteFile() { FileInfo[] files = new DirectoryInfo("BoomboxController\\other\\playlist").GetFiles(); foreach (FileInfo fileInfo in files) { fileInfo.Delete(); } FileInfo[] files2 = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); if (files2.Length == 1) { File.Delete("BoomboxController\\other\\" + files2[0].Name); } } } public class WinApi { public enum MessageBoxResult { Error = 0, Abort = 3, Cancel = 2, Continue = 11, Ignore = 5, No = 7, OK = 1, Retry = 4, TryAgain = 10, Yes = 6 } [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll", SetLastError = true)] private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern MessageBoxResult MessageBox(IntPtr hwnd, string text, string caption, uint type); public void SizeConsole(int width, int height) { MoveWindow(GetConsoleWindow(), 200, 200, width, height, bRepaint: true); } public static MessageBoxResult SendMessageBox(string text, string caption, uint type) { return MessageBox(GetConsoleWindow(), text, caption, type); } } [BepInPlugin("KoderTech.BoomboxController", "BoomboxController", "1.2.6")] public class Plugin : BaseUnityPlugin { public static Plugin instance; public static Harmony HarmonyLib; public static Configs config; public static BoomboxController controller; public const string Version = "1.2.6"; private void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown instance = this; config = new Configs(); controller = new BoomboxController(); HarmonyLib = new Harmony("com.kodertech.BoomboxController"); Startup(); } public void WriteLogo() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"\n \n`7MM\"\"\"Yp, *MM .g8\"\"\"bgd mm `7MM `7MM \n MM Yb MM .dP' `M MM MM MM \n MM dP ,pW\"Wq. ,pW\"Wq.`7MMpMMMb.pMMMb. MM,dMMb. ,pW\"Wq.`7M' `MF' dM' `,pW\"Wq.`7MMpMMMbmmMMmm `7Mb,od8 ,pW\"Wq. MM MM .gP\"Ya `7Mb,od8 \n MM\"\"\"bg. 6W' `Wb 6W' `Wb MM MM MM MM `Mb 6W' `Wb `VA ,V' MM 6W' `Wb MM MM MM MM' \"'6W' `Wb MM MM ,M' Yb MM' \"' \n MM `Y 8M M8 8M M8 MM MM MM MM M8 8M M8 XMX MM. 8M M8 MM MM MM MM 8M M8 MM MM 8M\"\"\"\"\"\" MM \n MM ,9 YA. ,A9 YA. ,A9 MM MM MM MM. ,M9 YA. ,A9 ,V' VA. `Mb. ,YA. ,A9 MM MM MM MM YA. ,A9 MM MM YM. , MM \n.JMMmmmd9 `Ybmd9' `Ybmd9'.JMML JMML JMMLP^YbmdP' `Ybmd9'.AM. .MA. `\"bmmmd' `Ybmd9'.JMML JMML`Mbmo.JMML. `Ybmd9'.JMML.JMML.`Mbmmd'.JMML. \n "); } public void Startup() { new WinApi().SizeConsole(1500, 500); WriteLogo(); SwitchLanguage(); if (File.Exists("BoomboxController\\lang\\boombox_ru.cfg")) { File.Delete("BoomboxController\\lang\\boombox_ru.cfg"); } if (File.Exists("BoomboxController\\lang\\boombox_en.cfg")) { File.Delete("BoomboxController\\lang\\boombox_en.cfg"); } if (!Directory.Exists("BoomboxController\\lang")) { Directory.CreateDirectory("BoomboxController\\lang"); } if (!Directory.Exists("BoomboxController\\other")) { Directory.CreateDirectory("BoomboxController\\other"); } if (!Directory.Exists("BoomboxController\\other\\local")) { Directory.CreateDirectory("BoomboxController\\other\\local"); } if (!Directory.Exists("BoomboxController\\other\\playlist")) { Directory.CreateDirectory("BoomboxController\\other\\playlist"); } if (!File.Exists("BoomboxController\\other\\ffmpeg.exe")) { if (File.Exists("BoomboxController\\other\\ffmpeg-master-latest-win64-gpl.zip")) { if (!Downloader.Unpacking()) { Thread thread = new Thread((ThreadStart)delegate { Downloader.DownloadFilesToUnpacking(new Uri("https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip"), "BoomboxController\\other\\ffmpeg-master-latest-win64-gpl.zip"); }); thread.Start(); } } else { Thread thread2 = new Thread((ThreadStart)delegate { Downloader.DownloadFilesToUnpacking(new Uri("https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip"), "BoomboxController\\other\\ffmpeg-master-latest-win64-gpl.zip"); }); thread2.Start(); } } controller.InitializationBoombox(); } public void SwitchLanguage() { string text = config.languages.Value.ToLower(); string text2 = text; if (!(text2 == "ru")) { if (text2 == "en") { config.GetLang().GetConfigEN(); } } else { config.GetLang().GetConfigRU(); } } public void Log(object message) { ((BaseUnityPlugin)this).Logger.LogInfo(message); } } public class Variables : MonoBehaviour { public static AudioBoomBox bom; public static VisualBoombox vbom; public static BoomboxItem boomboxItem = new BoomboxItem(); public static Dictionary<string, AudioClip> musicList; public static QuitManager quit; public static QuitManager quits; public static KeyControl up = null; public static KeyControl down = null; public static int timesPlayedWithoutTurningOff = 0; public static int isSendingItemRPC = 0; public static int Id = 0; public static int totalTack = 0; public static int currectTrack = 0; public static double curretTime = 0.0; public static double totalTime = 0.0; public static bool startMusics = true; public static bool LoadingMusicBoombox = false; public static bool LoadingLibrary = false; public static bool isplayList = false; internal static bool blockcompatibility = false; public static bool waitAutoNext = false; public static bool netSwitch = true; public static bool currentTrackChange = false; public static string LastMessage; public static string LastnameOfUserWhoTyped; public static string NameTrack; public static string[] sumbols = new string[3] { "+", "#", "\ufffd" }; public static string[] multi_name = new string[1] { "SyncSong" }; } public static class MyPluginInfo { public const string PLUGIN_GUID = "BoomboxController"; public const string PLUGIN_NAME = "BoomboxController"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace BoomboxController.Vision { public class VisionManager : BoomboxController { [HarmonyPatch(typeof(PlayerControllerB), "SetHoverTipAndCurrentInteractTrigger")] [HarmonyPrefix] public static bool SetHoverTipAndCurrentInteractTrigger_PlayerControllerB(PlayerControllerB __instance, ref RaycastHit ___hit, ref Ray ___interactRay, ref int ___playerMask, ref int ___interactableObjectsMask) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0d50: Unknown result type (might be due to invalid IL or missing references) if (!__instance.isGrabbingObjectAnimation) { ___interactRay = new Ray(((Component)__instance.gameplayCamera).transform.position, ((Component)__instance.gameplayCamera).transform.forward); if (Physics.Raycast(___interactRay, ref ___hit, __instance.grabDistance, ___interactableObjectsMask) && ((Component)((RaycastHit)(ref ___hit)).collider).gameObject.layer != 8) { string tag = ((Component)((RaycastHit)(ref ___hit)).collider).tag; if (!(tag == "PhysicsProp")) { if (tag == "InteractTrigger") { InteractTrigger component = ((Component)((RaycastHit)(ref ___hit)).transform).gameObject.GetComponent<InteractTrigger>(); if ((Object)(object)component != (Object)(object)__instance.previousHoveringOverTrigger && (Object)(object)__instance.previousHoveringOverTrigger != (Object)null) { __instance.previousHoveringOverTrigger.isBeingHeldByPlayer = false; } if (!((Object)(object)component == (Object)null)) { __instance.hoveringOverTrigger = component; if (!component.interactable) { __instance.cursorIcon.sprite = component.disabledHoverIcon; ((Behaviour)__instance.cursorIcon).enabled = (Object)(object)component.disabledHoverIcon != (Object)null; ((TMP_Text)__instance.cursorTip).text = component.disabledHoverTip; } else if (component.isPlayingSpecialAnimation) { ((Behaviour)__instance.cursorIcon).enabled = false; ((TMP_Text)__instance.cursorTip).text = ""; } else if (__instance.isHoldingInteract) { if (__instance.twoHanded) { ((TMP_Text)__instance.cursorTip).text = "[Hands full]"; } else if (!string.IsNullOrEmpty(component.holdTip)) { ((TMP_Text)__instance.cursorTip).text = component.holdTip; } } else { ((Behaviour)__instance.cursorIcon).enabled = true; __instance.cursorIcon.sprite = component.hoverIcon; ((TMP_Text)__instance.cursorTip).text = component.hoverTip; } } } } else { if (FirstEmptyItemSlot(__instance) == -1) { ((TMP_Text)__instance.cursorTip).text = "Inventory full!"; } else { GrabbableObject component2 = ((Component)((RaycastHit)(ref ___hit)).collider).gameObject.GetComponent<GrabbableObject>(); if (!GameNetworkManager.Instance.gameHasStarted && !component2.itemProperties.canBeGrabbedBeforeGameStart && (Object)(object)StartOfRound.Instance.testRoom == (Object)null) { ((TMP_Text)__instance.cursorTip).text = "(Cannot pickup until ship is landed)"; } if ((Object)(object)((Component)((RaycastHit)(ref ___hit)).transform).gameObject.GetComponent<BoomboxItem>() != (Object)null) { float volume = Variables.boomboxItem.boomboxAudio.volume; if ((Object)(object)component2 != (Object)null && !string.IsNullOrEmpty(component2.customGrabTooltip)) { ((TMP_Text)__instance.cursorTip).text = component2.customGrabTooltip; } if (GameNetworkManager.Instance.gameHasStarted && ((Object)((RaycastHit)(ref ___hit)).transform).name.ToString() == "Boombox(Clone)") { if (!File.Exists("BoomboxController\\other\\ffmpeg.exe") || !File.Exists("BoomboxController\\other\\yt-dlp.exe")) { ((TMP_Text)__instance.cursorTip).text = Plugin.config.GetLang().main_1.Value; } else { if (!Variables.boomboxItem.isPlayingMusic && !Variables.waitAutoNext) { Variables.curretTime = 0.0; Variables.totalTime = 0.0; } int num = (int)Variables.curretTime % 3600; string text = Mathf.Floor((float)((int)Variables.curretTime / 3600)).ToString("00"); string text2 = Mathf.Floor((float)(num / 60)).ToString("00"); string text3 = Mathf.Floor((float)(num % 60)).ToString("00"); int num2 = (int)Variables.totalTime % 3600; string text4 = Mathf.Floor((float)((int)Variables.totalTime / 3600)).ToString("00"); string text5 = Mathf.Floor((float)(num2 / 60)).ToString("00"); string text6 = Mathf.Floor((float)(num2 % 60)).ToString("00"); if (Plugin.config.languages.Value == "en" && (Variables.musicList == null || Variables.musicList.Count > 0)) { string text7 = (Variables.boomboxItem.isPlayingMusic ? "[Home]" : "Nothing"); ((TMP_Text)__instance.cursorTip).text = Plugin.config.GetLang().main_2.Value.Replace("@1", $"{Math.Round(volume * 100f)}%").Replace("@2", text + ":" + text2 + ":" + text3).Replace("@3", text4 + ":" + text5 + ":" + text6) .Replace("@4", text7 ?? "") .Replace("@5", $"{Variables.totalTack}") + "\nIncrease volume [" + ((Variables.up == null) ? "PU" : ((InputControl)Variables.up).displayName) + "]\nDecrease volume [" + ((Variables.down == null) ? "PD" : ((InputControl)Variables.down).displayName) + "]"; } if (Plugin.config.languages.Value == "ru" && (Variables.musicList == null || Variables.musicList.Count > 0)) { string text8 = (Variables.boomboxItem.isPlayingMusic ? "[Home]" : "Нечего"); ((TMP_Text)__instance.cursorTip).text = Plugin.config.GetLang().main_2.Value.Replace("@1", $"{Math.Round(volume * 100f)}%").Replace("@2", text + ":" + text2 + ":" + text3).Replace("@3", text4 + ":" + text5 + ":" + text6) .Replace("@4", text8 ?? "") .Replace("@5", $"{Variables.totalTack}") + "\nУвеличить громкость [" + ((Variables.up == null) ? "PU" : ((InputControl)Variables.up).displayName) + "]\nУменьшить громкость [" + ((Variables.down == null) ? "PD" : ((InputControl)Variables.down).displayName) + "]"; } if (Variables.up != null) { if (((ButtonControl)Variables.up).wasPressedThisFrame && volume < 1f) { float num3 = volume + 0.1f; Variables.boomboxItem.boomboxAudio.volume = num3; BoomboxController.saveManager.SaveCache(num3, (Variables.up == null) ? null : ((InputControl)Variables.up).displayName, (Variables.down == null) ? null : ((InputControl)Variables.down).displayName); } } else if (((ButtonControl)Keyboard.current.pageUpKey).wasPressedThisFrame && volume < 1f) { float num4 = volume + 0.1f; Variables.boomboxItem.boomboxAudio.volume = num4; BoomboxController.saveManager.SaveCache(num4, (Variables.up == null) ? null : ((InputControl)Variables.up).displayName, (Variables.down == null) ? null : ((InputControl)Variables.down).displayName); } if (Variables.down != null) { if (((ButtonControl)Variables.down).wasPressedThisFrame && volume > 0f) { float num5 = volume - 0.1f; Variables.boomboxItem.boomboxAudio.volume = num5; BoomboxController.saveManager.SaveCache(num5, (Variables.up == null) ? null : ((InputControl)Variables.up).displayName, (Variables.down == null) ? null : ((InputControl)Variables.down).displayName); } } else if (((ButtonControl)Keyboard.current.pageDownKey).wasPressedThisFrame && volume > 0f) { float num6 = volume - 0.1f; Variables.boomboxItem.boomboxAudio.volume = num6; BoomboxController.saveManager.SaveCache(num6, (Variables.up == null) ? null : ((InputControl)Variables.up).displayName, (Variables.down == null) ? null : ((InputControl)Variables.down).displayName); } if (InputControlExtensions.IsPressed((InputControl)(object)Keyboard.current.homeKey, 0f)) { if (Variables.musicList.Count == 1) { ((TMP_Text)__instance.cursorTip).text = Plugin.config.GetLang().main_2.Value.Replace("@1", $"{Math.Round(volume * 100f)}%").Replace("@2", text + ":" + text2 + ":" + text3).Replace("@3", text4 + ":" + text5 + ":" + text6) .Replace("@4", Variables.NameTrack.Substring(0, Variables.NameTrack.Length - 4) ?? "") .Replace("@5", $"{Variables.totalTack}"); } if (Variables.musicList.Count > 1) { ((TMP_Text)__instance.cursorTip).text = Plugin.config.GetLang().main_2.Value.Replace("@1", $"{Math.Round(volume * 100f)}%").Replace("@2", text + ":" + text2 + ":" + text3).Replace("@3", text4 + ":" + text5 + ":" + text6) .Replace("@4", Variables.NameTrack.Replace(" ", "") ?? "") .Replace("@5", $"{Variables.totalTack}"); } } } } } } ((Behaviour)__instance.cursorIcon).enabled = true; __instance.cursorIcon.sprite = __instance.grabItemIcon; } } else { ((Behaviour)__instance.cursorIcon).enabled = false; ((TMP_Text)__instance.cursorTip).text = ""; if ((Object)(object)__instance.hoveringOverTrigger != (Object)null) { __instance.previousHoveringOverTrigger = __instance.hoveringOverTrigger; } __instance.hoveringOverTrigger = null; } } if (StartOfRound.Instance.localPlayerUsingController) { StringBuilder stringBuilder = new StringBuilder(((TMP_Text)__instance.cursorTip).text); stringBuilder.Replace("[E]", "[X]"); stringBuilder.Replace("[LMB]", "[X]"); stringBuilder.Replace("[RMB]", "[R-Trigger]"); stringBuilder.Replace("[F]", "[R-Shoulder]"); stringBuilder.Replace("[Z]", "[L-Shoulder]"); ((TMP_Text)__instance.cursorTip).text = stringBuilder.ToString(); } else { ((TMP_Text)__instance.cursorTip).text = ((TMP_Text)__instance.cursorTip).text.Replace("[LMB]", "[E]"); } if (!__instance.isFreeCamera && Physics.Raycast(___interactRay, ref ___hit, 5f, ___playerMask)) { PlayerControllerB component3 = ((Component)((RaycastHit)(ref ___hit)).collider).gameObject.GetComponent<PlayerControllerB>(); if ((Object)(object)component3 != (Object)null) { component3.ShowNameBillboard(); } } return false; } public static int FirstEmptyItemSlot(PlayerControllerB __instance) { int result = -1; if ((Object)(object)__instance.ItemSlots[__instance.currentItemSlot] == (Object)null) { result = __instance.currentItemSlot; } else { for (int i = 0; i < __instance.ItemSlots.Length; i++) { if ((Object)(object)__instance.ItemSlots[i] == (Object)null) { result = i; break; } } } return result; } } } namespace BoomboxController.Startups { public class StartupManager : BoomboxController { [HarmonyPatch(typeof(GameNetworkManager), "OnEnable")] [HarmonyPostfix] public static void OnEnable_GameNetworkManager(GameNetworkManager __instance) { using StreamWriter streamWriter = new StreamWriter("BoomboxController\\logReport.txt"); streamWriter.WriteLine($"Game Version: {__instance.gameVersionNum}"); streamWriter.WriteLine($"Plugins: {Chainloader.PluginInfos.Count}"); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { if (pluginInfo.Key == "BoomboxSyncFix") { Plugin.instance.Log("Чтобы мод работал, удалите мод BoomboxSyncFix."); Plugin.instance.Log("For the mod to work, uninstall the BoomboxSyncFix mod."); Variables.blockcompatibility = true; } streamWriter.WriteLine(pluginInfo.Key + " " + pluginInfo.Value.Location); } } [HarmonyPatch(typeof(MenuManager), "OnEnable")] [HarmonyPrefix] public static void OnEnable_MenuManager() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown Variables.LastMessage = string.Empty; if ((Object)(object)Variables.quit == (Object)null) { Variables.quit = new GameObject("QuitManager").AddComponent<QuitManager>(); Object.DontDestroyOnLoad((Object)Variables.quit); } } [HarmonyPatch(typeof(StartOfRound), "OnEnable")] [HarmonyPrefix] public static void OnEnable_StartOfRound(StartOfRound __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if ((Object)(object)Variables.quits == (Object)null) { Variables.quits = new GameObject("QuitManager").AddComponent<QuitManager>(); Object.DontDestroyOnLoad((Object)Variables.quits); } } } } namespace BoomboxController.Save { public class Cache { public float Volume { get; set; } public string UpButton { get; set; } public string DownButton { get; set; } } public class SaveManager { public void SaveCache(float vol, string up, string down) { Cache cache = new Cache(); cache.Volume = vol; cache.UpButton = up; cache.DownButton = down; string value = JsonConvert.SerializeObject((object)cache); using StreamWriter streamWriter = new StreamWriter("BoomboxController\\cache"); streamWriter.WriteLine(value); } public Cache LoadCache() { string text = string.Empty; if (File.Exists("BoomboxController\\cache")) { using (StreamReader streamReader = new StreamReader("BoomboxController\\cache")) { text = streamReader.ReadToEnd(); } return JsonConvert.DeserializeObject<Cache>(text); } return null; } } } namespace BoomboxController.Multiplayer { public class MultiplayerManager : BoomboxController { [HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageServerRpc")] [HarmonyPostfix] [ServerRpc(RequireOwnership = false)] private static void AddPlayerChatMessageServerRpc_HUDManager(HUDManager __instance, string chatMessage, int playerId) { if (chatMessage.Length > 50) { ((object)__instance).GetType().GetMethod("AddPlayerChatMessageClientRpc", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[2] { chatMessage, playerId }); } } [HarmonyPatch(typeof(HUDManager), "AddPlayerChatMessageClientRpc")] [HarmonyPostfix] [ClientRpc] private static void AddPlayerChatMessageClientRpc_HUDManager(HUDManager __instance, string chatMessage, int playerId) { //IL_0060: 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) if (Plugin.config.radiuscheck.Value && IsCommand(chatMessage, new string[5] { "bhelp", "bplay", "btime", "bvolume", "btrack" }) && !(Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)__instance.playersManager.allPlayerScripts[playerId]).transform.position) < 25f)) { ((object)__instance).GetType().GetMethod("AddChatMessage", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[2] { chatMessage, __instance.playersManager.allPlayerScripts[playerId].playerUsername }); } } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] [HarmonyPrefix] private static void SubmitChat_performed_HUDManager(HUDManager __instance, ref CallbackContext context) { //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) if (Variables.LoadingMusicBoombox) { if (IsCommand(__instance.chatTextField.text, new string[5] { "bhelp", "bplay", "btime", "bvolume", "btrack" })) { __instance.chatTextField.text = string.Empty; } return; } if (!Variables.blockcompatibility && IsCommand(__instance.chatTextField.text, new string[5] { "bhelp", "bplay", "btime", "bvolume", "btrack" })) { SubmitChat(__instance); return; } if (!string.IsNullOrEmpty(__instance.chatTextField.text) && __instance.chatTextField.text.Length < 1000) { __instance.AddTextToChatOnServer(__instance.chatTextField.text, (int)__instance.localPlayer.playerClientId); } for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++) { if (StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position) > 24.4f && (!GameNetworkManager.Instance.localPlayerController.holdingWalkieTalkie || !StartOfRound.Instance.allPlayerScripts[i].holdingWalkieTalkie)) { __instance.playerCouldRecieveTextChatAnimator.SetTrigger("ping"); break; } } } public static void SubmitChat(HUDManager __instance) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(__instance.chatTextField.text) && __instance.chatTextField.text.Length < 1000) { __instance.AddTextToChatOnServer(__instance.chatTextField.text, (int)__instance.localPlayer.playerClientId); } for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++) { if (Plugin.config.radiuscheck.Value) { if (StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && (!GameNetworkManager.Instance.localPlayerController.holdingWalkieTalkie || !StartOfRound.Instance.allPlayerScripts[i].holdingWalkieTalkie)) { __instance.playerCouldRecieveTextChatAnimator.SetTrigger("ping"); break; } } else if (StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position) > 24.4f && (!GameNetworkManager.Instance.localPlayerController.holdingWalkieTalkie || !StartOfRound.Instance.allPlayerScripts[i].holdingWalkieTalkie)) { __instance.playerCouldRecieveTextChatAnimator.SetTrigger("ping"); break; } } __instance.localPlayer.isTypingChat = false; __instance.chatTextField.text = ""; EventSystem.current.SetSelectedGameObject((GameObject)null); __instance.PingHUDElement(__instance.Chat, 2f, 1f, 0.2f); ((Behaviour)__instance.typingIndicator).enabled = false; } public static bool IsCommand(string text, string[] args) { foreach (string value in args) { if (text.Contains(value)) { return true; } } return false; } public static string SelectCommand(string text, string[] args) { foreach (string text2 in args) { if (text.Contains(text2)) { return text2; } } return "None"; } [HarmonyPatch(typeof(HUDManager), "AddChatMessage")] [HarmonyPrefix] private static bool AddChatMessage_Multiplayer(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped = "") { if (IsCommand(chatMessage, Variables.multi_name)) { string text = SelectCommand(chatMessage, Variables.multi_name); string text2 = text; if (!(text2 == "SyncSong")) { if (text2 == "None") { } } else { Variables.currectTrack = int.Parse(chatMessage[1].ToString()); Variables.boomboxItem.boomboxAudio.clip = Variables.musicList.ToList()[Variables.currectTrack].Value; Variables.boomboxItem.boomboxAudio.pitch = 1f; Variables.boomboxItem.boomboxAudio.Play(); Variables.boomboxItem.isPlayingMusic = true; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = true; Variables.startMusics = false; } return false; } return true; } } } namespace BoomboxController.Options { public class OptionManager : BoomboxController { [CompilerGenerated] private static class <>O { public static UnityAction <0>__BoomboxController_onClickUp; public static UnityAction <1>__BoomboxController_onClickDown; } public static GameObject upbutton; public static GameObject downbutton; [HarmonyPatch(typeof(KepRemapPanel), "OnEnable")] [HarmonyPrefix] public static void OnEnable_KepRemapPanel(KepRemapPanel __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown ((Component)((Transform)__instance.keyRemapContainer).parent).GetComponent<RectTransform>().sizeDelta = new Vector2(0f, 900f); Cache cache = BoomboxController.saveManager.LoadCache(); GameObject val = Object.Instantiate<GameObject>(__instance.sectionTextPrefab, (Transform)(object)__instance.keyRemapContainer); val.GetComponent<RectTransform>().anchoredPosition = new Vector2(-40f, 0f - __instance.verticalOffset * 18f); ((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).text = "BOOMBOX CONTROLLER"; __instance.keySlots.Add(val); GameObject val2 = Object.Instantiate<GameObject>(__instance.keyRemapSlotPrefab, (Transform)(object)__instance.keyRemapContainer); __instance.keySlots.Add(val2); Object.Destroy((Object)(object)val2.GetComponentInChildren<SettingsOption>()); upbutton = val2; ((UnityEventBase)val2.GetComponentInChildren<Button>().onClick).RemoveAllListeners(); ButtonClickedEvent onClick = val2.GetComponentInChildren<Button>().onClick; object obj = <>O.<0>__BoomboxController_onClickUp; if (obj == null) { UnityAction val3 = BoomboxController_onClickUp; <>O.<0>__BoomboxController_onClickUp = val3; obj = (object)val3; } ((UnityEvent)onClick).AddListener((UnityAction)obj); ((TMP_Text)val2.GetComponentInChildren<TextMeshProUGUI>()).text = "Volume Up"; val2.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 0f - __instance.verticalOffset * 18f); if (cache == null) { ((TMP_Text)((Component)val2.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)Keyboard.current.pageUpKey).displayName; } else if (cache.UpButton == null && cache.DownButton == null) { ((TMP_Text)((Component)val2.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)Keyboard.current.pageUpKey).displayName; } else if (cache.UpButton == null) { ((TMP_Text)((Component)val2.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)Keyboard.current.pageUpKey).displayName; } else { KeyControl val4 = Keyboard.current.FindKeyOnCurrentKeyboardLayout(cache.UpButton); ((TMP_Text)((Component)val2.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)val4).displayName; } GameObject val5 = Object.Instantiate<GameObject>(__instance.keyRemapSlotPrefab, (Transform)(object)__instance.keyRemapContainer); __instance.keySlots.Add(val5); Object.Destroy((Object)(object)val5.GetComponentInChildren<SettingsOption>()); downbutton = val5; ((UnityEventBase)val5.GetComponentInChildren<Button>().onClick).RemoveAllListeners(); ButtonClickedEvent onClick2 = val5.GetComponentInChildren<Button>().onClick; object obj2 = <>O.<1>__BoomboxController_onClickDown; if (obj2 == null) { UnityAction val6 = BoomboxController_onClickDown; <>O.<1>__BoomboxController_onClickDown = val6; obj2 = (object)val6; } ((UnityEvent)onClick2).AddListener((UnityAction)obj2); ((TMP_Text)val5.GetComponentInChildren<TextMeshProUGUI>()).text = "Volume Down"; val5.GetComponent<RectTransform>().anchoredPosition = new Vector2(250f, 0f - __instance.verticalOffset * 18f); if (cache == null) { ((TMP_Text)((Component)val5.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)Keyboard.current.pageDownKey).displayName; return; } if (cache.UpButton == null && cache.DownButton == null) { ((TMP_Text)((Component)val5.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)Keyboard.current.pageDownKey).displayName; return; } if (cache.DownButton == null) { ((TMP_Text)((Component)val5.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)Keyboard.current.pageDownKey).displayName; return; } KeyControl val7 = Keyboard.current.FindKeyOnCurrentKeyboardLayout(cache.DownButton); ((TMP_Text)((Component)val5.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)val7).displayName; } private static async void BoomboxController_onClickUp() { Cache cache = BoomboxController.saveManager.LoadCache(); ((Behaviour)((Component)upbutton.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).enabled = false; ((Component)upbutton.transform.GetChild(3)).gameObject.SetActive(true); await Task.Run(delegate { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) bool flag = false; while (!flag) { if (((ButtonControl)Keyboard.current.anyKey).wasPressedThisFrame) { Enumerator<KeyControl> enumerator = Keyboard.current.allKeys.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyControl current = enumerator.Current; if (((ButtonControl)current).wasPressedThisFrame) { ((TMP_Text)((Component)upbutton.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)current).displayName; ((Behaviour)((Component)upbutton.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).enabled = true; ((Component)upbutton.transform.GetChild(3)).gameObject.SetActive(false); Variables.up = current; flag = true; break; } } } finally { ((IDisposable)enumerator).Dispose(); } } Thread.Sleep(5); } }); if (Variables.down == null) { if (cache != null) { BoomboxController.saveManager.SaveCache(cache.Volume, ((InputControl)Variables.up).displayName, cache.DownButton); } else { BoomboxController.saveManager.SaveCache(0.5f, ((InputControl)Variables.up).displayName, null); } } else if (cache != null) { BoomboxController.saveManager.SaveCache(cache.Volume, ((InputControl)Variables.up).displayName, ((InputControl)Variables.down).displayName); } else { BoomboxController.saveManager.SaveCache(0.5f, ((InputControl)Variables.up).displayName, ((InputControl)Variables.down).displayName); } } private static async void BoomboxController_onClickDown() { Cache cache = BoomboxController.saveManager.LoadCache(); ((Behaviour)((Component)downbutton.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).enabled = false; ((Component)downbutton.transform.GetChild(3)).gameObject.SetActive(true); await Task.Run(delegate { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) bool flag = false; while (!flag) { if (((ButtonControl)Keyboard.current.anyKey).wasPressedThisFrame) { Enumerator<KeyControl> enumerator = Keyboard.current.allKeys.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyControl current = enumerator.Current; if (((ButtonControl)current).wasPressedThisFrame) { ((TMP_Text)((Component)downbutton.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = ((InputControl)current).displayName; ((Behaviour)((Component)downbutton.transform.GetChild(2)).gameObject.GetComponentInChildren<TextMeshProUGUI>()).enabled = true; ((Component)downbutton.transform.GetChild(3)).gameObject.SetActive(false); Variables.down = current; flag = true; break; } } } finally { ((IDisposable)enumerator).Dispose(); } } Thread.Sleep(5); } }); if (Variables.up == null) { if (cache != null) { BoomboxController.saveManager.SaveCache(cache.Volume, cache.UpButton, ((InputControl)Variables.down).displayName); } else { BoomboxController.saveManager.SaveCache(0.5f, null, ((InputControl)Variables.down).displayName); } } else if (cache != null) { BoomboxController.saveManager.SaveCache(cache.Volume, ((InputControl)Variables.up).displayName, ((InputControl)Variables.down).displayName); } else { BoomboxController.saveManager.SaveCache(0.5f, ((InputControl)Variables.up).displayName, ((InputControl)Variables.down).displayName); } } } } namespace BoomboxController.Menu { public class MenuManager : BoomboxController { public static void CreateMenu() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("Canvas"); GameObject val2 = new GameObject("BoomboxMenu"); val2.AddComponent<Image>(); val2.AddComponent<RectTransform>(); val2.AddComponent<CanvasRenderer>(); val2.transform.localScale = new Vector3(5f, 2f, 1f); ((Graphic)val2.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0.18f); val2.transform.SetParent(val.transform, false); Variables.isplayList = false; } } } namespace BoomboxController.Commands { public class CommandManager : BoomboxController { [HarmonyPatch(typeof(HUDManager), "Update")] [HarmonyPrefix] private static void Update_HUDManager(HUDManager __instance) { if (File.Exists("BoomboxController\\other\\ffmpeg.exe") && File.Exists("BoomboxController\\other\\yt-dlp.exe") && Variables.LoadingLibrary) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_3.Value, "Boombox", "Boombox"); Variables.LoadingLibrary = false; } } [HarmonyPatch(typeof(HUDManager), "Start")] [HarmonyPrefix] private static void Start_HUDManager(HUDManager __instance) { __instance.chatTextField.characterLimit = 1000; } [HarmonyPatch(typeof(HUDManager), "AddChatMessage")] [HarmonyPostfix] private static void AddChatMessage_HUDManager(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped) { AddChatMessageMain(__instance, chatMessage, nameOfUserWhoTyped); } public static async void AddChatMessageMain(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped) { if (!File.Exists("BoomboxController\\other\\ffmpeg.exe") || !File.Exists("BoomboxController\\other\\yt-dlp.exe")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_1.Value, "Boombox", nameOfUserWhoTyped); Variables.LoadingLibrary = true; return; } string[] vs = chatMessage.Split(new char[1] { ' ' }); string text2 = vs[0].Replace("/", ""); string text3 = text2; string text4 = text3; if (text4 == null) { return; } switch (text4.Length) { case 5: switch (text4[1]) { case 'h': if (text4 == "bhelp") { if (Plugin.config.languages.Value.ToLower().Equals("en")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_5.Value + "\nThe creator of the mod is KoderTech.\nWith love from Russia", "Boombox", nameOfUserWhoTyped); } if (Plugin.config.languages.Value.ToLower().Equals("ru")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_5.Value + "\nСоздатель мода KoderTech.\nСпасибо что вы скачали именно этот мод)))", "Boombox", nameOfUserWhoTyped); } } break; case 'p': if (!(text4 == "bplay") || !Variables.netSwitch || vs.Length == 1) { break; } if (Uri.IsWellFormedUriString(vs[1], UriKind.Absolute)) { string url = vs[1].Remove(0, 8); switch (url.Substring(0, url.IndexOf('/'))) { case "music.youtube.com": { if (url.Remove(0, url.IndexOf('/')) == "/watch") { break; } if (vs[1].Contains("list")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox Music YouTube", nameOfUserWhoTyped); break; } Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.LoadingMusicBoombox = true; FileInfo[] files = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); if (files.Length == 1) { File.Delete("BoomboxController\\other\\" + files[0].Name); } BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_7.Value, "Boombox Music YouTube", nameOfUserWhoTyped); if (Variables.isplayList) { break; } Variables.isplayList = true; await Task.Run(delegate { bool flag = false; bool flag2 = false; Process process = new Process(); process.StartInfo.FileName = "BoomboxController\\other\\yt-dlp.exe"; process.StartInfo.UseShellExecute = false; process.StartInfo.Arguments = "-f bestaudio --extract-audio --ignore-config --audio-format mp3 --audio-quality 0 " + vs[1]; process.StartInfo.WorkingDirectory = "BoomboxController\\other"; process.StartInfo.CreateNoWindow = true; process.Start(); Variables.Id = process.Id; while (!flag) { if (flag2) { if (File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { flag = true; break; } } else { FileInfo[] files3 = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); foreach (FileInfo fileInfo in files3) { if (fileInfo.Exists) { Variables.NameTrack = fileInfo.Name; } } if (Process.GetProcessById(process.Id).HasExited) { if (!File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_11.Value, "Boombox Music YouTube", nameOfUserWhoTyped); break; } flag2 = true; } } Thread.Sleep(1000); } }); if (!File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { Variables.LoadingMusicBoombox = false; Variables.isplayList = false; break; } bool sumbBlock = false; List<string> sumbol = new List<string>(); FileInfo ext = new FileInfo("BoomboxController\\other\\" + Variables.NameTrack); string[] array4 = Variables.sumbols; foreach (string sumb in array4) { if (ext.Name.Contains(sumb)) { sumbol.Add(sumb); sumbBlock = true; } } if (sumbBlock) { string NameFile = string.Empty; foreach (string sumb2 in sumbol) { NameFile = Variables.NameTrack.Replace(sumb2, ""); ext.MoveTo("BoomboxController\\other\\" + Variables.NameTrack.Replace(sumb2, "")); } Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + NameFile, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox Music YouTube", nameOfUserWhoTyped); } else { Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + Variables.NameTrack, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox Music YouTube", nameOfUserWhoTyped); } break; } case "youtu.be": { if (url.Remove(0, url.IndexOf('/')) == "/watch") { break; } if (vs[1].Contains("list")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox Music YouTube", nameOfUserWhoTyped); break; } Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.LoadingMusicBoombox = true; FileInfo[] filesy = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); if (filesy.Length == 1) { File.Delete("BoomboxController\\other\\" + filesy[0].Name); } BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_7.Value, "Boombox YouTube", nameOfUserWhoTyped); if (Variables.isplayList) { break; } Variables.isplayList = true; await Task.Run(delegate { bool flag7 = false; bool flag8 = false; Process process5 = new Process(); process5.StartInfo.FileName = "BoomboxController\\other\\yt-dlp.exe"; process5.StartInfo.UseShellExecute = false; process5.StartInfo.Arguments = "-f bestaudio --extract-audio --ignore-config --audio-format mp3 --audio-quality 0 " + vs[1]; process5.StartInfo.WorkingDirectory = "BoomboxController\\other"; process5.StartInfo.CreateNoWindow = true; process5.Start(); Variables.Id = process5.Id; while (!flag7) { if (flag8) { if (File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { flag7 = true; break; } } else { FileInfo[] files6 = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); foreach (FileInfo fileInfo4 in files6) { if (fileInfo4.Exists) { Variables.NameTrack = fileInfo4.Name; } } if (Process.GetProcessById(process5.Id).HasExited) { if (!File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_11.Value, "Boombox YouTube", nameOfUserWhoTyped); break; } flag8 = true; } } Thread.Sleep(1000); } }); if (!File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { Variables.LoadingMusicBoombox = false; Variables.isplayList = false; break; } bool sumbBlock2 = false; List<string> sumbol2 = new List<string>(); FileInfo ext2 = new FileInfo("BoomboxController\\other\\" + Variables.NameTrack); string[] array = Variables.sumbols; foreach (string sumb3 in array) { if (ext2.Name.Contains(sumb3)) { sumbol2.Add(sumb3); sumbBlock2 = true; } } if (sumbBlock2) { string NameFile2 = string.Empty; foreach (string sumb4 in sumbol2) { NameFile2 = Variables.NameTrack.Replace(sumb4, ""); ext2.MoveTo("BoomboxController\\other\\" + Variables.NameTrack.Replace(sumb4, "")); } Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + NameFile2, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox YouTube", nameOfUserWhoTyped); } else { Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + Variables.NameTrack, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox YouTube", nameOfUserWhoTyped); } break; } case "www.youtube.com": { if (url.Remove(0, url.IndexOf('/')) == "/watch") { break; } if (vs[1].Contains("search_query")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox YouTube", nameOfUserWhoTyped); break; } if (vs[1].Contains("playlist")) { Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.LoadingMusicBoombox = true; if (File.Exists("BoomboxController\\other\\output.txt")) { File.Delete("BoomboxController\\other\\output.txt"); } FileInfo[] files2 = new DirectoryInfo("BoomboxController\\other\\playlist").GetFiles(); foreach (FileInfo track in files2) { track.Delete(); } BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_7.Value, "Boombox YouTube", nameOfUserWhoTyped); if (Variables.isplayList) { break; } Variables.isplayList = true; await Task.Run(delegate { bool flag6 = false; Process process4 = new Process(); process4.StartInfo.FileName = "BoomboxController\\other\\yt-dlp.exe"; process4.StartInfo.UseShellExecute = false; process4.StartInfo.Arguments = "-f bestaudio --extract-audio --ignore-config --audio-format mp3 --audio-quality 0 " + vs[1]; process4.StartInfo.WorkingDirectory = "BoomboxController\\other\\playlist"; process4.StartInfo.CreateNoWindow = true; process4.StartInfo.RedirectStandardOutput = true; process4.Start(); string value = process4.StandardOutput.ReadToEnd(); Variables.Id = process4.Id; while (!flag6) { if (Process.GetProcessById(process4.Id).HasExited && new DirectoryInfo("BoomboxController\\other\\playlist").GetFiles("*.webm").Length == 0) { flag6 = true; break; } Thread.Sleep(1000); } using StreamWriter streamWriter = File.CreateText("BoomboxController\\other\\output.txt"); streamWriter.WriteLine(value); }); if (new DirectoryInfo("BoomboxController\\other\\playlist").GetFiles("*.mp3").Length == 0) { Variables.LoadingMusicBoombox = false; Variables.isplayList = false; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox YouTube", nameOfUserWhoTyped); break; } using (StreamReader sr = new StreamReader("BoomboxController\\other\\output.txt")) { while (sr.Peek() >= 0) { string text = sr.ReadLine(); if (text.Contains("[download] Downloading playlist:")) { string[] vs2 = text.Split(new char[1] { ':' }); Variables.NameTrack = vs2[1]; } } } Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; await AudioManager.LoadPlaylist(__instance, nameOfUserWhoTyped); break; } if (vs[1].Contains("list")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox YouTube", nameOfUserWhoTyped); break; } Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.LoadingMusicBoombox = true; FileInfo[] file = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); if (file.Length == 1) { File.Delete("BoomboxController\\other\\" + file[0].Name); } BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_7.Value, "Boombox YouTube", nameOfUserWhoTyped); if (Variables.isplayList) { break; } Variables.isplayList = true; await Task.Run(delegate { bool flag4 = false; bool flag5 = false; Process process3 = new Process(); process3.StartInfo.FileName = "BoomboxController\\other\\yt-dlp.exe"; process3.StartInfo.UseShellExecute = false; process3.StartInfo.Arguments = "-f bestaudio --extract-audio --ignore-config --audio-format mp3 --audio-quality 0 " + vs[1]; process3.StartInfo.WorkingDirectory = "BoomboxController\\other"; process3.StartInfo.CreateNoWindow = true; process3.Start(); Variables.Id = process3.Id; while (!flag4) { if (flag5) { if (File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { flag4 = true; break; } } else { FileInfo[] files5 = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); foreach (FileInfo fileInfo3 in files5) { if (fileInfo3.Exists) { Variables.NameTrack = fileInfo3.Name; } } if (Process.GetProcessById(process3.Id).HasExited) { if (!File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_11.Value, "Boombox YouTube", nameOfUserWhoTyped); break; } flag5 = true; } } Thread.Sleep(1000); } }); if (!File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { Variables.LoadingMusicBoombox = false; Variables.isplayList = false; break; } bool sumbBlock3 = false; List<string> sumbol3 = new List<string>(); FileInfo ext3 = new FileInfo("BoomboxController\\other\\" + Variables.NameTrack); string[] array2 = Variables.sumbols; foreach (string sumb5 in array2) { if (ext3.Name.Contains(sumb5)) { sumbol3.Add(sumb5); sumbBlock3 = true; } } if (sumbBlock3) { string NameFile3 = string.Empty; foreach (string sumb6 in sumbol3) { NameFile3 = Variables.NameTrack.Replace(sumb6, ""); ext3.MoveTo("BoomboxController\\other\\" + Variables.NameTrack.Replace(sumb6, "")); } Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + NameFile3, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox YouTube", nameOfUserWhoTyped); } else { Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + Variables.NameTrack, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox YouTube", nameOfUserWhoTyped); } break; } case "soundcloud.com": { if (vs[1].Contains("sets")) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox SoundCloud", nameOfUserWhoTyped); break; } Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.LoadingMusicBoombox = true; FileInfo[] file2 = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); if (file2.Length == 1) { File.Delete("BoomboxController\\other\\" + file2[0].Name); } BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_7.Value, "Boombox SoundCloud", nameOfUserWhoTyped); if (Variables.isplayList) { break; } Variables.isplayList = true; await Task.Run(delegate { bool flag3 = false; Process process2 = new Process(); process2.StartInfo.FileName = "BoomboxController\\other\\yt-dlp.exe"; process2.StartInfo.UseShellExecute = false; process2.StartInfo.Arguments = "-f bestaudio --extract-audio --ignore-config --audio-format mp3 --audio-quality 0 " + vs[1]; process2.StartInfo.WorkingDirectory = "BoomboxController\\other"; process2.StartInfo.CreateNoWindow = true; process2.Start(); Variables.Id = process2.Id; while (!flag3) { FileInfo[] files4 = new DirectoryInfo("BoomboxController\\other").GetFiles("*.mp3"); foreach (FileInfo fileInfo2 in files4) { if (fileInfo2.Exists) { Variables.NameTrack = fileInfo2.Name; } } if (Process.GetProcessById(process2.Id).HasExited) { if (File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { flag3 = true; } else { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_11.Value, "Boombox SoundCloud", nameOfUserWhoTyped); } break; } Thread.Sleep(1000); } }); if (!File.Exists("BoomboxController\\other\\" + Variables.NameTrack)) { Variables.LoadingMusicBoombox = false; Variables.isplayList = false; break; } bool sumbBlock4 = false; List<string> sumbol4 = new List<string>(); FileInfo ext4 = new FileInfo("BoomboxController\\other\\" + Variables.NameTrack); string[] array3 = Variables.sumbols; foreach (string sumb7 in array3) { if (ext4.Name.Contains(sumb7)) { sumbol4.Add(sumb7); sumbBlock4 = true; } } if (sumbBlock4) { string NameFile4 = string.Empty; foreach (string sumb8 in sumbol4) { NameFile4 = Variables.NameTrack.Replace(sumb8, ""); ext4.MoveTo("BoomboxController\\other\\" + Variables.NameTrack.Replace(sumb8, "")); } Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + NameFile4, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox SoundCloud", nameOfUserWhoTyped); } else { Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.bom.Start(Variables.bom.GetAudioClip("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\" + Variables.NameTrack, Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox SoundCloud", nameOfUserWhoTyped); } break; } default: { int type = AudioManager.GetAudioType(vs[1].Remove(0, vs[1].Length - 3)); if (type == -1) { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox", nameOfUserWhoTyped); break; } Variables.LoadingMusicBoombox = true; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_7.Value, "Boombox", nameOfUserWhoTyped); Variables.bom.Start(Variables.bom.GetAudioClip(vs[1], Variables.boomboxItem, (AudioType)13)); BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_8.Value, "Boombox", nameOfUserWhoTyped); break; } } } else { BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_6.Value, "Boombox", nameOfUserWhoTyped); } break; case 't': { if (!(text4 == "btime") || vs.Length == 1) { break; } string[] arg = vs[1].Split(new char[1] { ':' }); switch (arg.Length) { case 2: { if (!Variables.boomboxItem.isPlayingMusic) { break; } int arg2 = Convert.ToInt32(arg[0]); int arg4 = Convert.ToInt32(arg[1]); switch (arg2) { case 0: switch (arg4) { case 0: Variables.boomboxItem.boomboxAudio.time = 0f; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", "00:00:00"), "Boombox", nameOfUserWhoTyped); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: Variables.boomboxItem.boomboxAudio.time = arg4; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", "00:00:" + arg4.ToString("00")), "Boombox", nameOfUserWhoTyped); break; } break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: { int correct = arg2 * 60; if (arg4 > 0 && arg4 < 60) { int correct_sec = correct + arg4; Variables.boomboxItem.boomboxAudio.time = correct_sec; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", "00:" + arg2.ToString("00") + ":" + arg4.ToString("00")), "Boombox", nameOfUserWhoTyped); } else { Variables.boomboxItem.boomboxAudio.time = correct; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", "00:" + arg2.ToString("00") + ":00"), "Boombox", nameOfUserWhoTyped); } break; } } break; } case 3: { if (!Variables.boomboxItem.isPlayingMusic) { break; } int arg3 = Convert.ToInt32(arg[0]); int arg5 = Convert.ToInt32(arg[1]); int arg6 = Convert.ToInt32(arg[2]); switch (arg3) { case 0: if (arg5 == 0 && arg6 == 0) { Variables.boomboxItem.boomboxAudio.time = 0f; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", "00:00:00"), "Boombox", nameOfUserWhoTyped); } else if (arg5 > 0 && arg5 < 60) { int correct2 = arg5 * 60; if (arg6 > 0 && arg6 < 60) { int correct_sec2 = correct2 + arg6; Variables.boomboxItem.boomboxAudio.time = correct_sec2; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", "00:" + arg5.ToString("00") + ":" + arg6.ToString("00")), "Boombox", nameOfUserWhoTyped); } else { Variables.boomboxItem.boomboxAudio.time = correct2; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", "00:" + arg5.ToString("00") + ":00"), "Boombox", nameOfUserWhoTyped); } } break; case 1: case 2: { int correct3 = arg3 * 3600; if (arg5 > 0 && arg5 < 60) { int correct_minutes = correct3 + arg5 * 60; if (arg6 > 0 && arg6 < 60) { int correct_sec3 = correct_minutes + arg6; Variables.boomboxItem.boomboxAudio.time = correct_sec3; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", arg3.ToString("00") + ":" + arg5.ToString("00") + ":" + arg6.ToString("00")), "Boombox", nameOfUserWhoTyped); } else { Variables.boomboxItem.boomboxAudio.time = correct_minutes; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", arg3.ToString("00") + ":" + arg5.ToString("00") + ":00"), "Boombox", nameOfUserWhoTyped); } } else { Variables.boomboxItem.boomboxAudio.time = correct3; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_12.Value.Replace("@1", arg3.ToString("00") + ":00:00"), "Boombox", nameOfUserWhoTyped); } break; } } break; } } break; } case 'l': if (text4 == "bload" && !Variables.netSwitch && Variables.isplayList) { Variables.isplayList = true; BoomboxController.DrawString(__instance, "Loading...", "Boombox", nameOfUserWhoTyped); Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; await AudioManager.LoadMusicLocal(__instance, nameOfUserWhoTyped); } break; } break; case 7: switch (text4[1]) { case 'v': if (text4 == "bvolume" && vs.Length != 1) { float volume = Variables.boomboxItem.boomboxAudio.volume; float correct_volume = (float)(Convert.ToInt32(vs[1]) / 10) * 0.1f; if (volume != correct_volume && (volume < correct_volume || volume > correct_volume)) { Variables.boomboxItem.boomboxAudio.volume = correct_volume; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_9.Value.Replace("@1", nameOfUserWhoTyped ?? "").Replace("@2", vs[1] + "%"), "Boombox", nameOfUserWhoTyped); } } break; case 's': { if (!(text4 == "bswitch") || vs.Length == 1) { break; } string text5 = vs[1]; string text6 = text5; text4 = text6; if (!(text4 == "net")) { if (text4 == "local" && !Variables.isplayList) { Variables.NameTrack = "Local-Music"; Variables.isplayList = true; BoomboxController.DrawString(__instance, "Loading...", "Boombox", nameOfUserWhoTyped); Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; await AudioManager.LoadMusicLocal(__instance, nameOfUserWhoTyped); Variables.netSwitch = false; BoomboxController.DrawString(__instance, "Local music is available!", "Boombox", nameOfUserWhoTyped); } } else { Variables.netSwitch = true; Variables.musicList = null; Variables.totalTack = 0; Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = false; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = false; Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; BoomboxController.DrawString(__instance, "The link URL is available!", "Boombox", nameOfUserWhoTyped); } break; } } break; case 6: if (text4 == "btrack" && vs.Length != 1 && Convert.ToInt32(vs[1]) > 0 && Convert.ToInt32(vs[1]) <= Variables.totalTack) { int track2 = Convert.ToInt32(vs[1]) - 1; Variables.currectTrack = track2; Variables.boomboxItem.boomboxAudio.Stop(); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.boomboxAudio.clip = Variables.musicList.ToList()[Variables.currectTrack].Value; Variables.boomboxItem.boomboxAudio.pitch = 1f; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.boomboxItem.boomboxAudio.Play(); if (Variables.startMusics) { Variables.boomboxItem.isPlayingMusic = true; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = true; Variables.startMusics = false; } Variables.currentTrackChange = true; BoomboxController.DrawString(__instance, Plugin.config.GetLang().main_14.Value.Replace("@1", vs[1] ?? ""), "Boombox", nameOfUserWhoTyped); } break; } } } } namespace BoomboxController.Boombox { public class BoomboxManager : BoomboxController { [HarmonyPatch(typeof(BoomboxItem), "Start")] [HarmonyPrefix] private static void Start_BoomboxItem(BoomboxItem __instance) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) Variables.bom = new AudioBoomBox(); Variables.vbom = new VisualBoombox(); if (Plugin.config.visual.Value) { Color color = default(Color); bool flag = ColorUtility.TryParseHtmlString(Plugin.config.body.Value, ref color); Color color2 = default(Color); bool flag2 = ColorUtility.TryParseHtmlString(Plugin.config.otherelem.Value, ref color2); if (flag) { ((Renderer)((Component)__instance).gameObject.GetComponent<MeshRenderer>()).materials[3].color = color; } if (flag2) { ((Renderer)((Component)__instance).gameObject.GetComponent<MeshRenderer>()).materials[1].color = color2; } if (File.Exists("BoomboxController\\back.jpg")) { Image val = Image.FromFile("BoomboxController\\back.jpg"); if (val.Width > val.Height && val.Width > 500) { Variables.vbom.Start(Variables.vbom.GetTexture("file:///" + Paths.GameRootPath + "\\BoomboxController\\back.jpg", __instance)); } } } __instance.boomboxAudio.volume = 0.5f; __instance.musicAudios = null; ((GrabbableObject)__instance).itemProperties.requiresBattery = Plugin.config.requstbattery.Value; Variables.boomboxItem = __instance; Cache cache = BoomboxController.saveManager.LoadCache(); if (cache != null) { __instance.boomboxAudio.volume = cache.Volume; if (cache.UpButton != null) { Variables.up = Keyboard.current.FindKeyOnCurrentKeyboardLayout(cache.UpButton); } if (cache.DownButton != null) { Variables.down = Keyboard.current.FindKeyOnCurrentKeyboardLayout(cache.DownButton); } } } [HarmonyPatch(typeof(BoomboxItem), "StartMusic")] [HarmonyPrefix] private static bool StartMusic_BoomboxItem(BoomboxItem __instance, bool startMusic, bool pitchDown, ref int ___timesPlayedWithoutTurningOff) { if (Variables.musicList != null && !Variables.LoadingMusicBoombox) { Plugin.instance.Log(startMusic + " startmusic"); if (startMusic) { if (!Variables.currentTrackChange) { Variables.currectTrack = Random.Range(0, Variables.totalTack - 1); } if (((NetworkBehaviour)__instance).IsOwner) { HUDManager.Instance.AddTextToChatOnServer($"[{Variables.currectTrack}]SyncSong", (int)HUDManager.Instance.localPlayer.playerClientId); } } else if (Variables.boomboxItem.isPlayingMusic) { Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.boomboxAudio.PlayOneShot(Variables.boomboxItem.stopAudios[Random.Range(0, Variables.boomboxItem.stopAudios.Length)]); Variables.timesPlayedWithoutTurningOff = 0; Variables.boomboxItem.isPlayingMusic = startMusic; ((GrabbableObject)Variables.boomboxItem).isBeingUsed = startMusic; Variables.startMusics = true; Variables.currentTrackChange = false; } } return false; } [HarmonyPatch(typeof(BoomboxItem), "Update")] [HarmonyPrefix] private static void Update_BoomboxItem(BoomboxItem __instance, ref int ___timesPlayedWithoutTurningOff) { if (Variables.timesPlayedWithoutTurningOff <= 0) { ___timesPlayedWithoutTurningOff = 0; } Variables.timesPlayedWithoutTurningOff = ___timesPlayedWithoutTurningOff; if (Variables.musicList != null) { Variables.totalTack = Variables.musicList.Count; } if (Variables.boomboxItem.isPlayingMusic) { Variables.curretTime = Variables.boomboxItem.boomboxAudio.time; Variables.totalTime = Variables.boomboxItem.boomboxAudio.clip.length; if (Variables.currectTrack + 1 != Variables.totalTack) { if (Math.Floor(Variables.curretTime) == Math.Floor(Variables.totalTime)) { Variables.boomboxItem.boomboxAudio.Stop(); Variables.boomboxItem.isPlayingMusic = false; Variables.waitAutoNext = true; } } else if (Variables.totalTack == 1) { if (Math.Floor(Variables.curretTime) == Math.Floor(Variables.totalTime)) { Variables.boomboxItem.boomboxAudio.time = 0f; } } else if (Math.Floor(Variables.curretTime) == Math.Floor(Variables.totalTime) - 1.0) { Variables.boomboxItem.boomboxAudio.Stop(); Variables.currectTrack = 0; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.boomboxItem.boomboxAudio.clip = Variables.musicList.ToList()[Variables.currectTrack].Value; Variables.boomboxItem.boomboxAudio.Play(); } } else if (Variables.musicList != null && Variables.waitAutoNext) { Variables.currectTrack++; Plugin.instance.Log($"Position track: {Variables.currectTrack}"); Variables.boomboxItem.boomboxAudio.clip = Variables.musicList.ToList()[Variables.currectTrack].Value; Variables.boomboxItem.boomboxAudio.time = 0f; Variables.boomboxItem.isPlayingMusic = true; Variables.waitAutoNext = false; Variables.boomboxItem.boomboxAudio.Play(); } } [HarmonyPatch(typeof(BoomboxItem), "PocketItem")] [HarmonyPrefix] private static bool PocketItem_BoomboxItem(BoomboxItem __instance) { if (Plugin.config.pocketitem.Value) { GrabbableObject component = ((Component)__instance).GetComponent<GrabbableObject>(); if ((Object)(object)component != (Object)null) { component.EnableItemMeshes(false); } } else { GrabbableObject component2 = ((Component)__instance).GetComponent<GrabbableObject>(); if ((Object)(object)component2 != (Object)null) { if (((NetworkBehaviour)component2).IsOwner && (Object)(object)component2.playerHeldBy != (Object)null) { component2.playerHeldBy.IsInspectingItem = false; } component2.isPocketed = true; component2.EnableItemMeshes(false); ((Component)__instance).gameObject.GetComponent<AudioSource>().PlayOneShot(component2.itemProperties.pocketSFX, 1f); } MethodInfo method = ((object)__instance).GetType().GetMethod("StartMusic", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(__instance, new object[2] { false, false }); } return false; } } } namespace BoomboxController.Audio { public class AudioBoomBox : MonoBehaviour { private static AudioBoomBox _instance; public Dictionary<string, AudioClip> audioclips = new Dictionary<string, AudioClip>(); public Dictionary<string, AudioClip> audioclipsplay = new Dictionary<string, AudioClip>(); public Coroutine Start(IEnumerator routine) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { _instance = new GameObject("AudioBoomBox").AddComponent<AudioBoomBox>(); Object.DontDestroyOnLoad((Object)_instance); } return ((MonoBehaviour)_instance).StartCoroutine(routine); } public IEnumerator GetAudioClip(string url, BoomboxItem boombox, AudioType type) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) audioclips.Clear(); UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, type); try { yield return www.SendWebRequest(); if ((int)www.result == 2) { Variables.LoadingMusicBoombox = false; Plugin.instance.Log(www.error); Variables.isplayList = false; } else { AudioClip myClip = DownloadHandlerAudioClip.GetContent(www); audioclips.Add(new FileInfo(url.Replace("file:///", "")).Name, myClip); Variables.musicList = audioclips; Variables.LoadingMusicBoombox = false; Variables.isplayList = false; } } finally { ((IDisposable)www)?.Dispose(); } } public async Task GetPlayList(string url, BoomboxItem boombox, AudioType type) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Plugin.instance.Log(url); UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, type); try { UnityWebRequestAsyncOperation content = www.SendWebRequest(); while (!((AsyncOperation)content).isDone) { await Task.Delay(100); } if ((int)www.result == 2) { Plugin.instance.Log(www.error); return; } AudioClip myClip = DownloadHandlerAudioClip.GetContent(www); audioclipsplay.Add(new FileInfo(url.Replace("file:///", "")).Name, myClip); } finally { ((IDisposable)www)?.Dispose(); } } } public class AudioManager : BoomboxController { public static int GetAudioType(string ext) { if (ext == "mp3") { return 13; } return -1; } public static async Task LoadMusicLocal(HUDManager __instance, string nameOfUserWhoTyped) { await Task.Run(async delegate { List<FileInfo> files = new List<FileInfo>(); List<FileInfo> dependMusic = await Dependants_LocalMusic(); FileInfo[] track = new DirectoryInfo("BoomboxController\\other\\local").GetFiles(); FileInfo[] array = track; foreach (FileInfo t in array) { string[] array2 = Variables.sumbols; foreach (string f in array2) { if (t.Exists && t.Name.Contains(f)) { t.MoveTo("BoomboxController\\other\\local\\" + t.Name.Replace(f.ToString(), "")); } } } files.AddRange(dependMusic); files.AddRange(track); foreach (FileInfo file in files) { await Variables.bom.GetPlayList("file:///" + file.FullName, Variables.boomboxItem, (AudioType)13); } if (track.Length != 0) { Variables.musicList = Variables.bom.audioclipsplay.ToDictionary((KeyValuePair<string, AudioClip> x) => x.Key, (KeyValuePair<string, AudioClip> y) => y.Value); Variables.bom.audioclipsplay.Clear(); } Variables.isplayList = false; Variables.LoadingMusicBoombox = false; BoomboxController.DrawString(__instance, "Tracks Loading", "Boombox", nameOfUserWhoTyped); }); } public static Task<List<FileInfo>> Dependants_LocalMusic() { List<FileInfo> list = new List<FileInfo>(); string location = Chainloader.PluginInfos.ToArray()[0].Value.Location; string text = location.Substring(0, location.IndexOf("plugins")); DirectoryInfo[] directories = new DirectoryInfo(text + "\\plugins").GetDirectories(); DirectoryInfo[] array = directories; foreach (DirectoryInfo directoryInfo in array) { DirectoryInfo[] directories2 = directoryInfo.GetDirectories(); foreach (DirectoryInfo directoryInfo2 in directories2) { if (directoryInfo2.Name.Contains("BoomboxMusic")) { FileInfo[] files = directoryInfo2.GetFiles("*.mp3"); foreach (FileInfo item in files) { list.Add(item); } } } } foreach (FileInfo item2 in list) { string[] array2 = Variables.sumbols; foreach (string text2 in array2) { if (item2.Name.Contains(text2)) { item2.MoveTo(item2.FullName.Replace(item2.Name.ToString(), "") + "\\" + item2.Name.Replace(text2.ToString(), "")); } } } return Task.FromResult(list); } public static async Task LoadPlaylist(HUDManager __instance, string nameOfUserWhoTyped) { await Task.Run(async delegate { FileInfo[] track = new DirectoryInfo("BoomboxController\\other\\playlist").GetFiles(); FileInfo[] array = track; foreach (FileInfo t in array) { string[] array2 = Variables.sumbols; foreach (string f in array2) { if (t.Exists && t.Name.Contains(f)) { t.MoveTo("BoomboxController\\other\\playlist\\" + t.Name.Replace(f, "")); } } } FileInfo[] array3 = track; foreach (FileInfo file in array3) { await Variables.bom.GetPlayList("file:///" + Paths.GameRootPath + "\\BoomboxController\\other\\playlist\\" + file.Name, Variables.boomboxItem, (AudioType)13); } Variables.musicList = Variables.bom.audioclipsplay.ToDictionary((KeyValuePair<string, AudioClip> x) => x.Key, (KeyValuePair<