fix: Fixes spawners, adds convertpremiumspawners, exportspawners, and replaces with neruns distro (#751)

### Additions
* Adds `[exportspawners <relative json file path to distro>`
  * If no path is provided, it will be saved to the `Data\Spawns` folder with the current timestamp as the file name.
  * Supports global, facet, region, multi, and area
* Fixes client disconnect for bad spawner generation command.
* Moves spawner commands to their own folder.
* Adds GUIDs for spawners. This allows for easy replacement during import to reduce duplication.
* Allows exporting the name of the spawner.
* Fixes globbing when using [generatespawners
* Adds [convertpremiumspawners to convert Premium Spawners (from Neruns distro)

Possibly in .NET 6 serializing JSON will be more performant using JSON nodes.


### Screenshots
![Screen_Shot_2021-08-31_at_10 20 06_PM](https://user-images.githubusercontent.com/3953314/131618495-cf7e3ae5-58e5-4f86-9d3c-3cc49906d9fc.png)
![Screen_Shot_2021-08-31_at_10 21 08_PM](https://user-images.githubusercontent.com/3953314/131618502-c39cc368-2266-47a5-9b87-e5ffa108b875.png)
![Screen_Shot_2021-08-31_at_10 13 29_PM](https://user-images.githubusercontent.com/3953314/131618512-f9807f1b-76e4-4503-989d-42324798fbf5.png)
This commit is contained in:
Kamron Batman 2021-09-03 21:52:44 -07:00 committed by GitHub
parent dbd4d6f13f
commit 0d1fffd9fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
211 changed files with 200435 additions and 91312 deletions

View file

@ -55,6 +55,7 @@ namespace Server
// TODO: Add SpawnMap and change Spawner.Map to use it
public interface ISpawner : IEntity
{
Guid Guid { get; }
bool UnlinkOnTaming { get; }
Point3D HomeLocation { get; }
int HomeRange { get; }

View file

@ -0,0 +1,38 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: GuidConverter.cs *
* *
* 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. *
* *
* 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.Net;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Server.Json
{
public class GuidConverter : JsonConverter<Guid>
{
public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (Guid.TryParse(reader.GetString()!, out var guid))
{
return guid;
}
throw new JsonException("Guid must be in the correct format");
}
public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString());
}
}

View file

@ -0,0 +1,30 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: GuidConverterFactory.cs *
* *
* 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. *
* *
* 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.Net;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Server.Json
{
public class GuidConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Guid);
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) =>
new GuidConverter();
}
}

View file

@ -22,15 +22,28 @@ namespace Server.Json
{
public class DynamicJson
{
public static DynamicJson Create(Type type) => new()
{
Type = type.Name,
Data = new Dictionary<string, JsonElement>()
};
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonExtensionData]
public Dictionary<string, JsonElement> data { get; set; }
public Dictionary<string, JsonElement> Data { get; set; }
// TODO: Use JSON Node in .NET 6
public void SetProperty<T>(string key, JsonSerializerOptions options, T value)
{
using var doc = JsonDocument.Parse(JsonSerializer.SerializeToUtf8Bytes(value, options));
Data[key] = doc.RootElement.Clone();
}
public bool GetProperty<T>(string key, JsonSerializerOptions options, out T t)
{
if (data.TryGetValue(key, out var el))
if (Data.TryGetValue(key, out var el))
{
t = el.ToObject<T>(options);
return true;
@ -42,7 +55,7 @@ namespace Server.Json
public bool GetEnumProperty<T>(string key, JsonSerializerOptions options, out T t) where T : struct, Enum
{
if (data.TryGetValue(key, out var el))
if (Data.TryGetValue(key, out var el))
{
return Enum.TryParse(el.ToObject<string>(options), out t);
}

View file

@ -39,6 +39,7 @@ namespace Server.Json
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
options.Converters.Add(new GuidConverterFactory());
options.Converters.Add(new JsonStringEnumConverter());
options.Converters.Add(new MapConverterFactory());
options.Converters.Add(new Point3DConverterFactory());

View file

@ -583,6 +583,46 @@ namespace Server
return count;
}
public List<Item> GetItems()
{
var list = new List<Item>();
for (var i = 0; i < Sectors?.Length; i++)
{
var sector = Sectors[i];
foreach (var item in sector.Items)
{
if (Find(item.Location, item.Map).IsPartOf(this))
{
list.Add(item);
}
}
}
return list;
}
public int GetItemCount()
{
var count = 0;
for (var i = 0; i < Sectors?.Length; i++)
{
var sector = Sectors[i];
foreach (var item in sector.Items)
{
if (Find(item.Location, item.Map).IsPartOf(this))
{
count++;
}
}
}
return count;
}
public override string ToString() => Name ?? GetType().Name;
public virtual void OnRegister()

View file

@ -106,6 +106,13 @@ namespace Server
return default;
}
Guid ReadGuid()
{
Span<byte> bytes = stackalloc byte[16];
Read(bytes);
return new Guid(bytes);
}
long Seek(long offset, SeekOrigin origin);
}
}

View file

@ -155,6 +155,12 @@ namespace Server
}
}
}
void Write(Guid guid)
{
Span<byte> stack = stackalloc byte[16];
guid.TryWriteBytes(stack);
Write(stack);
}
long Seek(long offset, SeekOrigin origin);
}