diff --git a/CollapseLauncher/Classes/Plugins/PluginInfo.cs b/CollapseLauncher/Classes/Plugins/PluginInfo.cs index dd551975a..8a28c1e7c 100644 --- a/CollapseLauncher/Classes/Plugins/PluginInfo.cs +++ b/CollapseLauncher/Classes/Plugins/PluginInfo.cs @@ -5,6 +5,7 @@ using Hi3Helper.Plugin.Core.Management.PresetConfig; using Hi3Helper.Plugin.Core.Update; using Hi3Helper.Plugin.Core.Utility; +using Hi3Helper.SentryHelper; using Hi3Helper.Shared.Region; using Hi3Helper.Win32.ManagedTools; using Microsoft.Extensions.Logging; @@ -229,7 +230,8 @@ public unsafe PluginInfo(string pluginFilePath, string pluginRelName, PluginMani pluginInstance.SetPluginLocaleId(LauncherConfig.GetAppConfigValue("AppLanguage")); - Logger.LogWriteLine($"[PluginInfo] Successfully loaded plugin: {Name} from: {pluginRelName}@0x{libraryHandle:x8} with version {Version} and standard version {StandardVersion}.", LogType.Debug, true); + Logger.LogWriteLine($"[PluginInfo] Successfully loaded plugin: {Name} from: {pluginRelName}@0x{libraryHandle:x8} with version {Version} and standard version {StandardVersion}.", LogType.Info, true); + PluginListBreadcrumb.Add(Name, Version.ToString(), StandardVersion.ToString()); PresetConfigs = new PluginPresetConfigWrapper[presetConfigCount]; for (int i = 0; i < presetConfigCount; i++) diff --git a/Hi3Helper.Core/Classes/SentryHelper/CollapseBreadcrumbExtension.cs b/Hi3Helper.Core/Classes/SentryHelper/CollapseBreadcrumbExtension.cs new file mode 100644 index 000000000..18b8958e3 --- /dev/null +++ b/Hi3Helper.Core/Classes/SentryHelper/CollapseBreadcrumbExtension.cs @@ -0,0 +1,249 @@ +using Microsoft.Win32; +using Sentry; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using static Hi3Helper.Shared.Region.LauncherConfig; + +namespace Hi3Helper.SentryHelper; + +// Migrated from main SentryHelper.cs file +public static partial class SentryHelper +{ + #nullable enable + private static int CpuThreadsTotal => Environment.ProcessorCount; + + private static string CpuName + { + get + { + try + { + string cpuName; + string env = Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER") ?? "Unknown CPU"; + object? reg = + Registry.GetValue(@"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\SYSTEM\CentralProcessor\0", + "ProcessorNameString", null); + if (reg != null) + { + cpuName = reg.ToString() ?? env; + cpuName = cpuName.Trim(); + } + else cpuName = env; + + return cpuName; + } + catch (Exception ex) + { + Logger.LogWriteLine("Failed when trying to get CPU Name!\r\n" + ex, LogType.Error, true); + return "Unknown CPU"; + } + } + } + + private static List<(string GpuName, string DriverVersion)> GetGpuInfo + { + get + { + List<(string GpuName, string DriverVersion)> gpuInfoList = []; + try + { + using RegistryKey? baseKey = + Registry.LocalMachine + .OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\"); + if (baseKey != null) + { + foreach (string subKeyName in baseKey.GetSubKeyNames()) + { + if (!int.TryParse(subKeyName, out int subKeyInt) || subKeyInt < 0 || subKeyInt > 9999) + continue; + + string? gpuName = "Unknown GPU"; + string? driverVersion = "Unknown Driver Version"; + try + { + using RegistryKey? subKey = baseKey.OpenSubKey(subKeyName); + if (subKey == null) continue; + + gpuName = subKey.GetValue("DriverDesc") as string; + driverVersion = subKey.GetValue("DriverVersion") as string; + if (!string.IsNullOrEmpty(gpuName) && !string.IsNullOrEmpty(driverVersion)) + { + gpuInfoList.Add((subKeyName + gpuName, driverVersion)); + } + } + catch (Exception) + { + gpuInfoList.Add((subKeyName + gpuName, driverVersion)!); + throw; + } + } + } + } + catch (Exception ex) + { + Logger.LogWriteLine($"Failed to retrieve GPU info from registry: {ex.Message}", LogType.Error, + true); + } + + return gpuInfoList; + } + } + + private static Breadcrumb? _buildInfo; + + private static Breadcrumb BuildInfo => + _buildInfo ??= new Breadcrumb("Build Info", "commit", new Dictionary + { + { "Branch", AppBuildBranch }, + { "Commit", AppBuildCommit }, + { "Repository", AppBuildRepo }, + { "IsPreview", IsPreview.ToString() } + }, "BuildInfo"); + + private static Breadcrumb? _cpuInfo; + + private static Breadcrumb CpuInfo => + _cpuInfo ??= new Breadcrumb("CPU Info", "system.cpu", new Dictionary + { + { "CPU Name", CpuName }, + { "Total Thread", CpuThreadsTotal.ToString() } + }, "CPUInfo"); + + private static Breadcrumb? _gpuInfo; + + private static Breadcrumb GpuInfo => + _gpuInfo ??= new Breadcrumb("GPU Info", "system.gpu", + GetGpuInfo.ToDictionary(item => item.GpuName, + item => item.DriverVersion), + "GPUInfo"); + + private static Breadcrumb GameInfo => + new("Current Loaded Game Info", "game", new Dictionary + { + { "Category", CurrentGameCategory }, + { "Region", CurrentGameRegion }, + { "Installed", CurrentGameInstalled.ToString() }, + { "Updated", CurrentGameUpdated.ToString() }, + { "HasPreload", CurrentGameHasPreload.ToString() }, + { "HasDelta", CurrentGameHasDelta.ToString() }, + { "IsGameFromPlugin", CurrentGameIsPlugin.ToString() }, + { "Location", CurrentGameLocation }, + { "CdnOption", AppCdnOption } + }, "GameInfo"); + + + [field: AllowNull, MaybeNull] + private static Breadcrumb AppConfig + { + get + { + field ??= new Breadcrumb("Collapse App Config", "app.config", new Dictionary + { + { "Proxy", ProxyBreadcrumb.IsUsingProxy ?? "" }, + { "Waifu2x", GetAppConfigValue("EnableWaifu2X") ? "enabled" : "disabled" }, + { + "HttpCache", + AppNetworkCacheEnabled + ? "enabled" + (AppNetworkCacheAggressiveModeEnabled ? "+agg" : "") + : "disabled" + }, + { "AppThread", $"{AppCurrentDownloadThread},{AppCurrentThread}" }, + { "SophonThread", $"{GetAppConfigValue("SophonHttpConnInt")},{GetAppConfigValue("SophonCpuThread")}" }, + { "DownloadPreallocated", (IsUsePreallocatedDownloader) ? "enabled" : "disabled" }, + { + "HttpOpts", + $"{(GetAppConfigValue("IsAllowHttpRedirections")? "Redirect" : "")}" + + $"{(GetAppConfigValue("IsAllowHttpCookies") ? "Cookie" : "" )}" + + $"{(GetAppConfigValue("IsAllowUntrustedCert") ? "Insecure" : "")}" + }, + { "ExternalDNS", GetAppConfigValue("IsUseExternalDns") ? "enabled" : "disabled" } + }, "AppConfig"); + return field; + } + } +} + +#nullable disable +public static class PluginListBreadcrumb +{ + private static readonly Collection<(string Name, string Version, string StdVersion)> List = []; + + public static void Add(string name, string version, string stdVersion) + { + List.Add((name, version, stdVersion)); + + SentryHelper.PluginInfo = new Breadcrumb("Plugin Info", "app.plugins", + List.ToDictionary( + item => item.Name, + item => $"{item.Version}-{item.StdVersion}" + ), + "PluginInfo"); + } +} + +#nullable enable +public static class ProxyBreadcrumb +{ + [field: AllowNull, MaybeNull] + public static string IsUsingProxy + { + get + { + field ??= string.Concat( + GetCollapseProxy() ? $"cl({GetCollapseProxyType()}" : "", + GetSystemProxy() ? "+sys" : "" + ); + return field; + } + } + + private static bool GetSystemProxy() + { + try + { + using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings"); + + return (key?.GetValue("ProxyEnable") as int? ?? 0) == 1; + } + catch (Exception ex) + { + Logger.LogWriteLine($"[CollapseSentryExtension::GetSystemProxy] Failure when grabbing system proxy settings! returning false...\r\n" + + $"{ex}", LogType.Error, true); + return false; + } + } + + private static bool GetCollapseProxy() + { + var useProxy = GetAppConfigValue("IsUseProxy").ToBool(); + if (!useProxy) + return false; + + return !string.IsNullOrEmpty(GetAppConfigValue("HttpProxyUrl")); + } + + private static string GetCollapseProxyType() + { + var cfg = GetAppConfigValue("HttpProxyUrl").ToString(); + + if (string.IsNullOrEmpty(cfg)) return string.Empty; + try + { + var proxy = new Uri(cfg); + + return proxy.Scheme; + } + catch (Exception ex) + { + Logger.LogWriteLine($"[CollapseSentryExtension::GetCollapseProxyType] Failure when parsing proxy URL scheme! returning empty string..." + + $"{ex}", LogType.Error, true); + + return string.Empty; + } + } +} \ No newline at end of file diff --git a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs index 39e5313ef..284ab2159 100644 --- a/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs +++ b/Hi3Helper.Core/Classes/SentryHelper/SentryHelper.cs @@ -1,13 +1,10 @@ using Hi3Helper.Shared.Region; -using Microsoft.Win32; using Sentry; using Sentry.Protocol; using System; using System.Buffers; -using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -385,127 +382,9 @@ public static async Task ExceptionHandler_ForLoopAsync(Exception ex, public static bool CurrentGameHasDelta { get; set; } public static bool CurrentGameIsPlugin { get; set; } - private static int CpuThreadsTotal => Environment.ProcessorCount; - - private static string CpuName - { - get - { - try - { - string cpuName; - string env = Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER") ?? "Unknown CPU"; - object? reg = - Registry.GetValue(@"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\SYSTEM\CentralProcessor\0", - "ProcessorNameString", null); - if (reg != null) - { - cpuName = reg.ToString() ?? env; - cpuName = cpuName.Trim(); - } - else cpuName = env; - - return cpuName; - } - catch (Exception ex) - { - Logger.LogWriteLine("Failed when trying to get CPU Name!\r\n" + ex, LogType.Error, true); - return "Unknown CPU"; - } - } - } - - private static List<(string GpuName, string DriverVersion)> GetGpuInfo - { - get - { - List<(string GpuName, string DriverVersion)> gpuInfoList = []; - try - { - using RegistryKey? baseKey = - Registry.LocalMachine - .OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\"); - if (baseKey != null) - { - foreach (string subKeyName in baseKey.GetSubKeyNames()) - { - if (!int.TryParse(subKeyName, out int subKeyInt) || subKeyInt < 0 || subKeyInt > 9999) - continue; - - string? gpuName = "Unknown GPU"; - string? driverVersion = "Unknown Driver Version"; - try - { - using RegistryKey? subKey = baseKey.OpenSubKey(subKeyName); - if (subKey == null) continue; - - gpuName = subKey.GetValue("DriverDesc") as string; - driverVersion = subKey.GetValue("DriverVersion") as string; - if (!string.IsNullOrEmpty(gpuName) && !string.IsNullOrEmpty(driverVersion)) - { - gpuInfoList.Add((subKeyName + gpuName, driverVersion)); - } - } - catch (Exception) - { - gpuInfoList.Add((subKeyName + gpuName, driverVersion)!); - throw; - } - } - } - } - catch (Exception ex) - { - Logger.LogWriteLine($"Failed to retrieve GPU info from registry: {ex.Message}", LogType.Error, - true); - } - - return gpuInfoList; - } - } - - private static Breadcrumb? _buildInfo; - - private static Breadcrumb BuildInfo => - _buildInfo ??= new Breadcrumb("Build Info", "commit", new Dictionary - { - { "Branch", AppBuildBranch }, - { "Commit", AppBuildCommit }, - { "Repository", AppBuildRepo }, - { "IsPreview", IsPreview.ToString() } - }, "BuildInfo"); - - private static Breadcrumb? _cpuInfo; - - private static Breadcrumb CpuInfo => - _cpuInfo ??= new Breadcrumb("CPU Info", "system.cpu", new Dictionary - { - { "CPU Name", CpuName }, - { "Total Thread", CpuThreadsTotal.ToString() } - }, "CPUInfo"); - - private static Breadcrumb? _gpuInfo; - - private static Breadcrumb GpuInfo => - _gpuInfo ??= new Breadcrumb("GPU Info", "system.gpu", - GetGpuInfo.ToDictionary(item => item.GpuName, - item => item.DriverVersion), - "GPUInfo"); - - private static Breadcrumb GameInfo => - new("Current Loaded Game Info", "game", new Dictionary - { - { "Category", CurrentGameCategory }, - { "Region", CurrentGameRegion }, - { "Installed", CurrentGameInstalled.ToString() }, - { "Updated", CurrentGameUpdated.ToString() }, - { "HasPreload", CurrentGameHasPreload.ToString() }, - { "HasDelta", CurrentGameHasDelta.ToString() }, - { "IsGameFromPlugin", CurrentGameIsPlugin.ToString() }, - { "Location", CurrentGameLocation }, - { "CdnOption", AppCdnOption } - }, "GameInfo"); - + #pragma warning disable CA2211 + public static Breadcrumb? PluginInfo = null; + #pragma warning restore CA2211 #endregion private static SentryId ExceptionHandlerInner(Exception ex, ExceptionType exT = ExceptionType.Handled) @@ -514,6 +393,10 @@ private static SentryId ExceptionHandlerInner(Exception ex, ExceptionType exT = SentrySdk.AddBreadcrumb(GameInfo); SentrySdk.AddBreadcrumb(CpuInfo); SentrySdk.AddBreadcrumb(GpuInfo); + SentrySdk.AddBreadcrumb(AppConfig); + + if (PluginInfo != null) + SentrySdk.AddBreadcrumb(PluginInfo); ex.Data[Mechanism.HandledKey] ??= exT == ExceptionType.Handled;