Skip to content

Commit

Permalink
Redo item json converters without .NET 7 features
Browse files Browse the repository at this point in the history
  • Loading branch information
sliekens committed Nov 23, 2024
1 parent 647569e commit d8d9649
Show file tree
Hide file tree
Showing 225 changed files with 8,633 additions and 203 deletions.
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
</Project>
</Project>
2 changes: 2 additions & 0 deletions GW2SDK/Features/Items/Models/Armors/Armor.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using GuildWars2.Hero;
using System.Text.Json.Serialization;

namespace GuildWars2.Items;

/// <summary>Information about an armor item. This type is the base type for all armor. Cast objects of this type to a more
/// specific type to access more properties.</summary>
[PublicAPI]
[Inheritable]
[JsonConverter(typeof(ArmorJsonConverter))]
public record Armor : Item
{
/// <summary>The default skin ID for the armor. This skin can be unlocked in the wardrobe by binding the item.</summary>
Expand Down
193 changes: 193 additions & 0 deletions GW2SDK/Features/Items/Models/Armors/ArmorJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using GuildWars2.Hero;
using GuildWars2.Json;

namespace GuildWars2.Items;

internal sealed class ArmorJsonConverter : JsonConverter<Armor>
{
public const string DiscriminatorValue = "armor";

public const string DiscriminatorName = "$armor_type";

public override bool CanConvert(Type typeToConvert)
{
return typeof(Armor).IsAssignableFrom(typeToConvert);
}

public override Armor Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options
)
{
using var json = JsonDocument.ParseValue(ref reader);
return Read(json.RootElement);
}

public override void Write(Utf8JsonWriter writer, Armor value, JsonSerializerOptions options)
{
Write(writer, value);
}

public static Armor Read(JsonElement json)
{
if (!json.GetProperty(ItemJsonConverter.DiscriminatorName).ValueEquals(DiscriminatorValue))
{
ThrowHelper.ThrowInvalidDiscriminator(
json.GetProperty(ItemJsonConverter.DiscriminatorName).GetString()
);
}

if (json.TryGetProperty(DiscriminatorName, out var discriminator))
{
switch (discriminator.GetString())
{
case BootsJsonConverter.DiscriminatorValue:
return BootsJsonConverter.Read(json);
case GlovesJsonConverter.DiscriminatorValue:
return GlovesJsonConverter.Read(json);
case CoatJsonConverter.DiscriminatorValue:
return CoatJsonConverter.Read(json);
case LeggingsJsonConverter.DiscriminatorValue:
return LeggingsJsonConverter.Read(json);
case ShouldersJsonConverter.DiscriminatorValue:
return ShouldersJsonConverter.Read(json);
case HelmJsonConverter.DiscriminatorValue:
return HelmJsonConverter.Read(json);
case HelmAquaticJsonConverter.DiscriminatorValue:
return HelmAquaticJsonConverter.Read(json);
}
}

return new Armor
{
Id = json.GetProperty("id").GetInt32(),
Name = json.GetProperty("name").GetStringRequired(),
Description = json.GetProperty("description").GetStringRequired(),
Level = json.GetProperty("level").GetInt32(),
Rarity = json.GetProperty("rarity").GetEnum<Rarity>(),
VendorValue = json.GetProperty("vendor_value").GetInt32(),
GameTypes =
json.GetProperty("game_types").GetList(static value => value.GetEnum<GameType>()),
Flags = ItemFlagsJsonConverter.Read(json.GetProperty("flags")),
Restrictions = ItemRestrictionJsonConverter.Read(json.GetProperty("restrictions")),
ChatLink = json.GetProperty("chat_link").GetStringRequired(),
IconHref = json.GetProperty("icon").GetString(),
DefaultSkinId = json.GetProperty("default_skin_id").GetInt32(),
WeightClass = json.GetProperty("weight_class").GetEnum<WeightClass>(),
Defense = json.GetProperty("defense").GetInt32(),
InfusionSlots = json.GetProperty("infusion_slots")
.GetList(InfusionSlotJsonConverter.Read),
AttributeAdjustment = json.GetProperty("attribute_adjustment").GetDouble(),
AttributeCombinationId =
json.GetProperty("attribute_combination_id").GetNullableInt32(),
Attributes =
json.GetProperty("attributes")
.GetMap(
static name => new Extensible<AttributeName>(name),
static value => value.GetInt32()
),
Buff = json.GetProperty("buff").GetNullable(BuffJsonConverter.Read),
SuffixItemId = json.GetProperty("suffix_item_id").GetNullableInt32(),
StatChoices = json.GetProperty("stat_choices").GetList(static value => value.GetInt32())
};
}

public static void Write(Utf8JsonWriter writer, Armor value)
{
switch (value)
{
case Boots boots:
BootsJsonConverter.Write(writer, boots);
break;
case Gloves gloves:
GlovesJsonConverter.Write(writer, gloves);
break;
case Coat coat:
CoatJsonConverter.Write(writer, coat);
break;
case Leggings leggings:
LeggingsJsonConverter.Write(writer, leggings);
break;
case Shoulders shoulders:
ShouldersJsonConverter.Write(writer, shoulders);
break;
case Helm helm:
HelmJsonConverter.Write(writer, helm);
break;
case HelmAquatic helmAquatic:
HelmAquaticJsonConverter.Write(writer, helmAquatic);
break;
default:
writer.WriteStartObject();
writer.WriteString(ItemJsonConverter.DiscriminatorName, DiscriminatorValue);
writer.WriteString(DiscriminatorName, DiscriminatorValue);
WriteCommonProperties(writer, value);
writer.WriteEndObject();
break;
}
}

public static void WriteCommonProperties(Utf8JsonWriter writer, Armor value)
{
ItemJsonConverter.WriteCommonProperties(writer, value);
writer.WriteNumber("default_skin_id", value.DefaultSkinId);
writer.WriteString("weight_class", value.WeightClass.ToString());
writer.WriteNumber("defense", value.Defense);
writer.WritePropertyName("infusion_slots");
writer.WriteStartArray();
foreach (var slot in value.InfusionSlots)
{
InfusionSlotJsonConverter.Write(writer, slot);
}

writer.WriteEndArray();
writer.WriteNumber("attribute_adjustment", value.AttributeAdjustment);
if (value.AttributeCombinationId.HasValue)
{
writer.WriteNumber("attribute_combination_id", value.AttributeCombinationId.Value);
}
else
{
writer.WriteNull("attribute_combination_id");
}

writer.WritePropertyName("attributes");
writer.WriteStartObject();
foreach (var attribute in value.Attributes)
{
writer.WriteNumber(attribute.Key.ToString(), attribute.Value);
}

writer.WriteEndObject();
if (value.Buff is not null)
{
writer.WritePropertyName("buff");
BuffJsonConverter.Write(writer, value.Buff);
}
else
{
writer.WriteNull("buff");
}

if (value.SuffixItemId.HasValue)
{
writer.WriteNumber("suffix_item_id", value.SuffixItemId.Value);
}
else
{
writer.WriteNull("suffix_item_id");
}

writer.WritePropertyName("stat_choices");
writer.WriteStartArray();
foreach (var statChoice in value.StatChoices)
{
writer.WriteNumberValue(statChoice);
}

writer.WriteEndArray();
}
}
5 changes: 4 additions & 1 deletion GW2SDK/Features/Items/Models/Armors/Boots.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
namespace GuildWars2.Items;
using System.Text.Json.Serialization;

namespace GuildWars2.Items;

/// <summary>Information about foot armor.</summary>
[PublicAPI]
[JsonConverter(typeof(BootsJsonConverter))]
public sealed record Boots : Armor;
72 changes: 72 additions & 0 deletions GW2SDK/Features/Items/Models/Armors/BootsJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using GuildWars2.Hero;
using GuildWars2.Json;

namespace GuildWars2.Items;

internal sealed class BootsJsonConverter : JsonConverter<Boots>
{
public const string DiscriminatorValue = "boots";

public override Boots Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var json = JsonDocument.ParseValue(ref reader);
return Read(json.RootElement);
}

public override void Write(Utf8JsonWriter writer, Boots value, JsonSerializerOptions options)
{
Write(writer, value);
}

public static Boots Read(JsonElement json)
{
if (!json.GetProperty(ItemJsonConverter.DiscriminatorName).ValueEquals(ArmorJsonConverter.DiscriminatorValue))
{
ThrowHelper.ThrowInvalidDiscriminator(json.GetProperty(ItemJsonConverter.DiscriminatorName).GetString());
}

if (!json.GetProperty(ArmorJsonConverter.DiscriminatorName).ValueEquals(DiscriminatorValue))
{
ThrowHelper.ThrowInvalidDiscriminator(json.GetProperty(ArmorJsonConverter.DiscriminatorName).GetString());
}

return new Boots
{
Id = json.GetProperty("id").GetInt32(),
Name = json.GetProperty("name").GetStringRequired(),
Description = json.GetProperty("description").GetStringRequired(),
Level = json.GetProperty("level").GetInt32(),
Rarity = json.GetProperty("rarity").GetEnum<Rarity>(),
VendorValue = json.GetProperty("vendor_value").GetInt32(),
GameTypes = json.GetProperty("game_types").GetList(static value => value.GetEnum<GameType>()),
Flags = ItemFlagsJsonConverter.Read(json.GetProperty("flags")),
Restrictions = ItemRestrictionJsonConverter.Read(json.GetProperty("restrictions")),
ChatLink = json.GetProperty("chat_link").GetStringRequired(),
IconHref = json.GetProperty("icon").GetString(),
DefaultSkinId = json.GetProperty("default_skin_id").GetInt32(),
WeightClass = json.GetProperty("weight_class").GetEnum<WeightClass>(),
Defense = json.GetProperty("defense").GetInt32(),
InfusionSlots = json.GetProperty("infusion_slots").GetList(InfusionSlotJsonConverter.Read),
AttributeAdjustment = json.GetProperty("attribute_adjustment").GetDouble(),
AttributeCombinationId = json.GetProperty("attribute_combination_id").GetNullableInt32(),
Attributes = json.GetProperty("attributes").GetMap(
static name => new Extensible<AttributeName>(name),
static value => value.GetInt32()
),
Buff = json.GetProperty("buff").GetNullable(BuffJsonConverter.Read),
SuffixItemId = json.GetProperty("suffix_item_id").GetNullableInt32(),
StatChoices = json.GetProperty("stat_choices").GetList(static value => value.GetInt32())
};
}

public static void Write(Utf8JsonWriter writer, Boots value)
{
writer.WriteStartObject();
writer.WriteString(ItemJsonConverter.DiscriminatorName, ArmorJsonConverter.DiscriminatorValue);
writer.WriteString(ArmorJsonConverter.DiscriminatorName, DiscriminatorValue);
ArmorJsonConverter.WriteCommonProperties(writer, value);
writer.WriteEndObject();
}
}
5 changes: 4 additions & 1 deletion GW2SDK/Features/Items/Models/Armors/Coat.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
namespace GuildWars2.Items;
using System.Text.Json.Serialization;

namespace GuildWars2.Items;

/// <summary>Information about chest armor.</summary>
[PublicAPI]
[JsonConverter(typeof(CoatJsonConverter))]
public sealed record Coat : Armor;
73 changes: 73 additions & 0 deletions GW2SDK/Features/Items/Models/Armors/CoatJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

using System.Text.Json;
using System.Text.Json.Serialization;
using GuildWars2.Hero;
using GuildWars2.Json;

namespace GuildWars2.Items;

internal sealed class CoatJsonConverter : JsonConverter<Coat>
{
public const string DiscriminatorValue = "coat";

public override Coat Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var json = JsonDocument.ParseValue(ref reader);
return Read(json.RootElement);
}

public override void Write(Utf8JsonWriter writer, Coat value, JsonSerializerOptions options)
{
Write(writer, value);
}

public static Coat Read(JsonElement json)
{
if (!json.GetProperty(ItemJsonConverter.DiscriminatorName).ValueEquals(ArmorJsonConverter.DiscriminatorValue))
{
ThrowHelper.ThrowInvalidDiscriminator(json.GetProperty(ItemJsonConverter.DiscriminatorName).GetString());
}

if (!json.GetProperty(ArmorJsonConverter.DiscriminatorName).ValueEquals(DiscriminatorValue))
{
ThrowHelper.ThrowInvalidDiscriminator(json.GetProperty(ArmorJsonConverter.DiscriminatorName).GetString());
}

return new Coat
{
Id = json.GetProperty("id").GetInt32(),
Name = json.GetProperty("name").GetStringRequired(),
Description = json.GetProperty("description").GetStringRequired(),
Level = json.GetProperty("level").GetInt32(),
Rarity = json.GetProperty("rarity").GetEnum<Rarity>(),
VendorValue = json.GetProperty("vendor_value").GetInt32(),
GameTypes = json.GetProperty("game_types").GetList(static value => value.GetEnum<GameType>()),
Flags = ItemFlagsJsonConverter.Read(json.GetProperty("flags")),
Restrictions = ItemRestrictionJsonConverter.Read(json.GetProperty("restrictions")),
ChatLink = json.GetProperty("chat_link").GetStringRequired(),
IconHref = json.GetProperty("icon").GetString(),
DefaultSkinId = json.GetProperty("default_skin_id").GetInt32(),
WeightClass = json.GetProperty("weight_class").GetEnum<WeightClass>(),
Defense = json.GetProperty("defense").GetInt32(),
InfusionSlots = json.GetProperty("infusion_slots").GetList(InfusionSlotJsonConverter.Read),
AttributeAdjustment = json.GetProperty("attribute_adjustment").GetDouble(),
AttributeCombinationId = json.GetProperty("attribute_combination_id").GetNullableInt32(),
Attributes = json.GetProperty("attributes").GetMap(
static name => new Extensible<AttributeName>(name),
static value => value.GetInt32()
),
Buff = json.GetProperty("buff").GetNullable(BuffJsonConverter.Read),
SuffixItemId = json.GetProperty("suffix_item_id").GetNullableInt32(),
StatChoices = json.GetProperty("stat_choices").GetList(static value => value.GetInt32())
};
}

public static void Write(Utf8JsonWriter writer, Coat value)
{
writer.WriteStartObject();
writer.WriteString(ItemJsonConverter.DiscriminatorName, ArmorJsonConverter.DiscriminatorValue);
writer.WriteString(ArmorJsonConverter.DiscriminatorName, DiscriminatorValue);
ArmorJsonConverter.WriteCommonProperties(writer, value);
writer.WriteEndObject();
}
}
5 changes: 4 additions & 1 deletion GW2SDK/Features/Items/Models/Armors/Gloves.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
namespace GuildWars2.Items;
using System.Text.Json.Serialization;

namespace GuildWars2.Items;

/// <summary>Information about hand armor.</summary>
[PublicAPI]
[JsonConverter(typeof(GlovesJsonConverter))]
public sealed record Gloves : Armor;
Loading

0 comments on commit d8d9649

Please sign in to comment.