Decompiled source of Interior Title Cards v1.3.1

BepInEx/plugins/interiortitlecards/Interior Title Cards.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InteriorTitleCards.Core;
using InteriorTitleCards.Managers;
using InteriorTitleCards.Utils;
using LethalLevelLoader;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal class ConfigurationManagerAttributes
{
	public int? Order;
}
public enum ImageSourceMode
{
	[Description("Developer images only")]
	DeveloperOnly,
	[Description("User-made images only")]
	UserOnly,
	[Description("Both (developer prioritized)")]
	BothDeveloperPriority,
	[Description("Both (user prioritized)")]
	BothUserPriority
}
public enum ImageDisplayType
{
	[Description("Top text image only")]
	TopTextOnly,
	[Description("Interior text image only")]
	InteriorTextOnly,
	[Description("Top text image and interior text image")]
	BothSeparate,
	[Description("Combined image")]
	Combined
}
namespace InteriorTitleCards
{
	[BepInPlugin("com.github.interiortitlecards", "Interior Title Cards", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static Plugin Instance;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private ConfigManager configManager;

		private TitleCardManager titleCardManager;

		private void Awake()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Logger.Initialize(Log);
			Logger.LogInfo("Initializing Interior Title Cards plugin");
			configManager = new ConfigManager(((BaseUnityPlugin)this).Config, Log, this);
			titleCardManager = new TitleCardManager(Log, configManager);
			configManager.SetOnConfigsBoundCallback(delegate
			{
				titleCardManager.ReInitializeBlacklist();
			});
			_harmony = new Harmony("com.github.interiortitlecards");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Harmony patches applied");
		}

		private void Start()
		{
			configManager?.Initialize();
		}

		internal void InitializeTitleCard()
		{
			titleCardManager?.CreateTitleCard();
		}

		internal void OnPlayerEnterFacility()
		{
			titleCardManager?.OnEnterFacility();
		}

		internal void OnPlayerExitFacility()
		{
			titleCardManager?.OnExitFacility();
		}

		internal void ResetTitleCard()
		{
			titleCardManager?.ResetTitleCard();
		}

		private void OnDestroy()
		{
			titleCardManager?.Cleanup();
		}
	}
}
namespace InteriorTitleCards.Utils
{
	public static class TitleCardConstants
	{
		public const float CardWidth = 400f;

		public const float CardHeight = 120f;

		public const float TextHeight = 40f;

		public const float TopTextOffset = 20f;

		public const float BottomTextOffset = -20f;

		public const float CenterAnchor = 0.5f;

		public static readonly Vector2 DefaultTopTextPosition = new Vector2(0f, 20f);

		public static readonly Vector2 DefaultInteriorTextPosition = new Vector2(0f, -20f);

		public static readonly Vector2 DefaultTopImagePosition = new Vector2(0f, 20f);

		public static readonly Vector2 DefaultInteriorImagePosition = new Vector2(0f, -20f);

		public static readonly Vector2 DefaultCombinedImagePosition = new Vector2(0f, 0f);

		public const int DefaultTopTextFontSize = 20;

		public const int DefaultBottomTextFontSize = 28;

		public const int TopTextFontSize = 20;

		public const int BottomTextFontSize = 28;

		public const string CustomDungeonPrefix = "Custom Dungeon:";

		public const string VanillaDungeonPrefix = "Vanilla Dungeon:";

		public const float DefaultDisplayDuration = 3f;

		public const float DefaultFadeDuration = 0.5f;

		public const int DefaultFontWeightNormal = 400;

		public const int DefaultFontWeightBold = 700;

		public const string DefaultTitleColor = "#fe6001";

		public const string DefaultTopTextColor = "#fe6001";

		public const string DefaultInteriorTextColor = "#fe6001";

		public const int MaxConfigRetryAttempts = 3;

		public const float ConfigRetryBaseDelay = 3f;

		public const float ConfigRetryMaxDelay = 30f;

		public const float ConfigInitializationDelay = 5f;

		public const string PluginGuid = "com.github.interiortitlecards";
	}
}
namespace InteriorTitleCards.Patches
{
	[HarmonyPatch(typeof(EntranceTeleport))]
	public class EntranceTeleportPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("TeleportPlayer")]
		public static void TeleportPlayerPostfix(EntranceTeleport __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					Plugin.Log.LogWarning((object)"EntranceTeleport instance is null in TeleportPlayerPostfix");
				}
				else if (__instance.isEntranceToBuilding)
				{
					if ((Object)(object)Plugin.Instance != (Object)null)
					{
						Plugin.Instance.OnPlayerEnterFacility();
					}
					else
					{
						Plugin.Log.LogWarning((object)"Plugin instance is null in TeleportPlayerPostfix");
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error in TeleportPlayerPostfix: " + ex.Message));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("TeleportPlayerClientRpc")]
		public static void TeleportPlayerClientRpcPostfix(EntranceTeleport __instance, int playerObj)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					Plugin.Log.LogWarning((object)"EntranceTeleport instance is null in TeleportPlayerClientRpcPostfix");
				}
				else if ((Object)(object)__instance.playersManager == (Object)null || __instance.playersManager.allPlayerScripts == null || playerObj < 0 || playerObj >= __instance.playersManager.allPlayerScripts.Length)
				{
					Plugin.Log.LogWarning((object)$"Invalid playerObj {playerObj} in TeleportPlayerClientRpcPostfix");
				}
				else if (__instance.isEntranceToBuilding && (Object)(object)__instance.playersManager.allPlayerScripts[playerObj] == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					if ((Object)(object)Plugin.Instance != (Object)null)
					{
						Plugin.Instance.OnPlayerEnterFacility();
					}
					else
					{
						Plugin.Log.LogWarning((object)"Plugin instance is null in TeleportPlayerClientRpcPostfix");
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error in TeleportPlayerClientRpcPostfix: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	public class HUDManagerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void HUDManagerAwakePostfix(HUDManager __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					Plugin.Log.LogWarning((object)"HUDManager instance is null in HUDManagerAwakePostfix");
					return;
				}
				Plugin.Log.LogInfo((object)"Initializing Interior Title Card Mod.");
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					Plugin.Instance.InitializeTitleCard();
				}
				else
				{
					Plugin.Log.LogWarning((object)"Plugin instance is null in HUDManagerAwakePostfix");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error in HUDManagerAwakePostfix: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("openingDoorsSequence")]
		public static void OpeningDoorsSequencePostfix()
		{
			try
			{
				Plugin.Log.LogInfo((object)"Ship doors opening - resetting title card state");
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					Plugin.Instance.ResetTitleCard();
				}
				else
				{
					Plugin.Log.LogWarning((object)"Plugin instance is null in OpeningDoorsSequencePostfix");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error in OpeningDoorsSequencePostfix: " + ex.Message));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("ShipLeave")]
		public static void ShipLeavePostfix()
		{
			try
			{
				Plugin.Log.LogInfo((object)"Ship leaving - resetting title card state");
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					Plugin.Instance.ResetTitleCard();
				}
				else
				{
					Plugin.Log.LogWarning((object)"Plugin instance is null in ShipLeavePostfix");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error in ShipLeavePostfix: " + ex.Message));
			}
		}
	}
}
namespace InteriorTitleCards.Managers
{
	public class ConfigManager
	{
		[CompilerGenerated]
		private sealed class <InitializeConfigsDelayed>d__116 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ConfigManager <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InitializeConfigsDelayed>d__116(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this.BindConfig();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RetryConfigGeneration>d__124 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public int attempt;

			public ConfigManager <>4__this;

			private float <delay>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RetryConfigGeneration>d__124(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<delay>5__1 = Mathf.Min(3f * Mathf.Pow(2f, (float)(attempt - 1)), 30f);
					<>4__this.LogDebug(string.Format("{0} called - retrying in {1} seconds... (Attempt {2})", "RetryConfigGeneration", <delay>5__1, attempt));
					<>2__current = (object)new WaitForSeconds(<delay>5__1);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (attempt < 3)
					{
						<>4__this.CreateInteriorNameOverrideConfigs();
					}
					else
					{
						<>4__this.logger.LogError((object)"Failed to generate configs after 3 attempts. Custom dungeons may not be available.");
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private readonly ConfigFile config;

		private readonly ManualLogSource logger;

		private readonly Plugin plugin;

		private ConfigEntry<string> topTextColorConfig;

		private ConfigEntry<string> interiorTextColorConfig;

		private ConfigEntry<bool> debugLoggingConfig;

		private ConfigEntry<string> customTopTextConfig;

		private ConfigEntry<int> topTextFontSizeConfig;

		private ConfigEntry<int> interiorTextFontSizeConfig;

		private ConfigEntry<int> topTextFontWeightConfig;

		private ConfigEntry<int> interiorTextFontWeightConfig;

		private ConfigEntry<string> topTextPositionConfig;

		private ConfigEntry<string> interiorTextPositionConfig;

		private ConfigEntry<string> topImagePositionConfig;

		private ConfigEntry<string> interiorImagePositionConfig;

		private ConfigEntry<string> combinedImagePositionConfig;

		private ConfigEntry<float> topTextDisplayDurationConfig;

		private ConfigEntry<float> interiorTextDisplayDurationConfig;

		private ConfigEntry<float> topTextFadeInDurationConfig;

		private ConfigEntry<float> topTextFadeOutDurationConfig;

		private ConfigEntry<float> interiorTextFadeInDurationConfig;

		private ConfigEntry<float> interiorTextFadeOutDurationConfig;

		private ConfigEntry<float> topTextStartDelayConfig;

		private ConfigEntry<float> interiorTextStartDelayConfig;

		private ConfigEntry<bool> topTextFadeEnabledConfig;

		private ConfigEntry<bool> interiorTextFadeEnabledConfig;

		private ConfigEntry<ImageSourceMode> imageSourceModeConfig;

		private ConfigEntry<bool> enableCustomImagesConfig;

		private ConfigEntry<ImageDisplayType> imageDisplayTypeConfig;

		private ConfigEntry<string> imageBlacklistConfig;

		private ConfigEntry<int> topTextImageWidthConfig;

		private ConfigEntry<int> topTextImageHeightConfig;

		private ConfigEntry<int> interiorTextImageWidthConfig;

		private ConfigEntry<int> interiorTextImageHeightConfig;

		private ConfigEntry<int> combinedImageWidthConfig;

		private ConfigEntry<int> combinedImageHeightConfig;

		private Dictionary<string, ConfigEntry<string>> interiorNameOverrideConfigs = new Dictionary<string, ConfigEntry<string>>();

		private static readonly Dictionary<string, string> variantToBaseMapping = new Dictionary<string, string>
		{
			{ "Facility (Level1Flow)", "Facility" },
			{ "Facility (Level1Flow3Exits)", "Facility" },
			{ "Facility (Level1FlowExtraLarge)", "Facility" },
			{ "Haunted Mansion (Level2Flow)", "Haunted Mansion" },
			{ "Mineshaft (Level3Flow)", "Mineshaft" }
		};

		private int retryAttempt = 0;

		private Action onConfigsBound;

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

		public Color TitleColor => ParseColorFromString("#fe6001", Color.white);

		public Color TopTextColor
		{
			get
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: 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_004f: 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)
				LogDebug("Accessing TopTextColor property");
				Color defaultColor = ParseColorFromString("#fe6001", ParseColorFromString("#fe6001", Color.white));
				Color val = ParseColorFromConfig(topTextColorConfig, defaultColor);
				LogDebug($"TopTextColor value: {val}");
				return val;
			}
		}

		public Color InteriorTextColor
		{
			get
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: 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_004f: 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)
				LogDebug("Accessing InteriorTextColor property");
				Color defaultColor = ParseColorFromString("#fe6001", ParseColorFromString("#fe6001", Color.white));
				Color val = ParseColorFromConfig(interiorTextColorConfig, defaultColor);
				LogDebug($"InteriorTextColor value: {val}");
				return val;
			}
		}

		public bool DebugLoggingEnabled => debugLoggingConfig?.Value ?? false;

		public string CustomTopText => customTopTextConfig?.Value ?? "NOW ENTERING...";

		public int TopTextFontSize => topTextFontSizeConfig?.Value ?? 20;

		public int InteriorTextFontSize => interiorTextFontSizeConfig?.Value ?? 28;

		public int TopTextFontWeight
		{
			get
			{
				int num = topTextFontWeightConfig?.Value ?? 400;
				LogDebug($"TopTextFontWeight: {num}");
				return num;
			}
		}

		public int InteriorTextFontWeight
		{
			get
			{
				int num = interiorTextFontWeightConfig?.Value ?? 700;
				LogDebug($"InteriorTextFontWeight: {num}");
				return num;
			}
		}

		public Vector2 TopTextPosition
		{
			get
			{
				//IL_0061: 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_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: 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)
				if (topTextPositionConfig?.Value != null)
				{
					string[] array = topTextPositionConfig.Value.Split(',');
					if (array.Length == 2 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2))
					{
						return new Vector2(result, result2);
					}
				}
				return TitleCardConstants.DefaultTopTextPosition;
			}
		}

		public Vector2 InteriorTextPosition
		{
			get
			{
				//IL_0061: 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_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: 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)
				if (interiorTextPositionConfig?.Value != null)
				{
					string[] array = interiorTextPositionConfig.Value.Split(',');
					if (array.Length == 2 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2))
					{
						return new Vector2(result, result2);
					}
				}
				return TitleCardConstants.DefaultInteriorTextPosition;
			}
		}

		public Vector2 TopImagePosition
		{
			get
			{
				//IL_0061: 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_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: 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)
				if (topImagePositionConfig?.Value != null)
				{
					string[] array = topImagePositionConfig.Value.Split(',');
					if (array.Length == 2 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2))
					{
						return new Vector2(result, result2);
					}
				}
				return TitleCardConstants.DefaultTopImagePosition;
			}
		}

		public Vector2 InteriorImagePosition
		{
			get
			{
				//IL_0061: 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_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: 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)
				if (interiorImagePositionConfig?.Value != null)
				{
					string[] array = interiorImagePositionConfig.Value.Split(',');
					if (array.Length == 2 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2))
					{
						return new Vector2(result, result2);
					}
				}
				return TitleCardConstants.DefaultInteriorImagePosition;
			}
		}

		public Vector2 CombinedImagePosition
		{
			get
			{
				//IL_0061: 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_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: 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)
				if (combinedImagePositionConfig?.Value != null)
				{
					string[] array = combinedImagePositionConfig.Value.Split(',');
					if (array.Length == 2 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2))
					{
						return new Vector2(result, result2);
					}
				}
				return TitleCardConstants.DefaultCombinedImagePosition;
			}
		}

		public float TopTextDisplayDuration => topTextDisplayDurationConfig?.Value ?? 3f;

		public float InteriorTextDisplayDuration => interiorTextDisplayDurationConfig?.Value ?? 3f;

		public float TopTextFadeInDuration => topTextFadeInDurationConfig?.Value ?? 0.5f;

		public float TopTextFadeOutDuration => topTextFadeOutDurationConfig?.Value ?? 0.5f;

		public float InteriorTextFadeInDuration => interiorTextFadeInDurationConfig?.Value ?? 0.5f;

		public float InteriorTextFadeOutDuration => interiorTextFadeOutDurationConfig?.Value ?? 0.5f;

		public float TopTextStartDelay => topTextStartDelayConfig?.Value ?? 0f;

		public float InteriorTextStartDelay => interiorTextStartDelayConfig?.Value ?? 0f;

		public bool TopTextFadeEnabled => topTextFadeEnabledConfig?.Value ?? true;

		public bool InteriorTextFadeEnabled => interiorTextFadeEnabledConfig?.Value ?? true;

		public int ImageSourceMode
		{
			get
			{
				ImageSourceMode? imageSourceMode = imageSourceModeConfig?.Value;
				ImageSourceMode imageSourceMode2 = (imageSourceMode.HasValue ? imageSourceMode.Value : global::ImageSourceMode.BothDeveloperPriority);
				int num = (int)imageSourceMode2;
				if (num < 0 || num > 3)
				{
					LogDebug($"Invalid ImageSourceMode value: {num}, defaulting to BothDeveloperPriority (2)");
					num = 2;
				}
				LogDebug($"ImageSourceMode: {num}");
				return num;
			}
		}

		public bool EnableCustomImages
		{
			get
			{
				bool flag = enableCustomImagesConfig?.Value ?? true;
				LogDebug($"EnableCustomImages: {flag}");
				return flag;
			}
		}

		public int ImageDisplayType
		{
			get
			{
				ImageDisplayType? imageDisplayType = imageDisplayTypeConfig?.Value;
				ImageDisplayType imageDisplayType2 = (imageDisplayType.HasValue ? imageDisplayType.Value : global::ImageDisplayType.BothSeparate);
				int num = (int)imageDisplayType2;
				LogDebug($"ImageDisplayType: {num}");
				return num;
			}
		}

		public string ImageBlacklist
		{
			get
			{
				string text = imageBlacklistConfig?.Value ?? "";
				LogDebug("ImageBlacklist: " + text);
				return text;
			}
		}

		public int TopTextImageWidth => topTextImageWidthConfig?.Value ?? 400;

		public int TopTextImageHeight => topTextImageHeightConfig?.Value ?? 40;

		public int InteriorTextImageWidth => interiorTextImageWidthConfig?.Value ?? 400;

		public int InteriorTextImageHeight => interiorTextImageHeightConfig?.Value ?? 40;

		public int CombinedImageWidth => combinedImageWidthConfig?.Value ?? 400;

		public int CombinedImageHeight => combinedImageHeightConfig?.Value ?? 40;

		public ConfigManager(ConfigFile config, ManualLogSource logger, Plugin plugin)
		{
			this.config = config;
			this.logger = logger;
			this.plugin = plugin;
		}

		public void SetOnConfigsBoundCallback(Action callback)
		{
			onConfigsBound = callback;
		}

		public void Initialize()
		{
			LogDebug("Initialize called - starting config initialization");
			((MonoBehaviour)plugin).StartCoroutine(InitializeConfigsDelayed());
		}

		public string GetInteriorNameOverride(string dungeonName)
		{
			LogDebug("GetInteriorNameOverride called with dungeon: " + dungeonName);
			if (string.IsNullOrEmpty(dungeonName))
			{
				LogDebug("Dungeon name is null or empty, returning 'Unknown'");
				return "Unknown";
			}
			if (nameOverrideCache.TryGetValue(dungeonName, out var value))
			{
				LogDebug("Found cached result for '" + dungeonName + "': " + value);
				return value;
			}
			LogDebug("No cached result for '" + dungeonName + "', processing");
			string text = dungeonName;
			if (variantToBaseMapping != null && variantToBaseMapping.ContainsKey(dungeonName))
			{
				text = variantToBaseMapping[dungeonName];
				LogDebug("Mapped variant '" + dungeonName + "' to base name '" + text + "'");
			}
			LogDebug("Checking for config override for base name: " + text);
			LogDebug($"Interior name override configs count: {interiorNameOverrideConfigs?.Count ?? 0}");
			if (interiorNameOverrideConfigs != null && interiorNameOverrideConfigs.ContainsKey(text))
			{
				ConfigEntry<string> val = interiorNameOverrideConfigs[text];
				if (val != null)
				{
					string value2 = val.Value;
					LogDebug("Found config entry for '" + text + "', value: '" + value2 + "'");
					if (!string.IsNullOrEmpty(value2))
					{
						LogDebug("Found override '" + value2 + "' for base name '" + text + "'");
						nameOverrideCache[dungeonName] = value2;
						LogDebug("Cached result for '" + dungeonName + "': " + value2);
						return value2;
					}
					LogDebug("Override value is null or empty for '" + text + "'");
				}
				else
				{
					LogDebug("Config entry for '" + text + "' is null");
				}
			}
			else
			{
				LogDebug("No config entry found for '" + text + "'");
			}
			LogDebug("No override found for '" + text + "', using original name: " + dungeonName);
			nameOverrideCache[dungeonName] = dungeonName;
			LogDebug("Cached original name for '" + dungeonName + "': " + dungeonName);
			return dungeonName;
		}

		public void LogDebug(string message)
		{
			if (DebugLoggingEnabled)
			{
				logger.LogInfo((object)("[DEBUG] " + message));
			}
		}

		private Color ParseColorFromConfig(ConfigEntry<string> colorConfig, Color defaultColor)
		{
			//IL_002a: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			if (colorConfig != null && !string.IsNullOrEmpty(colorConfig.Value) && ColorUtility.TryParseHtmlString(colorConfig.Value, ref result))
			{
				return result;
			}
			return defaultColor;
		}

		private Color ParseColorFromString(string colorString, Color defaultColor)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			Color result = default(Color);
			if (!string.IsNullOrEmpty(colorString) && ColorUtility.TryParseHtmlString(colorString, ref result))
			{
				return result;
			}
			return defaultColor;
		}

		[IteratorStateMachine(typeof(<InitializeConfigsDelayed>d__116))]
		private IEnumerator InitializeConfigsDelayed()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitializeConfigsDelayed>d__116(0)
			{
				<>4__this = this
			};
		}

		private void BindConfig()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Expected O, but got Unknown
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Expected O, but got Unknown
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Expected O, but got Unknown
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Expected O, but got Unknown
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Expected O, but got Unknown
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Expected O, but got Unknown
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Expected O, but got Unknown
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Expected O, but got Unknown
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Expected O, but got Unknown
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Expected O, but got Unknown
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Expected O, but got Unknown
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Expected O, but got Unknown
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a2: Expected O, but got Unknown
			//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e3: Expected O, but got Unknown
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Expected O, but got Unknown
			//IL_065b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0665: Expected O, but got Unknown
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Expected O, but got Unknown
			//IL_0708: Unknown result type (might be due to invalid IL or missing references)
			//IL_0712: Expected O, but got Unknown
			//IL_0770: Unknown result type (might be due to invalid IL or missing references)
			//IL_077a: Expected O, but got Unknown
			//IL_07d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e2: Expected O, but got Unknown
			//IL_081d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0827: Expected O, but got Unknown
			//IL_0860: Unknown result type (might be due to invalid IL or missing references)
			//IL_086a: Expected O, but got Unknown
			//IL_08a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b0: Expected O, but got Unknown
			//IL_08e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f3: Expected O, but got Unknown
			//IL_092f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0939: Expected O, but got Unknown
			//IL_0972: Unknown result type (might be due to invalid IL or missing references)
			//IL_097c: Expected O, but got Unknown
			LogDebug("BindConfig called - binding configuration entries");
			debugLoggingConfig = config.Bind<bool>("Debug Settings", "EnableDebugLogging", false, new ConfigDescription("Enable detailed debug logging for troubleshooting", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
			customTopTextConfig = config.Bind<string>("Text Appearance", "Top text override", "NOW ENTERING...", new ConfigDescription("Custom text displayed above the interior name (leave blank to use default 'NOW ENTERING...')", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
			topTextFontSizeConfig = config.Bind<int>("Text Appearance", "TopTextFontSize", 20, new ConfigDescription("Font size for the top text (e.g., 20 for default size)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2
				}
			}));
			interiorTextFontSizeConfig = config.Bind<int>("Text Appearance", "InteriorTextFontSize", 28, new ConfigDescription("Font size for the interior name text (e.g., 28 for default size)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3
				}
			}));
			topTextColorConfig = config.Bind<string>("Text Appearance", "TopTextColor", "#fe6001", new ConfigDescription("Color of the top text in hex format (e.g., #fe6001). Leave blank to use the default orange color", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4
				}
			}));
			interiorTextColorConfig = config.Bind<string>("Text Appearance", "InteriorTextColor", "#fe6001", new ConfigDescription("Color of the interior name text in hex format (e.g., #fe6001). Leave blank to use the default orange color", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 5
				}
			}));
			topTextFontWeightConfig = config.Bind<int>("Text Appearance", "TopTextFontWeight", 400, new ConfigDescription("Font weight (boldness) for the top text (400=Normal, 700=Bold)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 7
				}
			}));
			interiorTextFontWeightConfig = config.Bind<int>("Text Appearance", "InteriorTextFontWeight", 700, new ConfigDescription("Font weight (boldness) for the interior name text (400=Normal, 700=Bold)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 8
				}
			}));
			topTextPositionConfig = config.Bind<string>("Text Appearance", "TopTextPosition", $"{TitleCardConstants.DefaultTopTextPosition.x},{TitleCardConstants.DefaultTopTextPosition.y}", new ConfigDescription("Position of the top text as X,Y coordinates (e.g., 0,20). Default is centered horizontally with vertical offset.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 9
				}
			}));
			interiorTextPositionConfig = config.Bind<string>("Text Appearance", "InteriorTextPosition", $"{TitleCardConstants.DefaultInteriorTextPosition.x},{TitleCardConstants.DefaultInteriorTextPosition.y}", new ConfigDescription("Position of the interior text as X,Y coordinates (e.g., 0,-20). Default is centered horizontally with vertical offset.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 10
				}
			}));
			topTextDisplayDurationConfig = config.Bind<float>("Animation Timing", "TopTextDisplayDuration", 3f, new ConfigDescription("How long the top text displays on screen in seconds (e.g., 3.0 for 3 seconds)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
			interiorTextDisplayDurationConfig = config.Bind<float>("Animation Timing", "InteriorTextDisplayDuration", 3f, new ConfigDescription("How long the interior text displays on screen in seconds (e.g., 3.0 for 3 seconds)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2
				}
			}));
			topTextFadeInDurationConfig = config.Bind<float>("Animation Timing", "TopTextFadeInDuration", 0.5f, new ConfigDescription("How long the top text takes to fade in (e.g., 0.5 for half a second)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3
				}
			}));
			topTextFadeOutDurationConfig = config.Bind<float>("Animation Timing", "TopTextFadeOutDuration", 0.5f, new ConfigDescription("How long the top text takes to fade out (e.g., 0.5 for half a second)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4
				}
			}));
			interiorTextFadeInDurationConfig = config.Bind<float>("Animation Timing", "InteriorTextFadeInDuration", 0.5f, new ConfigDescription("How long the interior text takes to fade in (e.g., 0.5 for half a second)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 5
				}
			}));
			interiorTextFadeOutDurationConfig = config.Bind<float>("Animation Timing", "InteriorTextFadeOutDuration", 0.5f, new ConfigDescription("How long the interior text takes to fade out (e.g., 0.5 for half a second)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 6
				}
			}));
			topTextFadeEnabledConfig = config.Bind<bool>("Visual Effects", "TopTextFadeEnabled", true, new ConfigDescription("Enable fade in/out effect for top text", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
			interiorTextFadeEnabledConfig = config.Bind<bool>("Visual Effects", "InteriorTextFadeEnabled", true, new ConfigDescription("Enable fade in/out effect for interior text", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2
				}
			}));
			topTextStartDelayConfig = config.Bind<float>("Animation Timing", "TopTextStartDelay", 0f, new ConfigDescription("Delay in seconds before the top text starts displaying after entering (e.g., 1.0 for 1 second)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 7
				}
			}));
			interiorTextStartDelayConfig = config.Bind<float>("Animation Timing", "InteriorTextStartDelay", 0f, new ConfigDescription("Delay in seconds before the interior text starts displaying after entering (e.g., 1.0 for 1 second)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 8
				}
			}));
			enableCustomImagesConfig = config.Bind<bool>("Custom Images", "EnableCustomImages", true, new ConfigDescription("Enable or disable all custom image functionality", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
			imageDisplayTypeConfig = config.Bind<ImageDisplayType>("Custom Images", "ImageDisplayType", global::ImageDisplayType.BothSeparate, new ConfigDescription("Image display type", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2
				}
			}));
			imageSourceModeConfig = config.Bind<ImageSourceMode>("Custom Images", "ImageSourceMode", global::ImageSourceMode.BothDeveloperPriority, new ConfigDescription("Image source mode", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3
				}
			}));
			imageBlacklistConfig = config.Bind<string>("Custom Images", "ImageBlacklist", "", new ConfigDescription("Comma-separated list of image paths to exclude (e.g., dev/name/interiortext,user/othername/toptext)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4
				}
			}));
			topImagePositionConfig = config.Bind<string>("Custom Images", "TopImagePosition", $"{TitleCardConstants.DefaultTopImagePosition.x},{TitleCardConstants.DefaultTopImagePosition.y}", new ConfigDescription("Position of top images as X,Y coordinates", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 5
				}
			}));
			interiorImagePositionConfig = config.Bind<string>("Custom Images", "InteriorImagePosition", $"{TitleCardConstants.DefaultInteriorImagePosition.x},{TitleCardConstants.DefaultInteriorImagePosition.y}", new ConfigDescription("Position of interior images as X,Y coordinates", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 6
				}
			}));
			combinedImagePositionConfig = config.Bind<string>("Custom Images", "CombinedImagePosition", $"{TitleCardConstants.DefaultCombinedImagePosition.x},{TitleCardConstants.DefaultCombinedImagePosition.y}", new ConfigDescription("Position of combined images as X,Y coordinates", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 7
				}
			}));
			topTextImageWidthConfig = config.Bind<int>("Custom Images", "TopTextImageWidth", 400, new ConfigDescription("Width for top text images in pixels (0 = use original width)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 8
				}
			}));
			topTextImageHeightConfig = config.Bind<int>("Custom Images", "TopTextImageHeight", 40, new ConfigDescription("Height for top text images in pixels (0 = use original height)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 9
				}
			}));
			interiorTextImageWidthConfig = config.Bind<int>("Custom Images", "InteriorTextImageWidth", 400, new ConfigDescription("Width for interior text images in pixels (0 = use original width)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 10
				}
			}));
			interiorTextImageHeightConfig = config.Bind<int>("Custom Images", "InteriorTextImageHeight", 40, new ConfigDescription("Height for interior text images in pixels (0 = use original height)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 11
				}
			}));
			combinedImageWidthConfig = config.Bind<int>("Custom Images", "CombinedImageWidth", 400, new ConfigDescription("Width for combined images in pixels (0 = use original width)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 12
				}
			}));
			combinedImageHeightConfig = config.Bind<int>("Custom Images", "CombinedImageHeight", 40, new ConfigDescription("Height for combined images in pixels (0 = use original height)", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 13
				}
			}));
			LogDebug("Starting config binding process");
			CreateInteriorNameOverrideConfigs();
			onConfigsBound?.Invoke();
		}

		private void CreateInteriorNameOverrideConfigs()
		{
			LogDebug("CreateInteriorNameOverrideConfigs called");
			string lethalLevelLoaderConfigPath = GetLethalLevelLoaderConfigPath();
			if (string.IsNullOrEmpty(lethalLevelLoaderConfigPath))
			{
				LogDebug("Config path not found, trying runtime API approach");
				CreateInteriorNameOverrideConfigsFromRuntimeAPI();
				return;
			}
			HashSet<string> hashSet = ParseDungeonNamesFromConfigFile(lethalLevelLoaderConfigPath);
			if (hashSet.Count == 0)
			{
				LogDebug("No dungeons found in config file, trying runtime API approach");
				CreateInteriorNameOverrideConfigsFromRuntimeAPI();
			}
			else
			{
				CreateConfigEntriesForDungeons(hashSet);
			}
		}

		private string GetLethalLevelLoaderConfigPath()
		{
			string text = Path.Combine(Paths.ConfigPath, "LethalLevelLoader.cfg");
			LogDebug("Looking for LethalLevelLoader.cfg at: " + text);
			if (File.Exists(text))
			{
				LogDebug("Found LethalLevelLoader.cfg at: " + text);
				return text;
			}
			LogDebug("LethalLevelLoader.cfg not found at primary path, trying alternative path");
			text = Path.Combine(Path.GetDirectoryName(Application.dataPath), "BepInEx/config/LethalLevelLoader.cfg");
			LogDebug("Looking for LethalLevelLoader.cfg at alternative path: " + text);
			if (File.Exists(text))
			{
				return text;
			}
			LogDebug("LethalLevelLoader.cfg not found at alternative path, skipping Resources directory check for security");
			return null;
		}

		private HashSet<string> ParseDungeonNamesFromConfigFile(string configPath)
		{
			try
			{
				string[] array = File.ReadAllLines(configPath);
				HashSet<string> hashSet = new HashSet<string>();
				string[] array2 = array;
				foreach (string text in array2)
				{
					if (!text.StartsWith("[") || !text.EndsWith("]"))
					{
						continue;
					}
					string text2 = text.Substring(1, text.Length - 2);
					LogDebug("Processing config line: " + text2);
					if (text2.Contains("Custom Dungeon:"))
					{
						string text3 = ExtractDungeonName(text2, "Custom Dungeon:");
						if (!string.IsNullOrEmpty(text3))
						{
							hashSet.Add(text3);
							LogDebug("Found custom dungeon: " + text3);
						}
					}
					if (text2.Contains("Vanilla Dungeon:"))
					{
						string text4 = ExtractDungeonName(text2, "Vanilla Dungeon:");
						if (!string.IsNullOrEmpty(text4))
						{
							hashSet.Add(text4);
							LogDebug("Found vanilla dungeon: " + text4);
						}
					}
				}
				LogDebug($"Found {hashSet.Count} total dungeons");
				return hashSet;
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Error parsing dungeon names from config file: " + ex.Message));
				return new HashSet<string>();
			}
		}

		private string ExtractDungeonName(string content, string prefix)
		{
			int num = content.IndexOf(prefix);
			if (num >= 0)
			{
				int startIndex = num + prefix.Length;
				return content.Substring(startIndex).Trim();
			}
			return null;
		}

		private void CreateConfigEntriesForDungeons(HashSet<string> dungeonNames)
		{
			int num = 0;
			foreach (string dungeonName in dungeonNames)
			{
				if (!string.IsNullOrEmpty(dungeonName))
				{
					string text = dungeonName;
					if (variantToBaseMapping.ContainsKey(dungeonName))
					{
						text = variantToBaseMapping[dungeonName];
						LogDebug("Using base name '" + text + "' for variant '" + dungeonName + "'");
					}
					string text2 = text.Replace(" ", "_");
					LogDebug("Processing dungeon: " + dungeonName + " -> Base: " + text + " (Config Key: " + text2 + ")");
					if (!interiorNameOverrideConfigs.ContainsKey(text))
					{
						ConfigEntry<string> value = config.Bind<string>("Interior Name Overrides", text2 + "_NameOverride", "", "Override name for " + text + " interior (leave blank to use default)");
						interiorNameOverrideConfigs[text] = value;
						num++;
						LogDebug("Created config entry for: " + text);
					}
					else
					{
						LogDebug("Config entry already exists for base name: " + text);
					}
				}
			}
			LogDebug($"Finished creating {num} interior name override configs");
		}

		private void CreateInteriorNameOverrideConfigsFromRuntimeAPI()
		{
			try
			{
				retryAttempt++;
				LogDebug(string.Format("{0} called (Attempt {1})", "CreateInteriorNameOverrideConfigsFromRuntimeAPI", retryAttempt));
				if ((Object)(object)plugin == (Object)null)
				{
					logger.LogError((object)"Plugin reference is null, cannot create config entries");
					return;
				}
				LogDebug("PatchedContent.VanillaExtendedDungeonFlows: " + ((PatchedContent.VanillaExtendedDungeonFlows != null) ? "Available" : "NULL"));
				LogDebug("PatchedContent.CustomExtendedDungeonFlows: " + ((PatchedContent.CustomExtendedDungeonFlows != null) ? "Available" : "NULL"));
				if (PatchedContent.VanillaExtendedDungeonFlows == null && PatchedContent.CustomExtendedDungeonFlows == null)
				{
					logger.LogWarning((object)"LethalLevelLoader content not yet initialized. Will retry in a few seconds.");
					if ((Object)(object)plugin != (Object)null)
					{
						((MonoBehaviour)plugin).StartCoroutine(RetryConfigGeneration(retryAttempt));
					}
					return;
				}
				if (PatchedContent.VanillaExtendedDungeonFlows != null && PatchedContent.VanillaExtendedDungeonFlows.Count == 0 && PatchedContent.CustomExtendedDungeonFlows != null && PatchedContent.CustomExtendedDungeonFlows.Count == 0)
				{
					logger.LogWarning((object)"LethalLevelLoader content collections are empty. Will retry in a few seconds.");
					if ((Object)(object)plugin != (Object)null)
					{
						((MonoBehaviour)plugin).StartCoroutine(RetryConfigGeneration(retryAttempt));
					}
					return;
				}
				List<ExtendedDungeonFlow> list = new List<ExtendedDungeonFlow>();
				if (PatchedContent.VanillaExtendedDungeonFlows != null)
				{
					LogDebug($"Found {PatchedContent.VanillaExtendedDungeonFlows.Count} vanilla dungeon flows");
					list.AddRange(PatchedContent.VanillaExtendedDungeonFlows);
				}
				if (PatchedContent.CustomExtendedDungeonFlows != null)
				{
					LogDebug($"Found {PatchedContent.CustomExtendedDungeonFlows.Count} custom dungeon flows");
					list.AddRange(PatchedContent.CustomExtendedDungeonFlows);
				}
				LogDebug($"Total dungeon flows to process: {list.Count}");
				if (list.Count == 0)
				{
					logger.LogWarning((object)"No dungeon flows found. Will retry in a few seconds.");
					if ((Object)(object)plugin != (Object)null)
					{
						((MonoBehaviour)plugin).StartCoroutine(RetryConfigGeneration(retryAttempt));
					}
					return;
				}
				HashSet<string> hashSet = new HashSet<string>();
				foreach (ExtendedDungeonFlow item in list)
				{
					if ((Object)(object)item != (Object)null && !string.IsNullOrEmpty(item.DungeonName))
					{
						hashSet.Add(item.DungeonName);
					}
				}
				CreateConfigEntriesForDungeons(hashSet);
				retryAttempt = 0;
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Error creating interior name override configs from runtime API: " + ex.Message));
				logger.LogDebug((object)("Exception details: " + ex.GetType().Name + " - " + ex.StackTrace));
			}
		}

		[IteratorStateMachine(typeof(<RetryConfigGeneration>d__124))]
		private IEnumerator RetryConfigGeneration(int attempt = 1)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RetryConfigGeneration>d__124(0)
			{
				<>4__this = this,
				attempt = attempt
			};
		}
	}
	public class TitleCardManager
	{
		[CompilerGenerated]
		private sealed class <DelayedFadeInText>d__58 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextMeshProUGUI textComponent;

			public float delay;

			public float duration;

			public TitleCardManager <>4__this;

			private Coroutine <fadeCoroutine>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedFadeInText>d__58(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<fadeCoroutine>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (delay > 0f)
					{
						<>2__current = (object)new WaitForSeconds(delay);
						<>1__state = 1;
						return true;
					}
					goto IL_0062;
				case 1:
					<>1__state = -1;
					goto IL_0062;
				case 2:
					{
						<>1__state = -1;
						return false;
					}
					IL_0062:
					<fadeCoroutine>5__1 = ((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.FadeInText(textComponent, duration));
					<>2__current = <fadeCoroutine>5__1;
					<>1__state = 2;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DelayedShowText>d__57 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextMeshProUGUI textComponent;

			public float delay;

			public TitleCardManager <>4__this;

			private Color <color>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedShowText>d__57(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: 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_0043: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (delay > 0f)
					{
						<>2__current = (object)new WaitForSeconds(delay);
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				<color>5__1 = ((Graphic)textComponent).color;
				((Graphic)textComponent).color = new Color(<color>5__1.r, <color>5__1.g, <color>5__1.b, 1f);
				if ((Object)(object)textComponent == (Object)(object)<>4__this.titleCardText)
				{
					<>4__this.topTextFadeInCoroutine = null;
				}
				else if ((Object)(object)textComponent == (Object)(object)<>4__this.interiorNameText)
				{
					<>4__this.interiorTextFadeInCoroutine = null;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FadeInText>d__51 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextMeshProUGUI textComponent;

			public float duration;

			public TitleCardManager <>4__this;

			private Color <startColor>5__1;

			private float <elapsedTime>5__2;

			private float <alpha>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FadeInText>d__51(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: 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)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<startColor>5__1 = ((Graphic)textComponent).color;
					<elapsedTime>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsedTime>5__2 < duration)
				{
					<elapsedTime>5__2 += Time.deltaTime;
					<alpha>5__3 = Mathf.Lerp(0f, 1f, <elapsedTime>5__2 / duration);
					((Graphic)textComponent).color = new Color(<startColor>5__1.r, <startColor>5__1.g, <startColor>5__1.b, <alpha>5__3);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				((Graphic)textComponent).color = new Color(<startColor>5__1.r, <startColor>5__1.g, <startColor>5__1.b, 1f);
				if ((Object)(object)textComponent == (Object)(object)<>4__this.titleCardText)
				{
					<>4__this.topTextFadeInCoroutine = null;
				}
				else if ((Object)(object)textComponent == (Object)(object)<>4__this.interiorNameText)
				{
					<>4__this.interiorTextFadeInCoroutine = null;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FadeOutImage>d__56 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Image imageComponent;

			public float duration;

			public TitleCardManager <>4__this;

			private Color <startColor>5__1;

			private float <elapsedTime>5__2;

			private float <alpha>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FadeOutImage>d__56(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)imageComponent == (Object)null)
					{
						return false;
					}
					<startColor>5__1 = ((Graphic)imageComponent).color;
					<elapsedTime>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsedTime>5__2 < duration)
				{
					<elapsedTime>5__2 += Time.deltaTime;
					<alpha>5__3 = Mathf.Lerp(1f, 0f, <elapsedTime>5__2 / duration);
					((Graphic)imageComponent).color = new Color(<startColor>5__1.r, <startColor>5__1.g, <startColor>5__1.b, <alpha>5__3);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				((Graphic)imageComponent).color = new Color(<startColor>5__1.r, <startColor>5__1.g, <startColor>5__1.b, 0f);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FadeOutText>d__55 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextMeshProUGUI textComponent;

			public float duration;

			public TitleCardManager <>4__this;

			private Color <startColor>5__1;

			private float <elapsedTime>5__2;

			private float <alpha>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FadeOutText>d__55(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: 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)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<startColor>5__1 = ((Graphic)textComponent).color;
					<elapsedTime>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsedTime>5__2 < duration)
				{
					<elapsedTime>5__2 += Time.deltaTime;
					<alpha>5__3 = Mathf.Lerp(1f, 0f, <elapsedTime>5__2 / duration);
					((Graphic)textComponent).color = new Color(<startColor>5__1.r, <startColor>5__1.g, <startColor>5__1.b, <alpha>5__3);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				((Graphic)textComponent).color = new Color(<startColor>5__1.r, <startColor>5__1.g, <startColor>5__1.b, 0f);
				if ((Object)(object)textComponent == (Object)(object)<>4__this.titleCardText)
				{
					<>4__this.topTextFadeOutCoroutine = null;
				}
				else if ((Object)(object)textComponent == (Object)(object)<>4__this.interiorNameText)
				{
					<>4__this.interiorTextFadeOutCoroutine = null;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <HideImageElementAfterDelay>d__54 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Image imageComponent;

			public float displayDuration;

			public float fadeOutDuration;

			public bool fadeEnabled;

			public TitleCardManager <>4__this;

			private Coroutine <fadeCoroutine>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <HideImageElementAfterDelay>d__54(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<fadeCoroutine>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(displayDuration);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (fadeEnabled && fadeOutDuration > 0f)
					{
						<fadeCoroutine>5__1 = ((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.FadeOutImage(imageComponent, fadeOutDuration));
						<>2__current = <fadeCoroutine>5__1;
						<>1__state = 2;
						return true;
					}
					if ((Object)(object)imageComponent != (Object)null)
					{
						((Graphic)imageComponent).color = new Color(((Graphic)imageComponent).color.r, ((Graphic)imageComponent).color.g, ((Graphic)imageComponent).color.b, 0f);
					}
					break;
				case 2:
					<>1__state = -1;
					<fadeCoroutine>5__1 = null;
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <HideTextElementAfterDelay>d__53 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextMeshProUGUI textComponent;

			public float displayDuration;

			public float fadeOutDuration;

			public bool fadeEnabled;

			public TitleCardManager <>4__this;

			private bool <hasImage>5__1;

			private Coroutine <fadeCoroutine>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <HideTextElementAfterDelay>d__53(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<fadeCoroutine>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02df: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(displayDuration);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<hasImage>5__1 = ((Object)(object)textComponent == (Object)(object)<>4__this.titleCardText && <>4__this.topTextImageLoaded) || ((Object)(object)textComponent == (Object)(object)<>4__this.interiorNameText && <>4__this.interiorTextImageLoaded);
					if (<hasImage>5__1)
					{
						((Graphic)textComponent).color = new Color(((Graphic)textComponent).color.r, ((Graphic)textComponent).color.g, ((Graphic)textComponent).color.b, 0f);
						return false;
					}
					if (fadeEnabled && fadeOutDuration > 0f)
					{
						if ((Object)(object)textComponent == (Object)(object)<>4__this.titleCardText && <>4__this.topTextFadeOutCoroutine != null)
						{
							((MonoBehaviour)<>4__this.hudManager).StopCoroutine(<>4__this.topTextFadeOutCoroutine);
						}
						else if ((Object)(object)textComponent == (Object)(object)<>4__this.interiorNameText && <>4__this.interiorTextFadeOutCoroutine != null)
						{
							((MonoBehaviour)<>4__this.hudManager).StopCoroutine(<>4__this.interiorTextFadeOutCoroutine);
						}
						<fadeCoroutine>5__2 = null;
						if ((Object)(object)textComponent == (Object)(object)<>4__this.titleCardText)
						{
							<fadeCoroutine>5__2 = ((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.FadeOutText(<>4__this.titleCardText, fadeOutDuration));
							<>4__this.topTextFadeOutCoroutine = <fadeCoroutine>5__2;
						}
						else if ((Object)(object)textComponent == (Object)(object)<>4__this.interiorNameText)
						{
							<fadeCoroutine>5__2 = ((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.FadeOutText(<>4__this.interiorNameText, fadeOutDuration));
							<>4__this.interiorTextFadeOutCoroutine = <fadeCoroutine>5__2;
						}
						if (<fadeCoroutine>5__2 != null)
						{
							<>2__current = <fadeCoroutine>5__2;
							<>1__state = 2;
							return true;
						}
						goto IL_02a8;
					}
					((Graphic)textComponent).color = new Color(((Graphic)textComponent).color.r, ((Graphic)textComponent).color.g, ((Graphic)textComponent).color.b, 0f);
					break;
				case 2:
					{
						<>1__state = -1;
						goto IL_02a8;
					}
					IL_02a8:
					<fadeCoroutine>5__2 = null;
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <HideTitleCardAfterDelay>d__52 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TitleCardManager <>4__this;

			private float <maxDisplayDuration>5__1;

			private float <maxFadeOutDuration>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <HideTitleCardAfterDelay>d__52(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0275: Unknown result type (might be due to invalid IL or missing references)
				//IL_027f: Expected O, but got Unknown
				//IL_0217: Unknown result type (might be due to invalid IL or missing references)
				//IL_0221: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.HideTextElementAfterDelay(<>4__this.titleCardText, <>4__this.configManager.TopTextDisplayDuration, <>4__this.configManager.TopTextFadeOutDuration, <>4__this.configManager.TopTextFadeEnabled));
					((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.HideTextElementAfterDelay(<>4__this.interiorNameText, <>4__this.configManager.InteriorTextDisplayDuration, <>4__this.configManager.InteriorTextFadeOutDuration, <>4__this.configManager.InteriorTextFadeEnabled));
					if ((Object)(object)<>4__this.topTextImageObject != (Object)null && <>4__this.topTextImageObject.activeSelf)
					{
						((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.HideImageElementAfterDelay(<>4__this.topTextImageComponent, <>4__this.configManager.TopTextDisplayDuration, <>4__this.configManager.TopTextFadeOutDuration, <>4__this.configManager.TopTextFadeEnabled));
					}
					if ((Object)(object)<>4__this.interiorNameImageObject != (Object)null && <>4__this.interiorNameImageObject.activeSelf)
					{
						((MonoBehaviour)<>4__this.hudManager).StartCoroutine(<>4__this.HideImageElementAfterDelay(<>4__this.interiorNameImageComponent, <>4__this.configManager.InteriorTextDisplayDuration, <>4__this.configManager.InteriorTextFadeOutDuration, <>4__this.configManager.InteriorTextFadeEnabled));
					}
					<maxDisplayDuration>5__1 = Mathf.Max(<>4__this.configManager.TopTextDisplayDuration, <>4__this.configManager.InteriorTextDisplayDuration);
					<>2__current = (object)new WaitForSeconds(<maxDisplayDuration>5__1);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<maxFadeOutDuration>5__2 = Mathf.Max(<>4__this.configManager.TopTextFadeOutDuration, <>4__this.configManager.InteriorTextFadeOutDuration);
					if (<maxFadeOutDuration>5__2 > 0f)
					{
						<>2__current = (object)new WaitForSeconds(<maxFadeOutDuration>5__2);
						<>1__state = 2;
						return true;
					}
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)<>4__this.titleCardObject != (Object)null)
				{
					<>4__this.titleCardObject.SetActive(false);
					if (titleCardPool.Count < MaxPoolSize)
					{
						titleCardPool.Enqueue(<>4__this.titleCardObject);
					}
				}
				<>4__this.hideCardCoroutine = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private readonly ManualLogSource logger;

		private readonly ConfigManager configManager;

		private GameObject titleCardObject;

		private TextMeshProUGUI titleCardText;

		private TextMeshProUGUI interiorNameText;

		private bool hasShownCard = false;

		private HUDManager hudManager;

		private Coroutine hideCardCoroutine;

		private Coroutine topTextFadeInCoroutine;

		private Coroutine topTextFadeOutCoroutine;

		private Coroutine interiorTextFadeInCoroutine;

		private Coroutine interiorTextFadeOutCoroutine;

		private static readonly Queue<GameObject> titleCardPool = new Queue<GameObject>();

		private static readonly int MaxPoolSize = 10;

		private GameObject topTextImageObject;

		private GameObject interiorNameImageObject;

		private Image topTextImageComponent;

		private Image interiorNameImageComponent;

		private Dictionary<string, Sprite> cachedSprites = new Dictionary<string, Sprite>();

		private HashSet<string> blacklistSet = new HashSet<string>();

		private bool topTextImageLoaded = false;

		private bool interiorTextImageLoaded = false;

		private const int MaxCachedSprites = 50;

		private Queue<string> spriteCacheOrder = new Queue<string>();

		private static bool baseDirectoryStructureInitialized = false;

		public TitleCardManager(ManualLogSource logger, ConfigManager configManager)
		{
			this.logger = logger;
			this.configManager = configManager;
			InitializeBlacklist();
		}

		private void InitializeBlacklist()
		{
			string imageBlacklist = configManager.ImageBlacklist;
			if (string.IsNullOrEmpty(imageBlacklist))
			{
				return;
			}
			string[] array = imageBlacklist.Split(',');
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = text.Trim();
				if (!string.IsNullOrEmpty(text2))
				{
					blacklistSet.Add(text2.Replace('\\', '/').ToLowerInvariant());
				}
			}
		}

		public void ReInitializeBlacklist()
		{
			configManager.LogDebug("Re-initializing blacklist after config binding");
			blacklistSet.Clear();
			InitializeBlacklist();
			configManager.LogDebug($"Blacklist re-initialized with {blacklistSet.Count} entries");
		}

		private bool IsImageBlacklisted(string imagePath)
		{
			configManager.LogDebug("Checking if image is blacklisted: " + imagePath);
			if (string.IsNullOrEmpty(imagePath))
			{
				configManager.LogDebug("Image path is null or empty, considered blacklisted");
				return true;
			}
			string text = imagePath.Replace('\\', '/').ToLowerInvariant();
			bool flag = blacklistSet.Contains(text);
			configManager.LogDebug($"Image is blacklisted: {flag}");
			if (!flag)
			{
				string directoryName = Path.GetDirectoryName(text);
				while (!string.IsNullOrEmpty(directoryName))
				{
					directoryName = directoryName.Replace('\\', '/');
					if (blacklistSet.Contains(directoryName) || blacklistSet.Contains(directoryName + "/"))
					{
						configManager.LogDebug("Parent directory is blacklisted: " + directoryName);
						return true;
					}
					directoryName = Path.GetDirectoryName(directoryName);
				}
			}
			return flag;
		}

		private string GetImagesBasePath()
		{
			string pluginPath = Paths.PluginPath;
			if (string.IsNullOrEmpty(pluginPath))
			{
				logger.LogError((object)"BepInEx PluginPath is null or empty");
				return null;
			}
			string text = Path.Combine(pluginPath, "InteriorTitleCardsImages");
			configManager?.LogDebug("GetImagesBasePath returning: " + text);
			return text;
		}

		private bool EnsureImageDirectoryStructure()
		{
			if (baseDirectoryStructureInitialized)
			{
				return true;
			}
			try
			{
				string imagesBasePath = GetImagesBasePath();
				if (!Directory.Exists(imagesBasePath))
				{
					Directory.CreateDirectory(imagesBasePath);
					configManager.LogDebug("Created base images directory: " + imagesBasePath);
				}
				string text = Path.Combine(imagesBasePath, "dev");
				string text2 = Path.Combine(imagesBasePath, "user");
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
					configManager.LogDebug("Created dev directory: " + text);
				}
				if (!Directory.Exists(text2))
				{
					Directory.CreateDirectory(text2);
					configManager.LogDebug("Created user directory: " + text2);
				}
				baseDirectoryStructureInitialized = true;
				return true;
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Failed to create image directory structure: " + ex.Message));
				return false;
			}
		}

		private string SanitizeDungeonName(string dungeonName)
		{
			if (string.IsNullOrEmpty(dungeonName))
			{
				return "Unknown";
			}
			string text = dungeonName;
			text = text.Replace("\\", "_").Replace("/", "_");
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			char[] array = invalidFileNameChars;
			foreach (char oldChar in array)
			{
				text = text.Replace(oldChar, '_');
			}
			while (text.Contains("__"))
			{
				text = text.Replace("__", "_");
			}
			text = text.Trim().Trim('_');
			if (string.IsNullOrEmpty(text))
			{
				text = "Unknown";
			}
			if (text.Length > 100)
			{
				text = text.Substring(0, 100).TrimEnd('_');
			}
			configManager.LogDebug("Sanitized dungeon name: '" + dungeonName + "' -> '" + text + "'");
			return text;
		}

		private string ValidateAndCreateImageDirectory(string dungeonName, int imageType, bool isDeveloper)
		{
			try
			{
				string path = SanitizeDungeonName(dungeonName);
				if (!EnsureImageDirectoryStructure())
				{
					return null;
				}
				string imagesBasePath = GetImagesBasePath();
				string path2 = (isDeveloper ? "dev" : "user");
				string path3;
				switch (imageType)
				{
				case 0:
					path3 = "InteriorText";
					break;
				case 1:
					path3 = "TopText";
					break;
				case 2:
					path3 = "Combined";
					break;
				default:
					configManager.LogDebug($"Invalid imageType: {imageType}");
					return null;
				}
				string text = Path.Combine(imagesBasePath, path2, path, path3);
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
					configManager.LogDebug("Created image directory: " + text);
				}
				return text;
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Failed to validate/create image directory for " + dungeonName + ": " + ex.Message));
				return null;
			}
		}

		private Sprite LoadSpriteFromFile(string imagePath, int imageType = -1)
		{
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Expected O, but got Unknown
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Invalid comparison between Unknown and I4
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Invalid comparison between Unknown and I4
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Invalid comparison between Unknown and I4
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Invalid comparison between Unknown and I4
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Invalid comparison between Unknown and I4
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Invalid comparison between Unknown and I4
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Invalid comparison between Unknown and I4
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Invalid comparison between Unknown and I4
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Invalid comparison between Unknown and I4
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Invalid comparison between Unknown and I4
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Invalid comparison between Unknown and I4
			//IL_055b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Invalid comparison between Unknown and I4
			//IL_06cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			configManager.LogDebug("LoadSpriteFromFile called with path: " + imagePath);
			if (string.IsNullOrEmpty(imagePath))
			{
				configManager.LogDebug("Image path is null or empty");
				return null;
			}
			if (!File.Exists(imagePath))
			{
				configManager.LogDebug("Image file does not exist: " + imagePath);
				return null;
			}
			FileInfo fileInfo = new FileInfo(imagePath);
			if (fileInfo.Length == 0)
			{
				logger.LogWarning((object)("Image file is empty: " + imagePath));
				return null;
			}
			if (fileInfo.Length > 10485760)
			{
				logger.LogWarning((object)$"Image file too large ({fileInfo.Length} bytes): {imagePath}");
				return null;
			}
			string text = Path.GetExtension(imagePath).ToLowerInvariant();
			string[] source = new string[6] { ".png", ".jpg", ".jpeg", ".bmp", ".tga", ".gif" };
			if (!source.Contains(text))
			{
				logger.LogWarning((object)("Unsupported image format: " + text + " for file: " + imagePath));
				return null;
			}
			if (text == ".png")
			{
				try
				{
					using FileStream fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
					byte[] array = new byte[8];
					int num = fileStream.Read(array, 0, 8);
					if (num < 8)
					{
						logger.LogWarning((object)("PNG file too small to be valid: " + imagePath));
						return null;
					}
					byte[] array2 = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 };
					for (int i = 0; i < 8; i++)
					{
						if (array[i] != array2[i])
						{
							logger.LogWarning((object)("Invalid PNG signature: " + imagePath));
							return null;
						}
					}
				}
				catch (Exception ex)
				{
					logger.LogWarning((object)("Error validating PNG file " + imagePath + ": " + ex.Message));
					return null;
				}
			}
			if (cachedSprites.ContainsKey(imagePath))
			{
				configManager.LogDebug("Image found in cache");
				return cachedSprites[imagePath];
			}
			Texture2D val = null;
			try
			{
				configManager.LogDebug("Loading image from file");
				byte[] array3 = File.ReadAllBytes(imagePath);
				configManager.LogDebug($"Loaded {array3.Length} bytes of image data");
				if (array3.Length < 8)
				{
					logger.LogWarning((object)("Image data too small to be valid: " + imagePath));
					return null;
				}
				val = new Texture2D(2, 2);
				if (ImageConversion.LoadImage(val, array3))
				{
					configManager.LogDebug($"Texture loaded successfully. Format: {val.format}, Size: {((Texture)val).width}x{((Texture)val).height}");
					if (((Texture)val).width <= 0 || ((Texture)val).height <= 0)
					{
						logger.LogWarning((object)$"Invalid texture dimensions {((Texture)val).width}x{((Texture)val).height}: {imagePath}");
						Object.Destroy((Object)(object)val);
						return null;
					}
					if (((Texture)val).width > 4096 || ((Texture)val).height > 4096)
					{
						logger.LogWarning((object)$"Texture dimensions too large {((Texture)val).width}x{((Texture)val).height}: {imagePath}");
						Object.Destroy((Object)(object)val);
						return null;
					}
					if (((Texture)val).width < 16 || ((Texture)val).height < 16)
					{
						logger.LogWarning((object)$"Texture dimensions too small {((Texture)val).width}x{((Texture)val).height}: {imagePath}");
						Object.Destroy((Object)(object)val);
						return null;
					}
					float num2 = (float)((Texture)val).width / (float)((Texture)val).height;
					if (num2 > 10f || num2 < 0.1f)
					{
						logger.LogWarning((object)$"Extreme aspect ratio {num2:F2}: {imagePath}");
						Object.Destroy((Object)(object)val);
						return null;
					}
					if ((int)val.format == 10 || (int)val.format == 12 || (int)val.format == 25 || (int)val.format == 34 || (int)val.format == 45 || (int)val.format == 47)
					{
						configManager.LogDebug($"Texture format: {val.format} (compressed)");
					}
					else
					{
						if ((int)val.format != 4 && (int)val.format != 3 && (int)val.format != 14 && (int)val.format != 5 && (int)val.format != 13 && (int)val.format != 7)
						{
							logger.LogWarning((object)$"Unsupported texture format {val.format}: {imagePath}");
							Object.Destroy((Object)(object)val);
							return null;
						}
						configManager.LogDebug($"Texture format: {val.format} (uncompressed)");
					}
					configManager.LogDebug($"Successfully loaded image into texture, size: {((Texture)val).width}x{((Texture)val).height}");
					int num3 = 0;
					int num4 = 0;
					switch (imageType)
					{
					case 0:
						num3 = configManager.InteriorTextImageWidth;
						num4 = configManager.InteriorTextImageHeight;
						break;
					case 1:
						num3 = configManager.TopTextImageWidth;
						num4 = configManager.TopTextImageHeight;
						break;
					case 2:
						num3 = configManager.CombinedImageWidth;
						num4 = configManager.CombinedImageHeight;
						break;
					}
					if (num3 > 0 || num4 > 0)
					{
						val = ResizeTexture(val, num3, num4);
						configManager.LogDebug($"Resized texture to: {((Texture)val).width}x{((Texture)val).height}");
					}
					Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					if ((Object)(object)val2 == (Object)null)
					{
						logger.LogError((object)("Failed to create sprite from texture: " + imagePath));
						Object.Destroy((Object)(object)val);
						return null;
					}
					configManager.LogDebug("Created sprite from texture");
					ManageSpriteCache(imagePath, val2);
					configManager.LogDebug("Cached sprite");
					return val2;
				}
				logger.LogWarning((object)("Failed to load image data into texture (unsupported format?): " + imagePath));
			}
			catch (FileNotFoundException ex2)
			{
				logger.LogError((object)("Image file not found: " + imagePath + " - " + ex2.Message));
			}
			catch (IOException ex3)
			{
				logger.LogError((object)("IO error loading image: " + imagePath + " - " + ex3.Message));
			}
			catch (UnauthorizedAccessException ex4)
			{
				logger.LogError((object)("Access denied loading image: " + imagePath + " - " + ex4.Message));
			}
			catch (OutOfMemoryException ex5)
			{
				logger.LogError((object)("Out of memory loading image: " + imagePath + " - " + ex5.Message));
			}
			catch (Exception ex6)
			{
				logger.LogError((object)("Unexpected error loading sprite from " + imagePath + ": " + ex6.Message));
				configManager.LogDebug("Exception details: " + ex6.GetType().Name + " - " + ex6.Message);
			}
			finally
			{
				if ((Object)(object)val != (Object)null && !cachedSprites.ContainsKey(imagePath))
				{
					Object.Destroy((Object)(object)val);
				}
			}
			configManager.LogDebug("Failed to load sprite, returning null");
			return null;
		}

		private Texture2D ResizeTexture(Texture2D originalTexture, int maxWidth, int maxHeight)
		{
			//IL_008b: 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_0098: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			int num = ((maxWidth <= 0) ? ((Texture)originalTexture).width : maxWidth);
			int num2 = ((maxHeight <= 0) ? ((Texture)originalTexture).height : maxHeight);
			if (num >= ((Texture)originalTexture).width && num2 >= ((Texture)originalTexture).height)
			{
				return originalTexture;
			}
			float num3 = (float)((Texture)originalTexture).width / (float)((Texture)originalTexture).height;
			float num4 = (float)num / (float)num2;
			int num5;
			int num6;
			if (num3 > num4)
			{
				num5 = num;
				num6 = Mathf.RoundToInt((float)num / num3);
			}
			else
			{
				num6 = num2;
				num5 = Mathf.RoundToInt((float)num2 * num3);
			}
			Texture2D val = new Texture2D(num5, num6, originalTexture.format, false);
			Color[] pixels = originalTexture.GetPixels();
			Color[] array = (Color[])(object)new Color[num5 * num6];
			float num7 = (float)((Texture)originalTexture).width / (float)num5;
			float num8 = (float)((Texture)originalTexture).height / (float)num6;
			for (int i = 0; i < num6; i++)
			{
				for (int j = 0; j < num5; j++)
				{
					float num9 = (float)j * num7;
					float num10 = (float)i * num8;
					int num11 = Mathf.FloorToInt(num9);
					int num12 = Mathf.FloorToInt(num10);
					int num13 = Mathf.Min(num11 + 1, ((Texture)originalTexture).width - 1);
					int num14 = Mathf.Min(num12 + 1, ((Texture)originalTexture).height - 1);
					float num15 = num9 - (float)num11;
					float num16 = num10 - (float)num12;
					Color val2 = pixels[num12 * ((Texture)originalTexture).width + num11];
					Color val3 = pixels[num12 * ((Texture)originalTexture).width + num13];
					Color val4 = pixels[num14 * ((Texture)originalTexture).width + num11];
					Color val5 = pixels[num14 * ((Texture)originalTexture).width + num13];
					Color val6 = Color.Lerp(val2, val3, num15);
					Color val7 = Color.Lerp(val4, val5, num15);
					array[i * num5 + j] = Color.Lerp(val6, val7, num16);
				}
			}
			val.SetPixels(array);
			val.Apply();
			Object.Destroy((Object)(object)originalTexture);
			return val;
		}

		private string GetImagePath(string dungeonName, int imageType, bool isDeveloper)
		{
			configManager.LogDebug($"GetImagePath called - dungeon: {dungeonName}, imageType: {imageType}, isDeveloper: {isDeveloper}");
			string text = SanitizeDungeonName(dungeonName);
			string text2 = ValidateAndCreateImageDirectory(text, imageType, isDeveloper);
			if (string.IsNullOrEmpty(text2))
			{
				configManager.LogDebug("Failed to validate/create image directory");
				return null;
			}
			configManager.LogDebug("Image directory path: " + text2);
			configManager.LogDebug("Directory exists, checking for image files");
			string[] array = new string[5]
			{
				"image",
				text.ToLowerInvariant(),
				text.Replace("_", "").ToLowerInvariant(),
				"titlecard",
				"card"
			};
			string[] array2 = new string[6] { ".png", ".jpg", ".jpeg", ".bmp", ".tga", ".gif" };
			string[] array3 = array;
			foreach (string text3 in array3)
			{
				string[] array4 = array2;
				foreach (string text4 in array4)
				{
					string text5 = Path.Combine(text2, text3 + text4);
					configManager.LogDebug("Checking for " + text3 + text4 + ": " + text5);
					if (File.Exists(text5))
					{
						configManager.LogDebug("Found " + text4.ToUpper() + " image: " + text3 + text4);
						return text5;
					}
				}
			}
			configManager.LogDebug("No image file found");
			return null;
		}

		private Sprite LoadCustomImage(string dungeonName, int imageType)
		{
			configManager.LogDebug($"LoadCustomImage called for dungeon: {dungeonName}, imageType: {imageType}");
			if (!configManager.EnableCustomImages)
			{
				configManager.LogDebug("Custom images disabled, returning null");
				return null;
			}
			int imageSourceMode = configManager.ImageSourceMode;
			configManager.LogDebug($"Image source mode: {imageSourceMode}");
			Sprite val = null;
			switch (imageSourceMode)
			{
			case 0:
				val = TryLoadImage(dungeonName, imageType, isDeveloper: true);
				break;
			case 1:
				val = TryLoadImage(dungeonName, imageType, isDeveloper: false);
				break;
			case 2:
				val = TryLoadImage(dungeonName, imageType, isDeveloper: true) ?? TryLoadImage(dungeonName, imageType, isDeveloper: false);
				break;
			case 3:
				val = TryLoadImage(dungeonName, imageType, isDeveloper: false) ?? TryLoadImage(dungeonName, imageType, isDeveloper: true);
				break;
			default:
				configManager.LogDebug($"Invalid source mode: {imageSourceMode}, defaulting to developer priority");
				val = TryLoadImage(dungeonName, imageType, isDeveloper: true) ?? TryLoadImage(dungeonName, imageType, isDeveloper: false);
				break;
			}
			if ((Object)(object)val == (Object)null)
			{
				configManager.LogDebug("No valid image found, returning null");
			}
			return val;
		}

		private Sprite TryLoadImage(string dungeonName, int imageType, bool isDeveloper)
		{
			if (configManager == null)
			{
				logger.LogError((object)"ConfigManager is null in TryLoadImage");
				return null;
			}
			string text = (isDeveloper ? "developer" : "user");
			configManager.LogDebug("Checking " + text + " images");
			string imagePath = GetImagePath(dungeonName, imageType, isDeveloper);
			configManager.LogDebug(text + " image path: " + (imagePath ?? "null"));
			if (!string.IsNullOrEmpty(imagePath) && !IsImageBlacklisted(imagePath))
			{
				configManager.LogDebug(text + " image not blacklisted, attempting to load");
				Sprite val = LoadSpriteFromFile(imagePath, imageType);
				if ((Object)(object)val != (Object)null)
				{
					configManager.LogDebug("Successfully loaded " + text + " image");
					return val;
				}
				configManager.LogDebug("Failed to load " + text + " image");
			}
			else
			{
				configManager.LogDebug(text + " image is null/empty or blacklisted");
			}
			return null;
		}

		private string GetImageTypeFolder(int imageType)
		{
			return imageType switch
			{
				0 => "InteriorText", 
				1 => "TopText", 
				2 => "Combined", 
				_ => "", 
			};
		}

		private void ManageSpriteCache(string imagePath, Sprite sprite)
		{
			if (cachedSprites.ContainsKey(imagePath))
			{
				spriteCacheOrder = new Queue<string>(spriteCacheOrder.Where((string x) => x != imagePath));
			}
			else
			{
				while (cachedSprites.Count >= 50 && spriteCacheOrder.Count > 0)
				{
					string text = spriteCacheOrder.Dequeue();
					if (cachedSprites.TryGetValue(text, out var value))
					{
						if ((Object)(object)value.texture != (Object)null)
						{
							Object.Destroy((Object)(object)value.texture);
						}
						Object.Destroy((Object)(object)value);
						cachedSprites.Remove(text);
						configManager.LogDebug("Evicted sprite from cache: " + text);
					}
				}
			}
			cachedSprites[imagePath] = sprite;
			spriteCacheOrder.Enqueue(imagePath);
			configManager.LogDebug($"Cached sprite. Cache size: {cachedSprites.Count}/{50}");
		}

		private void ClearSpriteCache()
		{
			configManager.LogDebug("Clearing sprite cache");
			foreach (Sprite value in cachedSprites.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					if ((Object)(object)value.texture != (Object)null)
					{
						Object.Destroy((Object)(object)value.texture);
					}
					Object.Destroy((Object)(object)value);
				}
			}
			cachedSprites.Clear();
			spriteCacheOrder.Clear();
			configManager.LogDebug("Sprite cache cleared");
		}

		private string GetCacheStatistics()
		{
			long num = 0L;
			int num2 = 0;
			foreach (Sprite value in cachedSprites.Values)
			{
				if ((Object)(object)value != (Object)null && (Object)(object)value.texture != (Object)null)
				{
					num += (long)((Texture)value.texture).width * (long)((Texture)value.texture).height * 4;
					num2++;
				}
			}
			return $"Cache stats: {cachedSprites.Count} sprites, {num2} textures, ~{num / 1024} KB memory usage";
		}

		public void Cleanup()
		{
			configManager.LogDebug("TitleCardManager cleanup called");
			ClearSpriteCache();
		}

		public void CreateTitleCard()
		{
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Expected O, but got Unknown
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Expected O, but got Unknown
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Expected O, but got Unknown
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			configManager.LogDebug("CreateTitleCard called");
			hudManager = HUDManager.Instance;
			configManager.LogDebug($"HUDManager instance: {(Object)(object)hudManager != (Object)null}");
			if (titleCardPool.Count > 0)
			{
				configManager.LogDebug("Reusing title card from pool");