Convert Regions/Spawns to JSON (#138)
This commit is contained in:
parent
b8316e9202
commit
390f30e706
117 changed files with 97306 additions and 4848 deletions
|
|
@ -58,7 +58,8 @@ namespace Server
|
|||
|
||||
public static TypeCache GetTypeCache(Assembly asm)
|
||||
{
|
||||
if (asm == null) return m_NullCache ??= new TypeCache(null);
|
||||
if (asm == null)
|
||||
return m_NullCache ??= new TypeCache(null);
|
||||
|
||||
if (m_TypeCaches.TryGetValue(asm, out var c))
|
||||
return c;
|
||||
|
|
@ -68,6 +69,8 @@ namespace Server
|
|||
|
||||
public static Type FindFirstTypeForName(string name, bool ignoreCase = false, Func<Type, bool> predicate = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name)) return null;
|
||||
|
||||
var types = FindTypesByName(name, ignoreCase).ToList();
|
||||
if (types.Count == 0)
|
||||
return null;
|
||||
|
|
@ -87,14 +90,19 @@ namespace Server
|
|||
types[0];
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindTypesByName(string name, bool ignoreCase = false)
|
||||
public static List<Type> FindTypesByName(string name, bool ignoreCase = false)
|
||||
{
|
||||
var types = new List<Type>();
|
||||
|
||||
if (ignoreCase)
|
||||
name = name.ToLower();
|
||||
for (var i = 0; i < Assemblies.Length; i++) types.AddRange(GetTypeCache(Assemblies[i])[name]);
|
||||
|
||||
for (var i = 0; i < Assemblies.Length; i++)
|
||||
types.AddRange(GetTypeCache(Assemblies[i])[name]);
|
||||
|
||||
if (types.Count == 0)
|
||||
types.AddRange(GetTypeCache(Core.Assembly)[name]);
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
|
|
@ -122,6 +130,7 @@ namespace Server
|
|||
public TypeCache(Assembly asm)
|
||||
{
|
||||
m_Types = asm?.GetTypes() ?? Type.EmptyTypes;
|
||||
|
||||
var nameMap = new Dictionary<string, HashSet<int>>();
|
||||
HashSet<int> refs;
|
||||
Action<int, string> addToRefs = (index, key) =>
|
||||
|
|
@ -136,6 +145,7 @@ namespace Server
|
|||
nameMap.Add(key, refs);
|
||||
}
|
||||
};
|
||||
|
||||
var aliasType = typeof(TypeAliasAttribute);
|
||||
for (var i = 0; i < m_Types.Length; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Buffers
|
||||
|
|
|
|||
|
|
@ -71,14 +71,18 @@ namespace Server
|
|||
void OnStatsQuery(Mobile beholder, Mobile beheld);
|
||||
}
|
||||
|
||||
public interface ISpawner
|
||||
// TODO: Add SpawnMap and change Spawner.Map to use it
|
||||
public interface ISpawner : IEntity
|
||||
{
|
||||
bool UnlinkOnTaming { get; }
|
||||
Point3D HomeLocation { get; }
|
||||
int HomeRange { get; }
|
||||
Region Region { get; }
|
||||
bool ReturnOnDeactivate { get; }
|
||||
|
||||
void Remove(ISpawnable spawn);
|
||||
Point3D GetSpawnPosition(ISpawnable spawned, Map map);
|
||||
void Respawn();
|
||||
}
|
||||
|
||||
public interface ISpawnable : IEntity
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: MapConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class MapConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Map);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new MapConverter();
|
||||
}
|
||||
}
|
||||
105
Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs
Normal file
105
Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point2DConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point2DConverter : JsonConverter<Point2D>
|
||||
{
|
||||
private Point2D DeserializeArray(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[2];
|
||||
var count = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndArray)
|
||||
break;
|
||||
|
||||
if (reader.TokenType == JsonTokenType.Number)
|
||||
{
|
||||
if (count < 2)
|
||||
data[count] = reader.GetInt32();
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 2)
|
||||
throw new JsonException("Point2D must be an array of x, y");
|
||||
|
||||
return new Point2D(data[0], data[1]);
|
||||
}
|
||||
|
||||
private Point2D DeserializeObj(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[2];
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
break;
|
||||
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
throw new JsonException("Invalid Json structure for Point2D object");
|
||||
|
||||
var key = reader.GetString();
|
||||
|
||||
var i = key switch
|
||||
{
|
||||
"x" => 0,
|
||||
"y" => 1,
|
||||
_ => throw new JsonException($"Invalid property {key} for Point2D")
|
||||
};
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (reader.TokenType != JsonTokenType.Number)
|
||||
throw new JsonException($"Value for {key} must be a number");
|
||||
|
||||
data[i] = reader.GetInt32();
|
||||
}
|
||||
|
||||
return new Point2D(data[0], data[1]);
|
||||
}
|
||||
|
||||
public override Point2D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
|
||||
reader.TokenType switch
|
||||
{
|
||||
JsonTokenType.StartArray => DeserializeArray(ref reader),
|
||||
JsonTokenType.StartObject => DeserializeObj(ref reader),
|
||||
_ => throw new JsonException("Invalid Json for Point3D")
|
||||
};
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Point2D value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
writer.WriteNumberValue(value.X);
|
||||
writer.WriteNumberValue(value.Y);
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point2DConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point2DConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Point2D) || typeToConvert == typeof(IPoint2D);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new Point2DConverter();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point3dConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/02 *
|
||||
* File: Point3DConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
|
|
@ -25,14 +25,11 @@ using System.Text.Json.Serialization;
|
|||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point3dConverter : JsonConverter<Point3D>
|
||||
public class Point3DConverter : JsonConverter<Point3D>
|
||||
{
|
||||
public override Point3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
private Point3D DeserializeArray(ref Utf8JsonReader reader)
|
||||
{
|
||||
if (reader.TokenType != JsonTokenType.StartArray)
|
||||
throw new JsonException("Point3d must be an array of x, y, z");
|
||||
|
||||
var data = new int[3];
|
||||
Span<int> data = stackalloc int[3];
|
||||
var count = 0;
|
||||
|
||||
while (true)
|
||||
|
|
@ -50,12 +47,54 @@ namespace Server.Json
|
|||
}
|
||||
}
|
||||
|
||||
if (count < 2 || count > 3)
|
||||
throw new JsonException("Point3d must be an array of x, y, z");
|
||||
if (count > 3)
|
||||
throw new JsonException("Point3D must be an array of x, y, z");
|
||||
|
||||
return new Point3D(data[0], data[1], data[2]);
|
||||
}
|
||||
|
||||
private Point3D DeserializeObj(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[3];
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
break;
|
||||
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
throw new JsonException("Invalid Json structure for Point3D object");
|
||||
|
||||
var key = reader.GetString();
|
||||
|
||||
var i = key switch
|
||||
{
|
||||
"x" => 0,
|
||||
"y" => 1,
|
||||
"z" => 2,
|
||||
_ => throw new JsonException($"Invalid property {key} for Point3D")
|
||||
};
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (reader.TokenType != JsonTokenType.Number)
|
||||
throw new JsonException($"Value for {key} must be a number");
|
||||
|
||||
data[i] = reader.GetInt32();
|
||||
}
|
||||
|
||||
return new Point3D(data[0], data[1], data[2]);
|
||||
}
|
||||
|
||||
public override Point3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
|
||||
reader.TokenType switch
|
||||
{
|
||||
JsonTokenType.StartArray => DeserializeArray(ref reader),
|
||||
JsonTokenType.StartObject => DeserializeObj(ref reader),
|
||||
_ => throw new JsonException("Invalid Json for Point3D")
|
||||
};
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Point3D value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point3DConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point3DConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Point3D) || typeToConvert == typeof(IPoint3D);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new Point3DConverter();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Rectangle3DConverter.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Rectangle3DConverter : JsonConverter<Rectangle3D>
|
||||
{
|
||||
private Rectangle3D DeserializeArray(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[6];
|
||||
var count = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndArray)
|
||||
break;
|
||||
|
||||
if (reader.TokenType == JsonTokenType.Number)
|
||||
{
|
||||
if (count < 6)
|
||||
data[count] = reader.GetInt32();
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 6)
|
||||
throw new JsonException("Rectangle3D must be an array of x, y, z, h, w, d");
|
||||
|
||||
return new Rectangle3D(data[0], data[1], data[2], data[3], data[4], data[5]);
|
||||
}
|
||||
|
||||
private Rectangle3D DeserializeObj(ref Utf8JsonReader reader, JsonSerializerOptions options)
|
||||
{
|
||||
Span<int> data = stackalloc int[6];
|
||||
|
||||
// 0 - xyzwhd, 1 - x1y1z1x2y2z2, 2 - start/end
|
||||
int objType = -1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
break;
|
||||
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
throw new JsonException("Invalid Json structure for Rectangle3D object");
|
||||
|
||||
var key = reader.GetString();
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (key == "start" || key == "end")
|
||||
{
|
||||
if (objType > -1 && objType != 2)
|
||||
throw new JsonException("Rectangle3D must have a start/end, or x/y/z/w/h/d, but not both.");
|
||||
|
||||
objType = 2;
|
||||
|
||||
var point3D = reader.ToObject<Point3D>(options);
|
||||
var offset = key == "end" ? 3 : 0;
|
||||
data[0 + offset] = point3D.X;
|
||||
data[1 + offset] = point3D.Y;
|
||||
data[1 + offset] = point3D.Z;
|
||||
continue;
|
||||
}
|
||||
|
||||
var i = key switch
|
||||
{
|
||||
"x" => 0,
|
||||
"y" => 1,
|
||||
"z" => 2,
|
||||
"w" => 3,
|
||||
"width" => 3,
|
||||
"h" => 4,
|
||||
"height" => 4,
|
||||
"d" => 5,
|
||||
"depth" => 5,
|
||||
"x1" => 10,
|
||||
"y1" => 11,
|
||||
"z1" => 12,
|
||||
"x2" => 13,
|
||||
"y2" => 14,
|
||||
"z2" => 15,
|
||||
_ => throw new JsonException($"Invalid property {key} for Rectangle3D")
|
||||
};
|
||||
|
||||
if (i < 10)
|
||||
{
|
||||
if (objType > -1 && objType != 0)
|
||||
throw new JsonException("Rectangle3D must have a start/end, or x/y/z/w/h/d, but not both.");
|
||||
|
||||
objType = 0;
|
||||
data[i] = reader.GetInt32();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (objType > -1 && objType != 1)
|
||||
throw new JsonException("Rectangle3D must have a start/end, or x/y/z/w/h/d, but not both.");
|
||||
|
||||
objType = 1;
|
||||
data[i - 10] = reader.GetInt32();
|
||||
}
|
||||
|
||||
return objType == 0
|
||||
? new Rectangle3D(data[0], data[1], data[2], data[3], data[4], data[5])
|
||||
: new Rectangle3D(
|
||||
new Point3D(data[0], data[1], data[2]),
|
||||
new Point3D(data[3], data[4], data[5])
|
||||
);
|
||||
}
|
||||
|
||||
public override Rectangle3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
|
||||
reader.TokenType switch
|
||||
{
|
||||
JsonTokenType.StartArray => DeserializeArray(ref reader),
|
||||
JsonTokenType.StartObject => DeserializeObj(ref reader, options),
|
||||
_ => throw new JsonException("Invalid Json for Point3D")
|
||||
};
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Rectangle3D value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
writer.WriteNumberValue(value.Start.X);
|
||||
writer.WriteNumberValue(value.Start.Y);
|
||||
writer.WriteNumberValue(value.Start.Z);
|
||||
writer.WriteNumberValue(value.Width);
|
||||
writer.WriteNumberValue(value.Height);
|
||||
writer.WriteNumberValue(value.Depth);
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Rectangle3DConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Rectangle3DConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Rectangle3D);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) =>
|
||||
new Rectangle3DConverter();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: TimeSpanConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/02 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class TimeSpanConverter : JsonConverter<TimeSpan>
|
||||
{
|
||||
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
=> TimeSpan.Parse(reader.GetString());
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
|
||||
=> writer.WriteStringValue(value.ToString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: TimeSpanConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class TimeSpanConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(TimeSpan);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new TimeSpanConverter();
|
||||
}
|
||||
}
|
||||
57
Projects/Server/JsonConfiguration/DynamicJson.cs
Normal file
57
Projects/Server/JsonConfiguration/DynamicJson.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: DynamicJson.cs - Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class DynamicJson
|
||||
{
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, JsonElement> data { get; set; }
|
||||
|
||||
public bool GetProperty<T>(string key, JsonSerializerOptions options, out T t)
|
||||
{
|
||||
if (data.TryGetValue(key, out var el))
|
||||
{
|
||||
t = el.ToObject<T>(options);
|
||||
return true;
|
||||
}
|
||||
|
||||
t = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetEnumProperty<T>(string key, JsonSerializerOptions options, out T t) where T : struct, Enum
|
||||
{
|
||||
if (data.TryGetValue(key, out var el))
|
||||
return Enum.TryParse(el.ToObject<string>(options), out t);
|
||||
|
||||
t = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
|
|
@ -46,5 +48,23 @@ namespace Server.Json
|
|||
|
||||
File.WriteAllText(filePath, JsonSerializer.Serialize(value, options ?? Options));
|
||||
}
|
||||
|
||||
public static T ToObject<T>(this ref Utf8JsonReader reader, JsonSerializerOptions options = null) =>
|
||||
JsonSerializer.Deserialize<T>(ref reader, options);
|
||||
|
||||
public static T ToObject<T>(this JsonElement element, JsonSerializerOptions options = null)
|
||||
{
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
using (var writer = new Utf8JsonWriter(bufferWriter))
|
||||
element.WriteTo(writer);
|
||||
return JsonSerializer.Deserialize<T>(bufferWriter.WrittenSpan, options);
|
||||
}
|
||||
|
||||
public static T ToObject<T>(this JsonDocument document, JsonSerializerOptions options = null)
|
||||
{
|
||||
if (document == null)
|
||||
throw new ArgumentNullException(nameof(document));
|
||||
return document.RootElement.ToObject<T>(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ namespace Server
|
|||
|
||||
AssemblyHandler.Invoke("Configure");
|
||||
|
||||
Region.Load();
|
||||
RegionLoader.LoadRegions();
|
||||
World.Load();
|
||||
|
||||
AssemblyHandler.Invoke("Initialize");
|
||||
|
|
|
|||
|
|
@ -374,15 +374,9 @@ namespace Server
|
|||
|
||||
public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID);
|
||||
|
||||
public static string[] GetMapNames()
|
||||
{
|
||||
return Maps.Where(m => m != null).Select(m => m.Name).ToArray();
|
||||
}
|
||||
public static string[] GetMapNames() => Maps.Where(m => m != null).Select(m => m.Name).ToArray();
|
||||
|
||||
public static Map[] GetMapValues()
|
||||
{
|
||||
return Maps.Where(m => m != null).ToArray();
|
||||
}
|
||||
public static Map[] GetMapValues() => Maps.Where(m => m != null).ToArray();
|
||||
|
||||
public static Map Parse(string value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
|
|
@ -146,10 +145,10 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
public Region(XmlElement xml, Map map, Region parent)
|
||||
public Region(DynamicJson json, JsonSerializerOptions options)
|
||||
{
|
||||
Map = map;
|
||||
Parent = parent;
|
||||
Map = json.GetProperty("map", options, out Map map) ? map : null;
|
||||
Parent = json.GetProperty("parent", options, out string parent) ? Find(parent, Map) : null;
|
||||
Dynamic = false;
|
||||
|
||||
if (Parent == null)
|
||||
|
|
@ -163,31 +162,21 @@ namespace Server
|
|||
m_Priority = Parent.Priority;
|
||||
}
|
||||
|
||||
ReadString(xml, "name", ref m_Name, false);
|
||||
m_Name = json.GetProperty("name", options, out string name) ? name : null;
|
||||
|
||||
if (parent == null)
|
||||
ReadInt32(xml, "priority", ref m_Priority, false);
|
||||
m_Priority = json.GetProperty("priority", options, out int priority) ? priority : 0;
|
||||
|
||||
var minZ = MinZ;
|
||||
var maxZ = MaxZ;
|
||||
|
||||
var zrange = xml["zrange"];
|
||||
ReadInt32(zrange, "min", ref minZ, false);
|
||||
ReadInt32(zrange, "max", ref maxZ, false);
|
||||
|
||||
var area = new List<Rectangle3D>();
|
||||
foreach (XmlElement xmlRect in xml.SelectNodes("rect"))
|
||||
{
|
||||
if (ReadRectangle3D(xmlRect, minZ, maxZ, out var rect))
|
||||
area.Add(rect);
|
||||
}
|
||||
|
||||
Area = area.ToArray();
|
||||
Area = json.GetProperty("rects", options, out List<Rectangle3D> rects) ?
|
||||
rects.ToArray() : Array.Empty<Rectangle3D>();
|
||||
|
||||
if (Area.Length == 0)
|
||||
Console.WriteLine("Empty area for region '{0}'", this);
|
||||
|
||||
if (!ReadPoint3D(xml["go"], map, ref m_GoLocation, false) && Area.Length > 0)
|
||||
if (json.GetProperty("go", options, out Point3D go))
|
||||
{
|
||||
m_GoLocation = go;
|
||||
}
|
||||
else if (Area.Length > 0)
|
||||
{
|
||||
var start = Area[0].Start;
|
||||
var end = Area[0].End;
|
||||
|
|
@ -195,14 +184,10 @@ namespace Server
|
|||
var x = start.X + (end.X - start.X) / 2;
|
||||
var y = start.Y + (end.Y - start.Y) / 2;
|
||||
|
||||
m_GoLocation = new Point3D(x, y, Map.GetAverageZ(x, y));
|
||||
m_GoLocation = new Point3D(x, y, Map?.GetAverageZ(x, y) ?? start.Z + (end.Z - start.Z) / 2);
|
||||
}
|
||||
|
||||
var music = DefaultMusic;
|
||||
|
||||
ReadEnum(xml["music"], "name", ref music, false);
|
||||
|
||||
Music = music;
|
||||
Music = json.GetEnumProperty("music", options, out MusicName music) ? music : DefaultMusic;
|
||||
}
|
||||
|
||||
public static List<Region> Regions { get; } = new List<Region>();
|
||||
|
|
@ -267,6 +252,29 @@ namespace Server
|
|||
return reg.ChildLevel - ChildLevel;
|
||||
}
|
||||
|
||||
// This is not optimized. Use sparingly
|
||||
public static Region Find(string name, Map map, bool insensitive = false)
|
||||
{
|
||||
if (insensitive)
|
||||
name = name.ToLower();
|
||||
|
||||
for (int i = 0; i < Regions.Count; i++)
|
||||
{
|
||||
var region = Regions[i];
|
||||
if (region.Map != map)
|
||||
continue;
|
||||
|
||||
string rName = region.Name;
|
||||
if (insensitive)
|
||||
rName = rName.ToLower();
|
||||
|
||||
if (rName == name)
|
||||
return region;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Region Find(Point3D p, Map map)
|
||||
{
|
||||
if (map == null)
|
||||
|
|
@ -727,338 +735,5 @@ namespace Server
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Load()
|
||||
{
|
||||
if (!File.Exists("Data/Regions.xml"))
|
||||
{
|
||||
Console.WriteLine("Error: Data/Regions.xml does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.Write("Regions: Loading...");
|
||||
|
||||
var doc = new XmlDocument();
|
||||
doc.Load(Path.Combine(Core.BaseDirectory, "Data/Regions.xml"));
|
||||
|
||||
var root = doc["ServerRegions"];
|
||||
|
||||
if (root == null)
|
||||
{
|
||||
Console.WriteLine("Could not find root element 'ServerRegions' in Regions.xml");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (XmlElement facet in root.SelectNodes("Facet"))
|
||||
{
|
||||
Map map = null;
|
||||
if (ReadMap(facet, "name", ref map))
|
||||
{
|
||||
if (map == Map.Internal)
|
||||
Console.WriteLine("Invalid internal map in a facet element");
|
||||
else
|
||||
LoadRegions(facet, map, null);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("done");
|
||||
}
|
||||
|
||||
private static void LoadRegions(XmlElement xml, Map map, Region parent)
|
||||
{
|
||||
foreach (XmlElement xmlReg in xml.SelectNodes("region"))
|
||||
{
|
||||
var type = DefaultRegionType;
|
||||
|
||||
ReadType(xmlReg, "type", ref type, false);
|
||||
|
||||
if (!typeof(Region).IsAssignableFrom(type))
|
||||
{
|
||||
Console.WriteLine("Invalid region type '{0}' in regions.xml", type.FullName);
|
||||
continue;
|
||||
}
|
||||
|
||||
Region region;
|
||||
try
|
||||
{
|
||||
region = (Region)ActivatorUtil.CreateInstance(type, xmlReg, map, parent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error during the creation of region type '{0}': {1}", type.FullName, ex);
|
||||
continue;
|
||||
}
|
||||
|
||||
region.Register();
|
||||
|
||||
LoadRegions(xmlReg, map, region);
|
||||
}
|
||||
}
|
||||
|
||||
protected static string GetAttribute(XmlElement xml, string attribute, bool mandatory)
|
||||
{
|
||||
if (xml == null)
|
||||
{
|
||||
if (mandatory)
|
||||
Console.WriteLine("Missing element for attribute '{0}'", attribute);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (xml.HasAttribute(attribute)) return xml.GetAttribute(attribute);
|
||||
if (mandatory)
|
||||
Console.WriteLine("Missing attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool ReadString(XmlElement xml, string attribute, ref string value) =>
|
||||
ReadString(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadString(XmlElement xml, string attribute, ref string value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
value = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadInt32(XmlElement xml, string attribute, ref int value) =>
|
||||
ReadInt32(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadInt32(XmlElement xml, string attribute, ref int value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToInt32(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse integer attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadBoolean(XmlElement xml, string attribute, ref bool value) =>
|
||||
ReadBoolean(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadBoolean(XmlElement xml, string attribute, ref bool value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToBoolean(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse boolean attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadDateTime(XmlElement xml, string attribute, ref DateTime value) =>
|
||||
ReadDateTime(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadDateTime(XmlElement xml, string attribute, ref DateTime value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.Utc);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse DateTime attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadTimeSpan(XmlElement xml, string attribute, ref TimeSpan value) =>
|
||||
ReadTimeSpan(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadTimeSpan(XmlElement xml, string attribute, ref TimeSpan value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToTimeSpan(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse TimeSpan attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadEnum<T>(XmlElement xml, string attribute, ref T value) where T : struct =>
|
||||
ReadEnum(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadEnum<T>(XmlElement xml, string attribute, ref T value, bool mandatory)
|
||||
where T : struct // We can't limit the where clause to Enums only
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
var type = typeof(T);
|
||||
|
||||
if (type.IsEnum && Enum.TryParse(s, true, out T tempVal))
|
||||
{
|
||||
value = tempVal;
|
||||
return true;
|
||||
}
|
||||
|
||||
Console.WriteLine("Could not parse {0} enum attribute '{1}' in element '{2}'", type, attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ReadMap(XmlElement xml, string attribute, ref Map value) => ReadMap(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadMap(XmlElement xml, string attribute, ref Map value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = Map.Parse(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse Map attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadType(XmlElement xml, string attribute, ref Type value) =>
|
||||
ReadType(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadType(XmlElement xml, string attribute, ref Type value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
Type type;
|
||||
try
|
||||
{
|
||||
type = AssemblyHandler.FindFirstTypeForName(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse Type attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
Console.WriteLine("Could not find Type '{0}'", s);
|
||||
return false;
|
||||
}
|
||||
|
||||
value = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadPoint3D(XmlElement xml, Map map, ref Point3D value) => ReadPoint3D(xml, map, ref value, true);
|
||||
|
||||
public static bool ReadPoint3D(XmlElement xml, Map map, ref Point3D value, bool mandatory)
|
||||
{
|
||||
int x = 0, y = 0, z = 0;
|
||||
|
||||
var xyOk = ReadInt32(xml, "x", ref x, mandatory) & ReadInt32(xml, "y", ref y, mandatory);
|
||||
var zOk = ReadInt32(xml, "z", ref z, mandatory && map == null);
|
||||
|
||||
if (xyOk && (zOk || map != null))
|
||||
{
|
||||
if (!zOk)
|
||||
z = map.GetAverageZ(x, y);
|
||||
|
||||
value = new Point3D(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ReadRectangle3D(XmlElement xml, int defaultMinZ, int defaultMaxZ, out Rectangle3D value) =>
|
||||
ReadRectangle3D(xml, defaultMinZ, defaultMaxZ, out value, true);
|
||||
|
||||
public static bool ReadRectangle3D(XmlElement xml, int defaultMinZ, int defaultMaxZ, out Rectangle3D value,
|
||||
bool mandatory)
|
||||
{
|
||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
var z1 = defaultMinZ;
|
||||
var z2 = defaultMaxZ;
|
||||
|
||||
if (xml.HasAttribute("x"))
|
||||
{
|
||||
if (ReadInt32(xml, "x", ref x1, mandatory)
|
||||
& ReadInt32(xml, "y", ref y1, mandatory)
|
||||
& ReadInt32(xml, "width", ref x2, mandatory)
|
||||
& ReadInt32(xml, "height", ref y2, mandatory))
|
||||
{
|
||||
x2 += x1;
|
||||
y2 += y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = new Rectangle3D(new Point3D(x1, y1, z1), new Point3D(x2, y2, z2));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReadInt32(xml, "x1", ref x1, mandatory)
|
||||
| !ReadInt32(xml, "y1", ref y1, mandatory)
|
||||
| !ReadInt32(xml, "x2", ref x2, mandatory)
|
||||
| !ReadInt32(xml, "y2", ref y2, mandatory))
|
||||
{
|
||||
value = new Rectangle3D(new Point3D(x1, y1, z1), new Point3D(x2, y2, z2));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ReadInt32(xml, "zmin", ref z1, false);
|
||||
ReadInt32(xml, "zmax", ref z2, false);
|
||||
|
||||
value = new Rectangle3D(new Point3D(x1, y1, z1), new Point3D(x2, y2, z2));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Projects/Server/Regions/RegionLoader.cs
Normal file
60
Projects/Server/Regions/RegionLoader.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class RegionLoader
|
||||
{
|
||||
public static void LoadRegions()
|
||||
{
|
||||
var path = Path.Join(Core.BaseDirectory, "Data/regions.json");
|
||||
|
||||
// Json Deserialization options for custom objects
|
||||
JsonSerializerOptions options = new JsonSerializerOptions();
|
||||
options.Converters.Add(new MapConverterFactory());
|
||||
options.Converters.Add(new Point3DConverterFactory());
|
||||
options.Converters.Add(new Rectangle3DConverterFactory());
|
||||
|
||||
List<string> failures = new List<string>();
|
||||
int count = 0;
|
||||
|
||||
Console.Write("Regions: Loading...");
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
List<DynamicJson> regions = JsonConfig.Deserialize<List<DynamicJson>>(path);
|
||||
|
||||
foreach (var json in regions)
|
||||
{
|
||||
Type type = AssemblyHandler.FindFirstTypeForName(json.Type);
|
||||
|
||||
if (type == null || !typeof(Region).IsAssignableFrom(type))
|
||||
{
|
||||
failures.Add($"\tInvalid region type {json.Type}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var region = ActivatorUtil.CreateInstance(type, json, options) as Region;
|
||||
region?.Register();
|
||||
count++;
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
Console.ForegroundColor = failures.Count > 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
|
||||
Console.Write("done{0}. ", failures.Count > 0 ? " with failures" : "");
|
||||
Console.ResetColor();
|
||||
Console.WriteLine("({0} regions, {1} failures) ({2:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds);
|
||||
if (failures.Count > 0)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(string.Join("\n", failures));
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,10 +75,10 @@
|
|||
<CodeAnalysisRuleSet>..\..\Rules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Connections.Abstractions" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.3" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="4.7.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Connections.Abstractions" Version="3.1.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="3.1.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.4" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="4.7.2" />
|
||||
<PackageReference Include="ZLib.Bindings" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Configuration)'=='Analyze'">
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers">
|
||||
<Version>2.9.8</Version>
|
||||
<Version>3.0.0</Version>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace Server.Utilities
|
|||
// check all given args map to params.
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
// if a null reference is passed, but the type is not nullable
|
||||
if ((args[i] == null && paramList[i].ParameterType.IsValueType)
|
||||
if (args[i] == null && paramList[i].ParameterType.IsValueType
|
||||
// or if an arg is not null and is not assignable to the parameter type, skip.
|
||||
|| !(args[i] == null || paramList[i].ParameterType.IsAssignableFrom(args[i])))
|
||||
return false;
|
||||
|
|
@ -65,7 +65,8 @@ namespace Server.Utilities
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new TypeInitializationException(type.ToString(), e);
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ namespace Server
|
|||
{
|
||||
public interface IRandomProvider
|
||||
{
|
||||
public uint Next(uint c);
|
||||
public ulong Next(ulong max);
|
||||
public uint Next(uint max);
|
||||
public bool NextBool();
|
||||
public void GetBytes(Span<byte> b);
|
||||
public double NextDouble();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ namespace Server
|
|||
|
||||
public override void GetBytes(Span<byte> data) => m_Random.GetBytes(data);
|
||||
|
||||
public ulong Next(ulong c) => throw new NotImplementedException();
|
||||
|
||||
public uint Next(uint c) => throw new NotImplementedException();
|
||||
|
||||
public bool NextBool() => throw new NotImplementedException();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue