Decompiled source of YourOwnPersonalBoombox v1.4.4

PersonalBoombox.dll

Decompiled 5 months ago
using 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.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using PersonalBoombox.Patches;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
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.4f;
				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, 5, 1000);
				volume = Mathf.Clamp(volume, 0.1f, SyncedInstance<PluginConfig>.Default.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 = 15;

		public static AssetBundle MainAssetBundle = null;

		public static GameObject originalPrefab;

		public static GameObject[] prefabCopies;

		public static GameObject canvasPrefab;

		public static GameObject volumeControlCanvasPrefab;

		public static Sprite boomboxSprite;

		public static int LimitExceedCounter = 0;

		public static int BoomboxesLoading = 0;

		private static readonly string[] musicExts = new string[3] { "mp3", "ogg", "wav" };

		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", onlyReportErrors: true);
			prefabCopies = (GameObject[])(object)new GameObject[15];
			for (int i = 0; i < 15; i++)
			{
				GameObject val = Assets.Load<GameObject>($"prefab{i + 1}", onlyReportErrors: false);
				prefabCopies[i] = val;
			}
			canvasPrefab = Assets.Load<GameObject>("debugCanvas", onlyReportErrors: true);
			volumeControlCanvasPrefab = Assets.Load<GameObject>("volumeControlCanvas", onlyReportErrors: true);
			boomboxSprite = Assets.Load<Sprite>("boomboxIcon", onlyReportErrors: true);
		}

		public static T Load<T>(string name, bool onlyReportErrors = true) 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);
			}
			if (onlyReportErrors)
			{
				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)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			if (index >= 15)
			{
				logger.LogWarning((object)$"Loading too many boomboxes. There is a limit of {15}");
				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;
			pBData.icon = CreateSprite(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)
		{
			BoomboxesLoading++;
			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");
			}
			BoomboxesLoading--;
		}

		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);
				yield break;
			}
			((Texture)texture).filterMode = (FilterMode)0;
			data.decal = texture;
			data.decalScale = GetDecalRatio(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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			return (AudioType)(Path.GetExtension(path).ToLowerInvariant() switch
			{
				".mp3" => 13, 
				".ogg" => 14, 
				".wav" => 20, 
				_ => 0, 
			});
		}

		public static Vector3 GetDecalRatio(Texture2D texture)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)((Texture)texture).width / (float)((Texture)texture).height;
			float num2;
			float num3;
			if (num > 2.1014493f)
			{
				num2 = 1f;
				num3 = 2.1014493f / num;
			}
			else if (num < 2.1014493f)
			{
				num2 = num / 2.1014493f;
				num3 = 1f;
			}
			else
			{
				num2 = 1f;
				num3 = 1f;
			}
			return new Vector3(num2, num3, 1f);
		}

		public static Sprite CreateSprite(Color color)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = boomboxSprite;
			Texture2D texture = val.texture;
			Texture2D val2 = new Texture2D(((Texture)texture).width, ((Texture)texture).height);
			Color[] pixels = texture.GetPixels();
			for (int i = 0; i < pixels.Length; i++)
			{
				ref Color reference = ref pixels[i];
				reference *= color;
			}
			val2.SetPixels(pixels);
			val2.Apply();
			return Sprite.Create(val2, val.rect, val.pivot, val.pixelsPerUnit);
		}
	}
	[Serializable]
	public class PluginConfig : SyncedInstance<PluginConfig>
	{
		public static ConfigEntry<int> maxVolumeConfig;

		public static ConfigEntry<bool> pocketCarryConfig;

		public static ConfigEntry<int> batteryConfig;

		public bool pocketCarryValue;

		public int batteryValue;

		public float maxVolumeValue => (float)maxVolumeConfig.Value * 0.01f;

		public PluginConfig(ConfigFile cfg)
		{
			InitInstance(this);
			maxVolumeConfig = ConfigBindClamp("General", "Max Volume", 100, "Max possible volume value for all p. boomboxes. From 10 to 100.", 10, 100);
			pocketCarryConfig = cfg.Bind<bool>("Network General", "Pocket Play", false, "If true, lets the p. boombox keep playing when it's put in the inventory");
			batteryConfig = ConfigBindClamp("Network General", "Battery Charge", 350, "The battery charge (in seconds) for all p. boomboxes. Clamped from 30 to 720", 30, 720);
			pocketCarryValue = pocketCarryConfig.Value;
			batteryValue = batteryConfig.Value;
			ConfigEntry<int> ConfigBindClamp(string section, string key, int defaultValue, string description, int min, int max)
			{
				ConfigEntry<int> val = cfg.Bind<int>(section, key, defaultValue, description);
				val.Value = Mathf.Clamp(val.Value, min, max);
				return val;
			}
		}

		public static void RequestSync()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<PluginConfig>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(SyncedInstance<PluginConfig>.IntSize, (Allocator)2, -1);
			try
			{
				SyncedInstance<PluginConfig>.MessageManager.SendNamedMessage("PBoombox_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<PluginConfig>.IsHost)
			{
				return;
			}
			SyncedInstance<PluginConfig>.logger.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] array = SyncedInstance<PluginConfig>.SerializeToBytes(SyncedInstance<PluginConfig>.Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<PluginConfig>.IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				SyncedInstance<PluginConfig>.MessageManager.SendNamedMessage("PBoombox_OnReceieveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				SyncedInstance<PluginConfig>.logger.LogError((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_002d: 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)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<PluginConfig>.IntSize))
			{
				SyncedInstance<PluginConfig>.logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				SyncedInstance<PluginConfig>.logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			SyncedInstance<PluginConfig>.SyncInstance(data);
			SyncedInstance<PluginConfig>.logger.LogInfo((object)"Successfully synced config with host.");
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void InitializeLocalPlayer()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if (SyncedInstance<PluginConfig>.IsHost)
			{
				SyncedInstance<PluginConfig>.MessageManager.RegisterNamedMessageHandler("PBoombox_OnRequestConfigSync", new HandleNamedMessageDelegate(OnRequestSync));
				SyncedInstance<PluginConfig>.Synced = true;
			}
			else
			{
				SyncedInstance<PluginConfig>.Synced = false;
				SyncedInstance<PluginConfig>.MessageManager.RegisterNamedMessageHandler("PBoombox_OnReceieveConfigSync", new HandleNamedMessageDelegate(OnReceiveSync));
				RequestSync();
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			SyncedInstance<PluginConfig>.RevertSync();
		}
	}
	[Serializable]
	public class SyncedInstance<T>
	{
		[NonSerialized]
		protected static int IntSize = 4;

		internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;

		internal static bool IsClient => NetworkManager.Singleton.IsClient;

		internal static bool IsHost => NetworkManager.Singleton.IsHost;

		internal static ManualLogSource logger => PersonalBoomboxPlugin.Instance.logger;

		public static T Default { get; private set; }

		public static T Instance { get; private set; }

		public static bool Synced { get; internal set; }

		protected void InitInstance(T instance)
		{
			Default = instance;
			Instance = instance;
			IntSize = 4;
		}

		internal static void SyncInstance(byte[] data)
		{
			Instance = DeserializeFromBytes(data);
			Synced = true;
		}

		internal static void RevertSync()
		{
			Instance = Default;
			Synced = false;
		}

		public static byte[] SerializeToBytes(T val)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream memoryStream = new MemoryStream();
			try
			{
				binaryFormatter.Serialize(memoryStream, val);
				return memoryStream.ToArray();
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Error serializing instance: {arg}");
				return null;
			}
		}

		public static T DeserializeFromBytes(byte[] data)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream serializationStream = new MemoryStream(data);
			try
			{
				return (T)binaryFormatter.Deserialize(serializationStream);
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Error deserializing instance: {arg}");
				return default(T);
			}
		}
	}
	public class VolumeControl : MonoBehaviour
	{
		public float volumeModifier;

		private int volumeValue;

		public Image fillImage;

		public Image[] targetImages;

		private const float fillMin = 0.12f;

		private const float fillMax = 0.88f;

		private const float displayTime = 3f;

		private const float fadeTime = 0.25f;

		private Coroutine displayC;

		public static VolumeControl Instance { get; private set; }

		private void Awake()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			volumeValue = PlayerPrefs.GetInt("PBoombox_VolumeControlValue", 100);
			volumeModifier = (float)volumeValue * 0.01f;
			Image[] array = targetImages;
			foreach (Image val in array)
			{
				((Graphic)val).color = Color.clear;
			}
		}

		private void Update()
		{
			int num = 0;
			if (IfKeyPress(Keyboard.current.minusKey, Keyboard.current.numpadMinusKey))
			{
				num = -1;
			}
			else if (IfKeyPress(Keyboard.current.equalsKey, Keyboard.current.numpadPlusKey))
			{
				num = 1;
			}
			if (num != 0)
			{
				volumeValue = Mathf.Clamp(volumeValue + num * 10, 10, 100);
				volumeModifier = (float)volumeValue * 0.01f;
				PlayerPrefs.SetInt("PBoombox_VolumeControlValue", volumeValue);
				fillImage.fillAmount = Mathf.Lerp(0.12f, 0.88f, volumeModifier);
				Display();
			}
		}

		private bool IfKeyPress(params KeyControl[] keys)
		{
			foreach (KeyControl val in keys)
			{
				if (((ButtonControl)val).wasPressedThisFrame)
				{
					return true;
				}
			}
			return false;
		}

		private void Display()
		{
			if (displayC != null)
			{
				((MonoBehaviour)this).StopCoroutine(displayC);
			}
			displayC = ((MonoBehaviour)this).StartCoroutine(DisplayCoroutine());
		}

		private IEnumerator DisplayCoroutine()
		{
			Image[] array = targetImages;
			foreach (Image i in array)
			{
				((Graphic)i).color = Color.white;
			}
			yield return (object)new WaitForSeconds(3f);
			Image[] array2 = targetImages;
			foreach (Image j in array2)
			{
				((Graphic)j).color = Color.clear;
			}
			displayC = null;
		}
	}
	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 float baseAudio;

		public bool continuePlayingOnPocket;

		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);
			baseAudio = boomboxAudio.volume;
			HUDManager.Instance.DisplayTip("P. Boombox Volume Control", "Press +/- to change the volume of all personal boomboxes", false, true, "PBoombox_VolumeControl");
		}

		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();
			if (!continuePlayingOnPocket)
			{
				StartMusic(startMusic: false);
			}
		}

		public override void Update()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).Update();
			if (isPlayingMusic)
			{
				boomboxAudio.volume = baseAudio * VolumeControl.Instance.volumeModifier;
				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;
				}
			}
		}
	}
	[BepInPlugin("ImoutoSama.PersonalBoombox", "Personal Boombox", "1.4.4")]
	[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 GetMainReport()
				{
					return string.Join("\n", main);
				}

				public string GetSongsReport()
				{
					string empty = string.Empty;
					if (songs.Count == 0)
					{
						empty += "Found 0 songs".CreateWarning();
					}
					else
					{
						string arg = ((songs.Count != 1) ? "s" : string.Empty);
						empty += $"{songs.Count} song{arg}";
						foreach (string song in songs)
						{
							empty = empty + "\n" + song;
						}
					}
					return empty;
				}
			}

			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 Sprite icon;

			public Item item;

			public int itemIndex;

			public Texture2D decal;

			public Vector3 decalScale;

			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 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.4.4";

		private readonly Harmony harmony = new Harmony("ImoutoSama.PersonalBoombox");

		internal ManualLogSource logger;

		public static List<PBData> data;

		public static List<RequestData> requests;

		public static PersonalBoomboxPlugin Instance { get; private set; }

		public static PluginConfig MyConfig { get; internal 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!");
			MyConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			harmony.PatchAll(typeof(TerminalPatch));
			harmony.PatchAll(typeof(StartOfRoundPatch));
			harmony.PatchAll(typeof(GameNetworkManagerPatch));
			harmony.PatchAll(typeof(MenuManagerPatch));
			harmony.PatchAll(typeof(PluginConfig));
			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 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 GetBonusReport()
		{
			if (data == null)
			{
				return "Data variable is null. This should literally never happen?!".CreateError();
			}
			if (data.Count == 0)
			{
				return "No boomboxes were loaded".CreateWarning();
			}
			int limitExceedCounter = Assets.LimitExceedCounter;
			if (limitExceedCounter > 0)
			{
				return $"Ignored {limitExceedCounter} boomboxes as they exceed the limit of {15}".CreateWarning();
			}
			return "Everything seems good";
		}
	}
	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 contentGameObject;

		public static Transform contentParent;

		public static GameObject blockPrefab;

		public static GameObject spacingPrefab;

		public static TextMeshProUGUI errorsTextMesh;

		public static bool loadedReport;

		[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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			try
			{
				Transform parent = ((Component)__instance).transform.parent;
				Transform val = parent.Find("MenuContainer").Find("MainButtons");
				GameObject gameObject = ((Component)val.Find("HostButton")).gameObject;
				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));
				CanvasUpdateButtonVisibility canvasUpdateButtonVisibility = val2.AddComponent<CanvasUpdateButtonVisibility>();
				canvasUpdateButtonVisibility.button = ((Component)component).gameObject;
				canvasUpdateButtonVisibility.mainMenuTarget = gameObject;
				contentGameObject = ((Component)val2.transform.Find("Scroll View")).gameObject;
				contentParent = val2.transform.Find("Scroll View/Viewport/Content");
				blockPrefab = ((Component)contentParent.Find("Block")).gameObject;
				spacingPrefab = ((Component)contentParent.Find("Divider")).gameObject;
				errorsTextMesh = ((Component)contentParent.Find("Errors")).GetComponent<TextMeshProUGUI>();
				blockPrefab.SetActive(false);
				spacingPrefab.SetActive(false);
				loadedReport = false;
			}
			catch
			{
			}
		}

		private static void ToggleReportDisplay()
		{
			if (!contentGameObject.activeSelf)
			{
				if (Assets.BoomboxesLoading > 0)
				{
					((TMP_Text)errorsTextMesh).text = $"{Assets.BoomboxesLoading} boomboxes still loading... Please refresh this display in a moment";
					contentGameObject.SetActive(true);
					return;
				}
				if (!loadedReport)
				{
					SetupReportDisplay();
					loadedReport = true;
				}
				contentGameObject.SetActive(true);
			}
			else
			{
				contentGameObject.SetActive(false);
			}
		}

		private static void SetupReportDisplay()
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			foreach (PersonalBoomboxPlugin.PBData datum in PersonalBoomboxPlugin.data)
			{
				GameObject val = Object.Instantiate<GameObject>(blockPrefab, contentParent);
				Transform transform = val.transform;
				((TMP_Text)((Component)transform.Find("Title")).GetComponent<TextMeshProUGUI>()).text = "[" + datum.prefixName + "] " + datum.name;
				Transform val2 = transform.Find("Icon Area");
				((Component)val2.Find("Icon")).GetComponent<Image>().sprite = datum.icon;
				((TMP_Text)((Component)val2.Find("Text 1")).GetComponent<TextMeshProUGUI>()).text = datum.feedback.GetSongsReport();
				Transform val3 = val2.Find("Decal");
				if ((Object)(object)datum.decal == (Object)null)
				{
					((Component)val3).gameObject.SetActive(false);
				}
				else
				{
					RawImage component = ((Component)val3).GetComponent<RawImage>();
					component.texture = (Texture)(object)datum.decal;
					((Component)component).transform.localScale = datum.decalScale;
				}
				((TMP_Text)((Component)transform.Find("Errors")).GetComponent<TextMeshProUGUI>()).text = datum.feedback.GetMainReport();
				val.SetActive(true);
				GameObject val4 = Object.Instantiate<GameObject>(spacingPrefab, contentParent);
				val4.SetActive(true);
			}
			((TMP_Text)errorsTextMesh).text = PersonalBoomboxPlugin.GetBonusReport();
			((TMP_Text)errorsTextMesh).transform.SetAsLastSibling();
		}

		public static void SetContentDisplay(bool state)
		{
			if (!((Object)(object)contentGameObject == (Object)null))
			{
				contentGameObject.SetActive(state);
			}
		}

		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);
			}
		}
	}
	public class CanvasUpdateButtonVisibility : MonoBehaviour
	{
		public GameObject mainMenuTarget;

		public GameObject button;

		public void LateUpdate()
		{
			if (!((Object)(object)mainMenuTarget == (Object)null))
			{
				if (mainMenuTarget.activeInHierarchy)
				{
					button.SetActive(true);
					return;
				}
				button.SetActive(false);
				MenuManagerPatch.SetContentDisplay(state: false);
			}
		}
	}
	[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 TerminalKeyword buyKeyword;

		public static TerminalKeyword infoKeyword;

		public static CompatibleNoun buyNoun;

		public static CompatibleNoun infoNoun;

		public static int copyTerminalNodeId;

		[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"));
				}
			}
			Object.Instantiate<GameObject>(Assets.volumeControlCanvasPrefab);
			((MonoBehaviour)MyOwnCoroutine.Instance).StartCoroutine(UpdateNetworkConfig());
		}

		private static IEnumerator UpdateNetworkConfig()
		{
			while (!SyncedInstance<PluginConfig>.Synced)
			{
				yield return null;
			}
			int batvalue = SyncedInstance<PluginConfig>.Instance.batteryValue;
			bool pocketvalue = SyncedInstance<PluginConfig>.Instance.pocketCarryValue;
			foreach (PersonalBoomboxPlugin.PBData d in PersonalBoomboxPlugin.data)
			{
				d.item.batteryUsage = batvalue;
				d.prefab.GetComponent<PersonalBoomboxItem>().continuePlayingOnPocket = pocketvalue;
			}
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)"Set networked config values");
		}

		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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			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 = data.icon;
			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.transform.localScale = Vector3.Scale(gameObject.transform.localScale, data.decalScale);
				gameObject.SetActive(true);
			}
			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)
		{
			TerminalKeyword val = Object.Instantiate<TerminalKeyword>(target);
			((Object)val).name = $"{((Object)val).name} {++copyTerminalNodeId}";
			return val;
		}

		private static TerminalNode CopyTerminalNode(TerminalNode target)
		{
			TerminalNode val = Object.Instantiate<TerminalNode>(target);
			((Object)val).name = $"{((Object)val).name} {++copyTerminalNodeId}";
			return val;
		}

		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;
		}
	}
}