Decompiled source of Interior Title Cards v1.3.1
BepInEx/plugins/interiortitlecards/Interior Title Cards.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.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");