Decompiled source of PRJT NOSTROMO v1.0.3

BepInEx/plugins/Emblem.dll

Decompiled 8 hours 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.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Emblem;
using Emblem.Components;
using Emblem.Managers;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Emblem")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Emblem")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e4927ee1-3a47-4f93-8784-804356949316")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("Darkbrewery.Emblem", "Emblem", "1.2.5")]
public class EmblemPlugin : BaseUnityPlugin
{
	private UIComponent uiComponent;

	private HeaderReplacement headerReplacement;

	private Boardwalk boardwalk;

	private BackgroundManager backgroundManager;

	private LoadingText loadingText;

	private MenuMoodSetter menuMoodSetter;

	private Harmony harmony;

	private Configurator configManager;

	private CustomMediaManager customMediaManager;

	private SceneManagerHelper sceneManagerHelper;

	private InterfaceDecorator interfaceDecorator;

	private VersionStyler versionStyler;

	private void Awake()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		LogWarden.Initialize(((BaseUnityPlugin)this).Logger);
		LogWarden.LogInfo("Stirring from darkness...");
		try
		{
			harmony = new Harmony("com.darkbrewery.emblem.harmony");
			configManager = new Configurator(((BaseUnityPlugin)this).Config);
			customMediaManager = new CustomMediaManager();
			uiComponent = new UIComponent(configManager);
			backgroundManager = new BackgroundManager(configManager, customMediaManager);
			headerReplacement = new HeaderReplacement(configManager, uiComponent, customMediaManager);
			boardwalk = new Boardwalk(configManager);
			loadingText = ((Component)this).gameObject.AddComponent<LoadingText>();
			loadingText.Initialize(configManager);
			menuMoodSetter = new MenuMoodSetter(configManager);
			versionStyler = new VersionStyler(configManager);
			interfaceDecorator = new InterfaceDecorator(uiComponent, backgroundManager, headerReplacement, boardwalk, loadingText, menuMoodSetter, versionStyler);
			sceneManagerHelper = new SceneManagerHelper(interfaceDecorator);
			harmony.PatchAll();
			LogWarden.LogInfo("Successfully deployed, its intent shrouded");
		}
		catch (Exception arg)
		{
			LogWarden.LogError($"Error initializing Emblem plugin: {arg}");
		}
	}
}
public class DelayHelper : MonoBehaviour
{
	public static void StartDelayedAction(float delayInSeconds, Action action)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		new GameObject("DelayHelper").AddComponent<DelayHelper>().DelayedAction(delayInSeconds, action);
	}

	private void DelayedAction(float delayInSeconds, Action action)
	{
		((MonoBehaviour)this).StartCoroutine(DelayCoroutine(delayInSeconds, action));
	}

	private IEnumerator DelayCoroutine(float delayInSeconds, Action action)
	{
		yield return (object)new WaitForSeconds(delayInSeconds);
		action?.Invoke();
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}

	public static void StartRepeatingAction(float intervalInSeconds, Action action)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		new GameObject("RepeatingDelayHelper").AddComponent<DelayHelper>().RepeatingAction(intervalInSeconds, action);
	}

	private void RepeatingAction(float intervalInSeconds, Action action)
	{
		((MonoBehaviour)this).StartCoroutine(RepeatingActionCoroutine(intervalInSeconds, action));
	}

	private IEnumerator RepeatingActionCoroutine(float intervalInSeconds, Action action)
	{
		while (true)
		{
			yield return (object)new WaitForSeconds(intervalInSeconds);
			action?.Invoke();
		}
	}
}
public class EmblemFolder
{
	private readonly string basePluginsPath;

	private readonly Dictionary<string, string> fullPathCache = new Dictionary<string, string>();

	private readonly Dictionary<string, IEnumerable<string>> validPathsCache = new Dictionary<string, IEnumerable<string>>();

	private readonly Lazy<IEnumerable<string>> emblemDirectories;

	public EmblemFolder()
	{
		basePluginsPath = Path.Combine(Paths.BepInExRootPath, "plugins");
		emblemDirectories = new Lazy<IEnumerable<string>>(() => FindEmblemDirectories());
	}

	private IEnumerable<string> FindEmblemDirectories()
	{
		try
		{
			return (from dir in Directory.GetDirectories(basePluginsPath, "*", SearchOption.AllDirectories)
				where Path.GetFileName(dir).Equals("Emblem", StringComparison.OrdinalIgnoreCase)
				select dir).ToList();
		}
		catch (Exception ex)
		{
			LogWarden.LogError("[EmblemFolder] Error finding Emblem directories: " + ex.Message);
			return new List<string>();
		}
	}

	public string FindFullPath(string inputPath)
	{
		if (fullPathCache.TryGetValue(inputPath, out var value))
		{
			return value;
		}
		string path = ExtractRelativePathFromEmblem(inputPath);
		string[] directories = Directory.GetDirectories(basePluginsPath, "*", SearchOption.AllDirectories);
		foreach (string text in directories)
		{
			if (text.EndsWith("Emblem", StringComparison.OrdinalIgnoreCase))
			{
				string text2 = Path.Combine(text, path);
				if (File.Exists(text2) || Directory.Exists(text2))
				{
					fullPathCache[inputPath] = text2;
					return text2;
				}
			}
		}
		LogWarden.LogError("[EmblemFolder] Could not find a valid path for: " + inputPath);
		return null;
	}

	public IEnumerable<string> FindAllValidPaths(string inputPathPattern)
	{
		if (validPathsCache.TryGetValue(inputPathPattern, out var value))
		{
			return value;
		}
		string path = ExtractRelativePathFromEmblem(inputPathPattern);
		string[] directories = Directory.GetDirectories(basePluginsPath, "*", SearchOption.AllDirectories);
		List<string> list = new List<string>();
		string[] array = directories;
		foreach (string text in array)
		{
			if (text.EndsWith("Emblem", StringComparison.OrdinalIgnoreCase))
			{
				string searchPattern = Path.Combine(text, path);
				list.AddRange(Directory.GetFiles(text, searchPattern, SearchOption.AllDirectories));
			}
		}
		validPathsCache[inputPathPattern] = list;
		return list;
	}

	private string ExtractRelativePathFromEmblem(string path)
	{
		string[] array = path.Split(new char[2]
		{
			Path.DirectorySeparatorChar,
			Path.AltDirectorySeparatorChar
		}, StringSplitOptions.RemoveEmptyEntries);
		int num = Array.FindIndex(array, (string segment) => segment.Equals("Emblem", StringComparison.OrdinalIgnoreCase));
		if (num != -1 && num < array.Length - 1)
		{
			return Path.Combine(array.Skip(num + 1).ToArray());
		}
		return path;
	}
}
public class ImageFilters
{
	private readonly Configurator configManager;

	public ImageFilters(Configurator configManager)
	{
		this.configManager = configManager;
	}

	public void Blend(string targetImagePath, Color vignetteColor)
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		if (!configManager.enableRadiantTaper.Value)
		{
			return;
		}
		Transform val = PathFinder.Probe(targetImagePath);
		if ((Object)(object)val == (Object)null)
		{
			LogWarden.LogError("ImageFilters.Blend: Image with path '" + targetImagePath + "' not found.");
			return;
		}
		GameObject gameObject = ((Component)val).gameObject;
		if (!((Object)(object)gameObject.transform.Find("VignetteOverlay") != (Object)null))
		{
			GameObject val2 = new GameObject("VignetteOverlay");
			RectTransform val3 = val2.AddComponent<RectTransform>();
			((Transform)val3).SetParent(gameObject.transform, false);
			Image obj = val2.AddComponent<Image>();
			Texture2D val4 = CreateVignetteTexture(((Texture)gameObject.GetComponent<Image>().sprite.texture).width, ((Texture)gameObject.GetComponent<Image>().sprite.texture).height, vignetteColor);
			obj.sprite = Sprite.Create(val4, new Rect(0f, 0f, (float)((Texture)val4).width, (float)((Texture)val4).height), new Vector2(0.5f, 0.5f));
			Rect rect = gameObject.GetComponent<RectTransform>().rect;
			float width = ((Rect)(ref rect)).width;
			rect = gameObject.GetComponent<RectTransform>().rect;
			val3.sizeDelta = new Vector2(width, ((Rect)(ref rect)).height);
			((Graphic)obj).raycastTarget = false;
		}
	}

	private Texture2D CreateVignetteTexture(int width, int height, Color vignetteColor)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Expected O, but got Unknown
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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)
		Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
		Color val2 = default(Color);
		for (int i = 0; i < height; i++)
		{
			for (int j = 0; j < width; j++)
			{
				float distance2 = j;
				float distance3 = width - j;
				float distance4 = height - i;
				float distance5 = i;
				float num = Mathf.Max(CalculateExponentialBlend(distance2, width), CalculateExponentialBlend(distance3, width));
				float num2 = Mathf.Max(CalculateExponentialBlend(distance4, height), CalculateExponentialBlend(distance5, height));
				float num3 = Mathf.Max(num, num2);
				((Color)(ref val2))..ctor(vignetteColor.r, vignetteColor.g, vignetteColor.b, num3);
				val.SetPixel(j, i, val2);
			}
		}
		val.Apply();
		return val;
		static float CalculateExponentialBlend(float distance, float totalDistance)
		{
			float num4 = 0.97f * totalDistance;
			if (distance > num4)
			{
				return Mathf.Clamp01(Mathf.Pow((distance - num4) / (totalDistance - num4), 2f));
			}
			return 0f;
		}
	}
}
namespace Emblem
{
	public class CRTEffect
	{
		private Volume volume;

		public void SetupVolume(GameObject gameObject)
		{
			volume = gameObject.GetComponent<Volume>() ?? gameObject.AddComponent<Volume>();
			if ((Object)(object)volume == (Object)null)
			{
				LogWarden.LogError("[CRT] Failed to add or get Volume component on gameObject.");
				return;
			}
			volume.isGlobal = true;
			volume.priority = 2.1474836E+09f;
			if ((Object)(object)volume.profile == (Object)null)
			{
				volume.profile = ScriptableObject.CreateInstance<VolumeProfile>();
				if ((Object)(object)volume.profile == (Object)null)
				{
					LogWarden.LogError("[CRT] Failed to create a new VolumeProfile.");
					return;
				}
			}
			((Behaviour)volume).enabled = true;
			LogWarden.LogInfo("[CRT] Volume component for CRT effects has been enabled.");
			SetupCRTEffects();
		}

		private void SetupCRTEffects()
		{
			if ((Object)(object)volume.profile == (Object)null)
			{
				LogWarden.LogError("[CRT] VolumeProfile is null in SetupCRTEffects.");
				return;
			}
			ConfigureChromaticAberration();
			ConfigureFilmGrain();
			ConfigureVignette();
			ConfigureLensDistortion();
		}

		private T GetOrAddEffect<T>(bool overrides = true) where T : VolumeComponent, new()
		{
			VolumeComponent? obj = volume.profile.components.Find((VolumeComponent x) => x is T);
			return ((T)(object)((obj is T) ? obj : null)) ?? volume.profile.Add<T>(overrides);
		}

		private void ConfigureChromaticAberration()
		{
			ChromaticAberration orAddEffect = GetOrAddEffect<ChromaticAberration>(overrides: true);
			((VolumeComponent)orAddEffect).active = true;
			((VolumeParameter<float>)(object)orAddEffect.intensity).value = 0.04f;
		}

		private void ConfigureFilmGrain()
		{
			FilmGrain orAddEffect = GetOrAddEffect<FilmGrain>(overrides: true);
			((VolumeComponent)orAddEffect).active = true;
			((VolumeParameter<float>)(object)orAddEffect.intensity).value = 0.4f;
			((VolumeParameter<FilmGrainLookup>)(object)orAddEffect.type).value = (FilmGrainLookup)2;
			((VolumeParameter<float>)(object)orAddEffect.response).value = 0.2f;
		}

		private void ConfigureVignette()
		{
			//IL_0024: 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)
			Vignette orAddEffect = GetOrAddEffect<Vignette>(overrides: true);
			((VolumeComponent)orAddEffect).active = true;
			((VolumeParameter<float>)(object)orAddEffect.intensity).value = 0.4f;
			((VolumeParameter<Color>)(object)orAddEffect.color).value = Color.black;
			((VolumeParameter<Vector2>)(object)orAddEffect.center).value = new Vector2(0.5f, 0.5f);
			((VolumeParameter<float>)(object)orAddEffect.roundness).value = 1f;
			((VolumeParameter<float>)(object)orAddEffect.smoothness).value = 0.5f;
		}

		private void ConfigureLensDistortion()
		{
			LensDistortion orAddEffect = GetOrAddEffect<LensDistortion>(overrides: true);
			((VolumeComponent)orAddEffect).active = true;
			((VolumeParameter<float>)(object)orAddEffect.intensity).value = 0.27f;
			((VolumeParameter<float>)(object)orAddEffect.scale).value = 1.02f;
		}
	}
	public class ScanlineEffectApplier : MonoBehaviour
	{
		private static Material scanlineMaterial;

		private void LoadMaterialFromAssetBundle(string bundleResourceName, string materialName)
		{
			AssetBundle val = LoadAssetBundleFromEmbeddedResource(bundleResourceName);
			if ((Object)(object)val != (Object)null)
			{
				scanlineMaterial = val.LoadAsset<Material>(materialName);
				val.Unload(false);
			}
			else
			{
				LogWarden.LogError("[Scanlines] Failed to load the scanline material from the asset bundle.");
			}
		}

		private AssetBundle LoadAssetBundleFromEmbeddedResource(string resourceName)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				LogWarden.LogError("[Scanlines] Embedded resource not found.");
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			return AssetBundle.LoadFromMemory(array);
		}

		private void Awake()
		{
			if ((Object)(object)scanlineMaterial == (Object)null)
			{
				LoadMaterialFromAssetBundle("Emblem.Assets.scanlines", "Scanlines");
			}
		}

		public void ApplyScanlines(string targetGameObjectName)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)scanlineMaterial == (Object)null))
			{
				GameObject val = GameObject.Find(targetGameObjectName);
				if ((Object)(object)val == (Object)null)
				{
					LogWarden.LogError("[Scanlines] GameObject with name '" + targetGameObjectName + "' not found.");
					return;
				}
				Transform obj = val.transform.Find("Scanlines");
				GameObject val2 = (GameObject)(((object)((obj != null) ? ((Component)obj).gameObject : null)) ?? ((object)new GameObject("Scanlines")));
				val2.transform.SetParent(val.transform, false);
				Image obj2 = val2.GetComponent<Image>() ?? val2.AddComponent<Image>();
				((Graphic)obj2).material = scanlineMaterial;
				((Graphic)obj2).raycastTarget = false;
				RectTransform component = val2.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.sizeDelta = Vector2.zero;
				((Transform)component).localPosition = Vector3.zero;
				((Transform)component).SetAsLastSibling();
			}
		}
	}
	public static class ColorParser
	{
		public static Color RGBA(string rgbaString)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			string[] array = rgbaString.Split(new char[1] { ',' });
			if (array.Length != 4)
			{
				return Color.white;
			}
			float num = Mathf.Clamp01((float)int.Parse(array[0]) / 255f);
			float num2 = Mathf.Clamp01((float)int.Parse(array[1]) / 255f);
			float num3 = Mathf.Clamp01((float)int.Parse(array[2]) / 255f);
			float num4 = Mathf.Clamp01(float.Parse(array[3]));
			return new Color(num, num2, num3, num4);
		}

		public static Color RGB(string rgbString)
		{
			//IL_001e: 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)
			string[] array = rgbString.Split(new char[1] { ',' });
			if (array.Length < 3 || array.Length > 4)
			{
				return Color.white;
			}
			float num = Mathf.Clamp01((float)int.Parse(array[0]) / 255f);
			float num2 = Mathf.Clamp01((float)int.Parse(array[1]) / 255f);
			float num3 = Mathf.Clamp01((float)int.Parse(array[2]) / 255f);
			return new Color(num, num2, num3, 1f);
		}
	}
	public static class LogWarden
	{
		private static ManualLogSource loggerInstance;

		public static void Initialize(ManualLogSource logger)
		{
			loggerInstance = logger;
		}

		public static void LogError(string message)
		{
			ManualLogSource obj = loggerInstance;
			if (obj != null)
			{
				obj.LogError((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			ManualLogSource obj = loggerInstance;
			if (obj != null)
			{
				obj.LogWarning((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			ManualLogSource obj = loggerInstance;
			if (obj != null)
			{
				obj.LogInfo((object)message);
			}
		}
	}
	public static class PathFinder
	{
		public static Transform Probe(string path)
		{
			Transform val = null;
			string[] array = path.Split(new char[1] { '/' });
			foreach (string text in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					GameObject obj = GameObject.Find(text);
					val = ((obj != null) ? obj.transform : null);
				}
				else
				{
					val = val.Find(text);
				}
				if ((Object)(object)val == (Object)null)
				{
					GameObject[] array2 = Resources.FindObjectsOfTypeAll<GameObject>();
					foreach (GameObject val2 in array2)
					{
						if (((Object)val2).name == text)
						{
							val = val2.transform;
							break;
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					LogWarden.LogError("[Pathfinder] Element '" + text + "' not found in path '" + path + "'.");
					return null;
				}
			}
			return val;
		}
	}
	public class Configurator
	{
		public readonly ConfigFile config;

		public ConfigEntry<bool> enableReplaceMainHeader { get; private set; }

		public ConfigEntry<string> mainHeaderPath { get; private set; }

		public ConfigEntry<float> mainHeaderYOffset { get; private set; }

		public ConfigEntry<int> mainHeaderScale { get; private set; }

		public ConfigEntry<int> mainHeaderAlpha { get; private set; }

		public ConfigEntry<bool> enableMainBackground { get; private set; }

		public ConfigEntry<string> mainBackgroundPath { get; private set; }

		public ConfigEntry<string> mainBackgroundColor { get; private set; }

		public ConfigEntry<bool> enableMenuColorChange { get; private set; }

		public ConfigEntry<string> menuFontColor { get; private set; }

		public ConfigEntry<string> menuRolloverBGColor { get; private set; }

		public ConfigEntry<string> menuRolloverFontColor { get; private set; }

		public ConfigEntry<bool> enableReplaceLoadHeader { get; private set; }

		public ConfigEntry<string> loadHeaderPath { get; private set; }

		public ConfigEntry<float> loadHeaderYOffset { get; private set; }

		public ConfigEntry<int> loadHeaderScale { get; private set; }

		public ConfigEntry<int> loadHeaderAlpha { get; private set; }

		public ConfigEntry<bool> loadHeaderStretch { get; private set; }

		public ConfigEntry<bool> enableLoadBackground { get; private set; }

		public ConfigEntry<string> loadBackgroundPath { get; private set; }

		public ConfigEntry<string> loadBackgroundColor { get; private set; }

		public ConfigEntry<bool> enableLoadingTextChange { get; private set; }

		public ConfigEntry<string> loadTextString { get; private set; }

		public ConfigEntry<string> loadTextColor { get; private set; }

		public ConfigEntry<float> loadTextSize { get; private set; }

		public ConfigEntry<float> loadTextYOffset { get; private set; }

		public ConfigEntry<bool> enableReplaceBorder { get; private set; }

		public ConfigEntry<string> borderColor { get; private set; }

		public ConfigEntry<float> borderPadding { get; private set; }

		public ConfigEntry<bool> enableCustomVersion { get; private set; }

		public ConfigEntry<string> versionTextString { get; private set; }

		public ConfigEntry<string> versionColor { get; private set; }

		public ConfigEntry<float> versionFontSize { get; private set; }

		public ConfigEntry<float> versionYOffset { get; private set; }

		public ConfigEntry<bool> enableRadiantTaper { get; private set; }

		public ConfigEntry<bool> enableCRT { get; private set; }

		public ConfigEntry<bool> enableScanlines { get; private set; }

		public ConfigEntry<bool> enableSlideshow { get; private set; }

		public ConfigEntry<string> slideshowSections { get; private set; }

		public ConfigEntry<float> slideshowDelay { get; private set; }

		public Configurator(ConfigFile config)
		{
			this.config = config;
			Initialize();
		}

		private void Initialize()
		{
			enableReplaceMainHeader = BindConfig("1. Main Logo", "Enable", defaultValue: false, "Enable or disable header image replacement.");
			mainHeaderPath = BindConfig("1. Main Logo", "Path", "Defaults/Header/HeaderWhite.png", "Relative to your /Emblem/ folder: Specify a .png file. A folder will randomly select an image starting with the prefix 'Header'. Leave blank to use nothing.");
			mainHeaderYOffset = BindConfig("1. Main Logo", "Offset", 20f, "Vertical Y offset percentage from top. Set to -1 for no adjustment.");
			mainHeaderScale = BindConfig("1. Main Logo", "Scale", 60, "Image scale. This will maintain aspect ratio. 100 for apx original size");
			mainHeaderAlpha = BindConfig("1. Main Logo", "Alpha", 80, "Image transparency. 0 for invisible and 100 for completely opaque.");
			enableMainBackground = BindConfig("2. Main Background", "Enable", defaultValue: true, "Enable or disable the custom main menu background.");
			mainBackgroundPath = BindConfig("2. Main Background", "Path", "Defaults/Background", "Relative to your /Emblem/ folder: Specify a .png, .mp4. A folder will randomly select an image starting with the prefix 'Background'. Separate multiple mp4 paths with a | to pick one randomly");
			mainBackgroundColor = BindConfig("2. Main Background", "Color", "0,0,0", "Background color for Main Menu Screen in RGB format (ex: '0,0,0' for black). No alpha value as this is the bottom layer");
			enableMenuColorChange = BindConfig("3. Menu Colors", "Enable", defaultValue: false, "Do you even want to mess with menu colors?");
			menuFontColor = BindConfig("3. Menu Colors", "Color", "230,100,65,1", "Color of menu font.");
			menuRolloverBGColor = BindConfig("3. Menu Colors", "Highlight BG Color", "230,100,65,1", "Background color of a menu items on rollover.");
			menuRolloverFontColor = BindConfig("3. Menu Colors", "Highlight Font Color", "0,0,0,1", "Font color of menu items on rollover.");
			enableReplaceLoadHeader = BindConfig("4. Loading Image", "Enable", defaultValue: false, "Enable or disable loading image replacement.");
			loadHeaderPath = BindConfig("4. Loading Image", "Path", "Defaults/Loading", "Relative to your /Emblem/ folder: Specify a .png file. A folder will randomly select an image starting with the prefix 'Loading'. Leave blank to use nothing");
			loadHeaderYOffset = BindConfig("4. Loading Image", "Offset", 50f, "Vertical Y offset percentage from top. Set to -1 for no adjustment.");
			loadHeaderScale = BindConfig("4. Loading Image", "Scale", 60, "Image scale. This will maintain aspect ratio.");
			loadHeaderAlpha = BindConfig("4. Loading Image", "Alpha", 100, "Image transparency. 0 for invisible and 100 for completely opaque.");
			loadHeaderStretch = BindConfig("4. Loading Image", "Stretch", defaultValue: false, "Stretch the loading image to fit the screen vertically. This will override scale and offset");
			enableLoadBackground = BindConfig("5. Loading Background", "Enable", defaultValue: false, "Enable or disable the loading screen background.");
			loadBackgroundPath = BindConfig("5. Loading Background", "Path", "Defaults/Background", "Relative to your /Emblem/ folder: Specify a .png, .mp4. A folder will randomly select an image starting with the prefix 'LoadBackground'. Separate multiple mp4 paths with a | to pick one randomly");
			loadBackgroundColor = BindConfig("5. Loading Background", "Color", "0,0,0,1", "Background color for Loading Screen in RGBA format (ex: '255,255,255,1' for white).");
			enableLoadingTextChange = BindConfig("6. Loading Text", "Enable", defaultValue: false, "Enable or disable the custom loading text feature.");
			loadTextString = BindConfig("6. Loading Text", "Text", "Loading...", "Text displayed on the loading screen. Separate multiple texts with '|' to choose one at random");
			loadTextColor = BindConfig("6. Loading Text", "Color", "255,139,0,1", "Color of the font in RGBA format (ex: '0,0,0,1' for blue).");
			loadTextSize = BindConfig("6. Loading Text", "Font Size", 19.6f, "Size of the font used in the loading text.");
			loadTextYOffset = BindConfig("6. Loading Text", "Offset", -1f, "Vertical Y offset percentage from top. Set to -1 for no adjustment.");
			enableReplaceBorder = BindConfig("7. Borders", "Hide", defaultValue: false, "Enable or disable the corner borders.");
			borderColor = BindConfig("7. Borders", "Color", "115,59,0,1", "The color of the border in RGBA format (ex: '0,255,0,1' for green).");
			borderPadding = BindConfig("7. Borders", "Padding", 10f, "How far should the border be from corners of the screen.");
			enableCustomVersion = BindConfig("8. Version Number", "Enable", defaultValue: false, "Play around in version styling? This will center the text and disable word wrapping");
			versionTextString = BindConfig("8. Version Number", "Text", "[ %VERSION% ]", "Format string for the version text. Use %VERSION% for the original string.");
			versionColor = BindConfig("8. Version Number", "Color", "230,100,65,0.45", "The color of the text in RGBA format (ex: '255,0,0,1' for red)..");
			versionFontSize = BindConfig("8. Version Number", "Font Size", 16f, "Font size of the version text.");
			versionYOffset = BindConfig("8. Version Number", "Offset", 95.8f, "Vertical Y offset percentage from top.");
			enableRadiantTaper = BindConfig("9. Experimental", "Radiant Taper", defaultValue: false, "Use the vignette blending effect on background images and their background color");
			enableCRT = BindConfig("9. Experimental", "Retro TV Style", defaultValue: false, "Make the entire menu scene look like a CRT monitor");
			enableScanlines = BindConfig("9. Experimental", "Scanline Shader", defaultValue: false, "Add subtle scanlines to the entire scene");
			enableSlideshow = BindConfig("Slideshow", "Enable", defaultValue: false, "Enable or disable the slideshow feature. Each path section must be using image prefixs.");
			slideshowSections = BindConfig("Slideshow", "Apply To", "", "Specify which sections the slideshow applies to. Options: Header, Background, Loading, LoadBackground. Separate multiple sections with commas.");
			slideshowDelay = BindConfig("Slideshow", "Timer", 3f, "Set the delay timer in seconds for the slideshow feature. Range: 0.1 - 30 seconds.");
		}

		private ConfigEntry<T> BindConfig<T>(string section, string key, T defaultValue, string description)
		{
			return config.Bind<T>(section, key, defaultValue, description);
		}
	}
	public static class UI
	{
		public const string MenuCont = "Canvas/MenuContainer";

		public const string LoadScreen = "Canvas/LoadingScreen";

		public const string MainBtns = "Canvas/MenuContainer/MainButtons";

		public const string MainImg = "Canvas/MenuContainer/MainButtons/HeaderImage";

		public const string LoadImg = "Canvas/MenuContainer/LoadingScreen/Image";

		public const string CustBgImg = "Canvas/MenuContainer/MainButtons/Background";

		public const string LoadTextCont = "Canvas/MenuContainer/LoadingTextContainer";

		public const string LoadText = "Canvas/MenuContainer/LoadingTextContainer/LoadingText";
	}
}
namespace Emblem.Managers
{
	public class InterfaceDecorator
	{
		private readonly UIComponent uiComponent;

		private readonly BackgroundManager backgroundManager;

		private readonly HeaderReplacement headerReplacement;

		private readonly Boardwalk boardwalk;

		private readonly LoadingText loadingText;

		private readonly MenuMoodSetter menuMoodSetter;

		private readonly VersionStyler versionStyler;

		public InterfaceDecorator(UIComponent uiComponent, BackgroundManager backgroundManager, HeaderReplacement headerReplacement, Boardwalk boardwalk, LoadingText loadingText, MenuMoodSetter menuMoodSetter, VersionStyler versionStyler)
		{
			this.uiComponent = uiComponent;
			this.backgroundManager = backgroundManager;
			this.headerReplacement = headerReplacement;
			this.boardwalk = boardwalk;
			this.loadingText = loadingText;
			this.menuMoodSetter = menuMoodSetter;
			this.versionStyler = versionStyler;
		}

		public void ApplyMainMenuCustomizations()
		{
			uiComponent.ResetRectTransformProperties();
			uiComponent.CreateBackgrounds();
			uiComponent.SetVolumeLayerMaskOnAllCameras(-1);
			backgroundManager.ApplyMainMenuBackground();
			backgroundManager.ApplyLoadingBackground();
			headerReplacement.ReplaceMainImage();
			headerReplacement.ReplaceLoadImage();
			uiComponent.SetMainBackgroundColor();
			loadingText.ApplyLoadingCustomizations();
			menuMoodSetter.HarmonizeMenuHues();
			boardwalk.ToggleBorder();
			versionStyler.ApplyVersionStyling();
			uiComponent.ApplyCRTEffectIfNeeded();
			uiComponent.ApplyScanlinesIfNeeded();
			uiComponent.StartSlideshowIfEnabled(backgroundManager, headerReplacement);
			DelayHelper.StartDelayedAction(0.3f, menuMoodSetter.HarmonizeMenuHues);
		}
	}
	public class SceneManagerHelper
	{
		private readonly InterfaceDecorator interfaceDecorator;

		public SceneManagerHelper(InterfaceDecorator interfaceDecorator)
		{
			this.interfaceDecorator = interfaceDecorator;
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "MainMenu")
			{
				LogWarden.LogInfo("[SceneManager] Applying customizations to MainMenu.");
				interfaceDecorator.ApplyMainMenuCustomizations();
			}
		}

		public void Unsubscribe()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}
	}
}
namespace Emblem.Components
{
	public class BackgroundManager
	{
		private readonly Configurator configManager;

		private readonly CustomMediaManager customMediaManager;

		private readonly ImageFilters imageFilters;

		public BackgroundManager(Configurator configManager, CustomMediaManager customMediaManager)
		{
			this.configManager = configManager;
			this.customMediaManager = customMediaManager;
			imageFilters = new ImageFilters(configManager);
		}

		public void ApplyMainMenuBackground()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (configManager.enableMainBackground.Value)
			{
				string value = configManager.mainBackgroundPath.Value;
				Color backgroundColor = ColorParser.RGB(configManager.mainBackgroundColor.Value);
				ApplyBackground("MenuContainer", value, "MainVideo", 0, "Background", backgroundColor);
			}
		}

		public void ApplyLoadingBackground()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (configManager.enableLoadBackground.Value)
			{
				string value = configManager.loadBackgroundPath.Value;
				Color backgroundColor = ColorParser.RGB(configManager.loadBackgroundColor.Value);
				ApplyBackground("LoadingScreen", value, "LoadingVideo", 1, "LoadBackground", backgroundColor);
			}
		}

		private void ApplyBackground(string parentObjectName, string backgroundPath, string videoObjectName, int siblingIndex, string imagePrefix, Color backgroundColor)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(backgroundPath))
			{
				Transform obj = PathFinder.Probe(parentObjectName);
				GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
				if ((Object)(object)val == (Object)null)
				{
					LogWarden.LogError("[Background] " + parentObjectName + " not found in the scene.");
				}
				else if (backgroundPath.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase))
				{
					HandleVideoBackground(val, backgroundPath, videoObjectName, siblingIndex);
				}
				else
				{
					HandleImageBackground(val, backgroundPath, siblingIndex, imagePrefix, backgroundColor);
				}
			}
		}

		private void HandleVideoBackground(GameObject parentObject, string backgroundPath, string videoObjectName, int siblingIndex)
		{
			string text = customMediaManager.LoadCustomVideoPath(backgroundPath);
			if (text != null)
			{
				(parentObject.GetComponent<BackgroundVideoManager>() ?? parentObject.AddComponent<BackgroundVideoManager>()).InitializeVideo(parentObject, text, videoObjectName, siblingIndex);
			}
		}

		private void HandleImageBackground(GameObject parentObject, string backgroundPath, int siblingIndex, string imagePrefix, Color backgroundColor)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Sprite customSprite = customMediaManager.LoadCustomImage(backgroundPath, imagePrefix);
			CreateBackgroundImage(parentObject.transform, customSprite, siblingIndex, backgroundColor, imagePrefix + "Image");
		}

		private void CreateBackgroundImage(Transform parentTransform, Sprite customSprite, int siblingIndex, Color backgroundColor, string objectName)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)customSprite == (Object)null)
			{
				LogWarden.LogError("Background] No custom sprite provided for background image creation.");
				return;
			}
			GameObject orCreateBackgroundObject = GetOrCreateBackgroundObject(parentTransform, objectName, siblingIndex);
			Image val = SetImageComponent(orCreateBackgroundObject, customSprite);
			AdjustImageToFit(parentTransform, ((Component)val).GetComponent<RectTransform>(), customSprite);
			ManageOtherUIElements(parentTransform);
			imageFilters.Blend(((Object)orCreateBackgroundObject).name, backgroundColor);
		}

		private GameObject GetOrCreateBackgroundObject(Transform parentTransform, string objectName, int siblingIndex)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			Transform val = parentTransform.Find(objectName);
			GameObject val2;
			if ((Object)(object)val != (Object)null)
			{
				val2 = ((Component)val).gameObject;
				val2.transform.SetSiblingIndex(siblingIndex);
			}
			else
			{
				val2 = new GameObject(objectName);
				val2.transform.SetParent(parentTransform, false);
				val2.transform.SetSiblingIndex(siblingIndex);
			}
			return val2;
		}

		private Image SetImageComponent(GameObject backgroundImageObject, Sprite customSprite)
		{
			Image val = backgroundImageObject.GetComponent<Image>();
			if ((Object)(object)val == (Object)null)
			{
				val = backgroundImageObject.AddComponent<Image>();
			}
			val.sprite = customSprite;
			val.preserveAspect = true;
			return val;
		}

		private void AdjustImageToFit(Transform parentTransform, RectTransform rectTransform, Sprite customSprite)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0045: 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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchorMin = new Vector2(0.5f, 0f);
			rectTransform.anchorMax = new Vector2(0.5f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			Rect rect = ((Component)parentTransform).GetComponent<RectTransform>().rect;
			float height = ((Rect)(ref rect)).height;
			Bounds bounds = customSprite.bounds;
			float num = ((Bounds)(ref bounds)).size.y * customSprite.pixelsPerUnit;
			float num2 = height / num;
			bounds = customSprite.bounds;
			rectTransform.sizeDelta = new Vector2(((Bounds)(ref bounds)).size.x * customSprite.pixelsPerUnit * num2, 0f);
		}

		private void ManageOtherUIElements(Transform parentTransform)
		{
			Transform val = PathFinder.Probe("MenuContainer/MainButtons/HeaderImage");
			if ((Object)(object)val != (Object)null)
			{
				val.SetSiblingIndex(1);
			}
		}
	}
	public class BackgroundVideoManager : MonoBehaviour
	{
		private VideoPlayer videoPlayer;

		public string VideoPath { get; set; }

		public void InitializeVideo(GameObject targetGameObject, string videoPath, string videoObjectName, int siblingIndex)
		{
			VideoPath = videoPath;
			if ((Object)(object)targetGameObject == (Object)null)
			{
				LogWarden.LogError("[Video] Target GameObject not found in the scene.");
			}
			else
			{
				CreateBackgroundVideo(targetGameObject, videoObjectName, siblingIndex);
			}
		}

		private void CreateBackgroundVideo(GameObject targetGameObject, string videoObjectName, int siblingIndex)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			if (!string.IsNullOrEmpty(VideoPath))
			{
				string text = (VideoPath.StartsWith("file://", StringComparison.OrdinalIgnoreCase) ? VideoPath : ("file://" + VideoPath));
				string text2 = text.Replace(Paths.BepInExRootPath, "");
				text2 = text2.TrimStart(new char[1] { Path.DirectorySeparatorChar });
				LogWarden.LogInfo("[Video] Initializing video with relative path: " + text2);
				Transform val = targetGameObject.transform.Find(videoObjectName);
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				GameObject val2 = new GameObject(videoObjectName);
				val2.transform.SetParent(targetGameObject.transform, false);
				val2.transform.SetSiblingIndex(siblingIndex);
				RawImage rawImage = val2.AddComponent<RawImage>();
				videoPlayer = val2.AddComponent<VideoPlayer>();
				AudioSource audioSource = val2.AddComponent<AudioSource>();
				ConfigureVideoPlayer(text, audioSource, rawImage);
				AdjustRawImage(rawImage);
				LogWarden.LogInfo("[Video] Background video added to the scene.");
			}
		}

		private void ConfigureVideoPlayer(string fullPath, AudioSource audioSource, RawImage rawImage)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			videoPlayer.playOnAwake = true;
			videoPlayer.isLooping = true;
			videoPlayer.renderMode = (VideoRenderMode)2;
			videoPlayer.audioOutputMode = (VideoAudioOutputMode)1;
			videoPlayer.SetTargetAudioSource((ushort)0, audioSource);
			videoPlayer.source = (VideoSource)1;
			videoPlayer.url = fullPath;
			videoPlayer.aspectRatio = (VideoAspectRatio)1;
			RenderTexture val = new RenderTexture(1920, 1080, 0);
			videoPlayer.targetTexture = val;
			rawImage.texture = (Texture)(object)val;
			videoPlayer.errorReceived += new ErrorEventHandler(OnVideoErrorReceived);
			videoPlayer.prepareCompleted += new EventHandler(OnVideoPrepared);
			videoPlayer.Prepare();
		}

		private void AdjustRawImage(RawImage rawImage)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)rawImage).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
		}

		private void OnVideoErrorReceived(VideoPlayer source, string message)
		{
			LogWarden.LogError("Video Error: " + message);
		}

		private void OnVideoPrepared(VideoPlayer source)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			source.prepareCompleted -= new EventHandler(OnVideoPrepared);
			LogWarden.LogInfo("[Video] Prepared and ready to play.");
			source.Play();
		}
	}
	public class Boardwalk
	{
		private readonly Configurator configManager;

		public Boardwalk(Configurator configManager)
		{
			this.configManager = configManager;
		}

		public void ToggleBorder()
		{
			foreach (string item in new List<string> { "MainButtons", "LoadingScreen", "LobbyHostSettings", "DeleteFileConfirmation", "NewsPanel", "MenuNotification", "LANWarning", "LobbyList", "CreditsPanel" })
			{
				Transform val = PathFinder.Probe(item);
				if ((Object)(object)val != (Object)null)
				{
					HideOriginalBorder(val);
					if (item == "MainButtons" && !configManager.enableReplaceBorder.Value)
					{
						CreateBorderCopy(val);
					}
				}
				else
				{
					LogWarden.LogWarning("[Border] " + item + " not found.");
				}
			}
		}

		private void HideOriginalBorder(Transform borderTransform)
		{
			//IL_0012: 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)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Image component = ((Component)borderTransform).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = new Color(((Graphic)component).color.r, ((Graphic)component).color.g, ((Graphic)component).color.b, 0f);
			}
			else
			{
				LogWarden.LogWarning("[Border] No Image component found on " + ((Object)borderTransform).name);
			}
		}

		private void CreateBorderCopy(Transform borderTransform)
		{
			//IL_0037: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)borderTransform).gameObject;
			Image component = gameObject.GetComponent<Image>();
			if ((Object)(object)component == (Object)null)
			{
				LogWarden.LogWarning("[Border] No Image component found on " + ((Object)borderTransform).name + ". Cannot clone.");
				return;
			}
			GameObject val = new GameObject("Corners");
			val.transform.SetParent(gameObject.transform.parent);
			val.transform.SetSiblingIndex(3);
			RectTransform rectTransform = ((Graphic)component).rectTransform;
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).localPosition = ((Transform)rectTransform).localPosition;
			((Transform)obj).localRotation = ((Transform)rectTransform).localRotation;
			((Transform)obj).localScale = ((Transform)rectTransform).localScale;
			obj.anchorMin = rectTransform.anchorMin;
			obj.anchorMax = rectTransform.anchorMax;
			obj.anchoredPosition = rectTransform.anchoredPosition;
			obj.sizeDelta = rectTransform.sizeDelta;
			obj.pivot = rectTransform.pivot;
			float value = configManager.borderPadding.Value;
			obj.offsetMax = new Vector2(0f - value, 0f - value);
			obj.offsetMin = new Vector2(value, value);
			Image obj2 = val.AddComponent<Image>();
			obj2.sprite = component.sprite;
			obj2.type = component.type;
			obj2.fillCenter = component.fillCenter;
			((Graphic)obj2).color = ColorParser.RGBA(configManager.borderColor.Value);
			obj2.pixelsPerUnitMultiplier = component.pixelsPerUnitMultiplier;
			((Graphic)obj2).raycastTarget = false;
			LogWarden.LogInfo("[Border] " + ((Object)borderTransform).name + " border cloned with padding " + value + " and color set to " + configManager.borderColor.Value + ".");
		}
	}
	public class MenuMoodSetter
	{
		private readonly Configurator configManager;

		private static HashSet<string> loggedMessages = new HashSet<string>();

		public MenuMoodSetter(Configurator configManager)
		{
			this.configManager = configManager;
		}

		public void HarmonizeMenuHues()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			if (!configManager.enableMenuColorChange.Value)
			{
				LogWarden.LogInfo("[MoodSetter] Menu color change is disabled.");
				return;
			}
			LogOnce("[MoodSetter] Harmonizing menu hues...");
			Transform val = PathFinder.Probe("MainButtons");
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[MoodSetter] MainButtons object not found.");
				return;
			}
			LogOnce("[MoodSetter] MainButtons object found. Processing children...");
			LogOnce("[MoodSetter] Painting menu font color: " + configManager.menuFontColor.Value);
			LogOnce("[MoodSetter] Painting menu rollover font color: " + configManager.menuRolloverFontColor.Value);
			LogOnce("[MoodSetter] Painting menu rollover background: " + configManager.menuRolloverBGColor.Value);
			foreach (Transform item in val)
			{
				Transform val2 = item;
				if (!((Object)(object)((Component)val2).GetComponent<Button>() == (Object)null))
				{
					DisableAnimator(val2);
					SetupEventTriggers(val2);
					SetTextColor(val2, configManager.menuFontColor.Value);
				}
			}
		}

		private void LogOnce(string message)
		{
			if (!loggedMessages.Contains(message))
			{
				LogWarden.LogInfo(message);
				loggedMessages.Add(message);
			}
		}

		private void DisableAnimator(Transform buttonTransform)
		{
			Animator component = ((Component)buttonTransform).GetComponent<Animator>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
		}

		private void SetupEventTriggers(Transform buttonTransform)
		{
			EventTrigger orAddComponent = GetOrAddComponent<EventTrigger>(((Component)buttonTransform).gameObject);
			AddEventTrigger(orAddComponent, (EventTriggerType)0, delegate
			{
				OnMouseEnter(buttonTransform);
			});
			AddEventTrigger(orAddComponent, (EventTriggerType)1, delegate
			{
				OnMouseExit(buttonTransform);
			});
			AddEventTrigger(orAddComponent, (EventTriggerType)4, delegate
			{
				ResetButtonState(buttonTransform);
			});
		}

		private void OnMouseEnter(Transform buttonTransform)
		{
			SetTextColor(buttonTransform, configManager.menuRolloverFontColor.Value);
			SetSelectionHighlight(buttonTransform, enabled: true, configManager.menuRolloverBGColor.Value);
		}

		private void OnMouseExit(Transform buttonTransform)
		{
			SetTextColor(buttonTransform, configManager.menuFontColor.Value);
			SetSelectionHighlight(buttonTransform, enabled: false, "");
		}

		private void ResetButtonState(Transform buttonTransform)
		{
			SetTextColor(buttonTransform, configManager.menuFontColor.Value);
			SetSelectionHighlight(buttonTransform, enabled: false, "");
		}

		private void SetTextColor(Transform buttonTransform, string colorString)
		{
			//IL_001f: 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)
			//IL_0025: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text componentInChildren = ((Component)buttonTransform).GetComponentInChildren<TMP_Text>();
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				string text = RemoveColorTags(componentInChildren.text);
				Color val = ColorParser.RGBA(colorString);
				string text2 = ColorUtility.ToHtmlStringRGB(new Color(val.r, val.g, val.b));
				componentInChildren.text = "<color=#" + text2 + ">" + text + "</color>";
				componentInChildren.alpha = val.a;
			}
		}

		private string RemoveColorTags(string text)
		{
			return Regex.Replace(text, "<color=#[0-9A-Fa-f]{6,8}>(.*?)</color>", "$1");
		}

		private void SetSelectionHighlight(Transform buttonTransform, bool enabled, string colorString)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			Transform val = buttonTransform.Find("SelectionHighlight");
			Image val2 = default(Image);
			if (!((Object)(object)val == (Object)null) && ((Component)val).TryGetComponent<Image>(ref val2))
			{
				((Behaviour)val2).enabled = enabled;
				if (enabled)
				{
					Color color = ColorParser.RGBA(colorString);
					((Graphic)val2).color = color;
				}
			}
		}

		private T GetOrAddComponent<T>(GameObject obj) where T : Component
		{
			return obj.GetComponent<T>() ?? obj.AddComponent<T>();
		}

		private void AddEventTrigger(EventTrigger trigger, EventTriggerType type, UnityAction<BaseEventData> action)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			Entry val = new Entry
			{
				eventID = type
			};
			((UnityEvent<BaseEventData>)(object)val.callback).AddListener(action);
			trigger.triggers.Add(val);
		}
	}
	public class VersionStyler
	{
		private Configurator configManager;

		public VersionStyler(Configurator config)
		{
			configManager = config;
		}

		public void ApplyVersionStyling()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			if (!configManager.enableCustomVersion.Value)
			{
				LogWarden.LogInfo("[Version] Custom version styling is disabled.");
				return;
			}
			Transform val = PathFinder.Probe("Canvas/MenuContainer/VersionNum");
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[Version] Version number GameObject not found.");
				return;
			}
			TextMeshProUGUI val2 = default(TextMeshProUGUI);
			if (!((Component)val).TryGetComponent<TextMeshProUGUI>(ref val2))
			{
				LogWarden.LogError("[Version] TextMeshPro component not found on Version number GameObject.");
				return;
			}
			string value = configManager.versionTextString.Value;
			string text = ((TMP_Text)val2).text;
			string text2 = value.Replace("%VERSION%", text);
			Color val3 = ColorParser.RGBA(configManager.versionColor.Value);
			((TMP_Text)val2).text = "<color=#" + ColorUtility.ToHtmlStringRGB(val3) + ">" + text2 + "</color>";
			((TMP_Text)val2).alpha = val3.a;
			((TMP_Text)val2).fontSize = configManager.versionFontSize.Value;
			((TMP_Text)val2).enableWordWrapping = false;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			float num = 1f - configManager.versionYOffset.Value / 100f;
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, num);
			component.anchorMax = new Vector2(0.5f, num);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = new Vector2(0f, 0f);
			Color val4 = ColorParser.RGBA(configManager.versionColor.Value);
			float value2 = configManager.versionYOffset.Value;
			LogWarden.LogInfo("[Version] Text set to " + ((TMP_Text)val2).text);
			LogWarden.LogInfo($"[Version] Applied styling - Color {ColorUtility.ToHtmlStringRGBA(val4)}, Font Size {configManager.versionFontSize.Value}, Y Offset {value2}%");
		}
	}
	public class CustomMediaManager
	{
		private EmblemFolder emblemFolder;

		public CustomMediaManager()
		{
			emblemFolder = new EmblemFolder();
		}

		public string LoadCustomVideoPath(string path)
		{
			string text = path;
			if (path.Contains("|"))
			{
				string[] array = path.Split(new char[1] { '|' });
				text = array[Random.Range(0, array.Length)];
			}
			string text2 = emblemFolder.FindFullPath(text);
			if (text2 == null || !text2.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase))
			{
				LogWarden.LogError("[Media] Failed to find video at path: " + text);
				return null;
			}
			if (!Path.IsPathRooted(text2))
			{
				text2 = Path.Combine(Paths.BepInExRootPath, "plugins", text2);
				LogWarden.LogInfo("[Media] Using absolute path for video: " + text2);
			}
			return text2;
		}

		public Sprite LoadCustomImage(string path, string imagePrefix)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			string imagePath = GetImagePath(path, imagePrefix);
			if (imagePath == null)
			{
				LogWarden.LogError("[Media] Failed to find image at path: " + path);
				return null;
			}
			try
			{
				byte[] imageBytes = File.ReadAllBytes(imagePath);
				Texture2D val = LoadTextureFromBytes(imageBytes);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				string logPathForBepInEx = GetLogPathForBepInEx(imagePath);
				LogWarden.LogInfo("[Media] File ripped from " + logPathForBepInEx + ".");
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				LogWarden.LogError("[Media] Failed to read image bytes from path: " + imagePath + ". Exception: " + ex.Message);
				return null;
			}
		}

		private Texture2D LoadTextureFromBytes(byte[] imageBytes)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, imageBytes, true))
			{
				LogWarden.LogError("[Media] Failed to load image data into texture.");
				return null;
			}
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			return val;
		}

		private string GetLogPathForBepInEx(string fullPath)
		{
			int startIndex = fullPath.IndexOf("BepInEx") + "BepInEx".Length;
			return fullPath.Substring(startIndex).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
		}

		private string GetImagePath(string path, string imagePrefix = null)
		{
			string text = emblemFolder.FindFullPath(path);
			if (text != null && text.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
			{
				return text;
			}
			if (text != null && Directory.Exists(text) && !string.IsNullOrEmpty(imagePrefix))
			{
				return GetRandomPrefixFile(text, imagePrefix, ".png");
			}
			LogWarden.LogError("[Media] Path does not exist or is not a valid PNG file: " + path);
			return null;
		}

		private string GetRandomPrefixFile(string directory, string filePrefix, string extension)
		{
			string[] files = Directory.GetFiles(directory, filePrefix + "*.png");
			if (files.Length != 0)
			{
				return files[new Random().Next(files.Length)];
			}
			return GetRandomPngFile(directory);
		}

		private string GetRandomPngFile(string directory)
		{
			string[] files = Directory.GetFiles(directory, "*.png");
			if (files.Length == 0)
			{
				LogWarden.LogError("[Media] No PNG files found in directory " + directory + ".");
				return null;
			}
			return files[new Random().Next(files.Length)];
		}
	}
	public class HeaderReplacement
	{
		private readonly Configurator configManager;

		private readonly CustomMediaManager customMediaManager;

		private readonly UIComponent uiComponent;

		public HeaderReplacement(Configurator configManager, UIComponent uiComponent, CustomMediaManager customMediaManager)
		{
			this.configManager = configManager;
			this.customMediaManager = customMediaManager;
			this.uiComponent = uiComponent;
		}

		public void ReplaceMainImage()
		{
			ReplaceImage("Canvas/MenuContainer/MainButtons/HeaderImage", configManager.mainHeaderPath.Value, configManager.enableReplaceMainHeader.Value, isHeader: true);
		}

		public void ReplaceLoadImage()
		{
			ReplaceImage("Canvas/MenuContainer/LoadingScreen/Image", configManager.loadHeaderPath.Value, configManager.enableReplaceLoadHeader.Value, isHeader: false);
		}

		private void ReplaceImage(string uiPath, string imagePath, bool isEnabled, bool isHeader)
		{
			if (isEnabled && TryGetImageComponent(uiPath, out var targetImage))
			{
				if (!TryLoadCustomSprite(imagePath, isHeader, out var customSprite))
				{
					HideOriginalImage(targetImage);
					return;
				}
				SetupImage(targetImage, customSprite, isHeader);
				ApplyImageModifications(targetImage, isHeader, uiPath);
				LogWarden.LogInfo("[Header] " + uiPath + " image replaced and resized successfully.");
			}
		}

		private void HideOriginalImage(Image targetImage)
		{
			((Behaviour)targetImage).enabled = false;
			LogWarden.LogInfo("[Header] Original image hidden due to missing custom sprite.");
		}

		private bool TryGetImageComponent(string uiPath, out Image targetImage)
		{
			targetImage = GetImageComponent(uiPath);
			return (Object)(object)targetImage != (Object)null;
		}

		private bool TryLoadCustomSprite(string imagePath, bool isHeader, out Sprite customSprite)
		{
			customSprite = null;
			if (string.IsNullOrWhiteSpace(imagePath))
			{
				LogWarden.LogInfo("[Header] Skipping image load for " + (isHeader ? "header" : "loading") + " due to blank path.");
				return false;
			}
			customSprite = customMediaManager.LoadCustomImage(imagePath, isHeader ? "Header" : "Loading");
			if ((Object)(object)customSprite == (Object)null)
			{
				LogWarden.LogError("[Header] Failed to find image at path: " + imagePath);
			}
			return (Object)(object)customSprite != (Object)null;
		}

		private void SetupImage(Image targetImage, Sprite customSprite, bool isHeader)
		{
			targetImage.sprite = customSprite;
			targetImage.preserveAspect = true;
			ResetImageProperties(((Graphic)targetImage).rectTransform);
			SetImageTransparency(targetImage, isHeader ? configManager.mainHeaderAlpha.Value : configManager.loadHeaderAlpha.Value, isHeader ? "Header Image" : "Loading Header Image");
		}

		private void ApplyImageModifications(Image targetImage, bool isHeader, string uiPath)
		{
			if (isHeader || !configManager.loadHeaderStretch.Value)
			{
				SetImageYOffset(((Graphic)targetImage).rectTransform, isHeader ? configManager.mainHeaderYOffset.Value : configManager.loadHeaderYOffset.Value, isHeader);
				SetImageSize(((Graphic)targetImage).rectTransform, isHeader ? configManager.mainHeaderScale.Value : configManager.loadHeaderScale.Value, targetImage.sprite);
			}
			if (!isHeader && configManager.loadHeaderStretch.Value && uiPath == "Canvas/MenuContainer/LoadingScreen/Image")
			{
				StretchLoadingImage(((Graphic)targetImage).rectTransform);
			}
		}

		private Image GetImageComponent(string uiPath)
		{
			Transform val = PathFinder.Probe(uiPath);
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[Header] Failed to find UI element at path '" + uiPath + "'.");
				return null;
			}
			Image component = ((Component)val).GetComponent<Image>();
			if ((Object)(object)component == (Object)null)
			{
				LogWarden.LogError("[Header] Image component not found on UI element at path '" + uiPath + "'.");
				return null;
			}
			return component;
		}

		private void ResetImageProperties(RectTransform rectTransform)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			((Transform)rectTransform).localScale = Vector3.one;
			((Transform)rectTransform).rotation = Quaternion.identity;
			rectTransform.sizeDelta = Vector2.zero;
			rectTransform.anchoredPosition = Vector2.zero;
			rectTransform.anchoredPosition3D = Vector3.zero;
			((Transform)rectTransform).localRotation = Quaternion.identity;
		}

		public void SetImageTransparency(Image image, int transparencyPercent, string imageName)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0031: 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)
			if ((Object)(object)image == (Object)null)
			{
				LogWarden.LogError("[Header] Image component not found.");
				return;
			}
			float num = (float)transparencyPercent / 100f;
			Color color = ((Graphic)image).color;
			((Graphic)image).color = new Color(color.r, color.g, color.b, num);
			LogWarden.LogInfo($"[Header] {imageName} transparency set to {num * 100f}%.");
		}

		private void SetImageYOffset(RectTransform rectTransform, float yOffsetPercent, bool isHeader)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f - yOffsetPercent / 100f;
			rectTransform.anchorMin = new Vector2(0.5f, num);
			rectTransform.anchorMax = new Vector2(0.5f, num);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = new Vector2(0f, 0f);
			string arg = (isHeader ? "Header" : "Loading image");
			LogWarden.LogInfo($"[Header] {arg} Y offset set to {yOffsetPercent}% from the top.");
		}

		private void SetImageSize(RectTransform rectTransform, int scaleValue, Sprite sprite)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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)
			Rect rect = sprite.rect;
			float width = ((Rect)(ref rect)).width;
			rect = sprite.rect;
			float height = ((Rect)(ref rect)).height;
			float num = (float)scaleValue / 250f;
			float num2 = width * num;
			float num3 = height * num;
			rectTransform.sizeDelta = new Vector2(num2, num3);
		}

		public void StretchLoadingImage(RectTransform rectTransform)
		{
			//IL_0015: 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_0051: 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)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rectTransform == (Object)null)
			{
				LogWarden.LogError("[Header] Loading image RectTransform not found.");
				return;
			}
			((Transform)rectTransform).localScale = Vector3.one;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			if (configManager.loadHeaderStretch.Value)
			{
				rectTransform.anchorMin = new Vector2(0f, 0f);
				rectTransform.anchorMax = new Vector2(1f, 1f);
				rectTransform.sizeDelta = Vector2.zero;
				LogWarden.LogInfo("[Header] Loading image stretched to fill screen vertically.");
			}
		}
	}
	public class LoadingText : MonoBehaviour
	{
		private Configurator configManager;

		public void Initialize(Configurator configManager)
		{
			this.configManager = configManager;
		}

		public void ApplyLoadingCustomizations()
		{
			RectTransform val = FindLoadingTextContainer();
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[LoadText] LoadingTextContainer not found.");
				return;
			}
			SetSiblingIndex((Transform)(object)val);
			if (configManager.enableLoadingTextChange.Value)
			{
				SetLoadingText(val, configManager.loadTextString.Value);
			}
			else
			{
				LogWarden.LogInfo("[LoadText] Loading text change is disabled by configuration.");
			}
		}

		private void SetLoadingText(RectTransform loadingTextContainer, string text)
		{
			string[] array = text.Split(new char[1] { '|' });
			string text2 = array[Random.Range(0, array.Length)];
			if (array.Length > 1)
			{
				LogWarden.LogInfo($"[LoadText] Found {array.Length} strings.");
			}
			if (configManager.enableLoadingTextChange.Value)
			{
				SetTextProperties((Transform)(object)loadingTextContainer, text2);
			}
		}

		private RectTransform FindLoadingTextContainer()
		{
			Transform val = PathFinder.Probe("Canvas/MenuContainer/LoadingTextContainer");
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[LoadText] Loading text container not found at path: Canvas/MenuContainer/LoadingTextContainer.");
				return null;
			}
			return ((Component)val).GetComponent<RectTransform>();
		}

		private void SetSiblingIndex(Transform loadingTextContainer)
		{
			loadingTextContainer.SetSiblingIndex(9);
		}

		private void SetTextProperties(Transform loadingTextContainer, string text)
		{
			string text2 = "Canvas/MenuContainer/LoadingTextContainer/LoadingText";
			Transform val = PathFinder.Probe(((Object)loadingTextContainer).name + "/" + text2);
			TextMeshProUGUI val2 = default(TextMeshProUGUI);
			RectTransform loadingTextContainer2 = default(RectTransform);
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[LoadText] TMP component not found at path '" + ((Object)loadingTextContainer).name + "/" + text2 + "'.");
			}
			else if (!((Component)val).TryGetComponent<TextMeshProUGUI>(ref val2))
			{
				LogWarden.LogError("[LoadText] TMP component not found on object at path '" + ((Object)loadingTextContainer).name + "/" + text2 + "'.");
			}
			else if (!((Component)loadingTextContainer).TryGetComponent<RectTransform>(ref loadingTextContainer2))
			{
				LogWarden.LogError("[LoadText] RectTransform component not found on '" + ((Object)loadingTextContainer).name + "'.");
			}
			else
			{
				AdjustTextContainerAnchors(loadingTextContainer2);
				((TMP_Text)val2).text = text;
				((TMP_Text)val2).enableWordWrapping = false;
				((TMP_Text)val2).fontSize = configManager.loadTextSize.Value;
				SetTextColor(val2);
				LogWarden.LogInfo($"[LoadText] Set to: {text} with font size: {configManager.loadTextSize.Value}");
			}
		}

		private void SetTextColor(TextMeshProUGUI loadingTextTMP)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Color color = ColorParser.RGBA(configManager.loadTextColor.Value);
				((Graphic)loadingTextTMP).color = color;
				LogWarden.LogInfo("[LoadText] Font color set to: " + configManager.loadTextColor.Value);
			}
			catch (Exception ex)
			{
				LogWarden.LogError("[LoadText] Error setting font color using ColorParser: " + ex.Message);
			}
		}

		private void AdjustTextContainerAnchors(RectTransform loadingTextContainer)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			float value = configManager.loadTextYOffset.Value;
			if (value == -1f)
			{
				LogWarden.LogInfo("[LoadText] No vertical adjustment applied.");
				return;
			}
			float num = 1f - value / 100f;
			num = Mathf.Clamp(num, 0f, 1f);
			loadingTextContainer.pivot = new Vector2(loadingTextContainer.pivot.x, num);
			loadingTextContainer.anchorMin = new Vector2(loadingTextContainer.anchorMin.x, num);
			loadingTextContainer.anchorMax = new Vector2(loadingTextContainer.anchorMax.x, num);
			Vector2 anchoredPosition = loadingTextContainer.anchoredPosition;
			loadingTextContainer.anchoredPosition = new Vector2(anchoredPosition.x, 0f);
			LogWarden.LogInfo($"[LoadText] Vertical position adjusted with Y Offset: {value}");
		}
	}
	public class UIComponent
	{
		private readonly Configurator configManager;

		public UIComponent(Configurator configManager)
		{
			this.configManager = configManager;
		}

		public void ResetRectTransformProperties()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			List<string> obj = new List<string> { "MainButtons", "LoadingScreen", "LobbyHostSettings", "LobbyList" };
			List<string> list = new List<string>();
			foreach (string item in obj)
			{
				Transform val = PathFinder.Probe(item);
				if ((Object)(object)val == (Object)null)
				{
					LogWarden.LogError("[UI] " + item + " Transform not found.");
					return;
				}
				RectTransform component = ((Component)val).GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null)
				{
					LogWarden.LogError("[UI] " + item + " does not have a RectTransform component.");
					return;
				}
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				component.pivot = new Vector2(0.5f, 0.5f);
				component.anchoredPosition = Vector2.zero;
				component.anchoredPosition3D = Vector3.zero;
				val.localPosition = Vector3.zero;
				val.localScale = Vector3.one;
				list.Add(item);
			}
			if (list.Any())
			{
				LogWarden.LogInfo("[UI] De-borking... " + string.Join(", ", list) + ".");
			}
		}

		public void CreateBackgrounds()
		{
			CreateLoadingBackground();
			(string, string)[] array = new(string, string)[2]
			{
				("MenuContainer/SettingsPanel", "SettingsBackground"),
				("MenuContainer/LobbyList", "LobbyBackground")
			};
			for (int i = 0; i < array.Length; i++)
			{
				var (path, name) = array[i];
				CreateCommonBackground(path, name);
			}
		}

		private void CreateLoadingBackground()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Color val = ColorParser.RGBA(configManager.loadBackgroundColor.Value);
			CreateBackground("LoadingScreen", "LoadingBackground", val, val.a);
		}

		private void CreateCommonBackground(string path, string name)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Color black = Color.black;
			black.a = 0.95f;
			CreateBackground(path, name, black, black.a);
		}

		private void CreateBackground(string path, string name, Color backgroundColor, float alpha)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Transform val = PathFinder.Probe(path);
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[UI] CreateBackgrounds: '" + path + "' Transform not found using PathFinder.");
				return;
			}
			GameObject val2 = new GameObject(name);
			val2.transform.SetParent(val, false);
			val2.transform.SetSiblingIndex(0);
			((Graphic)val2.AddComponent<Image>()).color = backgroundColor;
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 1f);
			component.sizeDelta = Vector2.zero;
		}

		public void SetMainBackgroundColor()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Transform val = PathFinder.Probe("Canvas/MenuContainer");
			if ((Object)(object)val == (Object)null)
			{
				LogWarden.LogError("[UI] Canvas/MenuContainer element not found.");
				return;
			}
			((Graphic)(((Component)val).GetComponent<Image>() ?? ((Component)val).gameObject.AddComponent<Image>())).color = ColorParser.RGB(configManager.mainBackgroundColor.Value);
			LogWarden.LogInfo("[UI] Menu container color set to " + configManager.mainBackgroundColor.Value + ".");
		}

		public void SetVolumeLayerMaskOnAllCameras(int layerMask)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Camera[] array = Object.FindObjectsOfType<Camera>();
			for (int i = 0; i < array.Length; i++)
			{
				HDAdditionalCameraData component = ((Component)array[i]).GetComponent<HDAdditionalCameraData>();
				if ((Object)(object)component != (Object)null)
				{
					component.volumeLayerMask = LayerMask.op_Implicit(layerMask);
				}
			}
		}

		public void ApplyCRTEffectIfNeeded()
		{
			if (configManager.enableCRT.Value)
			{
				Transform val = PathFinder.Probe("Canvas");
				if ((Object)(object)val == (Object)null)
				{
					LogWarden.LogError("[UI] Canvas GameObject not found.");
					return;
				}
				GameObject gameObject = ((Component)val).gameObject;
				new CRTEffect().SetupVolume(gameObject);
			}
		}

		public void ApplyScanlinesIfNeeded()
		{
			if (!configManager.enableScanlines.Value)
			{
				return;
			}
			GameObject val = GameObject.Find("Canvas");
			if ((Object)(object)val != (Object)null)
			{
				ScanlineEffectApplier scanlineEffectApplier = val.GetComponent<ScanlineEffectApplier>();
				if ((Object)(object)scanlineEffectApplier == (Object)null)
				{
					scanlineEffectApplier = val.AddComponent<ScanlineEffectApplier>();
				}
				scanlineEffectApplier.ApplyScanlines("Canvas");
			}
			else
			{
				LogWarden.LogError("[UI] Canvas GameObject not found.");
			}
		}

		public void StartSlideshowIfEnabled(BackgroundManager backgroundManager, HeaderReplacement headerReplacement)
		{
			if (!configManager.enableSlideshow.Value)
			{
				return;
			}
			string[] array = configManager.slideshowSections.Value.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				switch (array[i].Trim().ToLower())
				{
				case "header":
					DelayHelper.StartRepeatingAction(configManager.slideshowDelay.Value, delegate
					{
						headerReplacement.ReplaceMainImage();
					});
					break;
				case "loading":
					DelayHelper.StartRepeatingAction(configManager.slideshowDelay.Value, delegate
					{
						headerReplacement.ReplaceLoadImage();
					});
					break;
				case "background":
					DelayHelper.StartRepeatingAction(configManager.slideshowDelay.Value, delegate
					{
						backgroundManager.ApplyMainMenuBackground();
					});
					break;
				case "loadbackground":
					DelayHelper.StartRepeatingAction(configManager.slideshowDelay.Value, delegate
					{
						backgroundManager.ApplyLoadingBackground();
					});
					break;
				}
			}
		}
	}
}

BepInEx/plugins/me.loaforc.soundapi.dll

Decompiled 8 hours ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using loaforcsSoundAPI.API;
using loaforcsSoundAPI.Behaviours;
using loaforcsSoundAPI.Data;
using loaforcsSoundAPI.LethalCompany;
using loaforcsSoundAPI.LethalCompany.Conditions;
using loaforcsSoundAPI.Providers.Conditions;
using loaforcsSoundAPI.Providers.Formats;
using loaforcsSoundAPI.Providers.Random;
using loaforcsSoundAPI.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("me.loaforc.soundapi")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5+11ed51c98a849d7f9152657957012f5d15f5d53a")]
[assembly: AssemblyProduct("loaforcsSoundAPI")]
[assembly: AssemblyTitle("me.loaforc.soundapi")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace loaforcsSoundAPI
{
	public static class SoundLoader
	{
		internal static Dictionary<string, AudioType> TYPE_MAPPINGS = new Dictionary<string, AudioType> { 
		{
			".ogg",
			(AudioType)14
		} };

		public static bool GetAudioClip(string packName, string folder, string soundName, out AudioClip clip)
		{
			clip = null;
			if (!GetAudioPath(packName, folder, soundName, out var path))
			{
				SoundPlugin.logger.LogError((object)"Failed getting path, check above for more detailed error!");
				return false;
			}
			clip = SoundReplacementAPI.FileFormats[Path.GetExtension(path).ToLower()].LoadAudioClip(path);
			if ((Object)(object)clip == (Object)null)
			{
				SoundPlugin.logger.LogError((object)"Failed getting clip from disk, check above for more detailed error!");
				return false;
			}
			if (string.IsNullOrEmpty(clip.GetName()))
			{
				((Object)clip).name = soundName;
			}
			return true;
		}

		private static bool GetAudioPath(string packName, string folder, string soundName, out string path)
		{
			string text = Path.Combine(Paths.PluginPath, packName, "sounds", folder);
			path = Path.Combine(text, soundName);
			if (!Directory.Exists(text))
			{
				SoundPlugin.logger.LogError((object)(text + " doesn't exist! (failed loading: " + soundName + ")"));
				path = null;
				return false;
			}
			if (!File.Exists(path))
			{
				SoundPlugin.logger.LogError((object)(path + " is a valid folder but the sound contained doesn't exist!"));
				path = null;
				return false;
			}
			return true;
		}
	}
	[BepInPlugin("me.loaforc.soundapi", "loaforcsSoundAPI", "1.0.5")]
	public class SoundPlugin : BaseUnityPlugin
	{
		internal static List<string> UniqueSounds;

		internal static List<SoundPack> SoundPacks = new List<SoundPack>();

		internal JoinableThreadPool nonstartupThreadPool;

		public static SoundPlugin Instance { get; private set; }

		internal static ManualLogSource logger { get; private set; }

		private void Awake()
		{
			logger = Logger.CreateLogSource("me.loaforc.soundapi");
			Instance = this;
			logger.LogInfo((object)"Patching...");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "me.loaforc.soundapi");
			logger.LogInfo((object)"Setting up config...");
			new SoundPluginConfig(((BaseUnityPlugin)this).Config);
			logger.LogInfo((object)"Searching for soundpacks...");
			string[] directories = Directory.GetDirectories(Paths.PluginPath);
			logger.LogInfo((object)"Beginning Bindings");
			logger.LogInfo((object)"Bindings => General => Audio Formats");
			SoundReplacementAPI.RegisterAudioFormatProvider(".mp3", new Mp3AudioFormat());
			SoundReplacementAPI.RegisterAudioFormatProvider(".ogg", new OggAudioFormat());
			SoundReplacementAPI.RegisterAudioFormatProvider(".wav", new WavAudioFormat());
			logger.LogInfo((object)"Bindings => General => Random Generators");
			SoundReplacementAPI.RegisterRandomProvider("pure", new PureRandomProvider());
			SoundReplacementAPI.RegisterRandomProvider("deterministic", new DeterminsticRandomProvider());
			logger.LogInfo((object)"Bindings => General => Conditions");
			SoundReplacementAPI.RegisterConditionProvider("config", new ConfigCondition());
			SoundReplacementAPI.RegisterConditionProvider("mod_installed", new ModInstalledConditionProvider());
			SoundReplacementAPI.RegisterConditionProvider("and", new AndCondition());
			SoundReplacementAPI.RegisterConditionProvider("not", new NotCondition());
			SoundReplacementAPI.RegisterConditionProvider("or", new OrCondition());
			LethalCompanyBindings.Bind();
			string[] array = directories;
			foreach (string text in array)
			{
				string[] directories2 = Directory.GetDirectories(text);
				foreach (string text2 in directories2)
				{
					string path = Path.Combine(text2, "sound_pack.json");
					((BaseUnityPlugin)this).Logger.LogDebug((object)text2);
					if (File.Exists(path))
					{
						SoundPacks.Add(new SoundPack(text2));
						break;
					}
				}
				string path2 = Path.Combine(text, "sound_pack.json");
				if (File.Exists(path2))
				{
					SoundPacks.Add(new SoundPack(text));
				}
			}
			logger.LogInfo((object)"Starting up JoinableThreadPool.");
			nonstartupThreadPool = new JoinableThreadPool(SoundPluginConfig.THREADPOOL_MAX_THREADS.Value);
			foreach (SoundPack soundPack in SoundPacks)
			{
				soundPack.QueueNonStartupOnThreadPool(nonstartupThreadPool);
			}
			nonstartupThreadPool.Start();
			if (!SoundPluginConfig.ENABLE_MULTITHREADING.Value)
			{
				logger.LogInfo((object)"Multithreading is disabled :(, joining the thread pool and blocking the main thread.");
				nonstartupThreadPool.Join();
			}
			logger.LogInfo((object)"Registering onSceneLoaded");
			SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode __)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				AudioSource[] array2 = Object.FindObjectsOfType<AudioSource>(true);
				foreach (AudioSource val in array2)
				{
					if (!(((Component)val).gameObject.scene != scene))
					{
						if (val.playOnAwake)
						{
							val.Stop();
						}
						AudioSourceReplaceHelper audioSourceReplaceHelper = ((Component)val).gameObject.AddComponent<AudioSourceReplaceHelper>();
						audioSourceReplaceHelper.source = val;
					}
				}
			};
			logger.LogInfo((object)"me.loaforc.soundapi:1.0.5 has loaded!");
		}

		private void OnDisable()
		{
			nonstartupThreadPool.Join();
		}
	}
	internal class SoundPluginConfig
	{
		internal static ConfigEntry<bool> ENABLE_MULTITHREADING;

		internal static ConfigEntry<int> THREADPOOL_MAX_THREADS;

		internal SoundPluginConfig(ConfigFile config)
		{
			ENABLE_MULTITHREADING = config.Bind<bool>("SoundLoading", "Multithreading", true, "Whether or not to use multithreading when loading a sound pack. If you haven't been told that you should disable multithreading, you probably don't need to!\nThis setting may not be needed with the new 1.0.0 rewrite of multithreading.");
			THREADPOOL_MAX_THREADS = config.Bind<int>("SoundLoading", "MaxThreadsInThreadPool", 32, "Max amount of threads the loading thread pool can create at once.\nIncreasing this number will decrease loading of non-startup packs but may be unsupported by your CPU.");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "me.loaforc.soundapi";

		public const string PLUGIN_NAME = "loaforcsSoundAPI";

		public const string PLUGIN_VERSION = "1.0.5";
	}
}
namespace loaforcsSoundAPI.Utils
{
	public static class ExtensionMethods
	{
		public static T GetValueOrDefault<T>(this JObject jsonObject, string key, T defaultValue = default(T))
		{
			JToken val = ((jsonObject != null) ? jsonObject.GetValue(key, StringComparison.OrdinalIgnoreCase) : null);
			if (val == null)
			{
				return defaultValue;
			}
			return val.ToObject<T>();
		}

		public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
		{
			if (!dictionary.TryGetValue(key, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, Func<TValue> defaultValueProvider)
		{
			if (!dictionary.TryGetValue(key, out var value))
			{
				return defaultValueProvider();
			}
			return value;
		}

		public static bool IsNumber(this object @object)
		{
			if (!(@object is int) && !(@object is double))
			{
				return @object is float;
			}
			return true;
		}
	}
	internal class JoinableThreadPool
	{
		private readonly ConcurrentQueue<Action> ActionQueue = new ConcurrentQueue<Action>();

		private Thread threadScheduler;

		private const int DEFAULT_MAX = 4;

		private int active;

		private int max;

		public void Queue(Action action)
		{
			ActionQueue.Enqueue(action);
		}

		public void Start()
		{
			threadScheduler = new Thread((ThreadStart)delegate
			{
				SoundPlugin.logger.LogInfo((object)("[Multithreading] Multithreading started, " + ActionQueue.Count + " actions are queued."));
				Stopwatch stopwatch = Stopwatch.StartNew();
				while (ActionQueue.Count > 0 || Volatile.Read(ref active) != 0)
				{
					if (active < max && ActionQueue.TryDequeue(out var action))
					{
						Interlocked.Increment(ref active);
						Thread thread = new Thread((ThreadStart)delegate
						{
							SoundPlugin.logger.LogDebug((object)("[Multithreading] Queued a new thread, at " + active + " out of " + max));
							try
							{
								action();
							}
							catch (Exception ex)
							{
								SoundPlugin.logger.LogError((object)ex);
							}
							Interlocked.Decrement(ref active);
							SoundPlugin.logger.LogDebug((object)("[Multithreading] Thread finished. " + ActionQueue.Count + " actions are left."));
						});
						thread.Start();
						Thread.Yield();
						Thread.Sleep(10);
					}
				}
				stopwatch.Stop();
				SoundPlugin.logger.LogInfo((object)("[Multithreading] Multithreading finished. JoinableThreadPool ran for " + stopwatch.ElapsedMilliseconds + " ms."));
			});
			threadScheduler.Start();
		}

		public void Join()
		{
			SoundPlugin.logger.LogDebug((object)"[Multithreading] Joined JoinableThreadPool.");
			threadScheduler.Join();
		}

		public JoinableThreadPool()
		{
			max = 4;
		}

		public JoinableThreadPool(int max)
		{
			this.max = max;
		}
	}
}
namespace loaforcsSoundAPI.Providers.Random
{
	internal class DeterminsticRandomProvider : RandomProvider
	{
		internal static Dictionary<SoundReplaceGroup, System.Random> Generators = new Dictionary<SoundReplaceGroup, System.Random>();

		public override int Range(SoundReplaceGroup group, int min, int max)
		{
			if (!Generators.TryGetValue(group, out var value))
			{
				value = new System.Random(group.pack.Name.GetHashCode());
				Generators[group] = value;
			}
			return value.Next(min, max);
		}
	}
	internal class PureRandomProvider : RandomProvider
	{
		public override int Range(SoundReplaceGroup group, int min, int max)
		{
			return Random.Range(min, max);
		}
	}
}
namespace loaforcsSoundAPI.Providers.Formats
{
	internal class Mp3AudioFormat : AudioFormatProvider
	{
		public override AudioClip LoadAudioClip(string path)
		{
			return LoadFromUWR(path, (AudioType)24);
		}
	}
	internal class OggAudioFormat : AudioFormatProvider
	{
		public override AudioClip LoadAudioClip(string path)
		{
			return LoadFromUWR(path, (AudioType)14);
		}
	}
	internal class WavAudioFormat : AudioFormatProvider
	{
		public override AudioClip LoadAudioClip(string path)
		{
			return LoadFromUWR(path, (AudioType)20);
		}
	}
}
namespace loaforcsSoundAPI.Providers.Conditions
{
	internal class AndCondition : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup pack, JObject conditionDef)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			foreach (JObject item in (IEnumerable<JToken>)conditionDef["conditions"])
			{
				JObject val = item;
				if (!SoundReplacementAPI.ConditionProviders[(string)val["type"]].Evaluate(pack, val))
				{
					return false;
				}
			}
			return true;
		}
	}
	internal class ConfigCondition : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup group, JObject conditionDef)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Invalid comparison between Unknown and I4
			if (!conditionDef.ContainsKey("value"))
			{
				return group.pack.GetConfigOption<bool>((string)conditionDef["config"]);
			}
			if ((int)conditionDef["value"].Type == 9)
			{
				return group.pack.GetConfigOption<bool>((string)conditionDef["config"]) == (bool)conditionDef["value"];
			}
			object rawConfigOption = group.pack.GetRawConfigOption((string)conditionDef["config"]);
			if ((int)conditionDef["value"].Type == 8)
			{
				if (rawConfigOption is ConfigEntry<float>)
				{
					return EvaluateRangeOperator((rawConfigOption as ConfigEntry<float>).Value, (string)conditionDef["value"]);
				}
				return (string)rawConfigOption == (string)conditionDef["value"];
			}
			return false;
		}
	}
	internal class ModInstalledConditionProvider : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup group, JObject conditionDef)
		{
			return Chainloader.PluginInfos.ContainsKey((string)conditionDef["value"]);
		}
	}
	internal class NotCondition : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup pack, JObject conditionDef)
		{
			ConditionProvider conditionProvider = SoundReplacementAPI.ConditionProviders[(string)conditionDef["condition"][(object)"type"]];
			JToken obj = conditionDef["condition"];
			return !conditionProvider.Evaluate(pack, (JObject)(object)((obj is JObject) ? obj : null));
		}
	}
	internal class OrCondition : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup pack, JObject conditionDef)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			foreach (JObject item in (IEnumerable<JToken>)conditionDef["conditions"])
			{
				JObject val = item;
				if (SoundReplacementAPI.ConditionProviders[(string)val["type"]].Evaluate(pack, val))
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace loaforcsSoundAPI.Patches
{
	[HarmonyPatch(typeof(AudioSource))]
	internal static class AudioSourcePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Play", new Type[] { })]
		[HarmonyPatch("Play", new Type[] { typeof(ulong) })]
		internal static void Play(AudioSource __instance)
		{
			if ((Object)(object)((Component)__instance).gameObject == (Object)null)
			{
				SoundPlugin.logger.LogWarning((object)"AudioSource has no GameObject!!");
			}
			else
			{
				if (AudioSourceReplaceHelper.helpers.TryGetValue(__instance, out var value) && value.DisableReplacing)
				{
					return;
				}
				SoundReplacementCollection collection;
				AudioClip replacementClip = GetReplacementClip(ProcessName(__instance, __instance.clip), out collection);
				if (!((Object)(object)replacementClip != (Object)null))
				{
					return;
				}
				((Object)replacementClip).name = ((Object)__instance.clip).name;
				__instance.clip = replacementClip;
				if ((Object)(object)value == (Object)null)
				{
					if (__instance.playOnAwake)
					{
						__instance.Stop();
					}
					value = ((Component)__instance).gameObject.AddComponent<AudioSourceReplaceHelper>();
					value.source = __instance;
				}
				value.replacedWith = collection;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("PlayOneShot", new Type[]
		{
			typeof(AudioClip),
			typeof(float)
		})]
		internal static void PlayOneShot(AudioSource __instance, ref AudioClip clip)
		{
			if ((Object)(object)((Component)__instance).gameObject == (Object)null)
			{
				SoundPlugin.logger.LogWarning((object)"AudioSource has no GameObject!!");
			}
			else
			{
				if (AudioSourceReplaceHelper.helpers.TryGetValue(__instance, out var value) && value.DisableReplacing)
				{
					return;
				}
				SoundReplacementCollection collection;
				AudioClip replacementClip = GetReplacementClip(ProcessName(__instance, clip), out collection);
				if (!((Object)(object)replacementClip != (Object)null))
				{
					return;
				}
				if ((Object)(object)value == (Object)null)
				{
					if (__instance.playOnAwake)
					{
						__instance.Stop();
					}
					value = ((Component)__instance).gameObject.AddComponent<AudioSourceReplaceHelper>();
					value.source = __instance;
				}
				((Object)replacementClip).name = ((Object)clip).name;
				clip = replacementClip;
				value.replacedWith = collection;
			}
		}

		internal static string TrimGameObjectName(GameObject gameObject)
		{
			string text = ((Object)gameObject).name.Replace("(Clone)", "");
			for (int i = 0; i < 10; i++)
			{
				text = text.Replace("(" + i + ")", "");
			}
			return text.Trim();
		}

		internal static string ProcessName(AudioSource source, AudioClip clip)
		{
			if ((Object)(object)clip == (Object)null)
			{
				return null;
			}
			string text = ":" + TrimGameObjectName(((Component)source).gameObject);
			if ((Object)(object)((Component)source).transform.parent != (Object)null)
			{
				text = TrimGameObjectName(((Component)((Component)source).transform.parent).gameObject) + text;
			}
			return text + ":" + ((Object)clip).name;
		}

		internal static AudioClip GetReplacementClip(string name, out SoundReplacementCollection collection)
		{
			collection = null;
			if (name == null)
			{
				return null;
			}
			if (!SoundReplacementAPI.SoundReplacements.ContainsKey(name.Split(":")[2]))
			{
				return null;
			}
			List<SoundReplacementCollection> list = (from x in SoundReplacementAPI.SoundReplacements[name.Split(":")[2]]
				where x.MatchesWith(name)
				where x.TestCondition()
				select x).ToList();
			if (list.Count == 0)
			{
				return null;
			}
			_ = list.Count;
			_ = 1;
			collection = list[Random.Range(0, list.Count)];
			List<SoundReplacement> list2 = collection.replacements.Where((SoundReplacement x) => x.TestCondition()).ToList();
			if (list2.Count == 0)
			{
				return null;
			}
			int totalWeight = 0;
			list2.ForEach(delegate(SoundReplacement replacement)
			{
				totalWeight += replacement.Weight;
			});
			int num = collection.group.Random.Range(collection.group, 0, totalWeight);
			int index = 0;
			while (num > 0)
			{
				index = collection.group.Random.Range(collection.group, 0, list2.Count);
				num -= collection.group.Random.Range(collection.group, 1, list2[index].Weight);
			}
			return list2[index].Clip;
		}
	}
	[HarmonyPatch(typeof(GameObject))]
	internal class GameObjectPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("AddComponent", new Type[] { typeof(Type) })]
		internal static void NewAudioSource(GameObject __instance, ref Component __result)
		{
			if (__result is AudioSource)
			{
				Component obj = __result;
				AudioSource val = (AudioSource)(object)((obj is AudioSource) ? obj : null);
				if (val.playOnAwake)
				{
					val.Stop();
				}
				AudioSourceReplaceHelper audioSourceReplaceHelper = __instance.AddComponent<AudioSourceReplaceHelper>();
				audioSourceReplaceHelper.source = val;
			}
		}
	}
	[HarmonyPatch(typeof(Object))]
	internal static class UnityObjectPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Instantiate", new Type[] { typeof(Object) })]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Transform),
			typeof(bool)
		})]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Vector3),
			typeof(Quaternion)
		})]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Vector3),
			typeof(Quaternion),
			typeof(Transform)
		})]
		internal static void FixPlayOnAwake(ref Object __result)
		{
			if (__result is GameObject)
			{
				Object obj = __result;
				CheckGameObject((GameObject)(object)((obj is GameObject) ? obj : null));
			}
		}

		private static void CheckGameObject(GameObject @object)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			AudioSourceReplaceHelper audioSourceReplaceHelper = default(AudioSourceReplaceHelper);
			if (@object.TryGetComponent<AudioSourceReplaceHelper>(ref audioSourceReplaceHelper))
			{
				return;
			}
			AudioSource[] components = @object.GetComponents<AudioSource>();
			AudioSource[] array = components;
			foreach (AudioSource val in array)
			{
				if (val.playOnAwake)
				{
					val.Stop();
				}
				AudioSourceReplaceHelper audioSourceReplaceHelper2 = @object.AddComponent<AudioSourceReplaceHelper>();
				audioSourceReplaceHelper2.source = val;
			}
			foreach (Transform item in @object.transform)
			{
				Transform val2 = item;
				CheckGameObject(((Component)val2).gameObject);
			}
		}
	}
}
namespace loaforcsSoundAPI.LethalCompany
{
	internal static class LethalCompanyBindings
	{
		internal static void Bind()
		{
			SoundReplacementAPI.RegisterConditionProvider("LethalCompany:dungeon_name", new DungeonConditionProvider());
			SoundReplacementAPI.RegisterConditionProvider("LethalCompany:moon_name", new MoonConditionProvider());
			SoundReplacementAPI.RegisterConditionProvider("LethalCompany:player_health", new PlayerHealthConditionProvider());
			SoundReplacementAPI.RegisterConditionProvider("LethalCompany:time_of_day", new TimeOfDayConditionProvider());
			SoundReplacementAPI.RegisterConditionProvider("LethalCompany:player_location", new PlayerLocationTypeConditionProvider());
		}
	}
}
namespace loaforcsSoundAPI.LethalCompany.Conditions
{
	internal class DungeonConditionProvider : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup group, JObject conditionDef)
		{
			SoundPlugin.logger.LogDebug((object)("LethalCompany:dungeon_name value: " + ((Object)RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow).name));
			return Extensions.Value<string>((IEnumerable<JToken>)conditionDef["value"]) == ((Object)RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow).name;
		}
	}
	internal class MoonConditionProvider : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup group, JObject conditionDef)
		{
			SoundPlugin.logger.LogDebug((object)("LethalCompany:moon_name value: " + ((Object)StartOfRound.Instance.currentLevel).name));
			return Extensions.Value<string>((IEnumerable<JToken>)conditionDef["value"]) == ((Object)StartOfRound.Instance.currentLevel).name;
		}
	}
	internal class PlayerHealthConditionProvider : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup group, JObject conditionDef)
		{
			return EvaluateRangeOperator(GameNetworkManager.Instance.localPlayerController.health, Extensions.Value<string>((IEnumerable<JToken>)conditionDef["value"]));
		}
	}
	internal class PlayerLocationTypeConditionProvider : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup group, JObject varDef)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (GameNetworkManager.Instance.localPlayerController.isPlayerDead)
			{
				return false;
			}
			if (GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				return Extensions.Value<string>((IEnumerable<JToken>)varDef["value"]) == "inside";
			}
			Bounds bounds = StartOfRound.Instance.shipBounds.bounds;
			if (((Bounds)(ref bounds)).Contains(((Component)GameNetworkManager.Instance.localPlayerController).transform.position))
			{
				return Extensions.Value<string>((IEnumerable<JToken>)varDef["value"]) == "on_ship";
			}
			return Extensions.Value<string>((IEnumerable<JToken>)varDef["value"]) == "outside";
		}
	}
	internal class TimeOfDayConditionProvider : ConditionProvider
	{
		public override bool Evaluate(SoundReplaceGroup group, JObject varDef)
		{
			return Extensions.Value<string>((IEnumerable<JToken>)varDef["value"]) == ((object)(DayMode)(ref TimeOfDay.Instance.dayMode)).ToString().ToLower();
		}
	}
}
namespace loaforcsSoundAPI.Data
{
	public class SoundPack
	{
		private static List<SoundPack> LoadedSoundPacks = new List<SoundPack>();

		private List<SoundReplaceGroup> replaceGroups = new List<SoundReplaceGroup>();

		private string[] loadOnStartup;

		private Dictionary<string, object> Config = new Dictionary<string, object>();

		public string Name { get; private set; }

		public string PackPath { get; private set; }

		public IReadOnlyCollection<SoundReplaceGroup> ReplaceGroups => replaceGroups.AsReadOnly();

		public T GetConfigOption<T>(string configID)
		{
			return ((ConfigEntry<T>)Config[configID]).Value;
		}

		internal object GetRawConfigOption(string configID)
		{
			return Config[configID];
		}

		public SoundPack(string folder)
		{
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected O, but got Unknown
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Expected I4, but got Unknown
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			SoundPlugin.logger.LogDebug((object)("Soundpack `" + folder + "` is being loaded."));
			Stopwatch stopwatch = Stopwatch.StartNew();
			PackPath = Path.Combine(Paths.PluginPath, folder);
			string text = File.ReadAllText(Path.Combine(PackPath, "sound_pack.json"));
			object obj = JsonConvert.DeserializeObject(text);
			JObject val = (JObject)((obj is JObject) ? obj : null);
			Name = (string)val["name"];
			if (string.IsNullOrEmpty(Name))
			{
				SoundPlugin.logger.LogError((object)("`name` is missing or empty in `" + folder + "/sound_pack.json`"));
				return;
			}
			if (!Directory.Exists(Path.Combine(PackPath, "replacers")))
			{
				SoundPlugin.logger.LogInfo((object)"You've succesfully made a Sound-Pack! Continue with the tutorial to learn how to begin replacing sounds.");
			}
			else
			{
				loadOnStartup = (from name in val.GetValueOrDefault("load_on_startup", new string[0])
					select name + ".json").ToArray();
				if (!val.ContainsKey("load_on_startup"))
				{
					SoundPlugin.logger.LogWarning((object)"No replacers were defined in `replacers` so every single replacer is being loaded on start-up. Consider adding some so that loaforcsSoundAPI can use multithreading.");
					loadOnStartup = Directory.GetFiles(Path.Combine(PackPath, "replacers")).Select(Path.GetFileName).ToArray();
				}
				SoundPlugin.logger.LogInfo((object)("Loading: " + string.Join(",", loadOnStartup) + " on startup."));
				ParseReplacers(loadOnStartup);
			}
			if (val.ContainsKey("config"))
			{
				Stopwatch stopwatch2 = Stopwatch.StartNew();
				ConfigFile val2 = new ConfigFile(Utility.CombinePaths(new string[2]
				{
					Paths.ConfigPath,
					"soundpack." + Name + ".cfg"
				}), false, MetadataHelper.GetMetadata((object)SoundPlugin.Instance));
				foreach (JProperty item in (IEnumerable<JToken>)val["config"])
				{
					JProperty val3 = item;
					JToken value = val3.Value;
					JObject val4 = (JObject)(object)((value is JObject) ? value : null);
					if (!val4.ContainsKey("default"))
					{
						SoundPlugin.logger.LogError((object)("`" + val3.Name + " doesn't have a default value!"));
						continue;
					}
					if (!val4.ContainsKey("description"))
					{
						SoundPlugin.logger.LogWarning((object)("`" + val3.Name + " doesn't have a description, consider adding one!"));
					}
					JTokenType type = val4["default"].Type;
					switch (type - 6)
					{
					case 3:
						Config.Add(val3.Name, val2.Bind<bool>(val3.Name.Split(":")[0], val3.Name.Split(":")[1], (bool)val4["default"], val4.GetValueOrDefault("description", "[no description was provided]")));
						break;
					case 2:
						Config.Add(val3.Name, val2.Bind<string>(val3.Name.Split(":")[0], val3.Name.Split(":")[1], (string)val4["default"], val4.GetValueOrDefault("description", "[no description was provided]")));
						break;
					case 0:
					case 1:
						Config.Add(val3.Name, val2.Bind<float>(val3.Name.Split(":")[0], val3.Name.Split(":")[1], (float)val4["default"], val4.GetValueOrDefault("description", "[no description was provided]")));
						break;
					default:
						SoundPlugin.logger.LogError((object)string.Format("`{0} configtype is currently unsupported! Supported values: bool, float, int, string", val4["default"].Type));
						break;
					}
				}
				stopwatch2.Stop();
				SoundPlugin.logger.LogInfo((object)$"Loaded {Name}(start-up:config) in {stopwatch2.ElapsedMilliseconds}ms.");
			}
			LoadedSoundPacks.Add(this);
			stopwatch.Stop();
			SoundPlugin.logger.LogInfo((object)$"Loaded {Name}(start-up) in {stopwatch.ElapsedMilliseconds}ms.");
		}

		internal void QueueNonStartupOnThreadPool(JoinableThreadPool threadPool)
		{
			if (!Directory.Exists(Path.Combine(PackPath, "replacers")))
			{
				return;
			}
			string[] array = (from replacer in Directory.GetFiles(Path.Combine(PackPath, "replacers")).Select(Path.GetFileName)
				where !loadOnStartup.Contains(replacer)
				select replacer).ToArray();
			string[] array2 = array;
			foreach (string replacer2 in array2)
			{
				threadPool.Queue(delegate
				{
					ParseReplacer(replacer2);
				});
			}
		}

		private void ParseReplacers(string[] replacers)
		{
			foreach (string replacer in replacers)
			{
				ParseReplacer(replacer);
			}
		}

		private void ParseReplacer(string replacer)
		{
			string path = Path.Combine(PackPath, "replacers", replacer);
			SoundPlugin.logger.LogDebug((object)("Parsing `" + Path.GetFileName(path) + "` as a sound replacer"));
			object obj = JsonConvert.DeserializeObject(File.ReadAllText(path));
			JObject data = (JObject)((obj is JObject) ? obj : null);
			new SoundReplaceGroup(this, data);
		}
	}
	public class SoundReplaceGroup : Conditonal
	{
		public SoundPack pack { get; private set; }

		internal RandomProvider Random { get; private set; }

		internal JObject RandomSettings { get; private set; }

		internal bool UpdateEveryFrame { get; private set; }

		public SoundReplaceGroup(SoundPack pack, JObject data)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			this.pack = pack;
			foreach (JObject item in (IEnumerable<JToken>)data["replacements"])
			{
				JObject data2 = item;
				new SoundReplacementCollection(this, data2);
			}
			Random = SoundReplacementAPI.RandomProviders["pure"];
			if (data.ContainsKey("randomness"))
			{
				JToken obj = data["randomness"];
				RandomSettings = (JObject)(object)((obj is JObject) ? obj : null);
				if (SoundReplacementAPI.RandomProviders.ContainsKey((string)RandomSettings["type"]))
				{
					Random = SoundReplacementAPI.RandomProviders[(string)RandomSettings["type"]];
				}
			}
			if (data.ContainsKey("condition"))
			{
				JToken obj2 = data["condition"];
				Setup(this, (JObject)(object)((obj2 is JObject) ? obj2 : null));
			}
			if (data.ContainsKey("update_every_frame"))
			{
				UpdateEveryFrame = (bool)data["update_every_frame"];
			}
		}
	}
	internal class SoundReplacementCollection : Conditonal
	{
		internal readonly List<SoundReplacement> replacements = new List<SoundReplacement>();

		private readonly List<string> matchers = new List<string>();

		internal readonly SoundReplaceGroup group;

		internal SoundReplacementCollection(SoundReplaceGroup group, JObject data)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			this.group = group;
			if (data.ContainsKey("condition"))
			{
				JToken obj = data["condition"];
				Setup(group, (JObject)(object)((obj is JObject) ? obj : null));
			}
			foreach (JObject item in (IEnumerable<JToken>)data["sounds"])
			{
				JObject val = item;
				SoundReplacement soundReplacement = new SoundReplacement(group, val)
				{
					SoundPath = (string)val["sound"],
					Weight = val.GetValueOrDefault("weight", 1)
				};
				SoundLoader.GetAudioClip(group.pack.PackPath, Path.GetDirectoryName(soundReplacement.SoundPath), Path.GetFileName(soundReplacement.SoundPath), out var clip);
				if ((Object)(object)clip == (Object)null)
				{
					SoundPlugin.logger.LogError((object)"Failed to get audio clip, check above more detailed error");
					continue;
				}
				soundReplacement.Clip = clip;
				replacements.Add(soundReplacement);
			}
			if (((object)data["matches"]).GetType() == typeof(JValue))
			{
				RegisterWithMatch((string)data["matches"]);
				return;
			}
			foreach (JToken item2 in (IEnumerable<JToken>)data["matches"])
			{
				string matchString = (string)item2;
				RegisterWithMatch(matchString);
			}
		}

		internal bool MatchesWith(string a)
		{
			foreach (string matcher in matchers)
			{
				if (SoundReplacementAPI.MatchStrings(a, matcher))
				{
					return true;
				}
			}
			return false;
		}

		private void RegisterWithMatch(string matchString)
		{
			string key = SoundReplacementAPI.FormatMatchString(matchString).Split(":")[2];
			List<SoundReplacementCollection> valueOrDefault = SoundReplacementAPI.SoundReplacements.GetValueOrDefault(key, new List<SoundReplacementCollection>());
			valueOrDefault.Add(this);
			matchers.Add(SoundReplacementAPI.FormatMatchString(matchString));
			SoundReplacementAPI.SoundReplacements[key] = valueOrDefault;
		}

		public override bool TestCondition()
		{
			if (base.TestCondition())
			{
				return group.TestCondition();
			}
			return false;
		}
	}
	internal class SoundReplacement : Conditonal
	{
		public int Weight = 1;

		public string SoundPath { get; set; }

		public AudioClip Clip { get; set; }

		public SoundReplacement(SoundReplaceGroup group, JObject data)
		{
			if (data.ContainsKey("condition"))
			{
				JToken obj = data["condition"];
				Setup(group, (JObject)(object)((obj is JObject) ? obj : null));
			}
		}
	}
}
namespace loaforcsSoundAPI.Behaviours
{
	public class AudioSourceReplaceHelper : MonoBehaviour
	{
		internal AudioSource source;

		internal SoundReplacementCollection replacedWith;

		internal static Dictionary<AudioSource, AudioSourceReplaceHelper> helpers = new Dictionary<AudioSource, AudioSourceReplaceHelper>();

		public bool DisableReplacing { get; private set; }

		private void Start()
		{
			if ((Object)(object)source == (Object)null)
			{
				SoundPlugin.logger.LogWarning((object)("AudioSource (on gameobject: " + ((Object)((Component)this).gameObject).name + ") became null between the OnSceneLoaded callback and Start. This is most likely because of another mod."));
				return;
			}
			if (source.playOnAwake && ((Behaviour)source).enabled)
			{
				source.Play();
			}
			helpers[source] = this;
		}

		private void OnEnable()
		{
			if (!((Object)(object)source == (Object)null))
			{
				helpers[source] = this;
			}
		}

		private void OnDestroy()
		{
			if (!((Object)(object)source == (Object)null) && helpers.ContainsKey(source))
			{
				helpers.Remove(source);
			}
		}

		private void LateUpdate()
		{
			if (replacedWith != null && replacedWith.group.UpdateEveryFrame)
			{
				DisableReplacing = true;
				float time = source.time;
				SoundReplacement soundReplacement = replacedWith.replacements.Where((SoundReplacement x) => x.TestCondition()).ToList()[0];
				if (!((Object)(object)soundReplacement.Clip == (Object)(object)source.clip))
				{
					source.clip = soundReplacement.Clip;
					source.Play();
					source.time = time;
				}
			}
		}
	}
}
namespace loaforcsSoundAPI.API
{
	public abstract class AudioFormatProvider
	{
		public abstract AudioClip LoadAudioClip(string path);

		protected AudioClip LoadFromUWR(string path, AudioType type)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			AudioClip result = null;
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, type);
			try
			{
				audioClip.SendWebRequest();
				try
				{
					while (!audioClip.isDone)
					{
					}
					if ((int)audioClip.result != 1)
					{
						SoundPlugin.logger.LogError((object)"============");
						SoundPlugin.logger.LogError((object)("UnityWebRequest failed while trying to get " + path + ". Full error below"));
						SoundPlugin.logger.LogError((object)audioClip.error);
						SoundPlugin.logger.LogError((object)"============");
					}
					else
					{
						result = DownloadHandlerAudioClip.GetContent(audioClip);
					}
				}
				catch (Exception ex)
				{
					SoundPlugin.logger.LogError((object)(ex.Message + ", " + ex.StackTrace));
				}
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
			return result;
		}
	}
	public abstract class ConditionProvider
	{
		public abstract bool Evaluate(SoundReplaceGroup group, JObject conditionDef);

		public bool EvaluateRangeOperator(JToken number, string condition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)number.Type == 7)
			{
				return EvaluateRangeOperator(Extensions.Value<float>((IEnumerable<JToken>)number), condition);
			}
			return EvaluateRangeOperator(Extensions.Value<int>((IEnumerable<JToken>)number), condition);
		}

		public bool EvaluateRangeOperator(int number, string condition)
		{
			return EvaluateRangeOperator((double)number, condition);
		}

		public bool EvaluateRangeOperator(float number, string condition)
		{
			return EvaluateRangeOperator((double)number, condition);
		}

		public bool EvaluateRangeOperator(double number, string condition)
		{
			string[] array = condition.Split("..");
			if (array.Length == 1)
			{
				if (double.TryParse(array[0], out var result))
				{
					return number == result;
				}
				return false;
			}
			if (array.Length == 2)
			{
				double result2;
				if (array[0] == "")
				{
					result2 = double.MinValue;
				}
				else if (!double.TryParse(array[0], out result2))
				{
					return false;
				}
				double result3;
				if (array[1] == "")
				{
					result3 = double.MaxValue;
				}
				else if (!double.TryParse(array[1], out result3))
				{
					return false;
				}
				if (number >= result2)
				{
					return number <= result3;
				}
				return false;
			}
			return false;
		}
	}
	public abstract class Conditonal
	{
		private ConditionProvider GroupCondition;

		private SoundReplaceGroup group;

		internal JObject ConditionSettings { get; private set; }

		protected void Setup(SoundReplaceGroup group, JObject settings)
		{
			this.group = group;
			if (settings != null)
			{
				ConditionSettings = settings;
				GroupCondition = SoundReplacementAPI.ConditionProviders[(string)ConditionSettings["type"]];
			}
		}

		public virtual bool TestCondition()
		{
			if (GroupCondition == null)
			{
				return true;
			}
			return GroupCondition.Evaluate(group, ConditionSettings);
		}
	}
	public abstract class RandomProvider
	{
		public abstract int Range(SoundReplaceGroup group, int min, int max);
	}
	public static class SoundReplacementAPI
	{
		internal static Dictionary<string, AudioFormatProvider> FileFormats = new Dictionary<string, AudioFormatProvider>();

		internal static Dictionary<string, RandomProvider> RandomProviders = new Dictionary<string, RandomProvider>();

		internal static Dictionary<string, ConditionProvider> ConditionProviders = new Dictionary<string, ConditionProvider>();

		internal static ConcurrentDictionary<string, List<SoundReplacementCollection>> SoundReplacements = new ConcurrentDictionary<string, List<SoundReplacementCollection>>();

		public static void RegisterAudioFormatProvider(string extension, AudioFormatProvider provider)
		{
			FileFormats.Add(extension, provider);
		}

		public static void RegisterRandomProvider(string extension, RandomProvider provider)
		{
			RandomProviders.Add(extension, provider);
		}

		public static void RegisterConditionProvider(string extension, ConditionProvider provider)
		{
			ConditionProviders.Add(extension, provider);
		}

		public static string FormatMatchString(string input)
		{
			if (input.Split(":").Length == 2)
			{
				input = "*:" + input;
			}
			return input;
		}

		public static bool MatchStrings(string a, string b)
		{
			SoundPlugin.logger.LogDebug((object)(a + " == " + b + "?"));
			string[] array = a.Split(":");
			string[] array2 = b.Split(":");
			if (array2[0] != "*" && array2[0] != array[0])
			{
				return false;
			}
			if (array2[1] != "*" && array2[1] != array[1])
			{
				return false;
			}
			return array[2] == array2[2];
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}