Decompiled source of ChronosRewind v1.2.0
ChronosRewind.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.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