Fixes JSON WorldConverter (#263)

- [X] Adds Map index support for JSON MapConverter
- [X] Files JSON WorldConverter
- [X] Removes LINQ for Map.Parse

Bumps release version
This commit is contained in:
Kamron Batman 2020-09-20 14:56:46 -07:00 committed by GitHub
parent 13e2693b59
commit 93cf40ec81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 54 deletions

View file

@ -6869,4 +6869,4 @@
"dst": { "map": "TerMur", "loc": [511, 585, 9] }, "dst": { "map": "TerMur", "loc": [511, 585, 9] },
"back": false "back": false
} }
] ]

View file

@ -104,12 +104,7 @@ namespace Server
public int CompareTo(WorldLocation other) public int CompareTo(WorldLocation other)
{ {
var locComparison = m_Loc.CompareTo(other.m_Loc); var locComparison = m_Loc.CompareTo(other.m_Loc);
if (locComparison != 0) return locComparison != 0 ? locComparison : Comparer<Map>.Default.Compare(m_Map, other.m_Map);
{
return locComparison;
}
return Comparer<Map>.Default.Compare(m_Map, other.m_Map);
} }
public static implicit operator Point3D(WorldLocation worldLocation) => worldLocation.Location; public static implicit operator Point3D(WorldLocation worldLocation) => worldLocation.Location;

View file

@ -21,10 +21,15 @@ namespace Server.Json
{ {
public class MapConverter : JsonConverter<Map> public class MapConverter : JsonConverter<Map>
{ {
public override Map Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) public override Map Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
=> Map.Parse(reader.GetString()); reader.TokenType switch
{
JsonTokenType.String => Map.Parse(reader.GetString()),
JsonTokenType.Number => Map.Maps[reader.GetInt32()],
_ => throw new JsonException($"Value must be a number or string")
};
public override void Write(Utf8JsonWriter writer, Map value, JsonSerializerOptions options) public override void Write(Utf8JsonWriter writer, Map value, JsonSerializerOptions options) =>
=> writer.WriteStringValue(value.Name); writer.WriteStringValue(value.Name);
} }
} }

View file

@ -21,6 +21,9 @@ namespace Server.Json
{ {
public class WorldLocationConverter : JsonConverter<WorldLocation> public class WorldLocationConverter : JsonConverter<WorldLocation>
{ {
private static Point3DConverter _point3DConverter;
private static MapConverter _mapConverter;
private WorldLocation DeserializeArray(ref Utf8JsonReader reader) private WorldLocation DeserializeArray(ref Utf8JsonReader reader)
{ {
Span<int> data = stackalloc int[3]; Span<int> data = stackalloc int[3];
@ -45,6 +48,7 @@ namespace Server.Json
else if (count == 3) else if (count == 3)
{ {
map = Map.Maps[reader.GetInt32()]; map = Map.Maps[reader.GetInt32()];
hasMap = true;
} }
count++; count++;
@ -52,12 +56,20 @@ namespace Server.Json
if (reader.TokenType == JsonTokenType.String) if (reader.TokenType == JsonTokenType.String)
{ {
map = Map.Parse(reader.GetString()); var key = reader.GetString();
if (count != 3 || hasMap)
{
throw new JsonException($"Value {key} is not valid for this element.");
}
map = Map.Parse(key);
hasMap = true;
break; break;
} }
} }
if (!hasMap || count < 3 || count > 4) if (!hasMap || count != 3)
{ {
throw new JsonException("WorldLocation must be an array of x, y, z, and map"); throw new JsonException("WorldLocation must be an array of x, y, z, and map");
} }
@ -131,7 +143,10 @@ namespace Server.Json
} }
hasLoc = true; hasLoc = true;
var loc = new Point3DConverter().Read(ref reader, typeof(Point3D), options);
_point3DConverter ??= new Point3DConverter();
var loc = _point3DConverter.Read(ref reader, typeof(Point3D), options);
data[0] = loc.X; data[0] = loc.X;
data[1] = loc.Y; data[1] = loc.Y;
data[2] = loc.Z; data[2] = loc.Z;
@ -139,15 +154,13 @@ namespace Server.Json
continue; continue;
} }
map = reader.TokenType switch _mapConverter ??= new MapConverter();
{ map = _mapConverter.Read(ref reader, typeof(Map), options);
JsonTokenType.String => Map.Parse(reader.GetString()),
JsonTokenType.Number => Map.Maps[reader.GetInt32()], hasMap = true;
_ => throw new JsonException($"Value for {key} must be a number or string")
};
} }
if (!hasMap || count < 2) if (!hasMap || count != 3)
{ {
throw new JsonException("WorldLocation must have an x, y, z, and map properties"); throw new JsonException("WorldLocation must have an x, y, z, and map properties");
} }

View file

@ -30,10 +30,10 @@ namespace Server.Json
// In the future this should be optimized by cloning DefaultOptions // In the future this should be optimized by cloning DefaultOptions
var options = new JsonSerializerOptions var options = new JsonSerializerOptions
{ {
ReadCommentHandling = JsonCommentHandling.Skip,
WriteIndented = true, WriteIndented = true,
AllowTrailingCommas = true, AllowTrailingCommas = true,
IgnoreNullValues = true IgnoreNullValues = true,
ReadCommentHandling = JsonCommentHandling.Skip
}; };
options.Converters.Add(new MapConverterFactory()); options.Converters.Add(new MapConverterFactory());
@ -43,6 +43,7 @@ namespace Server.Json
options.Converters.Add(new IPEndPointConverterFactory()); options.Converters.Add(new IPEndPointConverterFactory());
options.Converters.Add(new NullableStructSerializerFactory()); options.Converters.Add(new NullableStructSerializerFactory());
options.Converters.Add(new TypeConverterFactory()); options.Converters.Add(new TypeConverterFactory());
options.Converters.Add(new WorldLocationConverterFactory());
for (var i = 0; i < converters.Length; i++) for (var i = 0; i < converters.Length; i++)
{ {

View file

@ -404,10 +404,28 @@ namespace Server
if (!int.TryParse(value, out var index)) if (!int.TryParse(value, out var index))
{ {
return Maps.FirstOrDefault(m => m != null && Insensitive.Equals(m.Name, value)); index = -1;
}
else if (index == 127)
{
return Internal;
} }
return index == 127 ? Internal : Maps.FirstOrDefault(m => m?.MapIndex == index); for (int i = 0; i < Maps.Length; i++)
{
var map = Maps[i];
if (map == null)
{
continue;
}
if (index >= 0 && map.MapIndex == index || Insensitive.Equals(map.Name, value))
{
return map;
}
}
return null;
} }
public override string ToString() => Name; public override string ToString() => Name;

View file

@ -1,20 +1,22 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Server.Items; using Server.Items;
using Server.Json;
namespace Server.Commands namespace Server.Commands
{ {
public struct TeleporterDefinition public struct TeleporterDefinition
{ {
[JsonPropertyName("src")] public WorldLocation Source { get; set; } [JsonPropertyName("src")]
public WorldLocation Source { get; set; }
[JsonPropertyName("dst")] public WorldLocation Destination { get; set; } [JsonPropertyName("dst")]
public WorldLocation Destination { get; set; }
[JsonPropertyName("back")] public bool Back { get; set; } [JsonPropertyName("back")]
public bool Back { get; set; }
public override string ToString() => $"{{{Source},{Destination},{Back}}}"; public override string ToString() => $"{{{Source},{Destination},{Back}}}";
@ -29,14 +31,7 @@ namespace Server.Commands
public static class GenTeleporter public static class GenTeleporter
{ {
private const int SuccessHue = 72, WarningHue = 53, ErrorHue = 33; private const int SuccessHue = 72, WarningHue = 53, ErrorHue = 33;
private static readonly string TeleporterJsonDataPath = Path.Combine("Data", "teleporters.json"); private static readonly string TeleporterJsonDataPath = Path.Combine(Core.BaseDirectory, "Data/teleporters.json");
private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true,
ReadCommentHandling = JsonCommentHandling.Skip
};
public static void Initialize() public static void Initialize()
{ {
@ -108,17 +103,7 @@ namespace Server.Commands
{ {
try try
{ {
string json; JsonConfig.Deserialize<List<TeleporterDefinition>>(TeleporterJsonDataPath).ForEach(processor);
using (var reader = new StreamReader(TeleporterJsonDataPath))
{
json = reader.ReadToEnd();
}
var teleporters = JsonSerializer.Deserialize<List<TeleporterDefinition>>(json, JsonOptions);
for (var i = 0; i < teleporters.Count; i++)
{
processor(teleporters[i]);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -140,13 +125,15 @@ namespace Server.Commands
public static int DeleteTeleporters(WorldLocation worldLocation) public static int DeleteTeleporters(WorldLocation worldLocation)
{ {
var eable = worldLocation.Map.GetItemsInRange<Teleporter>(worldLocation, 0); var eable = worldLocation.Map.GetItemsInRange<Teleporter>(worldLocation, 0);
var items = eable
.Where(x => !(x is KeywordTeleporter || x is SkillTeleporter) && IsWithinZ(x.Z - worldLocation.Z));
var count = 0; var count = 0;
foreach (var item in items) foreach (var item in eable)
{ {
count++; if (!(item is KeywordTeleporter || item is SkillTeleporter) && IsWithinZ(item.Z - worldLocation.Z))
item.Delete(); {
count++;
item.Delete();
}
} }
eable.Free(); eable.Free();