Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TheFunnyBox v1.2.0
PersonalBoombox.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using PersonalBoombox.Patches; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; 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: AssemblyTitle("PersonalBoombox")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PersonalBoombox")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("90672a7b-b084-4f8d-9d78-46affb7b97e7")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace PersonalBoombox { public static class Assets { [Serializable] private class PBDataJson { public string name; public string description; public int price; public float volume; public int red; public int blue; public int green; public Color color; public string feedback; public static PBDataJson GetData(string path) { if (File.Exists(path)) { try { string json = File.ReadAllText(path); PBDataJson pBDataJson = CreateFromJson(json); pBDataJson.FillMissingValues(); pBDataJson.AdjustValues(); pBDataJson.feedback = "Loaded data.json file"; return pBDataJson; } catch { return GetDefault("Error reading data.json file".CreateError()); } } return GetDefault("Missing data.json file".CreateWarning()); } public static PBDataJson GetDefault(string feedback) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) PBDataJson pBDataJson = new PBDataJson(); pBDataJson.feedback = feedback; pBDataJson.name = "Untitled"; pBDataJson.description = "Missing Description"; pBDataJson.price = 60; pBDataJson.volume = 0.5f; pBDataJson.red = 255; pBDataJson.blue = 255; pBDataJson.green = 255; pBDataJson.color = Color.white; return pBDataJson; } private void FillMissingValues() { if (string.IsNullOrWhiteSpace(name)) { name = "Untitled"; } if (string.IsNullOrWhiteSpace(description)) { description = "Missing Description"; } } private void AdjustValues() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) int length = Mathf.Min(name.Length, 20); name = name.Substring(0, length); price = Mathf.Clamp(price, 0, 1000); volume = Mathf.Clamp(volume, 0f, PersonalBoomboxPlugin.Instance.maxVolumeValue); red = Mathf.Clamp(red, 0, 255); blue = Mathf.Clamp(blue, 0, 255); green = Mathf.Clamp(green, 0, 255); color = new Color((float)red / 255f, (float)green / 255f, (float)blue / 255f, 1f); } private static PBDataJson CreateFromJson(string json) { return JsonUtility.FromJson<PBDataJson>(json); } public string ToJson() { return JsonUtility.ToJson((object)this); } } private const string mainAssetBundleName = "personalboombox"; public const int prefabCopyCount = 10; public static AssetBundle MainAssetBundle = null; public static GameObject originalPrefab; public static GameObject[] prefabCopies; public static GameObject canvasPrefab; public static Texture2D boomboxTexture; public static int LimitExceedCounter = 0; private static readonly string[] musicExts = new string[1] { "mp3" }; private static ManualLogSource logger => PersonalBoomboxPlugin.Instance.logger; private static string GetAssemblyName() { return Assembly.GetExecutingAssembly().FullName.Split(new char[1] { ',' })[0]; } public static void LoadAssetBundle() { if ((Object)(object)MainAssetBundle == (Object)null) { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + ".personalboombox"); MainAssetBundle = AssetBundle.LoadFromStream(stream); } originalPrefab = Assets.Load<GameObject>("prefab"); prefabCopies = (GameObject[])(object)new GameObject[10]; for (int i = 0; i < 10; i++) { GameObject val = Assets.Load<GameObject>($"prefab{i + 1}"); val.AddComponent<PersonalBoomboxItem>(); prefabCopies[i] = val; } canvasPrefab = Assets.Load<GameObject>("debugCanvas"); boomboxTexture = Assets.Load<Texture2D>("BoomboxIcon"); } public static T Load<T>(string name) where T : Object { if ((Object)(object)MainAssetBundle == (Object)null) { logger.LogError((object)"Trying to load in asset but asset bundle is missing"); return default(T); } logger.LogInfo((object)("Loading asset " + name)); return MainAssetBundle.LoadAsset<T>(name); } public static void LoadMusicFolders() { List<PersonalBoomboxPlugin.RequestData> requests = PersonalBoomboxPlugin.requests; List<PersonalBoomboxPlugin.PBData> list = new List<PersonalBoomboxPlugin.PBData>(); int num = 0; foreach (PersonalBoomboxPlugin.RequestData item in requests) { string path = item.path; string[] directories = Directory.GetDirectories(path); string[] array = directories; foreach (string directory in array) { logger.LogInfo((object)("Reading from " + path + "!")); try { CreateFromDirectory(directory, list, num++, item); } catch (Exception ex) { logger.LogError((object)("Error loading at " + path)); logger.LogError((object)ex.ToString()); } } } list.Sort((PersonalBoomboxPlugin.PBData first, PersonalBoomboxPlugin.PBData second) => first.name.CompareTo(second.name)); num = 0; foreach (PersonalBoomboxPlugin.PBData item2 in list) { char c = (char)(65 + num); item2.prefixName = $"pb{c}"; item2.boomboxName = item2.prefixName + " " + item2.name; ((Object)item2.prefab).name = item2.boomboxName; num++; } PersonalBoomboxPlugin.data = list; } private static void CreateFromDirectory(string directory, List<PersonalBoomboxPlugin.PBData> data, int index, PersonalBoomboxPlugin.RequestData request) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (index >= 10) { logger.LogWarning((object)$"Loading too many boomboxes. There is a limit of {10}"); LimitExceedCounter++; return; } string path = Path.Combine(directory, "data.json"); IEnumerable<string> enumerable = from file in Directory.EnumerateFiles(directory, "*.*") where musicExts.Any((string x) => file.EndsWith(x, StringComparison.InvariantCultureIgnoreCase)) select file; string path2 = Path.Combine(directory, "decal.png"); PBDataJson data2 = PBDataJson.GetData(path); char c = (char)(97 + index); PersonalBoomboxPlugin.PBData pBData = new PersonalBoomboxPlugin.PBData(); pBData.request = request; pBData.feedback = new PersonalBoomboxPlugin.PBData.Feedback(); pBData.feedback.AddToMain(data2.feedback); pBData.name = data2.name; pBData.description = data2.description; pBData.price = data2.price; pBData.volume = data2.volume; pBData.prefab = prefabCopies[index]; pBData.script = pBData.prefab.GetComponent<PersonalBoomboxItem>(); pBData.script.musicAudios = new List<AudioClip>(); pBData.color = data2.color; List<Coroutine> list = new List<Coroutine>(); foreach (string item3 in enumerable) { Coroutine item = MyOwnCoroutine.AddCoroutine(LoadAudioClip(pBData, item3)); list.Add(item); } if (File.Exists(path2)) { Coroutine item2 = MyOwnCoroutine.AddCoroutine(LoadTexture2D(pBData, path2)); list.Add(item2); } else { pBData.feedback.AddToMain("Missing decal.png"); } MyOwnCoroutine.AddCoroutine(WaitForDownloads(pBData, list)); data.Add(pBData); } private static IEnumerator WaitForDownloads(PersonalBoomboxPlugin.PBData data, List<Coroutine> coroutines) { yield return null; int i = 0; foreach (Coroutine coroutine in coroutines) { yield return coroutine; i++; } PersonalBoomboxItem script = data.script; int count = script.musicAudios.Count; script.SortAudioClips(); script.finishedLoading = true; logger.LogInfo((object)$"{data.boomboxName} is fully set up with {count} songs!"); if (count == 0) { logger.LogWarning((object)"Boomboxes with 0 songs will be skipped in the initialization process"); } } private static IEnumerator LoadTexture2D(PersonalBoomboxPlugin.PBData data, string path) { UnityWebRequest loader = UnityWebRequestTexture.GetTexture(path); loader.SendWebRequest(); while (!loader.isDone) { yield return null; } if (loader.error != null) { string errorString2 = "Error loading decal.png. Download failed"; logger.LogError((object)errorString2); logger.LogError((object)loader.error); data.feedback.AddToMain(errorString2.CreateError()); yield break; } Texture2D texture = DownloadHandlerTexture.GetContent(loader); if ((Object)(object)texture == (Object)null) { string errorString = "Error loading decal.png. File is weird"; data.feedback.AddToMain(errorString.CreateError()); logger.LogError((object)errorString); } else { ((Texture)texture).filterMode = (FilterMode)0; data.decal = texture; string loadString = "Loaded decal.png"; logger.LogInfo((object)loadString); data.feedback.AddToMain(loadString); } } private static IEnumerator LoadAudioClip(PersonalBoomboxPlugin.PBData data, string path) { string fileName = Path.GetFileName(path); AudioType fileType = GetAudioType(path); if ((int)fileType == 0) { string errorString3 = "Error loading " + fileName + ". Unsupported file ext."; logger.LogError((object)errorString3); data.feedback.AddToSongs(errorString3.CreateError()); yield break; } UnityWebRequest loader = UnityWebRequestMultimedia.GetAudioClip(path, GetAudioType(path)); DownloadHandler downloadHandler = loader.downloadHandler; DownloadHandlerAudioClip handler = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null); handler.streamAudio = true; yield return loader.SendWebRequest(); while (!loader.isDone) { yield return null; } if (loader.error != null) { string errorString2 = "Error loading " + fileName + ". Download failed"; logger.LogError((object)errorString2); logger.LogError((object)loader.error); data.feedback.AddToSongs(errorString2.CreateError()); yield break; } AudioClip clip = DownloadHandlerAudioClip.GetContent(loader); if ((Object)(object)clip == (Object)null || (int)clip.loadState != 2) { string errorString = "Error loading " + fileName + ". File is weird"; logger.LogError((object)errorString); data.feedback.AddToSongs(errorString.CreateError()); } else { data.script.AddAudioClip(clip); string loadString = "Loaded " + fileName; logger.LogInfo((object)loadString); data.feedback.AddToSongs(loadString); } } public static AudioType GetAudioType(string path) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) string text = Path.GetExtension(path).ToLowerInvariant(); string text2 = text; if (text2 == ".mp3") { return (AudioType)13; } return (AudioType)0; } } public class PersonalBoomboxItem : GrabbableObject { public AudioSource boomboxAudio; public List<AudioClip> musicAudios; public bool finishedLoading; public AudioClip[] stopAudios; public Random musicRandomizer; private StartOfRound playersManager; private RoundManager roundManager; public bool isPlayingMusic; private float noiseInterval; private int timesPlayedWithoutTurningOff; public int pbIndex; public int AudioClipCount => (musicAudios != null) ? musicAudios.Count : 0; public void AddAudioClip(AudioClip clip) { musicAudios.Add(clip); } public void SortAudioClips() { musicAudios.Sort((AudioClip first, AudioClip second) => ((Object)first).name.CompareTo(((Object)second).name)); } public override void Start() { ((GrabbableObject)this).Start(); playersManager = Object.FindObjectOfType<StartOfRound>(); roundManager = Object.FindObjectOfType<RoundManager>(); musicRandomizer = new Random(playersManager.randomMapSeed - 10); } public override void ItemActivate(bool used, bool buttonDown = true) { ((GrabbableObject)this).ItemActivate(used, buttonDown); StartMusic(used); } private void StartMusic(bool startMusic, bool pitchDown = false) { if (startMusic && musicAudios.Count > 0) { boomboxAudio.clip = musicAudios[musicRandomizer.Next(0, musicAudios.Count)]; boomboxAudio.pitch = 1f; boomboxAudio.Play(); } else if (isPlayingMusic) { if (pitchDown) { ((MonoBehaviour)this).StartCoroutine(musicPitchDown()); } else { boomboxAudio.Stop(); boomboxAudio.PlayOneShot(stopAudios[Random.Range(0, stopAudios.Length)]); } timesPlayedWithoutTurningOff = 0; } base.isBeingUsed = startMusic; isPlayingMusic = startMusic; } private IEnumerator musicPitchDown() { for (int i = 0; i < 30; i++) { yield return null; AudioSource obj = boomboxAudio; obj.pitch -= 0.033f; if (boomboxAudio.pitch <= 0f) { break; } } boomboxAudio.Stop(); boomboxAudio.PlayOneShot(stopAudios[Random.Range(0, stopAudios.Length)]); } public override void UseUpBatteries() { ((GrabbableObject)this).UseUpBatteries(); StartMusic(startMusic: false, pitchDown: true); } public override void PocketItem() { ((GrabbableObject)this).PocketItem(); StartMusic(startMusic: false); } public override void Update() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) ((GrabbableObject)this).Update(); if (isPlayingMusic) { if (noiseInterval <= 0f) { noiseInterval = 1f; timesPlayedWithoutTurningOff++; roundManager.PlayAudibleNoise(((Component)this).transform.position, 16f, 0.9f, timesPlayedWithoutTurningOff, false, 5); } else { noiseInterval -= Time.deltaTime; } if (base.insertedBattery.charge < 0.05f) { boomboxAudio.pitch = 1f - (0.05f - base.insertedBattery.charge) * 4f; } } } protected override void __initializeVariables() { ((GrabbableObject)this).__initializeVariables(); } protected override string __getTypeName() { return "TouhouBoomboxItem"; } } [BepInPlugin("ImoutoSama.PersonalBoombox", "Personal Boombox", "1.2.0")] [BepInProcess("Lethal Company.exe")] public class PersonalBoomboxPlugin : BaseUnityPlugin { public class PBData { public class Feedback { private List<string> main; private List<string> songs; public Feedback() { main = new List<string>(); songs = new List<string>(); } public void AddToMain(string text) { main.Add(text); } public void AddToSongs(string text) { songs.Add(text); } public string GetReport() { string text = string.Empty; foreach (string item in main) { text = text + item + "\n"; } if (songs.Count == 0) { text += "\nFound 0 songs\n".CreateWarning(); } else { text += $"\nFound {songs.Count} songs\n"; foreach (string song in songs) { text = text + song + "\n"; } } return text; } } public RequestData request; public Feedback feedback; public string name; public string prefixName; public string boomboxName; public string description; public int price; public float volume; public Color color; public GameObject prefab; public PersonalBoomboxItem script; public Texture2D decal; public Item item; public int itemIndex; public bool addedToTerminalKeyword; public bool IsFinished => Object.op_Implicit((Object)(object)script) && script.finishedLoading; public bool IsValid => Object.op_Implicit((Object)(object)script) && script.AudioClipCount > 0; public int GetPrice => request.overridePriceFlag ? request.overridePriceValue : price; public string GetReport() { return "<b>[" + prefixName + "] " + name + "</b>\n" + feedback.GetReport(); } } public class RequestData { public string path; public bool overridePriceFlag; public int overridePriceValue; public RequestData(string path) { this.path = path; overridePriceFlag = false; overridePriceValue = 0; } public RequestData(string path, bool overridePrice, int overridePriceValue) { this.path = path; overridePriceFlag = overridePrice; this.overridePriceValue = overridePriceValue; } } private const string modGUID = "ImoutoSama.PersonalBoombox"; private const string modName = "Personal Boombox"; private const string modVersion = "1.2.0"; private readonly Harmony harmony = new Harmony("ImoutoSama.PersonalBoombox"); internal ManualLogSource logger; public static List<PBData> data; public static List<RequestData> requests; public ConfigEntry<int> maxVolumeConfig; public float maxVolumeValue; public static PersonalBoomboxPlugin Instance { get; private set; } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } logger = Logger.CreateLogSource("ImoutoSama.PersonalBoombox"); logger.LogInfo((object)"Plugin Personal Boombox has been added!"); maxVolumeConfig = ConfigBindClamp("General", "Max Volume", 100, "Max possible volume value. From 0 to 100.", 0, 100); maxVolumeValue = (float)maxVolumeConfig.Value * 0.01f; harmony.PatchAll(typeof(TerminalPatch)); harmony.PatchAll(typeof(StartOfRoundPatch)); harmony.PatchAll(typeof(GameNetworkManagerPatch)); harmony.PatchAll(typeof(MenuManagerPatch)); data = new List<PBData>(); requests = new List<RequestData>(); Assets.LoadAssetBundle(); AddDirectory(GetLazyPath()); } public string GetLazyPath() { string text = Path.Combine(Paths.PluginPath, "Your Own Personal Boomboxes"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); Instance.logger.LogInfo((object)"Creaing 'Your Own Personal Boomboxes' folder in the plugin directory"); CopyExampleZIP(text); } return text; } public void CopyExampleZIP(string targetPath) { string location = Assembly.GetExecutingAssembly().Location; string directoryName = Path.GetDirectoryName(location); string text = Path.Combine(directoryName, "EXAMPLE.zip"); if (!File.Exists(text)) { Instance.logger.LogError((object)"Tried to copy over EXAMPLE.zip file but could not find it"); return; } string destFileName = Path.Combine(targetPath, "EXAMPLE.zip"); File.Copy(text, destFileName); } public ConfigEntry<int> ConfigBindClamp(string section, string key, int defaultValue, string description, int min, int max) { ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>(section, key, defaultValue, description); val.Value = Mathf.Clamp(val.Value, min, max); return val; } public static bool ContainsPath(string path) { foreach (RequestData request in requests) { if (request.path == path) { return true; } } return false; } public static RequestData AddFromAssemblyDll(string dllPath) { string directoryName = Path.GetDirectoryName(dllPath); return AddDirectory(directoryName); } public static RequestData AddDirectory(string path) { if (ContainsPath(path)) { Instance.logger.LogWarning((object)("Trying to add boombox data path that's already been added: " + path)); return null; } Instance.logger.LogInfo((object)("Adding path to read boombox data from: " + path)); RequestData requestData = new RequestData(path); requests.Add(requestData); return requestData; } public static string GetLoadReport() { if (data == null) { return string.Empty; } string text = string.Empty; string text2 = new string('-', 60) + "\n"; foreach (PBData datum in data) { text += datum.GetReport(); text += text2; } if (Utility.IsNullOrWhiteSpace(text)) { text = "No boomboxes were loaded\n"; } int limitExceedCounter = Assets.LimitExceedCounter; if (limitExceedCounter > 0) { text += $"Ignored {limitExceedCounter} boomboxes as they exceed the limit of {10}\n".CreateWarning(); } return text; } } public static class StringUtilities { public static string CreateWarning(this string text) { return "<color=yellow>" + text + "</color>"; } public static string CreateError(this string text) { return "<color=red>" + text + "</color>"; } } public class MyOwnCoroutine : MonoBehaviour { private static MyOwnCoroutine _Instance; public static MyOwnCoroutine Instance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_Instance == (Object)null) { GameObject val = new GameObject("My Own Coroutine"); _Instance = val.AddComponent<MyOwnCoroutine>(); Object.DontDestroyOnLoad((Object)(object)val); } return _Instance; } } public static Coroutine AddCoroutine(IEnumerator c) { return ((MonoBehaviour)Instance).StartCoroutine(c); } } } namespace PersonalBoombox.Patches { [HarmonyPatch(typeof(GameNetworkManager))] internal class GameNetworkManagerPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void StartPatch(ref GameNetworkManager __instance) { PersonalBoomboxPlugin.Instance.logger.LogInfo((object)"Adding personal boomboxes to network list"); NetworkManager component = ((Component)__instance).GetComponent<NetworkManager>(); GameObject[] prefabCopies = Assets.prefabCopies; foreach (GameObject val in prefabCopies) { component.AddNetworkPrefab(val); } } } [HarmonyPatch(typeof(MenuManager))] internal class MenuManagerPatch { public static bool done; public static GameObject textMeshGameObj; public static TextMeshProUGUI textMesh; [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePatch(ref MenuManager __instance) { AddReportDisplay(ref __instance); if (!done) { done = true; Assets.LoadMusicFolders(); } } private static void AddReportDisplay(ref MenuManager __instance) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown try { Transform parent = ((Component)__instance).transform.parent; Transform val = parent.Find("MenuContainer").Find("MainButtons"); GameObject val2 = Object.Instantiate<GameObject>(Assets.canvasPrefab); Button component = ((Component)val2.transform.Find("Button")).GetComponent<Button>(); ((UnityEventBase)component.onClick).RemoveAllListeners(); ((UnityEvent)component.onClick).AddListener(new UnityAction(ToggleReportDisplay)); textMeshGameObj = ((Component)val2.transform.Find("Scroll View")).gameObject; TextMeshProUGUI component2 = ((Component)val2.transform.Find("Scroll View/Viewport/Content")).GetComponent<TextMeshProUGUI>(); textMesh = component2; } catch { } } private static void ToggleReportDisplay() { if (!textMeshGameObj.activeSelf) { ((TMP_Text)textMesh).text = PersonalBoomboxPlugin.GetLoadReport(); textMeshGameObj.SetActive(true); } else { textMeshGameObj.SetActive(false); } } private static void PrintTransforms(Transform parent, int counter) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown string text = new string(' ', counter); Canvas component = ((Component)parent).GetComponent<Canvas>(); string text2 = (Object.op_Implicit((Object)(object)component) ? $" ({component.sortingOrder})" : string.Empty); PersonalBoomboxPlugin.Instance.logger.LogInfo((object)(text + ((Object)parent).name + text2)); foreach (Transform item in parent) { Transform parent2 = item; PrintTransforms(parent2, counter + 1); } } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRoundPatch { public static bool done; [HarmonyPatch("Start")] [HarmonyPrefix] public static void StartPatch(ref StartOfRound __instance) { if (done) { return; } done = true; PersonalBoomboxPlugin.Instance.logger.LogInfo((object)"Adding personal boomboxes to items list"); foreach (PersonalBoomboxPlugin.PBData datum in PersonalBoomboxPlugin.data) { bool isFinished = datum.IsFinished; bool isValid = datum.IsValid; if (datum.IsFinished && datum.IsValid) { __instance.allItemsList.itemsList.Add(datum.item); } } } } [HarmonyPatch(typeof(Terminal))] internal class TerminalPatch { public static Item boomboxItem; public static GameObject boomboxPrefab; public static MeshFilter boomboxMeshFilter; public static MeshRenderer boomboxMeshRenderer; public static AudioSource boomboxAudioSource; public static BoomboxItem boomboxScript; public static Texture2D boomboxTexture1; public static Texture2D boomboxTexture3; public static TerminalKeyword buyKeyword; public static TerminalKeyword infoKeyword; public static CompatibleNoun buyNoun; public static CompatibleNoun infoNoun; [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePatch(ref Terminal __instance) { foreach (PersonalBoomboxPlugin.PBData datum in PersonalBoomboxPlugin.data) { bool isFinished = datum.IsFinished; bool isValid = datum.IsValid; if (datum.IsFinished && datum.IsValid) { AddToTerminal(ref __instance, datum); continue; } if (!datum.IsFinished) { PersonalBoomboxPlugin.Instance.logger.LogError((object)(datum.boomboxName + " has no script initialized or it is not done loading music")); } if (!datum.IsValid) { PersonalBoomboxPlugin.Instance.logger.LogError((object)(datum.boomboxName + " has no script initialized or it has no loaded music")); } } } private static void AddToTerminal(ref Terminal __instance, PersonalBoomboxPlugin.PBData data) { PersonalBoomboxPlugin.Instance.logger.LogInfo((object)("Adding " + data.boomboxName + " to terminal")); if ((Object)(object)data.item == (Object)null) { SetupPrefab(ref __instance, data); } List<Item> list = __instance.buyableItemsList.ToList(); data.itemIndex = list.Count; list.Add(data.item); __instance.buyableItemsList = list.ToArray(); if (!data.addedToTerminalKeyword) { AddToTerminalKeywords(ref __instance, data); data.addedToTerminalKeyword = true; } } private static void SetupPrefab(ref Terminal __instance, PersonalBoomboxPlugin.PBData data) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Expected O, but got Unknown if ((Object)(object)boomboxItem == (Object)null) { InitializePrefab(ref __instance); } Item val = Object.Instantiate<Item>(boomboxItem); GameObject prefab = data.prefab; PersonalBoomboxItem script = data.script; val.creditsWorth = data.GetPrice; val.spawnPrefab = prefab; val.itemName = data.boomboxName; val.itemIcon = CreateSprite(val.itemIcon, data.color); data.item = val; prefab.tag = boomboxPrefab.tag; prefab.layer = boomboxPrefab.layer; MeshFilter component = prefab.GetComponent<MeshFilter>(); component.mesh = boomboxMeshFilter.mesh; MeshRenderer component2 = prefab.GetComponent<MeshRenderer>(); ((Renderer)component2).materials = ((Renderer)boomboxMeshRenderer).materials; ((Renderer)component2).materials[3].color = data.color; ((Renderer)component2).materials[1].color = DarkenColor(data.color); AudioSource component3 = prefab.GetComponent<AudioSource>(); component3.volume = data.volume; component3.outputAudioMixerGroup = boomboxAudioSource.outputAudioMixerGroup; component3.SetCustomCurve((AudioSourceCurveType)0, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)0)); component3.SetCustomCurve((AudioSourceCurveType)1, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)1)); component3.SetCustomCurve((AudioSourceCurveType)3, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)3)); component3.SetCustomCurve((AudioSourceCurveType)2, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)2)); if (Object.op_Implicit((Object)(object)data.decal)) { GameObject gameObject = ((Component)prefab.transform.GetChild(0)).gameObject; MeshRenderer component4 = gameObject.GetComponent<MeshRenderer>(); Material material = ((Renderer)component4).material; material.mainTexture = (Texture)(object)data.decal; ((Renderer)component4).material = material; gameObject.SetActive(true); } ((GrabbableObject)script).grabbable = true; ((GrabbableObject)script).isInFactory = true; ((GrabbableObject)script).grabbableToEnemies = true; ((GrabbableObject)script).propColliders = ((Component)script).GetComponents<Collider>(); ((GrabbableObject)script).mainObjectRenderer = component2; script.boomboxAudio = component3; script.stopAudios = boomboxScript.stopAudios; ((GrabbableObject)script).insertedBattery = new Battery(false, ((GrabbableObject)boomboxScript).insertedBattery.charge); ((GrabbableObject)script).itemProperties = val; static Color DarkenColor(Color c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) return new Color(c.r * 0.9f, c.g * 0.9f, c.b * 0.9f, 1f); } } private static void InitializePrefab(ref Terminal __instance) { List<Item> list = __instance.buyableItemsList.ToList(); int num = -1; for (int i = 0; i < list.Count; i++) { Item val = list[i]; if (val.itemName.ToLowerInvariant() == "boombox") { num = i; break; } } if (num == -1) { PersonalBoomboxPlugin.Instance.logger.LogError((object)"Items has no boomerbox item to copy from"); return; } boomboxItem = list[num]; boomboxPrefab = boomboxItem.spawnPrefab; boomboxMeshFilter = boomboxPrefab.GetComponent<MeshFilter>(); boomboxMeshRenderer = boomboxPrefab.GetComponent<MeshRenderer>(); boomboxAudioSource = boomboxPrefab.GetComponent<AudioSource>(); boomboxScript = boomboxPrefab.GetComponent<BoomboxItem>(); } private static void AddToTerminalKeywords(ref Terminal __instance, PersonalBoomboxPlugin.PBData data) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown if ((Object)(object)buyKeyword == (Object)null) { InitializeKeyword(ref __instance); } string word = data.boomboxName.ToLowerInvariant(); string boomboxName = data.boomboxName; CompatibleNoun val = CopyNoun(buyNoun); TerminalKeyword noun = val.noun; noun.word = word; TerminalNode result = val.result; result.buyItemIndex = data.itemIndex; result.displayText = result.displayText.Replace("boom boxes", boomboxName + " boom boxes"); result.terminalOptions = CopyNouns(result.terminalOptions); TerminalNode val2 = FindNodeWithConfirm(result.terminalOptions); val2.buyItemIndex = data.itemIndex; val2.displayText = val2.displayText.Replace("boom boxes", boomboxName + " boom boxes"); List<CompatibleNoun> list = buyKeyword.compatibleNouns.ToList(); List<CompatibleNoun> list2 = infoKeyword.compatibleNouns.ToList(); List<TerminalKeyword> list3 = __instance.terminalNodes.allKeywords.ToList(); list.Add(val); buyKeyword.compatibleNouns = list.ToArray(); CompatibleNoun val3 = new CompatibleNoun(); val3.noun = val.noun; val3.result = CopyTerminalNode(infoNoun.result); val3.result.displayText = "\n" + data.description + "\n\n"; list2.Add(val3); infoKeyword.compatibleNouns = list2.ToArray(); list3.Add(noun); __instance.terminalNodes.allKeywords = list3.ToArray(); } private static void InitializeKeyword(ref Terminal __instance) { TerminalKeyword[] allKeywords = __instance.terminalNodes.allKeywords; buyKeyword = ((IEnumerable<TerminalKeyword>)allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword a) => a.word == "buy")); infoKeyword = ((IEnumerable<TerminalKeyword>)allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword a) => a.word == "info")); buyNoun = buyKeyword.compatibleNouns.First((CompatibleNoun b) => b.noun.word == "boombox"); infoNoun = infoKeyword.compatibleNouns.First((CompatibleNoun b) => b.noun.word == "boombox"); } private static TerminalKeyword CopyTerminalKeyword(TerminalKeyword target) { return Object.Instantiate<TerminalKeyword>(target); } private static TerminalNode CopyTerminalNode(TerminalNode target) { return Object.Instantiate<TerminalNode>(target); } private static CompatibleNoun CopyNoun(CompatibleNoun target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown CompatibleNoun val = new CompatibleNoun(); val.noun = CopyTerminalKeyword(target.noun); val.result = CopyTerminalNode(target.result); return val; } private static CompatibleNoun[] CopyNouns(CompatibleNoun[] target) { CompatibleNoun[] array = (CompatibleNoun[])(object)new CompatibleNoun[target.Length]; for (int i = 0; i < target.Length; i++) { array[i] = CopyNoun(target[i]); } return array; } private static TerminalNode FindNodeWithConfirm(CompatibleNoun[] nouns) { foreach (CompatibleNoun val in nouns) { if (val.noun.word.ToLowerInvariant() == "confirm") { return val.result; } } return null; } private static Sprite CreateSprite(Sprite copyTarget, Color color) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_002f: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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) Texture2D boomboxTexture = Assets.boomboxTexture; Texture2D val = new Texture2D(((Texture)boomboxTexture).width, ((Texture)boomboxTexture).height); Color[] pixels = boomboxTexture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { ref Color reference = ref pixels[i]; reference *= color; } val.SetPixels(pixels); val.Apply(); return Sprite.Create(val, copyTarget.rect, copyTarget.pivot, copyTarget.pixelsPerUnit); } } }