From 093ddbd50cd90482644f2a8c55bf712be63b0353 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Fri, 5 Apr 2024 22:40:14 +0300 Subject: [PATCH] Added partial support for net35 --- .../Analyzer/GenericSuggestedFix.cs | 14 +++++++++ .../Analyzer/ModuleSuggestedFix.cs | 17 ++++++++++ .../Analyzer/ModuleUpdate.cs | 20 ++++++++++++ .../AssemblyIdModel.cs | 22 ++++++++++--- .../AssemblyImportedReferenceModel.cs | 23 +++++++++++++- .../AssemblyImportedTypeReferenceModel.cs | 22 ++++++++++++- src/BUTR.CrashReport.Models/AssemblyModel.cs | 30 +++++++++++++++++- .../BUTR.CrashReport.Models.csproj | 4 +-- .../CapabilityModuleOrPluginModel.cs | 19 +++++++++++- .../CrashReportMetadataModel.cs | 27 +++++++++++++++- .../CrashReportModel.cs | 31 ++++++++++++++++++- .../DependencyMetadataModel.cs | 25 ++++++++++++++- .../EnhancedStacktraceFrameModel.cs | 27 +++++++++++++++- src/BUTR.CrashReport.Models/ExceptionModel.cs | 27 +++++++++++++++- .../HarmonyPatchModel.cs | 28 +++++++++++++++++ .../HarmonyPatchesModel.cs | 21 +++++++++++++ .../InvolvedModuleOrPluginModel.cs | 22 ++++++++++++- .../LoaderPluginModel.cs | 24 ++++++++++++++ src/BUTR.CrashReport.Models/LogEntry.cs | 23 +++++++++++++- src/BUTR.CrashReport.Models/LogSource.cs | 22 ++++++++++++- src/BUTR.CrashReport.Models/MetadataModel.cs | 19 +++++++++++- .../MethodExecuting.cs | 19 +++++++++++- .../MethodHarmonyPatch.cs | 19 +++++++++++- src/BUTR.CrashReport.Models/MethodSimple.cs | 28 +++++++++++++++++ src/BUTR.CrashReport.Models/ModuleModel.cs | 30 ++++++++++++++++++ .../ModuleSubModuleModel.cs | 23 +++++++++++++- .../UpdateInfoModuleOrLoaderPlugin.cs | 17 ++++++++++ .../Utils/AssemblyUtils.cs | 2 +- 28 files changed, 582 insertions(+), 23 deletions(-) diff --git a/src/BUTR.CrashReport.Models/Analyzer/GenericSuggestedFix.cs b/src/BUTR.CrashReport.Models/Analyzer/GenericSuggestedFix.cs index 12cc550..4294477 100644 --- a/src/BUTR.CrashReport.Models/Analyzer/GenericSuggestedFix.cs +++ b/src/BUTR.CrashReport.Models/Analyzer/GenericSuggestedFix.cs @@ -9,4 +9,18 @@ public sealed record GenericSuggestedFix /// The type of suggested fix. /// public required GenericSuggestedFixType Type { get; set; } + + /// + public bool Equals(GenericSuggestedFix? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Type == other.Type; + } + + /// + public override int GetHashCode() + { + return (int) Type; + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/Analyzer/ModuleSuggestedFix.cs b/src/BUTR.CrashReport.Models/Analyzer/ModuleSuggestedFix.cs index 01b26de..f7a7afd 100644 --- a/src/BUTR.CrashReport.Models/Analyzer/ModuleSuggestedFix.cs +++ b/src/BUTR.CrashReport.Models/Analyzer/ModuleSuggestedFix.cs @@ -15,4 +15,21 @@ public sealed record ModuleSuggestedFix /// The type of suggested fix. /// public required ModuleSuggestedFixType Type { get; set; } + + /// + public bool Equals(ModuleSuggestedFix? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return ModuleId == other.ModuleId && Type == other.Type; + } + + /// + public override int GetHashCode() + { + unchecked + { + return (ModuleId.GetHashCode() * 397) ^ (int) Type; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/Analyzer/ModuleUpdate.cs b/src/BUTR.CrashReport.Models/Analyzer/ModuleUpdate.cs index 79923e5..aa3c401 100644 --- a/src/BUTR.CrashReport.Models/Analyzer/ModuleUpdate.cs +++ b/src/BUTR.CrashReport.Models/Analyzer/ModuleUpdate.cs @@ -20,4 +20,24 @@ public sealed record ModuleUpdate /// Whether the module was involced in the crash. /// public required bool IsModuleInvolved { get; set; } + + /// + public bool Equals(ModuleUpdate? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return ModuleId == other.ModuleId && ModuleVersion == other.ModuleVersion && IsModuleInvolved == other.IsModuleInvolved; + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = ModuleId.GetHashCode(); + hashCode = (hashCode * 397) ^ ModuleVersion.GetHashCode(); + hashCode = (hashCode * 397) ^ IsModuleInvolved.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/AssemblyIdModel.cs b/src/BUTR.CrashReport.Models/AssemblyIdModel.cs index 62d7de5..6846a58 100644 --- a/src/BUTR.CrashReport.Models/AssemblyIdModel.cs +++ b/src/BUTR.CrashReport.Models/AssemblyIdModel.cs @@ -41,10 +41,24 @@ public sealed record AssemblyIdModel : IEquatable, IEquatable - public bool Equals(AssemblyIdModel? other) => other is not null && - Name == other.Name && - ((Version is null || other.Version is null) || Version == other.Version) && - PublicKeyToken == other.PublicKeyToken; + public bool Equals(AssemblyIdModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name && Version == other.Version && PublicKeyToken == other.PublicKeyToken; + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ (Version != null ? Version.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (PublicKeyToken != null ? PublicKeyToken.GetHashCode() : 0); + return hashCode; + } + } /// public bool Equals(AssemblyModel? other) => other is not null && other.Id.Equals(this); diff --git a/src/BUTR.CrashReport.Models/AssemblyImportedReferenceModel.cs b/src/BUTR.CrashReport.Models/AssemblyImportedReferenceModel.cs index 9a1755e..c9ef357 100644 --- a/src/BUTR.CrashReport.Models/AssemblyImportedReferenceModel.cs +++ b/src/BUTR.CrashReport.Models/AssemblyImportedReferenceModel.cs @@ -3,7 +3,7 @@ /// /// Represents an imported assembly reference. /// -public record AssemblyImportedReferenceModel +public sealed record AssemblyImportedReferenceModel { /// /// @@ -33,4 +33,25 @@ public record AssemblyImportedReferenceModel /// The empty default constructor. /// public AssemblyImportedReferenceModel() { } + + /// + public bool Equals(AssemblyImportedReferenceModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name && Version == other.Version && Culture == other.Culture && PublicKeyToken == other.PublicKeyToken; + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ Version.GetHashCode(); + hashCode = (hashCode * 397) ^ (Culture != null ? Culture.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (PublicKeyToken != null ? PublicKeyToken.GetHashCode() : 0); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/AssemblyImportedTypeReferenceModel.cs b/src/BUTR.CrashReport.Models/AssemblyImportedTypeReferenceModel.cs index 060f7a8..f26afd3 100644 --- a/src/BUTR.CrashReport.Models/AssemblyImportedTypeReferenceModel.cs +++ b/src/BUTR.CrashReport.Models/AssemblyImportedTypeReferenceModel.cs @@ -3,7 +3,7 @@ /// /// Represents an imported type reference. /// -public record AssemblyImportedTypeReferenceModel +public sealed record AssemblyImportedTypeReferenceModel { /// /// @@ -22,4 +22,24 @@ public record AssemblyImportedTypeReferenceModel /// /// public required string FullName { get; set; } + + /// + public bool Equals(AssemblyImportedTypeReferenceModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name && Namespace == other.Namespace && FullName == other.FullName; + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ Namespace.GetHashCode(); + hashCode = (hashCode * 397) ^ FullName.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/AssemblyModel.cs b/src/BUTR.CrashReport.Models/AssemblyModel.cs index 7e2267e..063ad90 100644 --- a/src/BUTR.CrashReport.Models/AssemblyModel.cs +++ b/src/BUTR.CrashReport.Models/AssemblyModel.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents a .NET assembly. /// -public record AssemblyModel +public sealed record AssemblyModel { /// /// Is null if not from a module. @@ -66,4 +66,32 @@ public record AssemblyModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(AssemblyModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return ModuleId == other.ModuleId && LoaderPluginId == other.LoaderPluginId && Id.Equals(other.Id) && CultureName == other.CultureName && Architecture == other.Architecture && Hash == other.Hash && AnonymizedPath == other.AnonymizedPath && Type == other.Type && ImportedTypeReferences.Equals(other.ImportedTypeReferences) && ImportedAssemblyReferences.Equals(other.ImportedAssemblyReferences) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (ModuleId != null ? ModuleId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LoaderPluginId != null ? LoaderPluginId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Id.GetHashCode(); + hashCode = (hashCode * 397) ^ (CultureName != null ? CultureName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Architecture.GetHashCode(); + hashCode = (hashCode * 397) ^ Hash.GetHashCode(); + hashCode = (hashCode * 397) ^ AnonymizedPath.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) Type; + hashCode = (hashCode * 397) ^ ImportedTypeReferences.GetHashCode(); + hashCode = (hashCode * 397) ^ ImportedAssemblyReferences.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/BUTR.CrashReport.Models.csproj b/src/BUTR.CrashReport.Models/BUTR.CrashReport.Models.csproj index a69f096..40bfb95 100644 --- a/src/BUTR.CrashReport.Models/BUTR.CrashReport.Models.csproj +++ b/src/BUTR.CrashReport.Models/BUTR.CrashReport.Models.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net35;net45;netstandard2.0 preview enable true @@ -31,7 +31,7 @@ - + diff --git a/src/BUTR.CrashReport.Models/CapabilityModuleOrPluginModel.cs b/src/BUTR.CrashReport.Models/CapabilityModuleOrPluginModel.cs index 9692faf..29ccd8f 100644 --- a/src/BUTR.CrashReport.Models/CapabilityModuleOrPluginModel.cs +++ b/src/BUTR.CrashReport.Models/CapabilityModuleOrPluginModel.cs @@ -3,7 +3,7 @@ /// /// Represents the functionality that is used by the module or plugin. /// -public record CapabilityModuleOrPluginModel +public sealed record CapabilityModuleOrPluginModel { /// /// The name of the capability. @@ -19,4 +19,21 @@ public record CapabilityModuleOrPluginModel /// Creates a new instance of . /// public CapabilityModuleOrPluginModel(string name) => Name = name; + + /// + public bool Equals(CapabilityModuleOrPluginModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name && Description == other.Description; + } + + /// + public override int GetHashCode() + { + unchecked + { + return (Name.GetHashCode() * 397) ^ Description.GetHashCode(); + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/CrashReportMetadataModel.cs b/src/BUTR.CrashReport.Models/CrashReportMetadataModel.cs index 05052b7..959482a 100644 --- a/src/BUTR.CrashReport.Models/CrashReportMetadataModel.cs +++ b/src/BUTR.CrashReport.Models/CrashReportMetadataModel.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents the metadata for a crash report. /// -public record CrashReportMetadataModel +public sealed record CrashReportMetadataModel { /// /// The game name. @@ -47,4 +47,29 @@ public record CrashReportMetadataModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(CrashReportMetadataModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return GameName == other.GameName && GameVersion == other.GameVersion && LoaderPluginProviderName == other.LoaderPluginProviderName && LoaderPluginProviderVersion == other.LoaderPluginProviderVersion && LauncherType == other.LauncherType && LauncherVersion == other.LauncherVersion && Runtime == other.Runtime && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (GameName != null ? GameName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ GameVersion.GetHashCode(); + hashCode = (hashCode * 397) ^ (LoaderPluginProviderName != null ? LoaderPluginProviderName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LoaderPluginProviderVersion != null ? LoaderPluginProviderVersion.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LauncherType != null ? LauncherType.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LauncherVersion != null ? LauncherVersion.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Runtime != null ? Runtime.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/CrashReportModel.cs b/src/BUTR.CrashReport.Models/CrashReportModel.cs index c3467c9..97c340b 100644 --- a/src/BUTR.CrashReport.Models/CrashReportModel.cs +++ b/src/BUTR.CrashReport.Models/CrashReportModel.cs @@ -6,7 +6,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents the main model of a crash report. /// -public record CrashReportModel +public sealed record CrashReportModel { /// /// The id of the crash report. @@ -77,4 +77,33 @@ public record CrashReportModel /// /// A key:value list of metadatas. public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(CrashReportModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Id.Equals(other.Id) && Version == other.Version && Exception.Equals(other.Exception) && Metadata.Equals(other.Metadata) && Modules.Equals(other.Modules) && InvolvedModules.Equals(other.InvolvedModules) && EnhancedStacktrace.Equals(other.EnhancedStacktrace) && Assemblies.Equals(other.Assemblies) && HarmonyPatches.Equals(other.HarmonyPatches) && LoaderPlugins.Equals(other.LoaderPlugins) && InvolvedLoaderPlugins.Equals(other.InvolvedLoaderPlugins) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Id.GetHashCode(); + hashCode = (hashCode * 397) ^ Version.GetHashCode(); + hashCode = (hashCode * 397) ^ Exception.GetHashCode(); + hashCode = (hashCode * 397) ^ Metadata.GetHashCode(); + hashCode = (hashCode * 397) ^ Modules.GetHashCode(); + hashCode = (hashCode * 397) ^ InvolvedModules.GetHashCode(); + hashCode = (hashCode * 397) ^ EnhancedStacktrace.GetHashCode(); + hashCode = (hashCode * 397) ^ Assemblies.GetHashCode(); + hashCode = (hashCode * 397) ^ HarmonyPatches.GetHashCode(); + hashCode = (hashCode * 397) ^ LoaderPlugins.GetHashCode(); + hashCode = (hashCode * 397) ^ InvolvedLoaderPlugins.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/DependencyMetadataModel.cs b/src/BUTR.CrashReport.Models/DependencyMetadataModel.cs index 4ec8736..885dd37 100644 --- a/src/BUTR.CrashReport.Models/DependencyMetadataModel.cs +++ b/src/BUTR.CrashReport.Models/DependencyMetadataModel.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents the dependency metadata for a module. /// -public record DependencyMetadataModel +public sealed record DependencyMetadataModel { /// /// Is null if not from a module. @@ -38,4 +38,27 @@ public record DependencyMetadataModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(DependencyMetadataModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return ModuleOrPluginId == other.ModuleOrPluginId && Type == other.Type && IsOptional == other.IsOptional && Version == other.Version && VersionRange == other.VersionRange && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = ModuleOrPluginId.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) Type; + hashCode = (hashCode * 397) ^ IsOptional.GetHashCode(); + hashCode = (hashCode * 397) ^ (Version != null ? Version.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (VersionRange != null ? VersionRange.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/EnhancedStacktraceFrameModel.cs b/src/BUTR.CrashReport.Models/EnhancedStacktraceFrameModel.cs index 8eba651..aeeb1db 100644 --- a/src/BUTR.CrashReport.Models/EnhancedStacktraceFrameModel.cs +++ b/src/BUTR.CrashReport.Models/EnhancedStacktraceFrameModel.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents a method from stack trace. /// -public record EnhancedStacktraceFrameModel +public sealed record EnhancedStacktraceFrameModel { /// /// @@ -50,4 +50,29 @@ public record EnhancedStacktraceFrameModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(EnhancedStacktraceFrameModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return FrameDescription == other.FrameDescription && MethodFromStackframeIssue == other.MethodFromStackframeIssue && ILOffset == other.ILOffset && NativeOffset == other.NativeOffset && ExecutingMethod.Equals(other.ExecutingMethod) && Equals(OriginalMethod, other.OriginalMethod) && PatchMethods.Equals(other.PatchMethods) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = FrameDescription.GetHashCode(); + hashCode = (hashCode * 397) ^ MethodFromStackframeIssue.GetHashCode(); + hashCode = (hashCode * 397) ^ ILOffset.GetHashCode(); + hashCode = (hashCode * 397) ^ NativeOffset.GetHashCode(); + hashCode = (hashCode * 397) ^ ExecutingMethod.GetHashCode(); + hashCode = (hashCode * 397) ^ (OriginalMethod != null ? OriginalMethod.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ PatchMethods.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/ExceptionModel.cs b/src/BUTR.CrashReport.Models/ExceptionModel.cs index 17bd3b0..c717995 100644 --- a/src/BUTR.CrashReport.Models/ExceptionModel.cs +++ b/src/BUTR.CrashReport.Models/ExceptionModel.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents the exception of the crash report. /// -public record ExceptionModel +public sealed record ExceptionModel { /// /// The assembly identity of the assembly. Is associated with the source of the exception. @@ -52,4 +52,29 @@ public record ExceptionModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(ExceptionModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(SourceAssemblyId, other.SourceAssemblyId) && SourceModuleId == other.SourceModuleId && SourceLoaderPluginId == other.SourceLoaderPluginId && Type == other.Type && Message == other.Message && CallStack == other.CallStack && Equals(InnerException, other.InnerException) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (SourceAssemblyId != null ? SourceAssemblyId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (SourceModuleId != null ? SourceModuleId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (SourceLoaderPluginId != null ? SourceLoaderPluginId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Type.GetHashCode(); + hashCode = (hashCode * 397) ^ Message.GetHashCode(); + hashCode = (hashCode * 397) ^ CallStack.GetHashCode(); + hashCode = (hashCode * 397) ^ (InnerException != null ? InnerException.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/HarmonyPatchModel.cs b/src/BUTR.CrashReport.Models/HarmonyPatchModel.cs index c1c4ff9..b263d8a 100644 --- a/src/BUTR.CrashReport.Models/HarmonyPatchModel.cs +++ b/src/BUTR.CrashReport.Models/HarmonyPatchModel.cs @@ -70,4 +70,32 @@ public sealed record HarmonyPatchModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(HarmonyPatchModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Type == other.Type && ModuleId == other.ModuleId && LoaderPluginId == other.LoaderPluginId && Equals(AssemblyId, other.AssemblyId) && Owner == other.Owner && Namespace == other.Namespace && Index == other.Index && Priority == other.Priority && Before.Equals(other.Before) && After.Equals(other.After) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (int) Type; + hashCode = (hashCode * 397) ^ (ModuleId != null ? ModuleId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LoaderPluginId != null ? LoaderPluginId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (AssemblyId != null ? AssemblyId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Owner.GetHashCode(); + hashCode = (hashCode * 397) ^ Namespace.GetHashCode(); + hashCode = (hashCode * 397) ^ Index; + hashCode = (hashCode * 397) ^ Priority; + hashCode = (hashCode * 397) ^ Before.GetHashCode(); + hashCode = (hashCode * 397) ^ After.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/HarmonyPatchesModel.cs b/src/BUTR.CrashReport.Models/HarmonyPatchesModel.cs index 60cfae8..2a7d097 100644 --- a/src/BUTR.CrashReport.Models/HarmonyPatchesModel.cs +++ b/src/BUTR.CrashReport.Models/HarmonyPatchesModel.cs @@ -27,4 +27,25 @@ public sealed record HarmonyPatchesModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(HarmonyPatchesModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return OriginalMethodDeclaredTypeName == other.OriginalMethodDeclaredTypeName && OriginalMethodName == other.OriginalMethodName && Patches.Equals(other.Patches) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (OriginalMethodDeclaredTypeName != null ? OriginalMethodDeclaredTypeName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (OriginalMethodName != null ? OriginalMethodName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Patches.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/InvolvedModuleOrPluginModel.cs b/src/BUTR.CrashReport.Models/InvolvedModuleOrPluginModel.cs index a545899..0a586aa 100644 --- a/src/BUTR.CrashReport.Models/InvolvedModuleOrPluginModel.cs +++ b/src/BUTR.CrashReport.Models/InvolvedModuleOrPluginModel.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents an involved module info. /// -public record InvolvedModuleOrPluginModel +public sealed record InvolvedModuleOrPluginModel { /// /// @@ -24,4 +24,24 @@ public record InvolvedModuleOrPluginModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(InvolvedModuleOrPluginModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return ModuleOrLoaderPluginId == other.ModuleOrLoaderPluginId && EnhancedStacktraceFrameName == other.EnhancedStacktraceFrameName && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = ModuleOrLoaderPluginId.GetHashCode(); + hashCode = (hashCode * 397) ^ EnhancedStacktraceFrameName.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/LoaderPluginModel.cs b/src/BUTR.CrashReport.Models/LoaderPluginModel.cs index eea54a3..91be085 100644 --- a/src/BUTR.CrashReport.Models/LoaderPluginModel.cs +++ b/src/BUTR.CrashReport.Models/LoaderPluginModel.cs @@ -42,4 +42,28 @@ public sealed record LoaderPluginModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(LoaderPluginModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Id == other.Id && Name == other.Name && Version == other.Version && Equals(UpdateInfo, other.UpdateInfo) && Dependencies.Equals(other.Dependencies) && Capabilities.Equals(other.Capabilities) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Id.GetHashCode(); + hashCode = (hashCode * 397) ^ Name.GetHashCode(); + hashCode = (hashCode * 397) ^ (Version != null ? Version.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (UpdateInfo != null ? UpdateInfo.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Dependencies.GetHashCode(); + hashCode = (hashCode * 397) ^ Capabilities.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/LogEntry.cs b/src/BUTR.CrashReport.Models/LogEntry.cs index eb58fd0..028bbde 100644 --- a/src/BUTR.CrashReport.Models/LogEntry.cs +++ b/src/BUTR.CrashReport.Models/LogEntry.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents a single log entry. /// -public record LogEntry +public sealed record LogEntry { /// /// The date and time this log entry was created. @@ -26,4 +26,25 @@ public record LogEntry /// The message of the log entry. /// public required string Message { get; set; } + + /// + public bool Equals(LogEntry? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Date.Equals(other.Date) && Type == other.Type && Level == other.Level && Message == other.Message; + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Date.GetHashCode(); + hashCode = (hashCode * 397) ^ Type.GetHashCode(); + hashCode = (hashCode * 397) ^ (int) Level; + hashCode = (hashCode * 397) ^ Message.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/LogSource.cs b/src/BUTR.CrashReport.Models/LogSource.cs index 3fd7c93..6a91a54 100644 --- a/src/BUTR.CrashReport.Models/LogSource.cs +++ b/src/BUTR.CrashReport.Models/LogSource.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents a log source. Could be a file or anything else. /// -public record LogSource +public sealed record LogSource { /// /// The name of the log source. @@ -22,4 +22,24 @@ public record LogSource /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(LogSource? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name && Logs.Equals(other.Logs) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ Logs.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/MetadataModel.cs b/src/BUTR.CrashReport.Models/MetadataModel.cs index c5f6211..2bfa441 100644 --- a/src/BUTR.CrashReport.Models/MetadataModel.cs +++ b/src/BUTR.CrashReport.Models/MetadataModel.cs @@ -3,7 +3,7 @@ /// /// Represents a generic metadata extension for any model. /// -public record MetadataModel +public sealed record MetadataModel { /// /// The key. @@ -14,4 +14,21 @@ public record MetadataModel /// The value. /// public required string Value { get; set; } + + /// + public bool Equals(MetadataModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Key == other.Key && Value == other.Value; + } + + /// + public override int GetHashCode() + { + unchecked + { + return (Key.GetHashCode() * 397) ^ Value.GetHashCode(); + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/MethodExecuting.cs b/src/BUTR.CrashReport.Models/MethodExecuting.cs index e730ee6..8b07024 100644 --- a/src/BUTR.CrashReport.Models/MethodExecuting.cs +++ b/src/BUTR.CrashReport.Models/MethodExecuting.cs @@ -5,10 +5,27 @@ namespace BUTR.CrashReport.Models; /// /// Represents the actual executing method of a stack trace frame. Can the the original method or a patched method. /// -public record MethodExecuting : MethodSimple +public sealed record MethodExecuting : MethodSimple { /// /// The native code of the method that was compiled by the JIT. /// public required IList NativeInstructions { get; set; } = new List(); + + /// + public bool Equals(MethodExecuting? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return base.Equals(other) && NativeInstructions.Equals(other.NativeInstructions); + } + + /// + public override int GetHashCode() + { + unchecked + { + return (base.GetHashCode() * 397) ^ NativeInstructions.GetHashCode(); + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/MethodHarmonyPatch.cs b/src/BUTR.CrashReport.Models/MethodHarmonyPatch.cs index ff162e2..f1896f7 100644 --- a/src/BUTR.CrashReport.Models/MethodHarmonyPatch.cs +++ b/src/BUTR.CrashReport.Models/MethodHarmonyPatch.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents a Harmony patch method. /// -public record MethodHarmonyPatch : MethodSimple +public sealed record MethodHarmonyPatch : MethodSimple { /// /// The type of the patch. @@ -36,4 +36,21 @@ public MethodHarmonyPatch(MethodSimple methodSimple, HarmonyPatchType patchType) AdditionalMetadata = methodSimple.AdditionalMetadata; PatchType = patchType; } + + /// + public bool Equals(MethodHarmonyPatch? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return base.Equals(other) && PatchType == other.PatchType; + } + + /// + public override int GetHashCode() + { + unchecked + { + return (base.GetHashCode() * 397) ^ (int) PatchType; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/MethodSimple.cs b/src/BUTR.CrashReport.Models/MethodSimple.cs index b7a10ef..d384cd7 100644 --- a/src/BUTR.CrashReport.Models/MethodSimple.cs +++ b/src/BUTR.CrashReport.Models/MethodSimple.cs @@ -67,4 +67,32 @@ public record MethodSimple /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public virtual bool Equals(MethodSimple? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(AssemblyId, other.AssemblyId) && ModuleId == other.ModuleId && LoaderPluginId == other.LoaderPluginId && MethodDeclaredTypeName == other.MethodDeclaredTypeName && MethodName == other.MethodName && MethodFullDescription == other.MethodFullDescription && MethodParameters.Equals(other.MethodParameters) && ILInstructions.Equals(other.ILInstructions) && CSharpILMixedInstructions.Equals(other.CSharpILMixedInstructions) && CSharpInstructions.Equals(other.CSharpInstructions) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = (AssemblyId != null ? AssemblyId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (ModuleId != null ? ModuleId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (LoaderPluginId != null ? LoaderPluginId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (MethodDeclaredTypeName != null ? MethodDeclaredTypeName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ MethodName.GetHashCode(); + hashCode = (hashCode * 397) ^ MethodFullDescription.GetHashCode(); + hashCode = (hashCode * 397) ^ MethodParameters.GetHashCode(); + hashCode = (hashCode * 397) ^ ILInstructions.GetHashCode(); + hashCode = (hashCode * 397) ^ CSharpILMixedInstructions.GetHashCode(); + hashCode = (hashCode * 397) ^ CSharpInstructions.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/ModuleModel.cs b/src/BUTR.CrashReport.Models/ModuleModel.cs index 83f2e51..b0c450d 100644 --- a/src/BUTR.CrashReport.Models/ModuleModel.cs +++ b/src/BUTR.CrashReport.Models/ModuleModel.cs @@ -72,4 +72,34 @@ public sealed record ModuleModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(ModuleModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Id == other.Id && Name == other.Name && Version == other.Version && IsExternal == other.IsExternal && IsOfficial == other.IsOfficial && IsSingleplayer == other.IsSingleplayer && IsMultiplayer == other.IsMultiplayer && Url == other.Url && Equals(UpdateInfo, other.UpdateInfo) && DependencyMetadatas.Equals(other.DependencyMetadatas) && SubModules.Equals(other.SubModules) && Capabilities.Equals(other.Capabilities) && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Id.GetHashCode(); + hashCode = (hashCode * 397) ^ Name.GetHashCode(); + hashCode = (hashCode * 397) ^ Version.GetHashCode(); + hashCode = (hashCode * 397) ^ IsExternal.GetHashCode(); + hashCode = (hashCode * 397) ^ IsOfficial.GetHashCode(); + hashCode = (hashCode * 397) ^ IsSingleplayer.GetHashCode(); + hashCode = (hashCode * 397) ^ IsMultiplayer.GetHashCode(); + hashCode = (hashCode * 397) ^ (Url != null ? Url.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (UpdateInfo != null ? UpdateInfo.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ DependencyMetadatas.GetHashCode(); + hashCode = (hashCode * 397) ^ SubModules.GetHashCode(); + hashCode = (hashCode * 397) ^ Capabilities.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/ModuleSubModuleModel.cs b/src/BUTR.CrashReport.Models/ModuleSubModuleModel.cs index 70d8afc..f48c586 100644 --- a/src/BUTR.CrashReport.Models/ModuleSubModuleModel.cs +++ b/src/BUTR.CrashReport.Models/ModuleSubModuleModel.cs @@ -5,7 +5,7 @@ namespace BUTR.CrashReport.Models; /// /// Represents a game submodule that is loaded into the process. /// -public record ModuleSubModuleModel +public sealed record ModuleSubModuleModel { /// /// The name of the SubModule. @@ -27,4 +27,25 @@ public record ModuleSubModuleModel /// /// public required IList AdditionalMetadata { get; set; } = new List(); + + /// + public bool Equals(ModuleSubModuleModel? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name && Equals(AssemblyId, other.AssemblyId) && Entrypoint == other.Entrypoint && AdditionalMetadata.Equals(other.AdditionalMetadata); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ (AssemblyId != null ? AssemblyId.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Entrypoint.GetHashCode(); + hashCode = (hashCode * 397) ^ AdditionalMetadata.GetHashCode(); + return hashCode; + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/UpdateInfoModuleOrLoaderPlugin.cs b/src/BUTR.CrashReport.Models/UpdateInfoModuleOrLoaderPlugin.cs index 80eca02..9c84466 100644 --- a/src/BUTR.CrashReport.Models/UpdateInfoModuleOrLoaderPlugin.cs +++ b/src/BUTR.CrashReport.Models/UpdateInfoModuleOrLoaderPlugin.cs @@ -17,4 +17,21 @@ public sealed record UpdateInfoModuleOrLoaderPlugin /// public override string ToString() => $"{Provider}:{Value}"; + + /// + public bool Equals(UpdateInfoModuleOrLoaderPlugin? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Provider == other.Provider && Value == other.Value; + } + + /// + public override int GetHashCode() + { + unchecked + { + return (Provider.GetHashCode() * 397) ^ Value.GetHashCode(); + } + } } \ No newline at end of file diff --git a/src/BUTR.CrashReport.Models/Utils/AssemblyUtils.cs b/src/BUTR.CrashReport.Models/Utils/AssemblyUtils.cs index 3a703ea..fd37984 100644 --- a/src/BUTR.CrashReport.Models/Utils/AssemblyUtils.cs +++ b/src/BUTR.CrashReport.Models/Utils/AssemblyUtils.cs @@ -14,5 +14,5 @@ public static class AssemblyUtils /// The public key token. /// The public key token as string. public static string PublicKeyAsString(byte[]? publicKeyToken) => - string.Join(string.Empty, Array.ConvertAll(publicKeyToken ?? Array.Empty(), x => x.ToString("x2", CultureInfo.InvariantCulture))); + string.Join(string.Empty, Array.ConvertAll(publicKeyToken ?? new byte[0], x => x.ToString("x2", CultureInfo.InvariantCulture))); } \ No newline at end of file