Decompiled source of ChronosRewind v1.2.0

ChronosRewind.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BlackMagicAPI.Managers;
using BlackMagicAPI.Modules.Spells;
using ChronoPara.Modules;
using ChronoPara.Patches;
using FishNet.Connection;
using FishNet.Object;
using FishUtilities.Network;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ChronosRewind")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+626e98102e05e77173a1d871b5e776fa4061c88f")]
[assembly: AssemblyProduct("Chronos Rewind")]
[assembly: AssemblyTitle("ChronosRewind")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.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;
		}
	}
}
namespace ChronoPara
{
	[BepInProcess("MageArena")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.cheekyentity.ChronosRewind.dev", "Chronos Rewind", "1.2.0")]
	public class ChronoParaPlugin : BaseUnityPlugin
	{
		private const string MyGUID = "com.cheekyentity.ChronosRewind.dev";

		internal const string PluginName = "Chronos Rewind";

		private const string VersionString = "1.2.0";

		private static Harmony Harmony;

		internal static ManualLogSource Logger;

		public static string modsync = "all";

		public static ConfigEntry<float> RecallCooldown;

		public static ConfigEntry<float> RewindDuration;

		public static ConfigEntry<float> RecallKillWindow;

		public static ConfigEntry<bool> CanSpawnInChests;

		public static ConfigEntry<bool> DebugMode;

		internal static ChronoParaPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			InitializeConfiguration();
			Harmony = new Harmony("com.cheekyentity.ChronosRewind.dev");
			try
			{
				Harmony.PatchAll();
				Logger.LogInfo((object)"Harmony patches applied successfully");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to apply Harmony patches: " + ex.Message));
				return;
			}
			InitializeSpellSystem();
			PerformanceManager.Initialize();
			Logger.LogInfo((object)"Plugin com.cheekyentity.ChronosRewind.dev v1.2.0 is loaded!");
		}

		private void Update()
		{
			try
			{
				PerformanceManager.Update();
			}
			catch (Exception ex)
			{
				ConfigEntry<bool> debugMode = DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					Logger.LogError((object)("Error in plugin update: " + ex.Message));
				}
			}
		}

		private void OnDestroy()
		{
			try
			{
				DiagnosticLogger.LogInfo("Starting plugin cleanup...", LogCategory.System);
				PerformanceManager.Shutdown();
				ConfigEntry<bool> debugMode = DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					string text = DiagnosticLogger.GenerateDiagnosticReport();
					Logger.LogDebug((object)("Final diagnostic report:\n" + text));
					string text2 = PerformanceOptimizer.GeneratePerformanceDiagnostic();
					Logger.LogDebug((object)("Final performance report:\n" + text2));
					PerformanceOptimizer.ForceGarbageCollection();
				}
				try
				{
					DeathTracker.Cleanup();
					DiagnosticLogger.LogInfo("DeathTracker cleanup completed", LogCategory.System);
				}
				catch (Exception ex)
				{
					DiagnosticLogger.LogError("Error during DeathTracker cleanup: " + ex.Message, LogCategory.System, ex);
				}
				try
				{
					AssetManager.Cleanup();
					DiagnosticLogger.LogInfo("AssetManager cleanup completed", LogCategory.System);
				}
				catch (Exception ex2)
				{
					DiagnosticLogger.LogError("Error during AssetManager cleanup: " + ex2.Message, LogCategory.System, ex2);
				}
				try
				{
					if (Harmony != null)
					{
						Harmony.UnpatchSelf();
						DiagnosticLogger.LogInfo("Harmony patches removed", LogCategory.System);
					}
					else
					{
						DiagnosticLogger.LogWarning("Harmony instance was null during cleanup", LogCategory.System);
					}
				}
				catch (Exception ex3)
				{
					DiagnosticLogger.LogError("Error during Harmony cleanup: " + ex3.Message, LogCategory.System, ex3);
				}
				int totalErrorCount = DiagnosticLogger.GetTotalErrorCount();
				if (totalErrorCount > 0)
				{
					Logger.LogWarning((object)$"Plugin cleanup completed with {totalErrorCount} total errors logged during session");
					Logger.LogInfo((object)"Check the diagnostic logs above for details on any issues encountered");
				}
				else
				{
					DiagnosticLogger.LogInfo("Plugin cleanup completed successfully with no errors", LogCategory.System);
				}
			}
			catch (Exception ex4)
			{
				Logger.LogError((object)("Critical error during plugin cleanup: " + ex4.Message));
				try
				{
					ConfigEntry<bool> debugMode2 = DebugMode;
					if (debugMode2 != null && debugMode2.Value)
					{
						Logger.LogDebug((object)("Cleanup error stack trace: " + ex4.StackTrace));
					}
				}
				catch
				{
				}
			}
		}

		private void InitializeConfiguration()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			try
			{
				ConfigDescription val = new ConfigDescription("Cooldown time in seconds for Chronos Rewind spell", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 120f), Array.Empty<object>());
				RecallCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Chronos Rewind", "Cooldown", 45f, val);
				ConfigDescription val2 = new ConfigDescription("How many seconds back to rewind when casting Chronos Rewind", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>());
				RewindDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Chronos Rewind", "Rewind Duration", 3f, val2);
				ConfigDescription val3 = new ConfigDescription("Time window after recall for kills to count as recall-related (in seconds)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>());
				RecallKillWindow = ((BaseUnityPlugin)this).Config.Bind<float>("Chronos Rewind", "Kill Window", 3f, val3);
				ConfigDescription val4 = new ConfigDescription("Allow Chronos Rewind spell to spawn in team chests for natural discovery", (AcceptableValueBase)null, Array.Empty<object>());
				CanSpawnInChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Chronos Rewind", "Can Spawn In Chests", false, val4);
				DebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable Debug Mode", false, "Enable detailed debug logging");
				Logger.LogInfo((object)"Configuration system initialized successfully");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to initialize configuration: " + ex.Message));
				Logger.LogWarning((object)"Using default configuration values");
			}
		}

		private void InitializeSpellSystem()
		{
			try
			{
				DiagnosticLogger.LogInfo("Initializing spell system...", LogCategory.System);
				if (!ConfigurationValidator.ValidateAllConfiguration().IsValid)
				{
					DiagnosticLogger.LogWarning("Configuration validation found issues, but continuing with initialization", LogCategory.Configuration);
					ConfigEntry<bool> debugMode = DebugMode;
					if (debugMode != null && debugMode.Value)
					{
						string text = ConfigurationValidator.GenerateUserFriendlyReport();
						Logger.LogInfo((object)("Configuration Report:\n" + text));
					}
				}
				ConfigEntry<bool> debugMode2 = DebugMode;
				if (debugMode2 != null && debugMode2.Value)
				{
					DiagnosticLogger.LogInfo("Running integration tests...", LogCategory.System);
					IntegrationTester.TestSuiteResult testSuiteResult = IntegrationTester.RunIntegrationTests();
					if (!testSuiteResult.AllPassed)
					{
						DiagnosticLogger.LogWarning($"Integration tests found issues: {testSuiteResult.FailedCount} failed tests", LogCategory.System);
					}
					DiagnosticLogger.LogInfo("Running performance tests...", LogCategory.System);
					PerformanceManager.RunPerformanceTests();
				}
				bool flag = LoadAssetBundle();
				bool flag2 = RegisterTemporalRecallSpell();
				bool flag3 = RegisterCustomDeathIcon();
				if (flag2)
				{
					DiagnosticLogger.LogInfo("Spell system initialized successfully", LogCategory.System);
					DiagnosticLogger.LogInfo("Initialization Summary - AssetBundle: " + (flag ? "Loaded" : "Fallback") + ", Spell: " + (flag2 ? "Registered" : "Failed") + ", DeathIcon: " + (flag3 ? "Registered" : "Failed"), LogCategory.System);
					UserFeedbackSystem.ProvideComprehensiveFeedback();
				}
				else
				{
					DiagnosticLogger.LogError("Critical failure in spell system initialization - spell registration failed", LogCategory.System);
					UserFeedbackSystem.ProvideTroubleshootingFeedback("spell_not_found");
				}
			}
			catch (Exception ex)
			{
				DiagnosticLogger.LogError("Failed to initialize spell system: " + ex.Message, LogCategory.System, ex);
				Logger.LogError((object)"Critical error during spell system initialization. Please check the following:");
				Logger.LogError((object)"1. Ensure all mod dependencies are installed and up to date");
				Logger.LogError((object)"2. Check for conflicts with other mods");
				Logger.LogError((object)"3. Verify game files are not corrupted");
				Logger.LogError((object)"4. Try reinstalling the Chronos Rewind mod");
			}
		}

		private bool LoadAssetBundle()
		{
			try
			{
				DiagnosticLogger.LogInfo("Loading asset bundle...", LogCategory.System);
				AssetManager.Initialize();
				if (AssetManager.IsBundleLoaded)
				{
					DiagnosticLogger.LogInfo("Custom assets loaded successfully", LogCategory.System);
					ConfigEntry<bool> debugMode = DebugMode;
					if (debugMode != null && debugMode.Value)
					{
						string assetInfo = AssetManager.GetAssetInfo();
						DiagnosticLogger.LogDebug("Asset bundle details: " + assetInfo, LogCategory.System);
					}
					return true;
				}
				DiagnosticLogger.LogWarning("Custom AssetBundle not found, using fallback assets", LogCategory.System);
				Logger.LogInfo((object)"Note: Some visual and audio effects may not be available without the custom AssetBundle");
				Logger.LogInfo((object)"To get the full experience, ensure 'chronomancer.bundle' is in the mod directory");
				return false;
			}
			catch (Exception ex)
			{
				DiagnosticLogger.LogError("Failed to load asset bundle: " + ex.Message, LogCategory.System, ex);
				Logger.LogWarning((object)"Asset bundle loading failed - continuing with fallback assets");
				Logger.LogInfo((object)"Recovery guidance:");
				Logger.LogInfo((object)"1. Check that 'chronomancer.bundle' exists in the mod directory");
				Logger.LogInfo((object)"2. Verify the file is not corrupted (try re-downloading the mod)");
				Logger.LogInfo((object)"3. Ensure you have sufficient disk space and permissions");
				return false;
			}
		}

		private bool RegisterTemporalRecallSpell()
		{
			try
			{
				DiagnosticLogger.LogInfo("Registering Chronos Rewind spell...", LogCategory.System);
				if (typeof(ChronosRewind_Data) == null)
				{
					DiagnosticLogger.LogError("ChronosRewind_Data type not found", LogCategory.System);
					return false;
				}
				if (typeof(ChronosRewind_Logic) == null)
				{
					DiagnosticLogger.LogError("ChronosRewind_Logic type not found", LogCategory.System);
					return false;
				}
				BlackMagicManager.RegisterSpell((BaseUnityPlugin)(object)this, typeof(ChronosRewind_Data), typeof(ChronosRewind_Logic));
				DiagnosticLogger.LogInfo("Successfully registered Chronos Rewind spell", LogCategory.System);
				ConfigEntry<bool> debugMode = DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					DiagnosticLogger.LogDebug($"Spell registered with cooldown: {ConfigManager.RecallCooldown}s", LogCategory.System);
				}
				return true;
			}
			catch (Exception ex)
			{
				DiagnosticLogger.LogError("Failed to register Chronos Rewind spell: " + ex.Message, LogCategory.System, ex);
				Logger.LogError((object)"Spell registration failed - the mod will not function correctly");
				Logger.LogInfo((object)"Recovery guidance:");
				Logger.LogInfo((object)"1. Ensure BlackMagicAPI is installed and up to date");
				Logger.LogInfo((object)"2. Check for conflicts with other spell mods");
				Logger.LogInfo((object)"3. Verify the mod files are not corrupted");
				Logger.LogInfo((object)"4. Try restarting the game");
				return false;
			}
		}

		private bool RegisterCustomDeathIcon()
		{
			try
			{
				DiagnosticLogger.LogInfo("Initializing death tracking system...", LogCategory.System);
				DeathTracker.Initialize();
				if (DeathTracker.IsInitialized)
				{
					DiagnosticLogger.LogInfo("Death tracking system initialized successfully", LogCategory.System);
					return true;
				}
				DiagnosticLogger.LogWarning("Death tracking system initialization failed - recall-related death attribution may not work", LogCategory.System);
				Logger.LogInfo((object)"Note: The core Chronos Rewind functionality will still work");
				Logger.LogInfo((object)"Only custom death messages and statistics will be affected");
				return false;
			}
			catch (Exception ex)
			{
				DiagnosticLogger.LogError("Failed to initialize death tracking system: " + ex.Message, LogCategory.System, ex);
				Logger.LogWarning((object)"Death tracking initialization failed - this is not critical for core functionality");
				Logger.LogInfo((object)"Recovery guidance:");
				Logger.LogInfo((object)"1. Check that the death icon asset is available");
				Logger.LogInfo((object)"2. Verify BlackMagicAPI death icon registration is working");
				Logger.LogInfo((object)"3. This may be caused by mod conflicts with other death-related mods");
				return false;
			}
		}
	}
}
namespace ChronoPara.Patches
{
	[HarmonyPatch(typeof(PlayerMovement))]
	public static class PlayerMovementPatch
	{
		[CompilerGenerated]
		private sealed class <RetryAttachmentCoroutine>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject playerObject;

			private int <attempt>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<attempt>5__2 = 1;
					break;
				case 1:
				{
					<>1__state = -1;
					if ((Object)(object)playerObject == (Object)null)
					{
						ManualLogSource logger = ChronoParaPlugin.Logger;
						if (logger != null)
						{
							logger.LogDebug((object)"Retry attachment cancelled - player object was destroyed");
						}
						return false;
					}
					if ((Object)(object)playerObject.GetComponent<PositionTracker>() != (Object)null)
					{
						ManualLogSource logger2 = ChronoParaPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogDebug((object)("Retry attachment cancelled - PositionTracker already exists on " + ((Object)playerObject).name));
						}
						return false;
					}
					bool flag = false;
					try
					{
						flag = AttachPositionTracker(playerObject);
					}
					catch (Exception ex)
					{
						ManualLogSource logger3 = ChronoParaPlugin.Logger;
						if (logger3 != null)
						{
							logger3.LogError((object)$"Exception during retry attachment attempt {<attempt>5__2}: {ex.Message}");
						}
						flag = false;
					}
					if (flag)
					{
						ManualLogSource logger4 = ChronoParaPlugin.Logger;
						if (logger4 != null)
						{
							logger4.LogInfo((object)$"Retry attachment successful for {((Object)playerObject).name} (attempt {<attempt>5__2})");
						}
						return false;
					}
					ManualLogSource logger5 = ChronoParaPlugin.Logger;
					if (logger5 != null)
					{
						logger5.LogWarning((object)$"Retry attachment failed for {((Object)playerObject).name} (attempt {<attempt>5__2}/{3})");
					}
					<attempt>5__2++;
					break;
				}
				}
				if (<attempt>5__2 <= 3)
				{
					float num = 1f * Mathf.Pow(2f, (float)(<attempt>5__2 - 1));
					<>2__current = (object)new WaitForSeconds(num);
					<>1__state = 1;
					return true;
				}
				ManualLogSource logger6 = ChronoParaPlugin.Logger;
				if (logger6 != null)
				{
					GameObject obj = playerObject;
					logger6.LogError((object)("All retry attempts exhausted for PositionTracker attachment on " + ((obj != null) ? ((Object)obj).name : 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();
			}
		}

		[HarmonyPatch("OnStartClient")]
		[HarmonyPostfix]
		public static void OnStartClient_Postfix(PlayerMovement __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).gameObject == (Object)null)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"OnStartClient_Postfix called with null PlayerMovement instance");
					}
					return;
				}
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogDebug((object)("OnStartClient_Postfix called for player: " + ((Object)((Component)__instance).gameObject).name));
				}
				if ((Object)(object)((Component)__instance).gameObject.GetComponent<PositionTracker>() != (Object)null)
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogDebug((object)("PositionTracker already exists on " + ((Object)((Component)__instance).gameObject).name));
					}
				}
				else if (HasConflictingComponents(((Component)__instance).gameObject))
				{
					ManualLogSource logger4 = ChronoParaPlugin.Logger;
					if (logger4 != null)
					{
						logger4.LogWarning((object)("Conflicting components detected on " + ((Object)((Component)__instance).gameObject).name + " - skipping PositionTracker attachment"));
					}
				}
				else
				{
					AttachPositionTracker(((Component)__instance).gameObject);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger5 = ChronoParaPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)("Error in OnStartClient_Postfix: " + ex.Message));
				}
				if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).gameObject != (Object)null)
				{
					ScheduleRetryAttachment(((Component)__instance).gameObject);
				}
			}
		}

		private static bool AttachPositionTracker(GameObject playerObject)
		{
			try
			{
				if ((Object)(object)playerObject == (Object)null)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogError((object)"Cannot attach PositionTracker - player GameObject is null");
					}
					return false;
				}
				if ((Object)(object)playerObject.GetComponent<PlayerMovement>() == (Object)null)
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)("GameObject " + ((Object)playerObject).name + " does not have PlayerMovement component - skipping PositionTracker attachment"));
					}
					return false;
				}
				if ((Object)(object)playerObject.GetComponent<PositionTracker>() != (Object)null)
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogDebug((object)("PositionTracker already attached to " + ((Object)playerObject).name));
					}
					return true;
				}
				PositionTracker positionTracker = playerObject.AddComponent<PositionTracker>();
				if ((Object)(object)positionTracker == (Object)null)
				{
					ManualLogSource logger4 = ChronoParaPlugin.Logger;
					if (logger4 != null)
					{
						logger4.LogError((object)("Failed to add PositionTracker component to " + ((Object)playerObject).name));
					}
					return false;
				}
				ManualLogSource logger5 = ChronoParaPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogInfo((object)("Successfully attached PositionTracker to player: " + ((Object)playerObject).name));
				}
				if (!ValidatePositionTracker(positionTracker))
				{
					ManualLogSource logger6 = ChronoParaPlugin.Logger;
					if (logger6 != null)
					{
						logger6.LogWarning((object)("PositionTracker attached but validation failed for " + ((Object)playerObject).name));
					}
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger7 = ChronoParaPlugin.Logger;
				if (logger7 != null)
				{
					logger7.LogError((object)("Exception while attaching PositionTracker to " + ((playerObject != null) ? ((Object)playerObject).name : null) + ": " + ex.Message));
				}
				return false;
			}
		}

		private static bool HasConflictingComponents(GameObject playerObject)
		{
			try
			{
				ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					Component[] components = playerObject.GetComponents<Component>();
					string text = string.Join(", ", Array.ConvertAll(components, (Component c) => ((object)c).GetType().Name));
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogDebug((object)("Components on " + ((Object)playerObject).name + ": " + text));
					}
				}
				return false;
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error checking for conflicting components: " + ex.Message));
				}
				return false;
			}
		}

		private static bool ValidatePositionTracker(PositionTracker tracker)
		{
			try
			{
				if ((Object)(object)tracker == (Object)null)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogError((object)"PositionTracker validation failed - component is null");
					}
					return false;
				}
				if ((Object)(object)((Component)tracker).gameObject == (Object)null)
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogError((object)"PositionTracker validation failed - GameObject is null");
					}
					return false;
				}
				if ((Object)(object)((Component)tracker).gameObject.GetComponent<PlayerMovement>() == (Object)null)
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogError((object)("PositionTracker validation failed - no PlayerMovement component on " + ((Object)((Component)tracker).gameObject).name));
					}
					return false;
				}
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogDebug((object)("PositionTracker validation passed for " + ((Object)((Component)tracker).gameObject).name));
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger5 = ChronoParaPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)("Exception during PositionTracker validation: " + ex.Message));
				}
				return false;
			}
		}

		private static void ScheduleRetryAttachment(GameObject playerObject)
		{
			try
			{
				if ((Object)(object)playerObject == (Object)null)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"Cannot schedule retry - player GameObject is null");
					}
					return;
				}
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogDebug((object)("Scheduling retry attachment for " + ((Object)playerObject).name));
				}
				MonoBehaviour component = (MonoBehaviour)(object)playerObject.GetComponent<PlayerMovement>();
				if ((Object)(object)component != (Object)null)
				{
					component.StartCoroutine(RetryAttachmentCoroutine(playerObject));
					return;
				}
				ManualLogSource logger3 = ChronoParaPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogWarning((object)("Cannot schedule retry - no MonoBehaviour found on " + ((Object)playerObject).name));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("Error scheduling retry attachment: " + ex.Message));
				}
			}
		}

		[IteratorStateMachine(typeof(<RetryAttachmentCoroutine>d__5))]
		private static IEnumerator RetryAttachmentCoroutine(GameObject playerObject)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RetryAttachmentCoroutine>d__5(0)
			{
				playerObject = playerObject
			};
		}

		[HarmonyPatch("OnStartClient")]
		[HarmonyPrefix]
		public static void OnStartClient_Prefix(PlayerMovement __instance)
		{
			try
			{
				ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					object obj;
					if (__instance == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = ((Component)__instance).gameObject;
						obj = ((gameObject != null) ? ((Object)gameObject).name : null);
					}
					if (obj == null)
					{
						obj = "Unknown";
					}
					string text = (string)obj;
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogDebug((object)("PlayerMovement.OnStartClient called for: " + text));
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error in OnStartClient_Prefix: " + ex.Message));
				}
			}
		}

		public static string GetAttachmentStatistics()
		{
			try
			{
				PlayerMovement[] array = Object.FindObjectsByType<PlayerMovement>((FindObjectsSortMode)0);
				int num = array.Length;
				int num2 = 0;
				int num3 = 0;
				PlayerMovement[] array2 = array;
				foreach (PlayerMovement val in array2)
				{
					if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null)
					{
						if ((Object)(object)((Component)val).gameObject.GetComponent<PositionTracker>() != (Object)null)
						{
							num2++;
						}
						else
						{
							num3++;
						}
					}
				}
				return "PositionTracker Attachment Statistics:\n" + $"  Total Players: {num}\n" + $"  With PositionTracker: {num2}\n" + $"  Without PositionTracker: {num3}\n" + $"  Attachment Rate: {((num > 0) ? ((float)num2 * 100f / (float)num) : 0f):F1}%";
			}
			catch (Exception ex)
			{
				return "Error generating attachment statistics: " + ex.Message;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerRespawnManager))]
	public static class PlayerRespawnManagerPatch
	{
		[HarmonyPatch("summonDeathMessage")]
		[HarmonyPrefix]
		public static bool SummonDeathMessage_Prefix(ref string name, ref string causeofdeath, ref string killer)
		{
			try
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("Death message intercepted - Player: " + name + ", Cause: " + causeofdeath + ", Killer: " + killer));
				}
				GameObject val = FindPlayerByName(name);
				if ((Object)(object)val != (Object)null)
				{
					string text = DeathTracker.ProcessPlayerDeath(val, killer);
					if (text != "none" && text != causeofdeath)
					{
						string text2 = causeofdeath;
						causeofdeath = text;
						ManualLogSource logger2 = ChronoParaPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogInfo((object)("Death attribution changed for " + name + ": " + text2 + " -> " + causeofdeath));
						}
					}
				}
				else
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)("Could not find player GameObject for death attribution: " + name));
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("Error in summonDeathMessage patch: " + ex.Message));
				}
				return true;
			}
		}

		private static GameObject FindPlayerByName(string playerName)
		{
			try
			{
				PlayerMovement[] array = Object.FindObjectsByType<PlayerMovement>((FindObjectsSortMode)0);
				foreach (PlayerMovement val in array)
				{
					if (!((Object)(object)val != (Object)null) || !((Object)(object)((Component)val).gameObject != (Object)null))
					{
						continue;
					}
					try
					{
						FieldInfo field = typeof(PlayerMovement).GetField("playername", BindingFlags.Instance | BindingFlags.Public);
						if (field != null && string.Equals((string)field.GetValue(val), playerName, StringComparison.OrdinalIgnoreCase))
						{
							ManualLogSource logger = ChronoParaPlugin.Logger;
							if (logger != null)
							{
								logger.LogDebug((object)("Found player GameObject for " + playerName));
							}
							return ((Component)val).gameObject;
						}
					}
					catch (Exception ex)
					{
						ManualLogSource logger2 = ChronoParaPlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogDebug((object)("Error accessing player name field: " + ex.Message));
						}
					}
					if (((Object)((Component)val).gameObject).name.Contains(playerName) || playerName.Contains(((Object)((Component)val).gameObject).name))
					{
						ManualLogSource logger3 = ChronoParaPlugin.Logger;
						if (logger3 != null)
						{
							logger3.LogDebug((object)("Found player GameObject by name matching: " + playerName + " -> " + ((Object)((Component)val).gameObject).name));
						}
						return ((Component)val).gameObject;
					}
				}
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogDebug((object)("Player GameObject not found for name: " + playerName));
				}
				return null;
			}
			catch (Exception ex2)
			{
				ManualLogSource logger5 = ChronoParaPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)("Error finding player by name '" + playerName + "': " + ex2.Message));
				}
				return null;
			}
		}

		[HarmonyPatch("summonDeathMessage")]
		[HarmonyPostfix]
		public static void SummonDeathMessage_Postfix(string name, string causeofdeath, string killer)
		{
			try
			{
				if (causeofdeath == "temporal_recall")
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)("Recall-related death processed: " + name + " killed by " + killer));
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error in summonDeathMessage postfix: " + ex.Message));
				}
			}
		}
	}
}
namespace ChronoPara.Modules
{
	public static class AssetManager
	{
		private static AssetBundle _chronoBundle;

		private static bool _bundleLoaded;

		private static GameObject _recallEffectPrefab;

		private static AudioClip _recallSound;

		private static Texture2D _recallKillIcon;

		private static Texture2D _spellIcon;

		private static Texture2D _spellMainTexture;

		private static Texture2D _spellEmissionTexture;

		private static ManualLogSource Logger => ChronoParaPlugin.Logger;

		public static bool IsBundleLoaded
		{
			get
			{
				if (_bundleLoaded)
				{
					return (Object)(object)_chronoBundle != (Object)null;
				}
				return false;
			}
		}

		public static void Initialize()
		{
			try
			{
				LoadAssetBundle();
				CacheAssets();
				Logger.LogInfo((object)"AssetManager initialized successfully");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to initialize AssetManager: " + ex.Message));
				Logger.LogWarning((object)"Mod will continue with fallback assets");
			}
		}

		private static void LoadAssetBundle()
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)ChronoParaPlugin.Instance).Info.Location), "chronomancer.bundle");
			if (!File.Exists(text))
			{
				Logger.LogInfo((object)"AssetBundle not found - using fallback assets");
				return;
			}
			try
			{
				_chronoBundle = AssetBundle.LoadFromFile(text);
				if ((Object)(object)_chronoBundle == (Object)null)
				{
					Logger.LogError((object)"Failed to load AssetBundle - bundle is null");
					return;
				}
				_bundleLoaded = true;
				Logger.LogInfo((object)"Successfully loaded chronomancer AssetBundle");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Exception loading AssetBundle: " + ex.Message));
				_chronoBundle = null;
			}
		}

		private static void CacheAssets()
		{
			if (!_bundleLoaded || (Object)(object)_chronoBundle == (Object)null)
			{
				return;
			}
			try
			{
				_recallEffectPrefab = _chronoBundle.LoadAsset<GameObject>("RecallEffect");
				_recallSound = _chronoBundle.LoadAsset<AudioClip>("RecallSound");
				_recallKillIcon = _chronoBundle.LoadAsset<Texture2D>("RecallKill_Icon");
				_spellIcon = _chronoBundle.LoadAsset<Texture2D>("Assets/ChronoAssets/Sprites/ChronosRewind_Ui.png");
				_spellMainTexture = _chronoBundle.LoadAsset<Texture2D>("Assets/ChronoAssets/Sprites/ChronosRewind_Main.png");
				_spellEmissionTexture = _chronoBundle.LoadAsset<Texture2D>("Assets/ChronoAssets/Sprites/ChronosRewind_Emission.png");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Exception caching assets: " + ex.Message));
			}
		}

		public static GameObject GetRecallEffectPrefab()
		{
			if ((Object)(object)_recallEffectPrefab != (Object)null)
			{
				return _recallEffectPrefab;
			}
			return CreateFallbackEffectPrefab();
		}

		public static AudioClip GetRecallSound()
		{
			if ((Object)(object)_recallSound != (Object)null)
			{
				return _recallSound;
			}
			Logger.LogDebug((object)"RecallSound not available, using fallback");
			return null;
		}

		public static Texture2D GetRecallKillIcon()
		{
			if ((Object)(object)_recallKillIcon != (Object)null)
			{
				return _recallKillIcon;
			}
			return CreateFallbackIcon();
		}

		public static Texture2D GetSpellIcon()
		{
			if ((Object)(object)_spellIcon != (Object)null)
			{
				return _spellIcon;
			}
			return CreateFallbackSpellIcon();
		}

		public static Texture2D GetSpellMainTexture()
		{
			if ((Object)(object)_spellMainTexture != (Object)null)
			{
				return _spellMainTexture;
			}
			return null;
		}

		public static Texture2D GetSpellEmissionTexture()
		{
			if ((Object)(object)_spellEmissionTexture != (Object)null)
			{
				return _spellEmissionTexture;
			}
			return null;
		}

		public static T LoadAsset<T>(string assetName) where T : Object
		{
			if (!_bundleLoaded || (Object)(object)_chronoBundle == (Object)null)
			{
				return default(T);
			}
			try
			{
				return _chronoBundle.LoadAsset<T>(assetName);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Exception loading asset '" + assetName + "': " + ex.Message));
				return default(T);
			}
		}

		private static GameObject CreateFallbackEffectPrefab()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject("FallbackRecallEffect");
				ParticleSystem obj = val.AddComponent<ParticleSystem>();
				MainModule main = obj.main;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.4f, 0.8f, 1f, 0.8f));
				((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(2f);
				((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(5f);
				((MainModule)(ref main)).maxParticles = 50;
				EmissionModule emission = obj.emission;
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(25f);
				ShapeModule shape = obj.shape;
				((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
				((ShapeModule)(ref shape)).radius = 1f;
				return val;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to create fallback effect prefab: " + ex.Message));
				return new GameObject("EmptyRecallEffect");
			}
		}

		private static Texture2D CreateFallbackSpellIcon()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Texture2D val = new Texture2D(128, 128);
				Color[] array = (Color[])(object)new Color[16384];
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(64f, 64f);
				float num = 58f;
				float num2 = 45f;
				for (int i = 0; i < 128; i++)
				{
					for (int j = 0; j < 128; j++)
					{
						float num3 = Vector2.Distance(new Vector2((float)j, (float)i), val2);
						if (num3 <= num && num3 >= num2)
						{
							array[i * 128 + j] = new Color(0.4f, 0.8f, 1f, 1f);
						}
						else if (num3 < num2)
						{
							float num4 = Mathf.Atan2((float)(i - 64), (float)(j - 64)) * 57.29578f;
							if ((Mathf.Abs(num4) < 5f && num3 < 40f) || (Mathf.Abs(num4 - 90f) < 3f && num3 < 50f))
							{
								array[i * 128 + j] = new Color(1f, 1f, 1f, 1f);
							}
							else
							{
								array[i * 128 + j] = new Color(0.2f, 0.4f, 0.6f, 0.8f);
							}
						}
						else
						{
							array[i * 128 + j] = Color.clear;
						}
					}
				}
				val.SetPixels(array);
				val.Apply();
				return val;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to create fallback spell icon: " + ex.Message));
				return Texture2D.whiteTexture;
			}
		}

		private static Texture2D CreateFallbackIcon()
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Texture2D val = new Texture2D(64, 64);
				Color[] array = (Color[])(object)new Color[4096];
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(32f, 32f);
				float num = 28f;
				for (int i = 0; i < 64; i++)
				{
					for (int j = 0; j < 64; j++)
					{
						float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2);
						if (num2 <= num)
						{
							float num3 = 1f - num2 / num * 0.5f;
							array[i * 64 + j] = new Color(0.4f, 0.8f, 1f, num3);
						}
						else
						{
							array[i * 64 + j] = Color.clear;
						}
					}
				}
				val.SetPixels(array);
				val.Apply();
				return val;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to create fallback icon: " + ex.Message));
				return Texture2D.whiteTexture;
			}
		}

		public static string GetAssetInfo()
		{
			if (!_bundleLoaded || (Object)(object)_chronoBundle == (Object)null)
			{
				return "AssetBundle not loaded";
			}
			string[] allAssetNames = _chronoBundle.GetAllAssetNames();
			return string.Format("AssetBundle loaded with {0} assets: {1}", allAssetNames.Length, string.Join(", ", allAssetNames));
		}

		public static void Cleanup()
		{
			try
			{
				if ((Object)(object)_chronoBundle != (Object)null)
				{
					_chronoBundle.Unload(false);
					_chronoBundle = null;
				}
				_bundleLoaded = false;
				_recallEffectPrefab = null;
				_recallSound = null;
				_recallKillIcon = null;
				_spellIcon = null;
				_spellMainTexture = null;
				_spellEmissionTexture = null;
				Logger.LogDebug((object)"AssetManager cleanup completed");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Exception during AssetManager cleanup: " + ex.Message));
			}
		}
	}
	internal class ChronosRewind_Data : SpellData
	{
		public override string Name => "Chronos Rewind";

		public override string[] SubNames => new string[2] { "Chronos", "Rewind" };

		public override float Cooldown => ConfigManager.RecallCooldown;

		public override Color GlowColor => new Color(0.4f, 0.8f, 1f, 1f);

		public override bool CanSpawnInTeamChest => ConfigManager.CanSpawnInChests;

		public override Texture2D GetMainTexture()
		{
			return AssetManager.GetSpellMainTexture() ?? ((SpellData)this).GetMainTexture();
		}

		public override Texture2D GetEmissionTexture()
		{
			return AssetManager.GetSpellEmissionTexture() ?? ((SpellData)this).GetEmissionTexture();
		}
	}
	internal class ChronosRewind_Logic : SpellLogic
	{
		public override bool CastSpell(PlayerMovement caster, PageController page, Vector3 spawnPos, Vector3 viewDirectionVector, int castingLevel)
		{
			try
			{
				if ((Object)(object)caster == (Object)null)
				{
					ChronoParaPlugin.Logger.LogError((object)"Cannot cast Chronos Rewind: caster is null");
					return false;
				}
				if (!((NetworkBehaviour)caster).IsOwner)
				{
					ChronoParaPlugin.Logger.LogDebug((object)"Ignoring Chronos Rewind cast from non-owner player");
					return false;
				}
				PositionTracker component = ((Component)caster).GetComponent<PositionTracker>();
				if ((Object)(object)component == (Object)null)
				{
					ChronoParaPlugin.Logger.LogError((object)"Cannot cast Chronos Rewind: PositionTracker component not found on player");
					return false;
				}
				ChronoParaPlugin.Logger.LogDebug((object)("Casting Chronos Rewind for player " + ((Object)((Component)caster).gameObject).name));
				component.RequestRecall();
				return true;
			}
			catch (Exception ex)
			{
				ChronoParaPlugin.Logger.LogError((object)("Error during Chronos Rewind cast: " + ex.Message));
				return false;
			}
		}
	}
	public static class ComponentValidator
	{
		public static bool ValidateComponent<T>(T component, string componentName, bool isRequired = true) where T : Component
		{
			try
			{
				if ((Object)(object)component == (Object)null)
				{
					LogComponentError(componentName + " component is null", isRequired);
					return false;
				}
				if ((Object)(object)((Component)component).gameObject == (Object)null)
				{
					LogComponentError(componentName + " component has null GameObject", isRequired);
					return false;
				}
				if (!((Component)component).gameObject.activeInHierarchy)
				{
					LogComponentError(componentName + " component's GameObject is not active", isRequired);
					return false;
				}
				if (!ValidateSpecificComponent((Component)(object)component, componentName))
				{
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				LogComponentError("Error validating " + componentName + " component: " + ex.Message, isRequired);
				return false;
			}
		}

		public static bool ValidateComponents(params (Component component, string name, bool required)[] validations)
		{
			try
			{
				bool result = true;
				for (int i = 0; i < validations.Length; i++)
				{
					var (component, text, flag) = validations[i];
					if (!ComponentValidator.ValidateComponent<Component>(component, text, flag))
					{
						result = false;
						if (flag)
						{
							LogComponentError("Required component " + text + " validation failed - stopping validation", isRequired: true);
							return false;
						}
					}
				}
				return result;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Error during multi-component validation: " + ex.Message));
				}
				return false;
			}
		}

		public static T SafeGetComponent<T>(GameObject gameObject, string componentName, bool isRequired = true, bool searchChildren = false) where T : Component
		{
			try
			{
				if ((Object)(object)gameObject == (Object)null)
				{
					LogComponentError("Cannot get " + componentName + " - GameObject is null", isRequired);
					return default(T);
				}
				T val = gameObject.GetComponent<T>();
				if ((Object)(object)val == (Object)null && searchChildren)
				{
					val = gameObject.GetComponentInChildren<T>();
					if ((Object)(object)val != (Object)null)
					{
						ManualLogSource logger = ChronoParaPlugin.Logger;
						if (logger != null)
						{
							logger.LogDebug((object)(componentName + " found in child object: " + ((Object)((Component)val).gameObject).name));
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					LogComponentError(componentName + " component not found on " + ((Object)gameObject).name, isRequired);
					if (isRequired)
					{
						ProvideComponentRecoveryGuidance<T>(componentName, gameObject);
					}
					return default(T);
				}
				if (!ValidateComponent(val, componentName, isRequired))
				{
					return default(T);
				}
				return val;
			}
			catch (Exception ex)
			{
				LogComponentError("Error getting " + componentName + " component: " + ex.Message, isRequired);
				return default(T);
			}
		}

		public static T SafeAddComponent<T>(GameObject gameObject, string componentName) where T : Component
		{
			try
			{
				if ((Object)(object)gameObject == (Object)null)
				{
					LogComponentError("Cannot add " + componentName + " - GameObject is null", isRequired: true);
					return default(T);
				}
				T component = gameObject.GetComponent<T>();
				if ((Object)(object)component != (Object)null)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogDebug((object)(componentName + " already exists on " + ((Object)gameObject).name));
					}
					return component;
				}
				T val = gameObject.AddComponent<T>();
				if ((Object)(object)val == (Object)null)
				{
					LogComponentError("Failed to add " + componentName + " component to " + ((Object)gameObject).name, isRequired: true);
					return default(T);
				}
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)("Successfully added " + componentName + " component to " + ((Object)gameObject).name));
				}
				return val;
			}
			catch (Exception ex)
			{
				LogComponentError("Error adding " + componentName + " component: " + ex.Message, isRequired: true);
				return default(T);
			}
		}

		public static bool IsValidHealth(float health, string context = "health check")
		{
			try
			{
				if (float.IsNaN(health))
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)("Invalid health value (NaN) detected in " + context));
					}
					return false;
				}
				if (float.IsInfinity(health))
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)("Invalid health value (Infinity) detected in " + context));
					}
					return false;
				}
				if (health < 0f)
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)$"Negative health value ({health}) detected in {context}");
					}
					return false;
				}
				if (health > 10000f)
				{
					ManualLogSource logger4 = ChronoParaPlugin.Logger;
					if (logger4 != null)
					{
						logger4.LogWarning((object)$"Extremely high health value ({health}) detected in {context}");
					}
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger5 = ChronoParaPlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogError((object)("Error validating health in " + context + ": " + ex.Message));
				}
				return false;
			}
		}

		public static float SanitizeHealth(float health, float defaultHealth = 100f, string context = "health sanitization")
		{
			try
			{
				if (IsValidHealth(health, context))
				{
					return health;
				}
				if (float.IsNaN(health) || float.IsInfinity(health))
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)$"Replacing invalid health value with default ({defaultHealth}) in {context}");
					}
					return defaultHealth;
				}
				if (health < 0f)
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)("Clamping negative health value to 0 in " + context));
					}
					return 0f;
				}
				if (health > 10000f)
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)("Clamping excessive health value to 10000 in " + context));
					}
					return 10000f;
				}
				return health;
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("Error sanitizing health in " + context + ": " + ex.Message));
				}
				return defaultHealth;
			}
		}

		public static bool IsValidPosition(Vector3 position, string context = "position check")
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (float.IsNaN(position.x) || float.IsNaN(position.y) || float.IsNaN(position.z))
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)$"Invalid position (NaN) detected in {context}: {position}");
					}
					return false;
				}
				if (float.IsInfinity(position.x) || float.IsInfinity(position.y) || float.IsInfinity(position.z))
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)$"Invalid position (Infinity) detected in {context}: {position}");
					}
					return false;
				}
				if (Mathf.Abs(position.x) > 50000f || Mathf.Abs(position.y) > 50000f || Mathf.Abs(position.z) > 50000f)
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)$"Position coordinates too large in {context}: {position}");
					}
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("Error validating position in " + context + ": " + ex.Message));
				}
				return false;
			}
		}

		public static Vector3 SanitizePosition(Vector3 position, Vector3 defaultPosition = default(Vector3), string context = "position sanitization")
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (IsValidPosition(position, context))
				{
					return position;
				}
				Vector3 val = position;
				if (float.IsNaN(position.x) || float.IsInfinity(position.x))
				{
					val.x = defaultPosition.x;
				}
				if (float.IsNaN(position.y) || float.IsInfinity(position.y))
				{
					val.y = defaultPosition.y;
				}
				if (float.IsNaN(position.z) || float.IsInfinity(position.z))
				{
					val.z = defaultPosition.z;
				}
				val.x = Mathf.Clamp(val.x, -50000f, 50000f);
				val.y = Mathf.Clamp(val.y, -50000f, 50000f);
				val.z = Mathf.Clamp(val.z, -50000f, 50000f);
				if (val != position)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)$"Position sanitized in {context}: {position} -> {val}");
					}
				}
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error sanitizing position in " + context + ": " + ex.Message));
				}
				return defaultPosition;
			}
		}

		private static bool ValidateSpecificComponent(Component component, string componentName)
		{
			try
			{
				if (component is PlayerMovement)
				{
					return true;
				}
				AudioSource val = (AudioSource)(object)((component is AudioSource) ? component : null);
				if (val != null)
				{
					if ((Object)(object)val.clip == (Object)null)
					{
						ManualLogSource logger = ChronoParaPlugin.Logger;
						if (logger != null)
						{
							logger.LogDebug((object)("AudioSource " + componentName + " has no clip assigned (this may be normal)"));
						}
					}
					return true;
				}
				((object)component).GetType().Name.Contains("NetworkObject");
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error in specific validation for " + componentName + ": " + ex.Message));
				}
				return false;
			}
		}

		private static void LogComponentError(string message, bool isRequired)
		{
			try
			{
				if (isRequired)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogError((object)("[COMPONENT ERROR] " + message));
					}
				}
				else
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)("[COMPONENT WARNING] " + message));
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger3 = ChronoParaPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("Component error: " + message + " (Logging error: " + ex.Message + ")"));
				}
			}
		}

		private static void ProvideComponentRecoveryGuidance<T>(string componentName, GameObject gameObject) where T : Component
		{
			try
			{
				string text = typeof(T).Name switch
				{
					"PlayerMovement" => "PlayerMovement component is required for Temporal Recall. This may indicate a mod conflict or game update.", 
					"AudioSource" => "AudioSource component missing - recall sounds may not play. This is not critical for functionality.", 
					"NetworkObject" => "NetworkObject component missing - network synchronization may fail. Check for mod conflicts.", 
					_ => componentName + " component is missing. This may affect mod functionality.", 
				};
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)("Recovery guidance: " + text));
				}
				if (!((Object)(object)gameObject != (Object)null))
				{
					return;
				}
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)$"Affected object: {((Object)gameObject).name} (Active: {gameObject.activeInHierarchy})");
				}
				ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					Component[] components = gameObject.GetComponents<Component>();
					string text2 = string.Join(", ", Array.ConvertAll(components, (Component c) => ((object)c).GetType().Name));
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogDebug((object)("Available components on " + ((Object)gameObject).name + ": " + text2));
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("Error providing component recovery guidance: " + ex.Message));
				}
			}
		}

		public static string GetComponentStatusReport(GameObject gameObject)
		{
			try
			{
				if ((Object)(object)gameObject == (Object)null)
				{
					return "Component Status: GameObject is null";
				}
				string text = "=== Component Status Report for " + ((Object)gameObject).name + " ===\n";
				text += $"Active: {gameObject.activeInHierarchy}\n";
				text += $"Layer: {gameObject.layer}\n";
				text = text + "Tag: " + gameObject.tag + "\n";
				Component[] components = gameObject.GetComponents<Component>();
				text += $"\nComponents ({components.Length}):\n";
				Component[] array = components;
				foreach (Component val in array)
				{
					if ((Object)(object)val != (Object)null)
					{
						string text2 = "Active";
						Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
						if (val2 != null)
						{
							text2 = (val2.enabled ? "Enabled" : "Disabled");
						}
						text = text + "  - " + ((object)val).GetType().Name + ": " + text2 + "\n";
					}
					else
					{
						text += "  - [NULL COMPONENT]\n";
					}
				}
				return text;
			}
			catch (Exception ex)
			{
				return "Error generating component status report: " + ex.Message;
			}
		}
	}
	public static class ConfigManager
	{
		public static float RecallCooldown
		{
			get
			{
				try
				{
					return ValidateAndClampCooldown(ChronoParaPlugin.RecallCooldown?.Value ?? 45f);
				}
				catch (Exception exception)
				{
					LogConfigurationError("RecallCooldown", exception);
					return 45f;
				}
			}
		}

		public static float RewindDuration
		{
			get
			{
				try
				{
					return ValidateAndClampRewindDuration(ChronoParaPlugin.RewindDuration?.Value ?? 3f);
				}
				catch (Exception exception)
				{
					LogConfigurationError("RewindDuration", exception);
					return 3f;
				}
			}
		}

		public static float RecallKillWindow
		{
			get
			{
				try
				{
					return ValidateAndClampKillWindow(ChronoParaPlugin.RecallKillWindow?.Value ?? 3f);
				}
				catch (Exception exception)
				{
					LogConfigurationError("RecallKillWindow", exception);
					return 3f;
				}
			}
		}

		public static int MaxHistorySize
		{
			get
			{
				try
				{
					float rewindDuration = RewindDuration;
					float num = RecordingInterval;
					if (num <= 0f)
					{
						ManualLogSource logger = ChronoParaPlugin.Logger;
						if (logger != null)
						{
							logger.LogWarning((object)"Invalid recording interval, using default");
						}
						num = 0.1f;
					}
					return Mathf.Clamp(Mathf.CeilToInt(rewindDuration / num), 10, 1000);
				}
				catch (Exception exception)
				{
					LogConfigurationError("MaxHistorySize", exception);
					return 30;
				}
			}
		}

		public static bool CanSpawnInChests
		{
			get
			{
				try
				{
					return ChronoParaPlugin.CanSpawnInChests?.Value ?? false;
				}
				catch (Exception exception)
				{
					LogConfigurationError("CanSpawnInChests", exception);
					return false;
				}
			}
		}

		public static float RecordingInterval => 0.1f;

		private static float ValidateAndClampCooldown(float value)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)$"Invalid cooldown value detected: {value}, using default");
				}
				return 45f;
			}
			float num = Mathf.Clamp(value, 5f, 300f);
			if (num != value)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)$"Cooldown value {value} was outside acceptable range, clamped to {num}");
				}
			}
			return num;
		}

		private static float ValidateAndClampRewindDuration(float value)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)$"Invalid rewind duration value detected: {value}, using default");
				}
				return 3f;
			}
			float num = Mathf.Clamp(value, 0.5f, 30f);
			if (num != value)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)$"Rewind duration value {value} was outside acceptable range, clamped to {num}");
				}
			}
			return num;
		}

		private static float ValidateAndClampKillWindow(float value)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)$"Invalid kill window value detected: {value}, using default");
				}
				return 3f;
			}
			float num = Mathf.Clamp(value, 0.5f, 15f);
			if (num != value)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)$"Kill window value {value} was outside acceptable range, clamped to {num}");
				}
			}
			return num;
		}

		private static void LogConfigurationError(string configName, Exception exception)
		{
			ManualLogSource logger = ChronoParaPlugin.Logger;
			if (logger != null)
			{
				logger.LogError((object)("Error accessing configuration '" + configName + "': " + exception.Message));
			}
			ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
			if (debugMode != null && debugMode.Value)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogDebug((object)("Configuration error stack trace: " + exception.StackTrace));
				}
			}
			ManualLogSource logger3 = ChronoParaPlugin.Logger;
			if (logger3 != null)
			{
				logger3.LogInfo((object)("Using default value for '" + configName + "'. If this persists, try resetting your configuration file or reinstalling the mod."));
			}
		}

		public static bool ValidateConfiguration()
		{
			bool result = true;
			try
			{
				float recallCooldown = RecallCooldown;
				float rewindDuration = RewindDuration;
				float recallKillWindow = RecallKillWindow;
				bool canSpawnInChests = CanSpawnInChests;
				int maxHistorySize = MaxHistorySize;
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)("Configuration validation - " + $"Cooldown: {recallCooldown}s, Duration: {rewindDuration}s, Kill Window: {recallKillWindow}s, Can Spawn: {canSpawnInChests}, History Size: {maxHistorySize}"));
				}
				if (recallKillWindow > rewindDuration)
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)($"Kill window ({recallKillWindow}s) is longer than rewind duration ({rewindDuration}s). " + "This may cause unexpected behavior."));
					}
					result = false;
				}
				if (recallCooldown < rewindDuration)
				{
					ManualLogSource logger3 = ChronoParaPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)($"Cooldown ({recallCooldown}s) is shorter than rewind duration ({rewindDuration}s). " + "Players may be able to chain recalls rapidly."));
					}
				}
				return result;
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = ChronoParaPlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogError((object)("Configuration validation failed: " + ex.Message));
				}
				return false;
			}
		}

		public static string GetConfigurationReport()
		{
			try
			{
				string text = string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(string.Concat("=== Chronomancer's Paradox Configuration Report ===\n" + $"Recall Cooldown: {RecallCooldown}s\n", $"Rewind Duration: {RewindDuration}s\n"), $"Recall Kill Window: {RecallKillWindow}s\n"), $"Can Spawn In Chests: {CanSpawnInChests}\n"), $"Recording Interval: {RecordingInterval}s\n"), $"Max History Size: {MaxHistorySize} snapshots\n"), "\n=== Configuration Sources ===\n"), "RecallCooldown Source: ", (ChronoParaPlugin.RecallCooldown != null) ? "Config File" : "Default", "\n"), "RewindDuration Source: ", (ChronoParaPlugin.RewindDuration != null) ? "Config File" : "Default", "\n"), "RecallKillWindow Source: ", (ChronoParaPlugin.RecallKillWindow != null) ? "Config File" : "Default", "\n"), "CanSpawnInChests Source: ", (ChronoParaPlugin.CanSpawnInChests != null) ? "Config File" : "Default", "\n");
				ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
				return text + "\nDebug Mode: " + ((debugMode != null && debugMode.Value) ? "Enabled" : "Disabled") + "\n";
			}
			catch (Exception ex)
			{
				return "Error generating configuration report: " + ex.Message;
			}
		}
	}
	public static class ConfigurationValidator
	{
		public struct ValidationResult
		{
			public bool IsValid;

			public List<ValidationIssue> Issues;

			public string Summary;

			public ValidationResult(bool isValid)
			{
				IsValid = isValid;
				Issues = new List<ValidationIssue>();
				Summary = string.Empty;
			}
		}

		public struct ValidationIssue
		{
			public ValidationSeverity Severity;

			public string ConfigurationName;

			public string Issue;

			public string Recommendation;

			public object CurrentValue;

			public object RecommendedValue;

			public ValidationIssue(ValidationSeverity severity, string configName, string issue, string recommendation, object currentValue = null, object recommendedValue = null)
			{
				Severity = severity;
				ConfigurationName = configName;
				Issue = issue;
				Recommendation = recommendation;
				CurrentValue = currentValue;
				RecommendedValue = recommendedValue;
			}
		}

		public enum ValidationSeverity
		{
			Info,
			Warning,
			Error,
			Critical
		}

		public static ValidationResult ValidateAllConfiguration()
		{
			ValidationResult result = new ValidationResult(isValid: true);
			try
			{
				ValidateRecallCooldown(result);
				ValidateRewindDuration(result);
				ValidateRecallKillWindow(result);
				ValidateRecordingInterval(result);
				ValidateConfigurationRelationships(result);
				ValidatePerformanceImplications(result);
				GenerateValidationSummary(result);
				LogValidationResults(result);
				return result;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Error during configuration validation: " + ex.Message));
				}
				result.IsValid = false;
				result.Issues.Add(new ValidationIssue(ValidationSeverity.Critical, "System", "Configuration validation system failed", "Check mod installation and dependencies"));
				return result;
			}
		}

		private static void ValidateRecallCooldown(ValidationResult result)
		{
			try
			{
				float recallCooldown = ConfigManager.RecallCooldown;
				if (float.IsNaN(recallCooldown) || float.IsInfinity(recallCooldown))
				{
					result.IsValid = false;
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Recall Cooldown", "Invalid numeric value detected", "Reset to default value (45 seconds)", recallCooldown, 45f));
					return;
				}
				if (recallCooldown < 5f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Recall Cooldown", "Very short cooldown may cause gameplay balance issues", "Consider increasing to at least 15 seconds for balanced gameplay", recallCooldown, 15f));
				}
				else if (recallCooldown > 180f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Recall Cooldown", "Very long cooldown may make the spell rarely useful", "Consider reducing to 60-90 seconds for better gameplay experience", recallCooldown, 60f));
				}
				if (recallCooldown >= 30f && recallCooldown <= 60f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Info, "Recall Cooldown", "Configuration is in the optimal range", "No changes needed", recallCooldown));
				}
			}
			catch (Exception ex)
			{
				result.IsValid = false;
				result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Recall Cooldown", "Failed to validate: " + ex.Message, "Check configuration file integrity", null, 45f));
			}
		}

		private static void ValidateRewindDuration(ValidationResult result)
		{
			try
			{
				float rewindDuration = ConfigManager.RewindDuration;
				if (float.IsNaN(rewindDuration) || float.IsInfinity(rewindDuration) || rewindDuration <= 0f)
				{
					result.IsValid = false;
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Rewind Duration", "Invalid or non-positive value detected", "Reset to default value (3 seconds)", rewindDuration, 3f));
					return;
				}
				if (rewindDuration < 1f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Rewind Duration", "Very short rewind duration may not provide meaningful tactical value", "Consider increasing to at least 2 seconds", rewindDuration, 2f));
				}
				else if (rewindDuration > 15f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Rewind Duration", "Very long rewind duration may cause memory and performance issues", "Consider reducing to 5-8 seconds for optimal performance", rewindDuration, 5f));
				}
				int maxHistorySize = ConfigManager.MaxHistorySize;
				if (maxHistorySize > 500)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Rewind Duration", $"Current setting will create large history buffers ({maxHistorySize} snapshots)", "Consider reducing duration or increasing recording interval for better performance", rewindDuration, Math.Min(rewindDuration, 5f)));
				}
			}
			catch (Exception ex)
			{
				result.IsValid = false;
				result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Rewind Duration", "Failed to validate: " + ex.Message, "Check configuration file integrity", null, 3f));
			}
		}

		private static void ValidateRecallKillWindow(ValidationResult result)
		{
			try
			{
				float recallKillWindow = ConfigManager.RecallKillWindow;
				if (float.IsNaN(recallKillWindow) || float.IsInfinity(recallKillWindow) || recallKillWindow < 0f)
				{
					result.IsValid = false;
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Recall Kill Window", "Invalid or negative value detected", "Reset to default value (3 seconds)", recallKillWindow, 3f));
					return;
				}
				if (recallKillWindow > 30f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Recall Kill Window", "Very long kill window may cause confusion about recall-related deaths", "Consider reducing to 5-10 seconds for clearer death attribution", recallKillWindow, 5f));
				}
				if (recallKillWindow == 0f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Info, "Recall Kill Window", "Kill window is disabled - no recall-related death tracking", "This is valid if you don't want recall-related death attribution", recallKillWindow));
				}
			}
			catch (Exception ex)
			{
				result.IsValid = false;
				result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Recall Kill Window", "Failed to validate: " + ex.Message, "Check configuration file integrity", null, 3f));
			}
		}

		private static void ValidateRecordingInterval(ValidationResult result)
		{
			try
			{
				float recordingInterval = ConfigManager.RecordingInterval;
				if (float.IsNaN(recordingInterval) || float.IsInfinity(recordingInterval) || recordingInterval <= 0f)
				{
					result.IsValid = false;
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Recording Interval", "Invalid or non-positive value detected", "Reset to default value (0.1 seconds)", recordingInterval, 0.1f));
				}
				else if (recordingInterval < 0.05f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Recording Interval", "Very frequent recording may impact performance", "Consider increasing to 0.1 seconds for better performance", recordingInterval, 0.1f));
				}
				else if (recordingInterval > 0.5f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Recording Interval", "Infrequent recording may reduce recall precision", "Consider reducing to 0.1-0.2 seconds for better precision", recordingInterval, 0.1f));
				}
			}
			catch (Exception ex)
			{
				result.IsValid = false;
				result.Issues.Add(new ValidationIssue(ValidationSeverity.Error, "Recording Interval", "Failed to validate: " + ex.Message, "Check configuration file integrity", null, 0.1f));
			}
		}

		private static void ValidateConfigurationRelationships(ValidationResult result)
		{
			try
			{
				float recallCooldown = ConfigManager.RecallCooldown;
				float rewindDuration = ConfigManager.RewindDuration;
				float recallKillWindow = ConfigManager.RecallKillWindow;
				if (recallKillWindow > rewindDuration && recallKillWindow > 0f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Configuration Relationship", $"Kill window ({recallKillWindow}s) is longer than rewind duration ({rewindDuration}s)", "Consider making kill window equal to or shorter than rewind duration", $"Kill Window: {recallKillWindow}s, Rewind Duration: {rewindDuration}s", $"Kill Window: {Math.Min(recallKillWindow, rewindDuration)}s"));
				}
				if (recallCooldown < rewindDuration * 2f && recallCooldown > 0f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Info, "Configuration Relationship", $"Cooldown ({recallCooldown}s) is less than twice the rewind duration ({rewindDuration}s)", "This allows for potential recall chaining - ensure this is intentional", $"Cooldown: {recallCooldown}s, Rewind Duration: {rewindDuration}s"));
				}
			}
			catch (Exception ex)
			{
				result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Configuration Relationship", "Failed to validate relationships: " + ex.Message, "Check individual configuration values"));
			}
		}

		private static void ValidatePerformanceImplications(ValidationResult result)
		{
			try
			{
				int maxHistorySize = ConfigManager.MaxHistorySize;
				float rewindDuration = ConfigManager.RewindDuration;
				float recordingInterval = ConfigManager.RecordingInterval;
				int num = maxHistorySize * 20;
				if (num > 50000)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Performance", $"High memory usage estimated: ~{num / 1024}KB per player", "Consider reducing rewind duration or increasing recording interval", $"Duration: {rewindDuration}s, Interval: {recordingInterval}s", "Reduce duration to 3-5s or increase interval to 0.15s"));
				}
				if (maxHistorySize > 1000)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Performance", $"Very large history buffer: {maxHistorySize} snapshots", "This may impact performance with many players", maxHistorySize, 500));
				}
				float num2 = 1f / recordingInterval;
				if (num2 > 20f)
				{
					result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Performance", $"Very frequent recording: {num2:F1} times per second", "This may impact game performance", recordingInterval, 0.1f));
				}
			}
			catch (Exception ex)
			{
				result.Issues.Add(new ValidationIssue(ValidationSeverity.Warning, "Performance", "Failed to validate performance implications: " + ex.Message, "Monitor game performance during play"));
			}
		}

		private static void GenerateValidationSummary(ValidationResult result)
		{
			try
			{
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				using (List<ValidationIssue>.Enumerator enumerator = result.Issues.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						switch (enumerator.Current.Severity)
						{
						case ValidationSeverity.Error:
						case ValidationSeverity.Critical:
							num++;
							break;
						case ValidationSeverity.Warning:
							num2++;
							break;
						case ValidationSeverity.Info:
							num3++;
							break;
						}
					}
				}
				if (num > 0)
				{
					result.Summary = $"Configuration validation found {num} error(s), {num2} warning(s), and {num3} info message(s). Please review and fix errors.";
				}
				else if (num2 > 0)
				{
					result.Summary = $"Configuration validation found {num2} warning(s) and {num3} info message(s). Review warnings for optimal experience.";
				}
				else
				{
					result.Summary = $"Configuration validation passed successfully with {num3} info message(s).";
				}
			}
			catch (Exception ex)
			{
				result.Summary = "Error generating validation summary: " + ex.Message;
			}
		}

		private static void LogValidationResults(ValidationResult result)
		{
			try
			{
				if (result.IsValid)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)("Configuration Validation: " + result.Summary));
					}
				}
				else
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)("Configuration Validation: " + result.Summary));
					}
				}
				foreach (ValidationIssue issue in result.Issues)
				{
					string text = "[" + issue.ConfigurationName + "] " + issue.Issue;
					if (!string.IsNullOrEmpty(issue.Recommendation))
					{
						text = text + " | Recommendation: " + issue.Recommendation;
					}
					if (issue.CurrentValue != null)
					{
						text += $" | Current: {issue.CurrentValue}";
					}
					if (issue.RecommendedValue != null)
					{
						text += $" | Suggested: {issue.RecommendedValue}";
					}
					switch (issue.Severity)
					{
					case ValidationSeverity.Error:
					case ValidationSeverity.Critical:
					{
						ManualLogSource logger4 = ChronoParaPlugin.Logger;
						if (logger4 != null)
						{
							logger4.LogError((object)text);
						}
						break;
					}
					case ValidationSeverity.Warning:
					{
						ManualLogSource logger5 = ChronoParaPlugin.Logger;
						if (logger5 != null)
						{
							logger5.LogWarning((object)text);
						}
						break;
					}
					case ValidationSeverity.Info:
					{
						ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
						if (debugMode != null && debugMode.Value)
						{
							ManualLogSource logger3 = ChronoParaPlugin.Logger;
							if (logger3 != null)
							{
								logger3.LogInfo((object)text);
							}
						}
						break;
					}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger6 = ChronoParaPlugin.Logger;
				if (logger6 != null)
				{
					logger6.LogError((object)("Error logging validation results: " + ex.Message));
				}
			}
		}

		public static string GenerateUserFriendlyReport()
		{
			try
			{
				ValidationResult validationResult = ValidateAllConfiguration();
				string text = "=== Chronomancer's Paradox Configuration Report ===\n\n";
				text += "Current Configuration:\n";
				text += $"  Recall Cooldown: {ConfigManager.RecallCooldown}s\n";
				text += $"  Rewind Duration: {ConfigManager.RewindDuration}s\n";
				text += $"  Recall Kill Window: {ConfigManager.RecallKillWindow}s\n";
				text += $"  Recording Interval: {ConfigManager.RecordingInterval}s\n";
				text += $"  Max History Size: {ConfigManager.MaxHistorySize} snapshots\n\n";
				text = text + "Validation Status: " + validationResult.Summary + "\n\n";
				if (validationResult.Issues.Count > 0)
				{
					text += "Issues and Recommendations:\n";
					foreach (ValidationIssue issue in validationResult.Issues)
					{
						string text2 = issue.Severity switch
						{
							ValidationSeverity.Critical => "❌", 
							ValidationSeverity.Error => "❌", 
							ValidationSeverity.Warning => "⚠\ufe0f", 
							ValidationSeverity.Info => "ℹ\ufe0f", 
							_ => "•", 
						};
						text = text + text2 + " [" + issue.ConfigurationName + "] " + issue.Issue + "\n";
						if (!string.IsNullOrEmpty(issue.Recommendation))
						{
							text = text + "   \ud83d\udca1 " + issue.Recommendation + "\n";
						}
						text += "\n";
					}
				}
				int maxHistorySize = ConfigManager.MaxHistorySize;
				int num = maxHistorySize * 20;
				text += "Performance Summary:\n";
				text += $"  Estimated Memory per Player: ~{num / 1024}KB\n";
				text += $"  Recording Frequency: {1f / ConfigManager.RecordingInterval:F1} times/second\n";
				return text + $"  History Buffer Size: {maxHistorySize} snapshots\n\n";
			}
			catch (Exception ex)
			{
				return "Error generating configuration report: " + ex.Message;
			}
		}
	}
	public static class DeathTracker
	{
		public const string RECALL_DEATH_REASON = "temporal_recall";

		public const string RECALL_DEATH_MESSAGE = "fell victim to temporal manipulation";

		private static Dictionary<int, DateTime> recentRecalls = new Dictionary<int, DateTime>();

		private static Dictionary<string, int> killStatistics = new Dictionary<string, int>();

		private static bool isDeathIconRegistered = false;

		public static int TotalRecallKills
		{
			get
			{
				if (!killStatistics.ContainsKey("temporal_recall"))
				{
					return 0;
				}
				return killStatistics["temporal_recall"];
			}
		}

		public static bool IsInitialized => isDeathIconRegistered;

		public static void Initialize()
		{
			try
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"Initializing death tracking system...");
				}
				RegisterCustomDeathIcon();
				InitializeStatistics();
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)"Death tracking system initialized successfully");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger3 = ChronoParaPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("Failed to initialize death tracking system: " + ex.Message));
				}
			}
		}

		private static void RegisterCustomDeathIcon()
		{
			try
			{
				Texture2D recallKillIcon = AssetManager.GetRecallKillIcon();
				if ((Object)(object)recallKillIcon != (Object)null)
				{
					BlackMagicManager.RegisterDeathIcon((BaseUnityPlugin)(object)ChronoParaPlugin.Instance, "temporal_recall", recallKillIcon);
					isDeathIconRegistered = true;
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)"Successfully registered custom death icon for 'temporal_recall'");
					}
				}
				else
				{
					ManualLogSource logger2 = ChronoParaPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)"Failed to get recall kill icon from AssetManager - using fallback registration");
					}
					RegisterFallbackDeathIcon();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger3 = ChronoParaPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("Failed to register custom death icon: " + ex.Message));
				}
				RegisterFallbackDeathIcon();
			}
		}

		private static void RegisterFallbackDeathIcon()
		{
			try
			{
				Texture2D val = CreateFallbackDeathIcon();
				BlackMagicManager.RegisterDeathIcon((BaseUnityPlugin)(object)ChronoParaPlugin.Instance, "temporal_recall", val);
				isDeathIconRegistered = true;
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"Registered fallback death icon for 'temporal_recall'");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Failed to register fallback death icon: " + ex.Message));
				}
			}
		}

		private static Texture2D CreateFallbackDeathIcon()
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Texture2D val = new Texture2D(32, 32);
				Color[] array = (Color[])(object)new Color[1024];
				for (int i = 0; i < 32; i++)
				{
					for (int j = 0; j < 32; j++)
					{
						bool flag = false;
						if ((i >= 26 && i <= 30 && j >= 8 && j <= 24) || (i >= 2 && i <= 6 && j >= 8 && j <= 24))
						{
							flag = true;
						}
						else if (i >= 14 && i <= 18 && j >= 14 && j <= 18)
						{
							flag = true;
						}
						else if ((j == 8 || j == 24) && i >= 6 && i <= 26)
						{
							flag = true;
						}
						if (flag)
						{
							array[i * 32 + j] = new Color(0.8f, 0.2f, 0.2f, 1f);
						}
						else
						{
							array[i * 32 + j] = Color.clear;
						}
					}
				}
				val.SetPixels(array);
				val.Apply();
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Failed to create fallback death icon: " + ex.Message));
				}
				return Texture2D.whiteTexture;
			}
		}

		private static void InitializeStatistics()
		{
			try
			{
				killStatistics["temporal_recall"] = 0;
				killStatistics["total_deaths"] = 0;
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)"Kill statistics system initialized");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Failed to initialize statistics: " + ex.Message));
				}
			}
		}

		public static void RecordRecallExecution(GameObject player)
		{
			if ((Object)(object)player == (Object)null)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"Cannot record recall execution - player is null");
				}
				return;
			}
			try
			{
				int instanceID = ((Object)player).GetInstanceID();
				DateTime now = DateTime.Now;
				recentRecalls[instanceID] = now;
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogDebug((object)$"Recorded recall execution for player {((Object)player).name} (ID: {instanceID}) at {now}");
				}
				CleanupOldRecallRecords();
			}
			catch (Exception ex)
			{
				ManualLogSource logger3 = ChronoParaPlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("Failed to record recall execution: " + ex.Message));
				}
			}
		}

		public static bool IsRecallRelatedDeath(GameObject player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			try
			{
				int instanceID = ((Object)player).GetInstanceID();
				if (!recentRecalls.ContainsKey(instanceID))
				{
					return false;
				}
				DateTime dateTime = recentRecalls[instanceID];
				double totalSeconds = (DateTime.Now - dateTime).TotalSeconds;
				double num = ConfigManager.RecallKillWindow;
				bool flag = totalSeconds <= num;
				ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogDebug((object)$"Death attribution check for {((Object)player).name}: Time since recall: {totalSeconds:F2}s, Kill window: {num:F2}s, Is recall-related: {flag}");
					}
				}
				return flag;
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error checking recall-related death: " + ex.Message));
				}
				return false;
			}
		}

		public static string ProcessPlayerDeath(GameObject player, string killer = "")
		{
			if ((Object)(object)player == (Object)null)
			{
				return "none";
			}
			try
			{
				if (IsRecallRelatedDeath(player))
				{
					RecordRecallKill(player, killer);
					int instanceID = ((Object)player).GetInstanceID();
					recentRecalls.Remove(instanceID);
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)("Processed recall-related death for " + ((Object)player).name));
					}
					return "temporal_recall";
				}
				return "none";
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error processing player death: " + ex.Message));
				}
				return "none";
			}
		}

		private static void RecordRecallKill(GameObject victim, string killer)
		{
			try
			{
				if (killStatistics.ContainsKey("temporal_recall"))
				{
					killStatistics["temporal_recall"]++;
				}
				else
				{
					killStatistics["temporal_recall"] = 1;
				}
				if (killStatistics.ContainsKey("total_deaths"))
				{
					killStatistics["total_deaths"]++;
				}
				else
				{
					killStatistics["total_deaths"] = 1;
				}
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)string.Format("Recorded recall kill - Victim: {0}, Killer: {1}, Total recall kills: {2}", ((Object)victim).name, killer, killStatistics["temporal_recall"]));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Failed to record recall kill: " + ex.Message));
				}
			}
		}

		private static void CleanupOldRecallRecords()
		{
			try
			{
				DateTime dateTime = DateTime.Now.AddSeconds((0f - ConfigManager.RecallKillWindow) * 2f);
				List<int> list = new List<int>();
				foreach (KeyValuePair<int, DateTime> recentRecall in recentRecalls)
				{
					if (recentRecall.Value < dateTime)
					{
						list.Add(recentRecall.Key);
					}
				}
				foreach (int item in list)
				{
					recentRecalls.Remove(item);
				}
				if (list.Count <= 0)
				{
					return;
				}
				ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					ManualLogSource logger = ChronoParaPlugin.Logger;
					if (logger != null)
					{
						logger.LogDebug((object)$"Cleaned up {list.Count} expired recall records");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Failed to cleanup old recall records: " + ex.Message));
				}
			}
		}

		public static int GetKillCount(string deathReason)
		{
			try
			{
				return killStatistics.ContainsKey(deathReason) ? killStatistics[deathReason] : 0;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Error getting kill count for '" + deathReason + "': " + ex.Message));
				}
				return 0;
			}
		}

		public static Dictionary<string, int> GetAllStatistics()
		{
			try
			{
				return new Dictionary<string, int>(killStatistics);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Error getting all statistics: " + ex.Message));
				}
				return new Dictionary<string, int>();
			}
		}

		public static void ResetStatistics()
		{
			try
			{
				killStatistics.Clear();
				InitializeStatistics();
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"Kill statistics reset");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Failed to reset statistics: " + ex.Message));
				}
			}
		}

		public static string GetStatisticsReport()
		{
			try
			{
				Dictionary<string, int> allStatistics = GetAllStatistics();
				string text = "=== Chronomancer's Paradox Kill Statistics ===\n";
				foreach (KeyValuePair<string, int> item in allStatistics)
				{
					string key = item.Key;
					string text2 = ((key == "temporal_recall") ? "Recall-Related Deaths" : ((!(key == "total_deaths")) ? item.Key : "Total Deaths Tracked"));
					string arg = text2;
					text += $"{arg}: {item.Value}\n";
				}
				return text;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Error generating statistics report: " + ex.Message));
				}
				return "Error generating statistics report";
			}
		}

		public static void Cleanup()
		{
			try
			{
				recentRecalls?.Clear();
				killStatistics?.Clear();
				isDeathIconRegistered = false;
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)"DeathTracker cleanup completed");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = ChronoParaPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Error during DeathTracker cleanup: " + ex.Message));
				}
			}
		}
	}
	public static class DiagnosticLogger
	{
		private const int MAX_LOG_ENTRIES = 1000;

		private const int MAX_ERROR_HISTORY = 100;

		private static readonly Queue<LogEntry> recentLogs = new Queue<LogEntry>();

		private static readonly Queue<ErrorEntry> errorHistory = new Queue<ErrorEntry>();

		private static readonly Dictionary<string, int> errorCounts = new Dictionary<string, int>();

		private static readonly object logLock = new object();

		public static void LogNetworkOperation(string operation, bool success, string details = "", float duration = -1f)
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("[NETWORK] " + operation + ": " + (success ? "SUCCESS" : "FAILED"));
				if (duration >= 0f)
				{
					stringBuilder.Append($" ({duration:F2}ms)");
				}
				if (!string.IsNullOrEmpty(details))
				{
					stringBuilder.Append(" - " + details);
				}
				if (success)
				{
					LogInfo(stringBuilder.ToString(), LogCategory.Network);
				}
				else
				{
					LogError(stringBuilder.ToString(), LogCategory.Network);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Error logging network operation: " + ex.Message));
				}
			}
		}

		public static void LogRecallOperation(string playerName, bool success, Vector3 fromPosition, Vector3 toPosition, float healthBefore, float healthAfter, string reason = "")
		{
			//IL_002f: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("[RECALL] Player " + playerName + ": " + (success ? "SUCCESS" : "FAILED"));
				if (success)
				{
					float num = Vector3.Distance(fromPosition, toPosition);
					float num2 = healthAfter - healthBefore;
					stringBuilder.Append($" - Teleported {num:F2}m, Health: {healthBefore:F1} -> {healthAfter:F1} ({num2:+F1;-F1;+0})");
				}
				else if (!string.IsNullOrEmpty(reason))
				{
					stringBuilder.Append(" - " + reason);
				}
				if (success)
				{
					LogInfo(stringBuilder.ToString(), LogCategory.Recall);
				}
				else
				{
					LogWarning(stringBuilder.ToString(), LogCategory.Recall);
				}
				ConfigEntry<bool> debugMode = ChronoParaPlugin.DebugMode;
				if (debugMode != null && debugMode.Value)
				{
					LogDebug($"Recall details - From: {fromPosition}, To: {toPosition}", LogCategory.Recall);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = ChronoParaPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Error logging recall operation: " + ex.Message));
				}
			}
		}

		public static void LogPerformanceMetrics(int historySize, float recordingInterval, int cleanupCount, float processingTime)
		{
			try
			{
				ConfigEn