diff --git a/GW2SDK.Generators/EnumJsonConverterGenerator.cs b/GW2SDK.Generators/EnumJsonConverterGenerator.cs index dca8d3bbf..cdc9feda6 100644 --- a/GW2SDK.Generators/EnumJsonConverterGenerator.cs +++ b/GW2SDK.Generators/EnumJsonConverterGenerator.cs @@ -8,78 +8,173 @@ namespace GW2SDK.Generators; [Generator] public class EnumJsonConverterGenerator : ISourceGenerator { - public void Initialize(GeneratorInitializationContext context) - { - context.RegisterForSyntaxNotifications(() => new EnumSyntaxReceiver()); - } - - public void Execute(GeneratorExecutionContext context) - { - if (context.SyntaxReceiver is not EnumSyntaxReceiver receiver) - { - return; - } - - var enums = receiver.EnumDeclarations; - - var registrations = new StringBuilder(); - foreach (var enumDeclaration in enums) - { - var enumName = enumDeclaration.Identifier.Text; - var namespaceName = GetNamespace(enumDeclaration); - string fullyQualifiedEnumName; - if (string.IsNullOrEmpty(namespaceName)) - { - context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor( - "GWSDK001", "Missing Namespace", $"Enum '{enumName}' is missing a namespace.", "EnumJsonConverterGenerator", DiagnosticSeverity.Warning, true), enumDeclaration.GetLocation())); - fullyQualifiedEnumName = $"global::{enumName}"; - } - else - { - fullyQualifiedEnumName = $"{namespaceName}.{enumName}"; + public void Initialize(GeneratorInitializationContext context) + { + context.RegisterForSyntaxNotifications(() => new EnumSyntaxReceiver()); + } + + public void Execute(GeneratorExecutionContext context) + { + if (context.SyntaxReceiver is not EnumSyntaxReceiver receiver) + { + return; + } + + var enumTypes = new List(); + + foreach (var enumDeclaration in receiver.EnumDeclarations) + { + var model = context.Compilation.GetSemanticModel(enumDeclaration.SyntaxTree); + var enumSymbol = model.GetDeclaredSymbol(enumDeclaration); + if (enumSymbol is not INamedTypeSymbol namedTypeSymbol) + { + continue; } - if (fullyQualifiedEnumName.StartsWith("GuildWars2", StringComparison.Ordinal)) + if (namedTypeSymbol.DeclaredAccessibility != Accessibility.Public) { - registrations.AppendLine($" Register<{fullyQualifiedEnumName}>();"); + continue; } - } - var sourceBuilder = new StringBuilder($$""" - namespace GuildWars2; - - internal partial class ExtensibleEnumJsonConverterFactory + var namespaceName = enumSymbol.ContainingNamespace.ToDisplayString(); + if (!namespaceName.StartsWith("GuildWars2")) + { + continue; + } + + var enumName = enumSymbol.Name; + enumTypes.Add($"{namespaceName}.{enumName}"); + var source = GenerateEnumJsonConverter(enumName, namespaceName, namedTypeSymbol); + context.AddSource( + $"{namespaceName}.{enumName}JsonConverter.g.cs", + SourceText.From(source, Encoding.UTF8) + ); + } + + var factorySource = GenerateExtensibleEnumJsonConverterFactory(enumTypes); + context.AddSource( + "GuildWars2.ExtensibleEnumJsonConverterFactory.g.cs", + SourceText.From(factorySource, Encoding.UTF8) + ); + } + + private string GenerateEnumJsonConverter(string enumName, string namespaceName, INamedTypeSymbol enumSymbol) + { + var enumValues = enumSymbol.GetMembers() + .Where(m => m.Kind == SymbolKind.Field) + .OfType() + .Where(f => f.ConstantValue != null) + .Select(f => f.Name) + .ToList(); + + var readCases = new StringBuilder(); + foreach (var value in enumValues) + { + readCases.AppendLine($$""" + + if (reader.ValueTextEquals(nameof({{enumName}}.{{value}}))) + { + return {{enumName}}.{{value}}; + } + """); + } + + var writeCases = new StringBuilder(); + foreach (var value in enumValues) + { + writeCases.AppendLine($""" + {enumName}.{value} => nameof({enumName}.{value}), + """); + } + + return $$""" + #nullable enable + + using System; + using System.Text.Json; + using System.Text.Json.Serialization; + + namespace {{namespaceName}}; + + internal sealed class {{enumName}}JsonConverter : JsonConverter<{{enumName}}> { - private static partial void RegisterEnums() + public override {{enumName}} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + {{readCases}} + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, {{enumName}} value, JsonSerializerOptions options) { - {{registrations}} - static void Register() where TEnum : struct, Enum + writer.WriteStringValue(value switch { - Converters[typeof(TEnum)] = new ExtensibleEnumJsonConverter(); - } + {{writeCases}} + _ => throw new ArgumentOutOfRangeException(nameof(value), value, null) + }); } } - """); - context.AddSource("EnumJsonConverters.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8)); - } + """; + } + + private string GenerateExtensibleEnumJsonConverterFactory(List enumTypes) + { + var cases = new StringBuilder(); + foreach (var enumType in enumTypes) + { + cases.AppendLine($$""" + if (enumType == typeof({{enumType}})) + { + return new ExtensibleEnumJsonConverter<{{enumType}}>(); + } - private string GetNamespace(EnumDeclarationSyntax enumDeclaration) - { - var namespaceDeclaration = enumDeclaration.Ancestors().OfType().FirstOrDefault(); - return namespaceDeclaration?.Name.ToString() ?? string.Empty; - } + """); + } - private class EnumSyntaxReceiver : ISyntaxReceiver - { - public List EnumDeclarations { get; } = []; + return $$""" + #nullable enable - public void OnVisitSyntaxNode(SyntaxNode syntaxNode) - { - if (syntaxNode is EnumDeclarationSyntax enumDeclaration) + using System; + using System.Text.Json; + using System.Text.Json.Serialization; + + namespace GuildWars2; + + internal sealed class ExtensibleEnumJsonConverterFactory : JsonConverterFactory { - EnumDeclarations.Add(enumDeclaration); + public override bool CanConvert(Type typeToConvert) + { + if (!typeToConvert.IsGenericType) + { + return false; + } + + return typeToConvert.GetGenericTypeDefinition() == typeof(Extensible<>); + } + + public override JsonConverter? CreateConverter( + Type typeToConvert, + JsonSerializerOptions options + ) + { + var enumType = typeToConvert.GetGenericArguments()[0]; + {{cases}} + return null; + } } - } - } + """; + } + + private class EnumSyntaxReceiver : ISyntaxReceiver + { + public List EnumDeclarations { get; } = []; + + public void OnVisitSyntaxNode(SyntaxNode syntaxNode) + { + if (syntaxNode is EnumDeclarationSyntax enumDeclaration) + { + EnumDeclarations.Add(enumDeclaration); + } + } + } } diff --git a/GW2SDK.Tests/Features/EnumJsonSerializer.cs b/GW2SDK.Tests/Features/EnumJsonSerializer.cs new file mode 100644 index 000000000..a155a18d1 --- /dev/null +++ b/GW2SDK.Tests/Features/EnumJsonSerializer.cs @@ -0,0 +1,28 @@ +using System.Text.Json; +using GuildWars2.Hero.Accounts; + +namespace GuildWars2.Tests.Features; + +public class EnumJsonSerializer +{ + [Fact] + public void Has_json_conversion() + { + var product = ProductName.GuildWars2; + var json = JsonSerializer.Serialize(product); + var actual = JsonSerializer.Deserialize(json); + Assert.Equal(product, actual); + } + + [Fact] + public void Throws_for_undefined_values() + { + Assert.Throws( + () => + { + var product = (ProductName)69; + _ = JsonSerializer.Serialize(product); + } + ); + } +} diff --git a/GW2SDK.Tests/Features/ExtensibleEnum.cs b/GW2SDK.Tests/Features/ExtensibleEnum.cs index fe0b7aff3..2b2df1427 100644 --- a/GW2SDK.Tests/Features/ExtensibleEnum.cs +++ b/GW2SDK.Tests/Features/ExtensibleEnum.cs @@ -1,4 +1,5 @@ -using GuildWars2.Hero.Accounts; +using System.Text.Json; +using GuildWars2.Hero.Accounts; using GuildWars2.Items; namespace GuildWars2.Tests.Features; @@ -115,4 +116,21 @@ public void Converts_unknown_names_to_null_when_enum_has_a_default_value() var actual = extensible.ToEnum(); Assert.Null(actual); } + + [Fact] + public void Has_json_conversion() + { + Extensible extensible = ProductName.GuildWars2; + var json = JsonSerializer.Serialize(extensible); + var actual = JsonSerializer.Deserialize>(json); + Assert.Equal(extensible, actual); + } + [Fact] + public void Has_json_conversion_for_undefined_values() + { + Extensible extensible = "GuildWars3"; + var json = JsonSerializer.Serialize(extensible); + var actual = JsonSerializer.Deserialize>(json); + Assert.Equal(extensible, actual); + } } diff --git a/GW2SDK.Tests/PatternsAndPractices/JsonConverterTest.cs b/GW2SDK.Tests/PatternsAndPractices/JsonConverterTest.cs new file mode 100644 index 000000000..2b633a6f7 --- /dev/null +++ b/GW2SDK.Tests/PatternsAndPractices/JsonConverterTest.cs @@ -0,0 +1,26 @@ +using System.Text.Json.Serialization; +using GuildWars2.Tests.TestInfrastructure; + +namespace GuildWars2.Tests.PatternsAndPractices; + +public class JsonConverterTest(AssemblyFixture fixture) : IClassFixture +{ + [Fact] + public void AllEnumsShouldHaveJsonConverterAttribute() + { + // Get all enum types in the assembly + var enumTypes = fixture.Assembly.GetTypes() + .Where(t => t is { IsEnum: true, IsPublic: true, Namespace: not null } && t.Namespace.StartsWith("GuildWars2")); + + Assert.All(enumTypes, + enumType => + { + var hasJsonConverterAttribute = + enumType.GetCustomAttributes(typeof(JsonConverterAttribute), false).Any(); + Assert.True( + hasJsonConverterAttribute, + $"Enum {enumType.Name} does not have a JsonConverterAttribute." + ); + }); + } +} diff --git a/GW2SDK/Features/Authorization/Permission.cs b/GW2SDK/Features/Authorization/Permission.cs index 826938bca..3faaa0d94 100644 --- a/GW2SDK/Features/Authorization/Permission.cs +++ b/GW2SDK/Features/Authorization/Permission.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Authorization; +using System.Text.Json.Serialization; + +namespace GuildWars2.Authorization; /// Represents the permissions available for Guild Wars 2 authorization. [PublicAPI] +[JsonConverter(typeof(PermissionJsonConverter))] public enum Permission { /// Grants access to the account information. diff --git a/GW2SDK/Features/Chat/SelectedTrait.cs b/GW2SDK/Features/Chat/SelectedTrait.cs index 652bc27e5..6b38ad254 100644 --- a/GW2SDK/Features/Chat/SelectedTrait.cs +++ b/GW2SDK/Features/Chat/SelectedTrait.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Chat; /// Represents a selected trait. [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(SelectedTraitJsonConverter))] public enum SelectedTrait { // THE VALUES OF THIS ENUM ARE USED IN THE BINARY FORMAT OF THE LINK diff --git a/GW2SDK/Features/Exploration/Maps/MapKind.cs b/GW2SDK/Features/Exploration/Maps/MapKind.cs index aeb7c4920..262e64edb 100644 --- a/GW2SDK/Features/Exploration/Maps/MapKind.cs +++ b/GW2SDK/Features/Exploration/Maps/MapKind.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Exploration.Maps; /// The kind of maps in Guild Wars 2. [PublicAPI] [DefaultValue(Unknown)] +[JsonConverter(typeof(MapKindJsonConverter))] public enum MapKind { /// An unknown map kind. diff --git a/GW2SDK/Features/ExtensibleEnumJsonConverter.cs b/GW2SDK/Features/ExtensibleEnumJsonConverter.cs index 67c4fe5ba..568fbe95d 100644 --- a/GW2SDK/Features/ExtensibleEnumJsonConverter.cs +++ b/GW2SDK/Features/ExtensibleEnumJsonConverter.cs @@ -7,13 +7,19 @@ namespace GuildWars2; /// A JSON converter for the Extensible struct with a specific enum type. /// /// The type of the enum. -internal class ExtensibleEnumJsonConverter : JsonConverter> where TEnum : struct, Enum +internal class ExtensibleEnumJsonConverter + : JsonConverter> where TEnum : struct, Enum { /// public override Extensible Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var name = reader.GetString(); - return new Extensible(name!); + if (name is null) + { + ThrowHelper.ThrowInvalidOperationException("Expected a string but got null."); + } + + return new Extensible(name); } /// @@ -26,7 +32,12 @@ public override void Write(Utf8JsonWriter writer, Extensible value, JsonS public override Extensible ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var name = reader.GetString(); - return new Extensible(name!); + if (name is null) + { + ThrowHelper.ThrowInvalidOperationException("Expected a string but got null."); + } + + return new Extensible(name); } /// diff --git a/GW2SDK/Features/ExtensibleEnumJsonConverterFactory.cs b/GW2SDK/Features/ExtensibleEnumJsonConverterFactory.cs deleted file mode 100644 index 24afd2e79..000000000 --- a/GW2SDK/Features/ExtensibleEnumJsonConverterFactory.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace GuildWars2; - -internal partial class ExtensibleEnumJsonConverterFactory : JsonConverterFactory -{ - private static readonly Dictionary Converters = []; - - static ExtensibleEnumJsonConverterFactory() - { - RegisterEnums(); - } - - private static partial void RegisterEnums(); - - /// - public override bool CanConvert(Type typeToConvert) - { - if (!typeToConvert.IsGenericType) return false; - return typeToConvert.GetGenericTypeDefinition() == typeof(Extensible<>); - } - - /// - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - var enumType = typeToConvert.GetGenericArguments()[0]; - if (!Converters.TryGetValue(enumType, out var converter)) - { - throw new NotSupportedException($"Enum type {enumType} is not supported"); - } - - return converter; - } -} diff --git a/GW2SDK/Features/Guilds/Logs/GuildBankOperationKind.cs b/GW2SDK/Features/Guilds/Logs/GuildBankOperationKind.cs index 481559481..ea2a940e5 100644 --- a/GW2SDK/Features/Guilds/Logs/GuildBankOperationKind.cs +++ b/GW2SDK/Features/Guilds/Logs/GuildBankOperationKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Guilds.Logs; +using System.Text.Json.Serialization; + +namespace GuildWars2.Guilds.Logs; /// The kinds of guild bank operations. [PublicAPI] +[JsonConverter(typeof(GuildBankOperationKindJsonConverter))] public enum GuildBankOperationKind { /// Used when items or coins are deposited into the guild bank. diff --git a/GW2SDK/Features/Guilds/Logs/GuildMissionState.cs b/GW2SDK/Features/Guilds/Logs/GuildMissionState.cs index ac1a390fd..8eaa449a4 100644 --- a/GW2SDK/Features/Guilds/Logs/GuildMissionState.cs +++ b/GW2SDK/Features/Guilds/Logs/GuildMissionState.cs @@ -1,7 +1,10 @@ +using System.Text.Json.Serialization; + namespace GuildWars2.Guilds.Logs; /// The guild mission state transitions. [PublicAPI] +[JsonConverter(typeof(GuildMissionStateJsonConverter))] public enum GuildMissionState { /// Logged when the mission starts. diff --git a/GW2SDK/Features/Guilds/Logs/GuildUpgradeAction.cs b/GW2SDK/Features/Guilds/Logs/GuildUpgradeAction.cs index 4e2faf713..1ea2c0750 100644 --- a/GW2SDK/Features/Guilds/Logs/GuildUpgradeAction.cs +++ b/GW2SDK/Features/Guilds/Logs/GuildUpgradeAction.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Guilds.Logs; +using System.Text.Json.Serialization; + +namespace GuildWars2.Guilds.Logs; /// The guild upgrade actions. [PublicAPI] +[JsonConverter(typeof(GuildUpgradeActionJsonConverter))] public enum GuildUpgradeAction { /// The upgrade was queued for processing. diff --git a/GW2SDK/Features/Guilds/Logs/InfluenceActivityKind.cs b/GW2SDK/Features/Guilds/Logs/InfluenceActivityKind.cs index 920d483a8..74c4a1c95 100644 --- a/GW2SDK/Features/Guilds/Logs/InfluenceActivityKind.cs +++ b/GW2SDK/Features/Guilds/Logs/InfluenceActivityKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Guilds.Logs; +using System.Text.Json.Serialization; + +namespace GuildWars2.Guilds.Logs; /// The kinds of changes to guild influence. [PublicAPI] +[JsonConverter(typeof(InfluenceActivityKindJsonConverter))] public enum InfluenceActivityKind { /// A guild member gifted influence to the guild. diff --git a/GW2SDK/Features/Guilds/Teams/GuildTeamRole.cs b/GW2SDK/Features/Guilds/Teams/GuildTeamRole.cs index 356f67ea9..f9a233796 100644 --- a/GW2SDK/Features/Guilds/Teams/GuildTeamRole.cs +++ b/GW2SDK/Features/Guilds/Teams/GuildTeamRole.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Guilds.Teams; +using System.Text.Json.Serialization; + +namespace GuildWars2.Guilds.Teams; /// The roles that a guild PvP team member can have. [PublicAPI] +[JsonConverter(typeof(GuildTeamRoleJsonConverter))] public enum GuildTeamRole { /// The captain of the team. diff --git a/GW2SDK/Features/Guilds/Teams/GuildTeamState.cs b/GW2SDK/Features/Guilds/Teams/GuildTeamState.cs index 2b719f5e0..bc172012a 100644 --- a/GW2SDK/Features/Guilds/Teams/GuildTeamState.cs +++ b/GW2SDK/Features/Guilds/Teams/GuildTeamState.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Guilds.Teams; +using System.Text.Json.Serialization; + +namespace GuildWars2.Guilds.Teams; /// The active state of a guild team. [PublicAPI] +[JsonConverter(typeof(GuildTeamStateJsonConverter))] public enum GuildTeamState { /// Used when the team is active. diff --git a/GW2SDK/Features/Hero/Accounts/ProductName.cs b/GW2SDK/Features/Hero/Accounts/ProductName.cs index 06e0e6897..c4b71ce28 100644 --- a/GW2SDK/Features/Hero/Accounts/ProductName.cs +++ b/GW2SDK/Features/Hero/Accounts/ProductName.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero.Accounts; /// The names of Guild Wars 2 products. [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(ProductNameJsonConverter))] public enum ProductName { /// Nothing. Zero, zilch, zip, nada, nothing. diff --git a/GW2SDK/Features/Hero/AttributeName.cs b/GW2SDK/Features/Hero/AttributeName.cs index caf5f342a..2a1320c7c 100644 --- a/GW2SDK/Features/Hero/AttributeName.cs +++ b/GW2SDK/Features/Hero/AttributeName.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero; @@ -6,6 +7,7 @@ namespace GuildWars2.Hero; /// attributes have a base value of 1000 at level 80, while secondary attributes have a base value of 0. [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(AttributeNameJsonConverter))] public enum AttributeName { /// No attribute. diff --git a/GW2SDK/Features/Hero/Attunement.cs b/GW2SDK/Features/Hero/Attunement.cs index 03434fb42..89b8b4aba 100644 --- a/GW2SDK/Features/Hero/Attunement.cs +++ b/GW2SDK/Features/Hero/Attunement.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero; /// The attunement of an Elementalist. [PublicAPI] +[JsonConverter(typeof(AttunementJsonConverter))] public enum Attunement { /// Attunement to Earth. diff --git a/GW2SDK/Features/Hero/BodyType.cs b/GW2SDK/Features/Hero/BodyType.cs index 35672d7a2..09729e061 100644 --- a/GW2SDK/Features/Hero/BodyType.cs +++ b/GW2SDK/Features/Hero/BodyType.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero; /// The body types of characters. [PublicAPI] +[JsonConverter(typeof(BodyTypeJsonConverter))] public enum BodyType { /// Female body type. diff --git a/GW2SDK/Features/Hero/Builds/Facts/ComboFieldName.cs b/GW2SDK/Features/Hero/Builds/Facts/ComboFieldName.cs index 9f52dc152..28cedc20a 100644 --- a/GW2SDK/Features/Hero/Builds/Facts/ComboFieldName.cs +++ b/GW2SDK/Features/Hero/Builds/Facts/ComboFieldName.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Builds.Facts; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Builds.Facts; /// The combo field (area effect) that is created by a skill. [PublicAPI] +[JsonConverter(typeof(ComboFieldNameJsonConverter))] public enum ComboFieldName { /// Dark fields whose combos cause Blindness or Life Stealing. diff --git a/GW2SDK/Features/Hero/Builds/Facts/ComboFinisherName.cs b/GW2SDK/Features/Hero/Builds/Facts/ComboFinisherName.cs index 321f5b595..48bcaa478 100644 --- a/GW2SDK/Features/Hero/Builds/Facts/ComboFinisherName.cs +++ b/GW2SDK/Features/Hero/Builds/Facts/ComboFinisherName.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Builds.Facts; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Builds.Facts; /// The combo finisher that is applied by a skill. [PublicAPI] +[JsonConverter(typeof(ComboFinisherNameJsonConverter))] public enum ComboFinisherName { /// Blast finishers creates area effects. diff --git a/GW2SDK/Features/Hero/Builds/SkillCategoryName.cs b/GW2SDK/Features/Hero/Builds/SkillCategoryName.cs index 19ca5ebf1..433da0185 100644 --- a/GW2SDK/Features/Hero/Builds/SkillCategoryName.cs +++ b/GW2SDK/Features/Hero/Builds/SkillCategoryName.cs @@ -1,8 +1,11 @@ -namespace GuildWars2.Hero.Builds; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Builds; /// Skills with similar behaviors are grouped into one of these categories. Many traits affect all skills in a /// certain category. [PublicAPI] +[JsonConverter(typeof(SkillCategoryNameJsonConverter))] public enum SkillCategoryName { /// Elementalist utility skills. Non-elemental magical energy sources of critical damage. diff --git a/GW2SDK/Features/Hero/Builds/SkillSlot.cs b/GW2SDK/Features/Hero/Builds/SkillSlot.cs index 272670300..5b8ee7dc9 100644 --- a/GW2SDK/Features/Hero/Builds/SkillSlot.cs +++ b/GW2SDK/Features/Hero/Builds/SkillSlot.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Builds; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Builds; /// The skill slots for abilities which can be activated by the player. [PublicAPI] +[JsonConverter(typeof(SkillSlotJsonConverter))] public enum SkillSlot { /// The first weapon skill. Granted by two-handed weapons or one-handed weapons in the main hand. diff --git a/GW2SDK/Features/Hero/Builds/TraitSlot.cs b/GW2SDK/Features/Hero/Builds/TraitSlot.cs index 8b599528e..16a5456cf 100644 --- a/GW2SDK/Features/Hero/Builds/TraitSlot.cs +++ b/GW2SDK/Features/Hero/Builds/TraitSlot.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Builds; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Builds; /// The trait slots. [PublicAPI] +[JsonConverter(typeof(TraitSlotJsonConverter))] public enum TraitSlot { /// A minor trait which is always active. diff --git a/GW2SDK/Features/Hero/Builds/Transformation.cs b/GW2SDK/Features/Hero/Builds/Transformation.cs index 12ac9523c..945cfacf7 100644 --- a/GW2SDK/Features/Hero/Builds/Transformation.cs +++ b/GW2SDK/Features/Hero/Builds/Transformation.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Builds; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Builds; /// Transformations related to specializations. [PublicAPI] +[JsonConverter(typeof(TransformationJsonConverter))] public enum Transformation { /// Druid's Celestial Avatar. diff --git a/GW2SDK/Features/Hero/Builds/WeaponType.cs b/GW2SDK/Features/Hero/Builds/WeaponType.cs index c85500395..48c0782b2 100644 --- a/GW2SDK/Features/Hero/Builds/WeaponType.cs +++ b/GW2SDK/Features/Hero/Builds/WeaponType.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Builds; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Builds; /// The weapon types. [PublicAPI] +[JsonConverter(typeof(WeaponTypeJsonConverter))] public enum WeaponType { /// No weapon type. diff --git a/GW2SDK/Features/Hero/Crafting/Disciplines/CraftingDisciplineName.cs b/GW2SDK/Features/Hero/Crafting/Disciplines/CraftingDisciplineName.cs index d4cc6a6f4..c3d263672 100644 --- a/GW2SDK/Features/Hero/Crafting/Disciplines/CraftingDisciplineName.cs +++ b/GW2SDK/Features/Hero/Crafting/Disciplines/CraftingDisciplineName.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Crafting.Disciplines; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Crafting.Disciplines; /// The different crafting disciplines in the game. [PublicAPI] +[JsonConverter(typeof(CraftingDisciplineNameJsonConverter))] public enum CraftingDisciplineName { /// The Armorsmith crafting discipline. diff --git a/GW2SDK/Features/Hero/Crafting/IngredientKind.cs b/GW2SDK/Features/Hero/Crafting/IngredientKind.cs index 01f0a8bc3..9cb4c92cc 100644 --- a/GW2SDK/Features/Hero/Crafting/IngredientKind.cs +++ b/GW2SDK/Features/Hero/Crafting/IngredientKind.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero.Crafting; /// The ingredient kinds used in crafting recipes. [PublicAPI] [DefaultValue(Item)] +[JsonConverter(typeof(IngredientKindJsonConverter))] public enum IngredientKind { /// The ingredient is an item, for example planks. diff --git a/GW2SDK/Features/Hero/Equipment/Dyes/ColorSet.cs b/GW2SDK/Features/Hero/Equipment/Dyes/ColorSet.cs index a25d38e14..ab4a830e6 100644 --- a/GW2SDK/Features/Hero/Equipment/Dyes/ColorSet.cs +++ b/GW2SDK/Features/Hero/Equipment/Dyes/ColorSet.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero.Equipment.Dyes; /// The color sets by which dyes are grouped. [PublicAPI] [DefaultValue(Unspecified)] +[JsonConverter(typeof(ColorSetJsonConverter))] public enum ColorSet { /// Dye remover. diff --git a/GW2SDK/Features/Hero/Equipment/Dyes/Hue.cs b/GW2SDK/Features/Hero/Equipment/Dyes/Hue.cs index 305f84b29..5dc56a658 100644 --- a/GW2SDK/Features/Hero/Equipment/Dyes/Hue.cs +++ b/GW2SDK/Features/Hero/Equipment/Dyes/Hue.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero.Equipment.Dyes; /// The colors by which dyes are grouped. [PublicAPI] [DefaultValue(Unspecified)] +[JsonConverter(typeof(HueJsonConverter))] public enum Hue { /// Dye remover. diff --git a/GW2SDK/Features/Hero/Equipment/Dyes/Material.cs b/GW2SDK/Features/Hero/Equipment/Dyes/Material.cs index a8c8cad0d..c75135403 100644 --- a/GW2SDK/Features/Hero/Equipment/Dyes/Material.cs +++ b/GW2SDK/Features/Hero/Equipment/Dyes/Material.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero.Equipment.Dyes; /// The materials by which dyes are grouped. [PublicAPI] [DefaultValue(Unspecified)] +[JsonConverter(typeof(MaterialJsonConverter))] public enum Material { /// Dye remover. diff --git a/GW2SDK/Features/Hero/Equipment/Material.cs b/GW2SDK/Features/Hero/Equipment/Material.cs index 6b83c24ca..fd1361e17 100644 --- a/GW2SDK/Features/Hero/Equipment/Material.cs +++ b/GW2SDK/Features/Hero/Equipment/Material.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Equipment; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Equipment; /// The material of an armor piece, which determines its appearance. [PublicAPI] +[JsonConverter(typeof(MaterialJsonConverter))] public enum Material { /// Cloth armor. diff --git a/GW2SDK/Features/Hero/Equipment/Mounts/MountName.cs b/GW2SDK/Features/Hero/Equipment/Mounts/MountName.cs index e3b9adefc..17689a122 100644 --- a/GW2SDK/Features/Hero/Equipment/Mounts/MountName.cs +++ b/GW2SDK/Features/Hero/Equipment/Mounts/MountName.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Equipment.Mounts; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Equipment.Mounts; /// The mount types. [PublicAPI] +[JsonConverter(typeof(MountNameJsonConverter))] public enum MountName { /// Swift, strong, and agile, raptors are stalwart explorers and great companions for exploring the far reaches of diff --git a/GW2SDK/Features/Hero/Equipment/Novelties/NoveltyKind.cs b/GW2SDK/Features/Hero/Equipment/Novelties/NoveltyKind.cs index 440deda82..a3a58214c 100644 --- a/GW2SDK/Features/Hero/Equipment/Novelties/NoveltyKind.cs +++ b/GW2SDK/Features/Hero/Equipment/Novelties/NoveltyKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Equipment.Novelties; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Equipment.Novelties; /// The novelty kinds. [PublicAPI] +[JsonConverter(typeof(NoveltyKindJsonConverter))] public enum NoveltyKind { /// Makes the character sit on a chair. diff --git a/GW2SDK/Features/Hero/Equipment/Templates/EquipmentLocation.cs b/GW2SDK/Features/Hero/Equipment/Templates/EquipmentLocation.cs index 8be84ce92..27a79c9ec 100644 --- a/GW2SDK/Features/Hero/Equipment/Templates/EquipmentLocation.cs +++ b/GW2SDK/Features/Hero/Equipment/Templates/EquipmentLocation.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Equipment.Templates; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Equipment.Templates; /// The location of an equipment item. [PublicAPI] +[JsonConverter(typeof(EquipmentLocationJsonConverter))] public enum EquipmentLocation { /// The item is equipped in the current active template. diff --git a/GW2SDK/Features/Hero/Equipment/Templates/EquipmentSlot.cs b/GW2SDK/Features/Hero/Equipment/Templates/EquipmentSlot.cs index 4d710a4d2..866f39da1 100644 --- a/GW2SDK/Features/Hero/Equipment/Templates/EquipmentSlot.cs +++ b/GW2SDK/Features/Hero/Equipment/Templates/EquipmentSlot.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Equipment.Templates; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Equipment.Templates; /// The equipment slots in which an item can be equipped. [PublicAPI] +[JsonConverter(typeof(EquipmentSlotJsonConverter))] public enum EquipmentSlot { /// The first accessory slot. diff --git a/GW2SDK/Features/Hero/ItemBinding.cs b/GW2SDK/Features/Hero/ItemBinding.cs index 619d1740d..ebf83708a 100644 --- a/GW2SDK/Features/Hero/ItemBinding.cs +++ b/GW2SDK/Features/Hero/ItemBinding.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero; /// Represents the types of item binding in Guild Wars 2. [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(ItemBindingJsonConverter))] public enum ItemBinding { /// The item is not bound and can be traded with other players. diff --git a/GW2SDK/Features/Hero/Masteries/MasteryRegionName.cs b/GW2SDK/Features/Hero/Masteries/MasteryRegionName.cs index d95d72462..77eeab9a1 100644 --- a/GW2SDK/Features/Hero/Masteries/MasteryRegionName.cs +++ b/GW2SDK/Features/Hero/Masteries/MasteryRegionName.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero.Masteries; /// The mastery regions. [PublicAPI] [DefaultValue(Unknown)] +[JsonConverter(typeof(MasteryRegionNameJsonConverter))] public enum MasteryRegionName { /// Unknown mastery point region. diff --git a/GW2SDK/Features/Hero/Offhand.cs b/GW2SDK/Features/Hero/Offhand.cs index 8148c098e..172dfe239 100644 --- a/GW2SDK/Features/Hero/Offhand.cs +++ b/GW2SDK/Features/Hero/Offhand.cs @@ -1,17 +1,19 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Hero; /// The offhands which may be required for a weapon skill. [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(OffhandJsonConverter))] public enum Offhand { /// Nothing in the offhand (empty). None, /// Nothing in the offhand (empty). - Nothing = None, + Nothing, /// A dagger in the offhand. Dagger, diff --git a/GW2SDK/Features/Hero/ProfessionName.cs b/GW2SDK/Features/Hero/ProfessionName.cs index 5d82a039e..77dbe19be 100644 --- a/GW2SDK/Features/Hero/ProfessionName.cs +++ b/GW2SDK/Features/Hero/ProfessionName.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero; /// The playable professions. [PublicAPI] +[JsonConverter(typeof(ProfessionNameJsonConverter))] public enum ProfessionName { /// Guardian uses heavy armor and focuses on defensive magic. diff --git a/GW2SDK/Features/Hero/RaceName.cs b/GW2SDK/Features/Hero/RaceName.cs index 88dbb7f7c..93598a8bd 100644 --- a/GW2SDK/Features/Hero/RaceName.cs +++ b/GW2SDK/Features/Hero/RaceName.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero; /// The playable races. [PublicAPI] +[JsonConverter(typeof(RaceNameJsonConverter))] public enum RaceName { /// These alchemagical inventors may be short in stature, but they're intellectual giants. Among the asura, it's diff --git a/GW2SDK/Features/Hero/Training/TrainingCategory.cs b/GW2SDK/Features/Hero/Training/TrainingCategory.cs index 50e918e47..830c1d9d2 100644 --- a/GW2SDK/Features/Hero/Training/TrainingCategory.cs +++ b/GW2SDK/Features/Hero/Training/TrainingCategory.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero.Training; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero.Training; /// The categories of training. [PublicAPI] +[JsonConverter(typeof(TrainingCategoryJsonConverter))] public enum TrainingCategory { /// Skill training tracks. diff --git a/GW2SDK/Features/Hero/WeightClass.cs b/GW2SDK/Features/Hero/WeightClass.cs index 4bd1f5b26..c18ee4559 100644 --- a/GW2SDK/Features/Hero/WeightClass.cs +++ b/GW2SDK/Features/Hero/WeightClass.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Hero; +using System.Text.Json.Serialization; + +namespace GuildWars2.Hero; /// The weight classes of armor. [PublicAPI] +[JsonConverter(typeof(WeightClassJsonConverter))] public enum WeightClass { /// Clothing can be worn by any profession. diff --git a/GW2SDK/Features/Items/Models/GameType.cs b/GW2SDK/Features/Items/Models/GameType.cs index 51ddb47a6..6307f0777 100644 --- a/GW2SDK/Features/Items/Models/GameType.cs +++ b/GW2SDK/Features/Items/Models/GameType.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Items; +using System.Text.Json.Serialization; + +namespace GuildWars2.Items; /// The game types where items can be used. [PublicAPI] +[JsonConverter(typeof(GameTypeJsonConverter))] public enum GameType { /// Usable in activities. diff --git a/GW2SDK/Features/Items/Models/InfusionSlotUpgradeKind.cs b/GW2SDK/Features/Items/Models/InfusionSlotUpgradeKind.cs index 4a2b1337e..471b50d75 100644 --- a/GW2SDK/Features/Items/Models/InfusionSlotUpgradeKind.cs +++ b/GW2SDK/Features/Items/Models/InfusionSlotUpgradeKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Items; +using System.Text.Json.Serialization; + +namespace GuildWars2.Items; /// The types of infusion slot upgrades. [PublicAPI] +[JsonConverter(typeof(InfusionSlotUpgradeKindJsonConverter))] public enum InfusionSlotUpgradeKind { /// Attunement is a process where an ascended ring is upgraded in the Mystic Forge to gain one extra infusion diff --git a/GW2SDK/Features/Items/Models/Rarity.cs b/GW2SDK/Features/Items/Models/Rarity.cs index 05e6f88d6..79cdb73c4 100644 --- a/GW2SDK/Features/Items/Models/Rarity.cs +++ b/GW2SDK/Features/Items/Models/Rarity.cs @@ -1,7 +1,11 @@ -namespace GuildWars2.Items; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace GuildWars2.Items; /// The item rarities. [PublicAPI] +[JsonConverter(typeof(RarityJsonConverter))] public enum Rarity { /// Gray items. diff --git a/GW2SDK/Features/Items/Models/Weapons/DamageType.cs b/GW2SDK/Features/Items/Models/Weapons/DamageType.cs index ec1fbaf89..881024016 100644 --- a/GW2SDK/Features/Items/Models/Weapons/DamageType.cs +++ b/GW2SDK/Features/Items/Models/Weapons/DamageType.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Items; /// The type of damage dealt by a weapon. It is a purely visual effect and does not affect the damage calculation. [PublicAPI] [DefaultValue(Physical)] +[JsonConverter(typeof(DamageTypeJsonConverter))] public enum DamageType { /// The default damage type of most weapons, which does not have a special visual effect. diff --git a/GW2SDK/Features/Markup/MarkupLexerState.cs b/GW2SDK/Features/Markup/MarkupLexerState.cs index 6f870e718..8d25961f9 100644 --- a/GW2SDK/Features/Markup/MarkupLexerState.cs +++ b/GW2SDK/Features/Markup/MarkupLexerState.cs @@ -1,5 +1,4 @@ - -namespace GuildWars2.Markup; +namespace GuildWars2.Markup; internal enum MarkupLexerState { diff --git a/GW2SDK/Features/Markup/MarkupNodeType.cs b/GW2SDK/Features/Markup/MarkupNodeType.cs index 794493e59..5c6fbe702 100644 --- a/GW2SDK/Features/Markup/MarkupNodeType.cs +++ b/GW2SDK/Features/Markup/MarkupNodeType.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Markup; @@ -7,6 +8,7 @@ namespace GuildWars2.Markup; /// [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(MarkupNodeTypeJsonConverter))] public enum MarkupNodeType { /// diff --git a/GW2SDK/Features/Markup/MarkupTokenType.cs b/GW2SDK/Features/Markup/MarkupTokenType.cs index 8f612f3f6..64930f3a0 100644 --- a/GW2SDK/Features/Markup/MarkupTokenType.cs +++ b/GW2SDK/Features/Markup/MarkupTokenType.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Markup; @@ -7,6 +8,7 @@ namespace GuildWars2.Markup; /// [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(MarkupTokenTypeJsonConverter))] public enum MarkupTokenType { /// diff --git a/GW2SDK/Features/MissingMemberBehavior.cs b/GW2SDK/Features/MissingMemberBehavior.cs index 9e426a6ba..1feb3a662 100644 --- a/GW2SDK/Features/MissingMemberBehavior.cs +++ b/GW2SDK/Features/MissingMemberBehavior.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2; /// Describes the desired program behavior when a source JSON document does not exactly match the target CLR type. [PublicAPI] [DefaultValue(Error)] +[JsonConverter(typeof(MissingMemberBehaviorJsonConverter))] public enum MissingMemberBehavior { /// Throws an error for unexpected JSON properties and for polymorphic types when the JSON can't be matched to any diff --git a/GW2SDK/Features/Mumble/MapType.cs b/GW2SDK/Features/Mumble/MapType.cs index 70c7424e5..88c016f26 100644 --- a/GW2SDK/Features/Mumble/MapType.cs +++ b/GW2SDK/Features/Mumble/MapType.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Mumble; +using System.Text.Json.Serialization; + +namespace GuildWars2.Mumble; /// The map types. [PublicAPI] +[JsonConverter(typeof(MapTypeJsonConverter))] public enum MapType : uint { // Keep the enum values in sync with the enum from the game, provided below. diff --git a/GW2SDK/Features/Mumble/UiSize.cs b/GW2SDK/Features/Mumble/UiSize.cs index 59e7c1d1c..3dc4f8a1d 100644 --- a/GW2SDK/Features/Mumble/UiSize.cs +++ b/GW2SDK/Features/Mumble/UiSize.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Mumble; /// The user interface size choices provided by the game client. [PublicAPI] [DefaultValue(Small)] +[JsonConverter(typeof(UiSizeJsonConverter))] public enum UiSize { /// Smallest user interface size. diff --git a/GW2SDK/Features/Mumble/UiState.cs b/GW2SDK/Features/Mumble/UiState.cs index feeb8bb80..7643c2df2 100644 --- a/GW2SDK/Features/Mumble/UiState.cs +++ b/GW2SDK/Features/Mumble/UiState.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Mumble; @@ -6,6 +7,7 @@ namespace GuildWars2.Mumble; [PublicAPI] [Flags] [DefaultValue(None)] +[JsonConverter(typeof(UiStateJsonConverter))] public enum UiState : uint { /// No flags are set. diff --git a/GW2SDK/Features/Pve/Dungeons/DungeonKind.cs b/GW2SDK/Features/Pve/Dungeons/DungeonKind.cs index e5dc2c5c3..4cc9e50e4 100644 --- a/GW2SDK/Features/Pve/Dungeons/DungeonKind.cs +++ b/GW2SDK/Features/Pve/Dungeons/DungeonKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Pve.Dungeons; +using System.Text.Json.Serialization; + +namespace GuildWars2.Pve.Dungeons; /// The kind of paths in a dungeon. [PublicAPI] +[JsonConverter(typeof(DungeonKindJsonConverter))] public enum DungeonKind { /// A story path, which does not reward dungeon tokens, only some coins. diff --git a/GW2SDK/Features/Pve/Home/CollectionBox.cs b/GW2SDK/Features/Pve/Home/CollectionBox.cs index ebfa36c4d..6b29ea9e4 100644 --- a/GW2SDK/Features/Pve/Home/CollectionBox.cs +++ b/GW2SDK/Features/Pve/Home/CollectionBox.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Pve.Home; +using System.Text.Json.Serialization; + +namespace GuildWars2.Pve.Home; /// The homestead collection boxes. [PublicAPI] +[JsonConverter(typeof(CollectionBoxJsonConverter))] public enum CollectionBox { /// The harvesting collection box. diff --git a/GW2SDK/Features/Pve/Raids/EncounterKind.cs b/GW2SDK/Features/Pve/Raids/EncounterKind.cs index 81c8a3e5c..5cd098188 100644 --- a/GW2SDK/Features/Pve/Raids/EncounterKind.cs +++ b/GW2SDK/Features/Pve/Raids/EncounterKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Pve.Raids; +using System.Text.Json.Serialization; + +namespace GuildWars2.Pve.Raids; /// The kind of raid encounters. [PublicAPI] +[JsonConverter(typeof(EncounterKindJsonConverter))] public enum EncounterKind { /// A non-boss encounter, such as an escort event. diff --git a/GW2SDK/Features/Pve/SuperAdventureBox/SuperAdventureBoxMode.cs b/GW2SDK/Features/Pve/SuperAdventureBox/SuperAdventureBoxMode.cs index f5afb6e42..cde12bcdc 100644 --- a/GW2SDK/Features/Pve/SuperAdventureBox/SuperAdventureBoxMode.cs +++ b/GW2SDK/Features/Pve/SuperAdventureBox/SuperAdventureBoxMode.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Pve.SuperAdventureBox; +using System.Text.Json.Serialization; + +namespace GuildWars2.Pve.SuperAdventureBox; /// The difficulty modes of Super Adventure Box zones. [PublicAPI] +[JsonConverter(typeof(SuperAdventureBoxModeJsonConverter))] public enum SuperAdventureBoxMode { /// The easiest difficulty mode. diff --git a/GW2SDK/Features/Pvp/Games/PvpRatingType.cs b/GW2SDK/Features/Pvp/Games/PvpRatingType.cs index 92af7131c..1c31f3be9 100644 --- a/GW2SDK/Features/Pvp/Games/PvpRatingType.cs +++ b/GW2SDK/Features/Pvp/Games/PvpRatingType.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Pvp.Games; /// The PvP game rating types. Player skill is rated differently for each game type. [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(PvpRatingTypeJsonConverter))] public enum PvpRatingType { /// An unrated game. diff --git a/GW2SDK/Features/Pvp/Games/PvpResult.cs b/GW2SDK/Features/Pvp/Games/PvpResult.cs index c55b2c4d3..9a3ff6395 100644 --- a/GW2SDK/Features/Pvp/Games/PvpResult.cs +++ b/GW2SDK/Features/Pvp/Games/PvpResult.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Pvp.Games; +using System.Text.Json.Serialization; + +namespace GuildWars2.Pvp.Games; /// The result of a PvP match. [PublicAPI] +[JsonConverter(typeof(PvpResultJsonConverter))] public enum PvpResult { /// Your team won. diff --git a/GW2SDK/Features/Pvp/Games/PvpTeamColor.cs b/GW2SDK/Features/Pvp/Games/PvpTeamColor.cs index b83fc6637..3f443b598 100644 --- a/GW2SDK/Features/Pvp/Games/PvpTeamColor.cs +++ b/GW2SDK/Features/Pvp/Games/PvpTeamColor.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Pvp.Games; +using System.Text.Json.Serialization; + +namespace GuildWars2.Pvp.Games; /// The PvP team colors. [PublicAPI] +[JsonConverter(typeof(PvpTeamColorJsonConverter))] public enum PvpTeamColor { /// The red team. diff --git a/GW2SDK/Features/Pvp/Seasons/LeaderboardTierKind.cs b/GW2SDK/Features/Pvp/Seasons/LeaderboardTierKind.cs index 4952bafa4..96dd86f21 100644 --- a/GW2SDK/Features/Pvp/Seasons/LeaderboardTierKind.cs +++ b/GW2SDK/Features/Pvp/Seasons/LeaderboardTierKind.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Pvp.Seasons; /// The method used to calculate the tier of a player or team on a PvP League leaderboard. [PublicAPI] [DefaultValue(Rank)] +[JsonConverter(typeof(LeaderboardTierKindJsonConverter))] public enum LeaderboardTierKind { /// The player or team rank is used to calculate the tier. diff --git a/GW2SDK/Features/WizardsVault/ObjectiveTrack.cs b/GW2SDK/Features/WizardsVault/ObjectiveTrack.cs index 4780f96cf..24b8373f9 100644 --- a/GW2SDK/Features/WizardsVault/ObjectiveTrack.cs +++ b/GW2SDK/Features/WizardsVault/ObjectiveTrack.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.WizardsVault; +using System.Text.Json.Serialization; + +namespace GuildWars2.WizardsVault; /// The Wizard's Vault objective tracks. [PublicAPI] +[JsonConverter(typeof(ObjectiveTrackJsonConverter))] public enum ObjectiveTrack { /// PvE objectives such as completing events. diff --git a/GW2SDK/Features/WizardsVault/RewardKind.cs b/GW2SDK/Features/WizardsVault/RewardKind.cs index db29aa264..17ea2c80f 100644 --- a/GW2SDK/Features/WizardsVault/RewardKind.cs +++ b/GW2SDK/Features/WizardsVault/RewardKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.WizardsVault; +using System.Text.Json.Serialization; + +namespace GuildWars2.WizardsVault; /// The kind of rewards available in the Wizard's Vault. [PublicAPI] +[JsonConverter(typeof(RewardKindJsonConverter))] public enum RewardKind { /// Seasonal rewards such as crafting materials, gold, mystic coins and legendary starter kits. The rewards are diff --git a/GW2SDK/Features/Worlds/WorldPopulation.cs b/GW2SDK/Features/Worlds/WorldPopulation.cs index 403d46e3c..6351c2fbc 100644 --- a/GW2SDK/Features/Worlds/WorldPopulation.cs +++ b/GW2SDK/Features/Worlds/WorldPopulation.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Worlds; +using System.Text.Json.Serialization; + +namespace GuildWars2.Worlds; /// The population levels of a world in Guild Wars 2. [PublicAPI] +[JsonConverter(typeof(WorldPopulationJsonConverter))] public enum WorldPopulation { /// A world with a low population. diff --git a/GW2SDK/Features/Worlds/WorldRegion.cs b/GW2SDK/Features/Worlds/WorldRegion.cs index 15aeef7cb..57ba6efbb 100644 --- a/GW2SDK/Features/Worlds/WorldRegion.cs +++ b/GW2SDK/Features/Worlds/WorldRegion.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Worlds; /// The world region where a world is located. [PublicAPI] [DefaultValue(None)] +[JsonConverter(typeof(WorldRegionJsonConverter))] public enum WorldRegion { /// The world region is missing or unknown. diff --git a/GW2SDK/Features/Wvw/Matches/BonusKind.cs b/GW2SDK/Features/Wvw/Matches/BonusKind.cs index 21ddb19a4..e53d9a8d6 100644 --- a/GW2SDK/Features/Wvw/Matches/BonusKind.cs +++ b/GW2SDK/Features/Wvw/Matches/BonusKind.cs @@ -1,7 +1,10 @@ -namespace GuildWars2.Wvw.Matches; +using System.Text.Json.Serialization; + +namespace GuildWars2.Wvw.Matches; /// The bonus kinds. [PublicAPI] +[JsonConverter(typeof(BonusKindJsonConverter))] public enum BonusKind { /// Borderlands Bloodlust, gained by holding three ruins. diff --git a/GW2SDK/Features/Wvw/TeamColor.cs b/GW2SDK/Features/Wvw/TeamColor.cs index 96433bf1e..f87c2cde6 100644 --- a/GW2SDK/Features/Wvw/TeamColor.cs +++ b/GW2SDK/Features/Wvw/TeamColor.cs @@ -1,10 +1,12 @@ using System.ComponentModel; +using System.Text.Json.Serialization; namespace GuildWars2.Wvw; /// The team colors in World vs. World. [PublicAPI] [DefaultValue(Neutral)] +[JsonConverter(typeof(TeamColorJsonConverter))] public enum TeamColor { /// The neutral color (white) for objectives that are not controlled by any team. diff --git a/GW2SDK/Internal/ThrowHelper.cs b/GW2SDK/Internal/ThrowHelper.cs index 6a414918c..527fd9c5c 100644 --- a/GW2SDK/Internal/ThrowHelper.cs +++ b/GW2SDK/Internal/ThrowHelper.cs @@ -9,23 +9,27 @@ namespace GuildWars2; [StackTraceHidden] internal static class ThrowHelper { + [DoesNotReturn] + internal static void ThrowInvalidOperationException(string? message) => + throw new InvalidOperationException(message); + [DoesNotReturn] internal static void ThrowUnexpectedMember(string memberName) => - throw new InvalidOperationException($"Unexpected member '{memberName}'."); + ThrowInvalidOperationException($"Unexpected member '{memberName}'."); [DoesNotReturn] internal static void ThrowUnexpectedArrayLength(int length) => - throw new InvalidOperationException($"Unexpected array length [{length}]."); + ThrowInvalidOperationException($"Unexpected array length [{length}]."); [DoesNotReturn] internal static void ThrowUnexpectedDiscriminator(string? discriminatorValue) => - throw new InvalidOperationException( + ThrowInvalidOperationException( $"Unexpected discriminator value '{discriminatorValue}'." ); [DoesNotReturn] internal static void ThrowInvalidDiscriminator(string? discriminatorValue) => - throw new InvalidOperationException($"Invalid discriminator value '{discriminatorValue}'."); + ThrowInvalidOperationException($"Invalid discriminator value '{discriminatorValue}'."); [DoesNotReturn] internal static void ThrowArgumentNull(string? paramName) => diff --git a/gw2sdk.sln.DotSettings b/gw2sdk.sln.DotSettings index 17806771f..446e4373f 100644 --- a/gw2sdk.sln.DotSettings +++ b/gw2sdk.sln.DotSettings @@ -164,6 +164,7 @@ True True True + True True True