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] },
"back": false
}
]
]

View file

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

View file

@ -21,10 +21,15 @@ namespace Server.Json
{
public class MapConverter : JsonConverter<Map>
{
public override Map Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> Map.Parse(reader.GetString());
public override Map Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
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)
=> writer.WriteStringValue(value.Name);
public override void Write(Utf8JsonWriter writer, Map value, JsonSerializerOptions options) =>
writer.WriteStringValue(value.Name);
}
}

View file

@ -21,6 +21,9 @@ namespace Server.Json
{
public class WorldLocationConverter : JsonConverter<WorldLocation>
{
private static Point3DConverter _point3DConverter;
private static MapConverter _mapConverter;
private WorldLocation DeserializeArray(ref Utf8JsonReader reader)
{
Span<int> data = stackalloc int[3];
@ -45,6 +48,7 @@ namespace Server.Json
else if (count == 3)
{
map = Map.Maps[reader.GetInt32()];
hasMap = true;
}
count++;
@ -52,12 +56,20 @@ namespace Server.Json
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;
}
}
if (!hasMap || count < 3 || count > 4)
if (!hasMap || count != 3)
{
throw new JsonException("WorldLocation must be an array of x, y, z, and map");
}
@ -131,7 +143,10 @@ namespace Server.Json
}
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[1] = loc.Y;
data[2] = loc.Z;
@ -139,15 +154,13 @@ namespace Server.Json
continue;
}
map = reader.TokenType switch
{
JsonTokenType.String => Map.Parse(reader.GetString()),
JsonTokenType.Number => Map.Maps[reader.GetInt32()],
_ => throw new JsonException($"Value for {key} must be a number or string")
};
_mapConverter ??= new MapConverter();
map = _mapConverter.Read(ref reader, typeof(Map), options);
hasMap = true;
}
if (!hasMap || count < 2)
if (!hasMap || count != 3)
{
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
var options = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
WriteIndented = true,
AllowTrailingCommas = true,
IgnoreNullValues = true
IgnoreNullValues = true,
ReadCommentHandling = JsonCommentHandling.Skip
};
options.Converters.Add(new MapConverterFactory());
@ -43,6 +43,7 @@ namespace Server.Json
options.Converters.Add(new IPEndPointConverterFactory());
options.Converters.Add(new NullableStructSerializerFactory());
options.Converters.Add(new TypeConverterFactory());
options.Converters.Add(new WorldLocationConverterFactory());
for (var i = 0; i < converters.Length; i++)
{

View file

@ -404,10 +404,28 @@ namespace Server
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;

View file

@ -1,20 +1,22 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Server.Items;
using Server.Json;
namespace Server.Commands
{
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}}}";
@ -29,14 +31,7 @@ namespace Server.Commands
public static class GenTeleporter
{
private const int SuccessHue = 72, WarningHue = 53, ErrorHue = 33;
private static readonly string TeleporterJsonDataPath = Path.Combine("Data", "teleporters.json");
private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true,
ReadCommentHandling = JsonCommentHandling.Skip
};
private static readonly string TeleporterJsonDataPath = Path.Combine(Core.BaseDirectory, "Data/teleporters.json");
public static void Initialize()
{
@ -108,17 +103,7 @@ namespace Server.Commands
{
try
{
string json;
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]);
}
JsonConfig.Deserialize<List<TeleporterDefinition>>(TeleporterJsonDataPath).ForEach(processor);
}
catch (Exception ex)
{
@ -140,13 +125,15 @@ namespace Server.Commands
public static int DeleteTeleporters(WorldLocation worldLocation)
{
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;
foreach (var item in items)
foreach (var item in eable)
{
count++;
item.Delete();
if (!(item is KeywordTeleporter || item is SkillTeleporter) && IsWithinZ(item.Z - worldLocation.Z))
{
count++;
item.Delete();
}
}
eable.Free();