Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Interior Title Cards v1.3.1
BepInEx/plugins/interiortitlecards/Interior Title Cards.dll
Decompiled 7 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");