From 51169ddbb09b229374ae7791373e656473bd26bf Mon Sep 17 00:00:00 2001
From: Stefano Merotta <97297186+stefanomerotta@users.noreply.github.com>
Date: Sat, 8 Jan 2022 07:42:37 +0100
Subject: [PATCH 001/178] Refactored map selector benchmarks (#914)
---
Projects/Benchmarks/Benchmarks.csproj | 2 +
.../Benchmarks/Map/MapEntitiesSelectors.cs | 545 ++++++++++++++
.../Benchmarks/Map/MapItemSelectors.cs | 403 +++++++++++
.../Benchmarks/Map/MapMobileSelectors.cs | 255 +++++++
.../Benchmarks/Map/MapMultiSelectors.cs | 311 ++++++++
.../Benchmarks/Map/MapMultiTilesSelectors.cs | 352 +++++++++
.../Benchmarks/Benchmarks/Map/MapSelectors.cs | 665 ------------------
Projects/Benchmarks/Program.cs | 16 +-
8 files changed, 1880 insertions(+), 669 deletions(-)
create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs
create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs
create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs
create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs
create mode 100644 Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs
delete mode 100644 Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs
diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj
index eff9ed660..ca226bba4 100644
--- a/Projects/Benchmarks/Benchmarks.csproj
+++ b/Projects/Benchmarks/Benchmarks.csproj
@@ -10,6 +10,8 @@
+
+
diff --git a/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs
new file mode 100644
index 000000000..7348824c8
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Map/MapEntitiesSelectors.cs
@@ -0,0 +1,545 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using NetFabric.Hyperlinq;
+using Server;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using static NetFabric.Hyperlinq.ArrayExtensions;
+
+namespace Benchmarks.EntitiesSelectors
+{
+ [SimpleJob(RuntimeMoniker.Net60)]
+ [MemoryDiagnoser]
+ public class MapEntitiesSelectors
+ {
+ private static readonly Sector sector = new();
+ private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
+
+ public static Rectangle2D[] BoundsArray() => new[]
+ {
+ new Rectangle2D(70, 70, 100, 100),
+ new Rectangle2D(30, 30, 100, 100),
+ new Rectangle2D(0, 0, 100, 100),
+ };
+
+ [GlobalSetup]
+ public static void Init()
+ {
+ for (int j = 0; j < locations.Length; j++)
+ {
+ Point3D loc = locations[j];
+
+ for (int i = 0; i < 500; ++i)
+ {
+ sector.BItems.Add(new BItem(loc));
+ }
+
+ for (int i = 0; i < 25; ++i)
+ {
+ sector.Mobiles.Add(new Mobile(loc));
+ }
+ }
+ }
+
+ [ParamsSource(nameof(BoundsArray))]
+ public Rectangle2D bounds;
+
+ [Benchmark(Baseline = true)]
+ public IEntity SelectEntitiesFor()
+ {
+ IEntity toRet = null;
+ for (int i = sector.Mobiles.Count - 1; i >= 0; --i)
+ {
+ Mobile mob = sector.Mobiles[i];
+ if (mob is { Deleted: false } tMob && bounds.Contains(mob.Location))
+ {
+ toRet = tMob;
+ }
+ }
+
+ for (int i = sector.BItems.Count - 1; i >= 0; --i)
+ {
+ BItem item = sector.BItems[i];
+ if (item is { Deleted: false, Parent: null } tItem && bounds.Contains(item.Location))
+ {
+ toRet = tItem;
+ }
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public IEntity SelectEntitiesNew()
+ {
+ IEntity toRet = null;
+ foreach (IEntity e in SelectEntitiesNew(sector, bounds))
+ {
+ toRet = e;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public IEntity SelectEntitiesLinq()
+ {
+ IEntity toRet = null;
+ foreach (IEntity e in SelectEntitiesLinq(sector, bounds))
+ {
+ toRet = e;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public IEntity SelectMobilesHyperLinq()
+ {
+ IEntity toRet = null;
+ foreach (IEntity e in SelectEntitiesHyperlinq(sector, bounds))
+ {
+ toRet = e;
+ }
+
+ return toRet;
+ }
+
+
+ public IEnumerable SelectEntitiesLinq(Sector s, Rectangle2D bounds)
+ {
+ return Enumerable.Empty()
+ .Union(s.Mobiles.Where(o => o is { Deleted: false } && bounds.Contains(o.Location)))
+ .Union(s.BItems.Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location)));
+ }
+
+ private readonly List entities = new(10);
+
+ public IEnumerable SelectEntitiesNew(Sector s, Rectangle2D bounds)
+ {
+ entities.Clear();
+ entities.EnsureCapacity(s.Mobiles.Count + s.BItems.Count);
+
+ for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j)
+ {
+ if (j >= 0)
+ {
+ BItem BItem = s.BItems[j];
+ if (BItem is { Deleted: false, Parent: null } && bounds.Contains(BItem.Location))
+ {
+ entities.Add(BItem);
+ }
+ }
+ if (i >= 0)
+ {
+ Mobile mob = s.Mobiles[i];
+ if (mob is { Deleted: false } && bounds.Contains(mob.Location))
+ {
+ entities.Add(mob);
+ }
+ }
+ }
+ return entities;
+ }
+
+ public IEnumerable SelectEntitiesHyperlinq(Sector s, Rectangle2D bounds)
+ {
+ ArraySegmentWhereSelectEnumerable> mobiles =
+ s.Mobiles.AsValueEnumerable().Where(new MobileWhereHyper(bounds)).Select>();
+
+ ArraySegmentWhereSelectEnumerable> items =
+ s.BItems.AsValueEnumerable().Where(new BItemWhereHyper(bounds)).Select>();
+
+ return mobiles.Concat(items);
+ }
+ }
+
+ public class BItem : IPoint3D, IEntity
+ {
+ public object Parent { get; set; } = null;
+
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new NotImplementedException();
+
+ public Point3D Location { get; }
+ public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public Region Region => throw new NotImplementedException();
+
+ public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ Point3D IEntity.Location => Location;
+
+ Map IEntity.Map => throw new NotImplementedException();
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public BItem(Point3D location)
+ {
+ Location = location;
+ }
+
+ public void Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnStatsQuery(Server.Mobile m)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void InvalidateProperties()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(IEntity other)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveBItem(BItem BItem)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class Mobile : IPoint3D, IEntity
+ {
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new NotImplementedException();
+
+ public Point3D Location { get; }
+ public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public Region Region => throw new NotImplementedException();
+
+ public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
+ public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ Point3D IEntity.Location => Location;
+
+ Map IEntity.Map => throw new NotImplementedException();
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public Mobile(Point3D location)
+ {
+ Location = location;
+ }
+
+ public void Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnStatsQuery(Server.Mobile m)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void InvalidateProperties()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(IEntity other)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveBItem(BItem BItem)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ void IEntity.ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ bool IEntity.InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class Sector
+ {
+ public List BItems { get; set; } = new List();
+ public List Mobiles { get; set; } = new List();
+ }
+
+ public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction
+ {
+ private readonly Rectangle2D bounds;
+
+ public BItemWhereHyper(Rectangle2D bounds)
+ {
+ this.bounds = bounds;
+ }
+
+ public bool Invoke(BItem element)
+ {
+ return element is { Deleted: false, Parent: null } && bounds.Contains(element.Location);
+ }
+ }
+
+ public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction
+ {
+ private readonly Rectangle2D bounds;
+
+ public MobileWhereHyper(Rectangle2D bounds)
+ {
+ this.bounds = bounds;
+ }
+
+ public bool Invoke(Mobile element)
+ {
+ return element is { Deleted: false } && bounds.Contains(element.Location);
+ }
+ }
+
+ public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TSource : TDest
+ {
+ public TDest Invoke(TSource arg)
+ {
+ return arg;
+ }
+ }
+}
diff --git a/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs
new file mode 100644
index 000000000..8eb1758d2
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Map/MapItemSelectors.cs
@@ -0,0 +1,403 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using NetFabric.Hyperlinq;
+using Server;
+using StructLinq;
+using StructLinq.Array;
+using StructLinq.List;
+using StructLinq.Select;
+using StructLinq.Where;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Linq;
+using static NetFabric.Hyperlinq.ArrayExtensions;
+
+namespace Benchmarks.ItemSelectors
+{
+ [SimpleJob(RuntimeMoniker.Net60)]
+ [MemoryDiagnoser]
+ public class MapItemSelectors
+ {
+ private static readonly Sector sector = new();
+ private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
+
+ public static Rectangle2D[] BoundsArray() => new[]
+ {
+ new Rectangle2D(70, 70, 100, 100),
+ new Rectangle2D(30, 30, 100, 100),
+ new Rectangle2D(0, 0, 100, 100),
+ };
+
+ [GlobalSetup]
+ public static void Init()
+ {
+ for (int j = 0; j < locations.Length; j++)
+ {
+ Point3D loc = locations[j];
+
+ for (int i = 0; i < 500; ++i)
+ {
+ sector.BItems.Add(new BItemDerived(loc));
+ }
+ }
+ }
+
+ [ParamsSource(nameof(BoundsArray))]
+ public Rectangle2D bounds;
+
+ [Benchmark(Baseline = true)]
+ public BItemDerived SelectBItemsFor()
+ {
+ BItemDerived toRet = null;
+ for (int i = sector.BItems.Count - 1; i >= 0; --i)
+ {
+ BItem BItem = sector.BItems[i];
+ if (BItem is BItemDerived { Deleted: false, Parent: null } tItem && bounds.Contains(BItem.Location))
+ {
+ toRet = tItem;
+ }
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BItemDerived SelectBItemsNew()
+ {
+ BItemDerived toRet = null;
+ foreach (BItemDerived i in SelectBItems(sector, bounds))
+ {
+ toRet = i;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BItemDerived SelectBItemsLinq()
+ {
+ BItemDerived toRet = null;
+ foreach (BItemDerived i in SelectBItemsLinq(sector, bounds))
+ {
+ toRet = i;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BItemDerived SelectBItemsLinqStruct()
+ {
+ BItemDerived toRet = null;
+ foreach (BItemDerived i in SelectBItemsLinqStruct(sector, bounds))
+ {
+ toRet = i;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BItemDerived SelectBItemsLinqStructInterface()
+ {
+ BItemDerived toRet = null;
+ IEnumerable enumerable = SelectBItemsLinqStruct(sector, bounds).ToEnumerable();
+
+ foreach (BItemDerived i in enumerable)
+ {
+ toRet = i;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BItemDerived SelectBItemsHyperLinq()
+ {
+ BItemDerived toRet = null;
+ foreach (BItemDerived i in SelectBItemsHyperlinq(sector, bounds))
+ {
+ toRet = i;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BItemDerived SelectBItemsHyperLinqInterface()
+ {
+ BItemDerived toRet = null;
+ IEnumerable enumerable = SelectBItemsHyperlinq(sector, bounds);
+
+ foreach (BItemDerived i in enumerable)
+ {
+ toRet = i;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BItemDerived SelectBItemsHyperLinqArrayPool()
+ {
+ BItemDerived toRet = null;
+ using Lease lease = SelectBItemsHyperlinq(sector, bounds).ToArray(ArrayPool.Shared);
+
+ foreach (BItemDerived i in lease)
+ {
+ toRet = i;
+ }
+
+ return toRet;
+ }
+
+ public IEnumerable SelectBItemsLinq(Sector s, Rectangle2D bounds) where T : BItem
+ {
+ return s.BItems.OfType().Where(o => o is { Deleted: false, Parent: null } && bounds.Contains(o.Location));
+ }
+
+ public IEnumerable SelectBItems(Sector s, Rectangle2D bounds) where T : BItem
+ {
+ List items = s.BItems;
+ List entities = new(items.Count);
+
+ for (int i = items.Count - 1; i >= 0; --i)
+ {
+ if (items[i] is T { Deleted: false, Parent: null } tItem && bounds.Contains(tItem.Location))
+ {
+ entities.Add(tItem);
+ }
+ }
+ return entities;
+ }
+
+ public SelectEnumerable, ArrayStructEnumerator, BItemWhere>,
+ WhereEnumerator, BItemWhere>, BItemSelect>
+ SelectBItemsLinqStruct(Sector s, Rectangle2D bounds) where T : BItem
+ {
+ BItemWhere bitemWhere = new(bounds);
+ BItemSelect bitemSelect = new();
+
+ return s.BItems.ToStructEnumerable()
+ .Where(ref bitemWhere, x => x)
+ .Select(ref bitemSelect, x => x, x => x);
+ }
+
+ public ArraySegmentWhereSelectEnumerable, SelectHyper>
+ SelectBItemsHyperlinq(Sector s, Rectangle2D bounds) where T : BItem
+ {
+ return s.BItems.AsValueEnumerable()
+ .Where(new BItemWhereHyper(bounds))
+ .Select>();
+ }
+ }
+
+ public class BItem : IPoint3D, IEntity
+ {
+ public object Parent { get; set; } = null;
+
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new NotImplementedException();
+
+ public Point3D Location { get; }
+
+ public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public Region Region => throw new NotImplementedException();
+
+ public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ Point3D IEntity.Location => Location;
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public BItem(Point3D location)
+ {
+ Location = location;
+ }
+
+ public void Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnStatsQuery(Server.Mobile m)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void InvalidateProperties()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(IEntity other)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveBItem(BItem BItem)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class BItemDerived : BItem
+ {
+ public BItemDerived(Point3D location) : base(location) { }
+ }
+
+ public class Sector
+ {
+ public List BItems { get; set; } = new List();
+ }
+
+ public struct BItemWhere : StructLinq.IFunction where T : BItem
+ {
+ private readonly Rectangle2D bounds;
+
+ public BItemWhere(Rectangle2D bounds)
+ {
+ this.bounds = bounds;
+ }
+
+ public bool Eval(BItem element)
+ {
+ return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location);
+ }
+ }
+
+ public struct BItemSelect : StructLinq.IFunction where T : BItem
+ {
+ public T Eval(BItem element)
+ {
+ return (T)element;
+ }
+ }
+
+ public struct BItemWhereHyper : NetFabric.Hyperlinq.IFunction where T : BItem
+ {
+ private readonly Rectangle2D bounds;
+
+ public BItemWhereHyper(Rectangle2D bounds)
+ {
+ this.bounds = bounds;
+ }
+
+ public bool Invoke(BItem element)
+ {
+ return element is T { Deleted: false, Parent: null } && bounds.Contains(element.Location);
+ }
+ }
+
+ public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TDest : TSource
+ {
+ public TDest Invoke(TSource arg)
+ {
+ return (TDest)arg;
+ }
+ }
+}
diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs
new file mode 100644
index 000000000..c9932070f
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Map/MapMobileSelectors.cs
@@ -0,0 +1,255 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using NetFabric.Hyperlinq;
+using Server;
+using StructLinq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using static NetFabric.Hyperlinq.ArrayExtensions;
+
+namespace Benchmarks.MobileSelectors
+{
+ [SimpleJob(RuntimeMoniker.Net60)]
+ [MemoryDiagnoser]
+ public class MapMobileSelectors
+ {
+ private static readonly Sector sector = new();
+ private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
+
+ public static Rectangle2D[] BoundsArray() => new[]
+ {
+ new Rectangle2D(70, 70, 100, 100),
+ new Rectangle2D(30, 30, 100, 100),
+ new Rectangle2D(0, 0, 100, 100),
+ };
+
+ [GlobalSetup]
+ public static void Init()
+ {
+ for (int j = 0; j < locations.Length; j++)
+ {
+ Point3D loc = locations[j];
+
+ for (int i = 0; i < 500; ++i)
+ {
+ sector.Mobiles.Add(new MobileDerived(loc));
+ }
+ }
+ }
+
+ [ParamsSource(nameof(BoundsArray))]
+ public Rectangle2D bounds;
+
+ [Benchmark(Baseline = true)]
+ public MobileDerived SelectMobilesFor()
+ {
+ MobileDerived toRet = null;
+ for (int i = sector.Mobiles.Count - 1; i >= 0; --i)
+ {
+ Mobile mob = sector.Mobiles[i];
+ if (mob is MobileDerived { Deleted: false } tMob && bounds.Contains(mob.Location))
+ {
+ toRet = tMob;
+ }
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public MobileDerived SelectMobilesNew()
+ {
+ MobileDerived toRet = null;
+ foreach (MobileDerived m in SelectMobiles(sector, bounds))
+ {
+ toRet = m;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public MobileDerived SelectMobilesLinq()
+ {
+ MobileDerived toRet = null;
+ foreach (MobileDerived m in SelectMobilesLinq(sector, bounds))
+ {
+ toRet = m;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public MobileDerived SelectMobilesHyperLinq()
+ {
+ MobileDerived toRet = null;
+ foreach (MobileDerived m in SelectMobilesHyperlinq(sector, bounds))
+ {
+ toRet = m;
+ }
+
+ return toRet;
+ }
+
+ public IEnumerable SelectMobilesLinq(Sector s, Rectangle2D bounds) where T : Mobile
+ {
+ return s.Mobiles.OfType().Where(o => o is { Deleted: false } && bounds.Contains(o.Location));
+ }
+
+ public IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile
+ {
+ List mobiles = s.Mobiles;
+ List entities = new(mobiles.Count);
+
+ for (int i = mobiles.Count - 1; i >= 0; --i)
+ {
+ if (mobiles[i] is T { Deleted: false } tMob && bounds.Contains(tMob.Location))
+ {
+ entities.Add(tMob);
+ }
+ }
+ return entities;
+ }
+
+ public ArraySegmentWhereSelectEnumerable, SelectHyper>
+ SelectMobilesHyperlinq(Sector s, Rectangle2D bounds) where T : Mobile
+ {
+ return s.Mobiles.AsValueEnumerable()
+ .Where(new MobileWhereHyper(bounds))
+ .Select>();
+ }
+ }
+
+ public class Mobile : IPoint3D, IEntity
+ {
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new NotImplementedException();
+
+ public Point3D Location { get; }
+
+ public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public Region Region => throw new NotImplementedException();
+
+ public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public int Hue { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
+ public Direction Direction { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public Mobile(Point3D location)
+ {
+ Location = location;
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class MobileDerived : Mobile
+ {
+ public MobileDerived(Point3D location) : base(location) { }
+ }
+
+ public class Sector
+ {
+ public List Mobiles { get; set; } = new List();
+ }
+
+ public struct MobileWhereHyper : NetFabric.Hyperlinq.IFunction where T : Mobile
+ {
+ private readonly Rectangle2D bounds;
+
+ public MobileWhereHyper(Rectangle2D bounds)
+ {
+ this.bounds = bounds;
+ }
+
+ public bool Invoke(Mobile element)
+ {
+ return element is T { Deleted: false } && bounds.Contains(element.Location);
+ }
+ }
+
+ public struct SelectHyper : NetFabric.Hyperlinq.IFunction where TDest : TSource
+ {
+ public TDest Invoke(TSource arg)
+ {
+ return (TDest)arg;
+ }
+ }
+}
diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs
new file mode 100644
index 000000000..e5c6605f5
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Map/MapMultiSelectors.cs
@@ -0,0 +1,311 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using NetFabric.Hyperlinq;
+using Server;
+using StructLinq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using static NetFabric.Hyperlinq.ArrayExtensions;
+
+namespace Benchmarks.MultiSelectors
+{
+ [SimpleJob(RuntimeMoniker.Net60)]
+ [MemoryDiagnoser]
+ public class MapMultiSelectors
+ {
+ private static readonly Sector sector = new();
+ private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
+
+ public static Rectangle2D[] BoundsArray() => new[]
+ {
+ new Rectangle2D(70, 70, 100, 100),
+ new Rectangle2D(30, 30, 100, 100),
+ new Rectangle2D(0, 0, 100, 100),
+ };
+
+ [GlobalSetup]
+ public static void Init()
+ {
+ for (int j = 0; j < locations.Length; j++)
+ {
+ Point3D loc = locations[j];
+
+ for (int i = 0; i < 25; ++i)
+ {
+ sector.Multis.Add(new BaseMulti(loc));
+ }
+ }
+ }
+
+ [ParamsSource(nameof(BoundsArray))]
+ public Rectangle2D bounds;
+
+ [Benchmark(Baseline = true)]
+ public BaseMulti SelectMultiFor()
+ {
+ BaseMulti toRet = null;
+ for (int i = sector.Multis.Count - 1; i >= 0; --i)
+ {
+ BaseMulti multi = sector.Multis[i];
+ if (multi is { Deleted: false } tMulti && bounds.Contains(multi.Location))
+ {
+ toRet = tMulti;
+ }
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BaseMulti SelectMultiNew()
+ {
+ BaseMulti toRet = null;
+ foreach (BaseMulti m in SelectMultiNew(sector, bounds))
+ {
+ toRet = m;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BaseMulti SelectMultiLinq()
+ {
+ BaseMulti toRet = null;
+ foreach (BaseMulti m in SelectMultiLinq(sector, bounds))
+ {
+ toRet = m;
+ }
+
+ return toRet;
+ }
+
+ [Benchmark]
+ public BaseMulti SelectMultiHyperLinq()
+ {
+ BaseMulti toRet = null;
+ foreach (BaseMulti m in SelectMultiHyperlinq(sector, bounds))
+ {
+ toRet = m;
+ }
+
+ return toRet;
+ }
+
+ public IEnumerable SelectMultiLinq(Sector s, Rectangle2D bounds)
+ {
+ return s.Multis.Where(o => o is { Deleted: false } && bounds.Contains(o.Location));
+ }
+
+ public IEnumerable SelectMultiNew(Sector s, Rectangle2D bounds)
+ {
+ List entities = new(s.Multis.Count);
+
+ for (int i = s.Multis.Count - 1; i >= 0; --i)
+ {
+ BaseMulti multiItem = s.Multis[i];
+ if (multiItem is { Deleted: false } && bounds.Contains(multiItem.Location))
+ {
+ entities.Add(multiItem);
+ }
+ }
+ return entities;
+ }
+
+ public ArraySegmentWhereEnumerable
+ SelectMultiHyperlinq(Sector s, Rectangle2D bounds)
+ {
+ return s.Multis.AsValueEnumerable().Where(new MultiWhereHyper(bounds));
+ }
+ }
+
+ public class BItem : IPoint3D, IEntity
+ {
+ public object Parent { get; set; } = null;
+
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new NotImplementedException();
+
+ public Point3D Location { get; }
+
+ public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public Region Region => throw new NotImplementedException();
+
+ public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public BItem(Point3D location)
+ {
+ Location = location;
+ }
+
+ public void Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnStatsQuery(Server.Mobile m)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void InvalidateProperties()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(IEntity other)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveBItem(BItem BItem)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class BaseMulti : BItem
+ {
+ public MultiComponentList Components = MultiComponentList.Empty;
+
+ public BaseMulti(Point3D location) : base(location)
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ for (int j = 0; j < 20; ++j)
+ {
+ for (int z = 0; z < 20; ++z)
+ {
+ Components.Add(123, i, j, z);
+ }
+ }
+ }
+ }
+ }
+
+ public class Sector
+ {
+ public List Multis { get; set; } = new List();
+ }
+
+ public struct MultiWhereHyper : NetFabric.Hyperlinq.IFunction
+ {
+ private readonly Rectangle2D bounds;
+
+ public MultiWhereHyper(Rectangle2D bounds)
+ {
+ this.bounds = bounds;
+ }
+
+ public bool Invoke(BaseMulti element)
+ {
+ return element is { Deleted: false } && bounds.Contains(element.Location);
+ }
+ }
+}
diff --git a/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs
new file mode 100644
index 000000000..553016f93
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Map/MapMultiTilesSelectors.cs
@@ -0,0 +1,352 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using NetFabric.Hyperlinq;
+using Server;
+using StructLinq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Benchmarks.MultiTilesSelectors
+{
+ [SimpleJob(RuntimeMoniker.Net60)]
+ [MemoryDiagnoser]
+ public class MapMultiTilesSelectors
+ {
+ private static readonly Sector sector = new();
+ private static readonly Point3D[] locations = new[] { new Point3D(0, 0, 0), new Point3D(50, 50, 0) };
+
+ public static Rectangle2D[] BoundsArray() => new[]
+ {
+ new Rectangle2D(70, 70, 100, 100),
+ new Rectangle2D(30, 30, 100, 100),
+ new Rectangle2D(0, 0, 100, 100),
+ };
+
+ [GlobalSetup]
+ public static void Init()
+ {
+ for (int j = 0; j < locations.Length; j++)
+ {
+ Point3D loc = locations[j];
+
+ for (int i = 0; i < 25; ++i)
+ {
+ sector.Multis.Add(new BaseMulti(loc));
+ }
+ }
+ }
+
+ [ParamsSource(nameof(BoundsArray))]
+ public Rectangle2D bounds;
+
+ [Benchmark]
+ public int SelectMultiTilesNew()
+ {
+ int toRet = 0;
+
+ foreach (StaticTile[] tiles in SelectMultiTilesNew(sector, bounds))
+ {
+ for (int i = 0; i < tiles.Length; ++i)
+ {
+ toRet = tiles[i].ID;
+ }
+ }
+
+ return toRet;
+ }
+
+ [Benchmark(Baseline = true)]
+ public int SelectMultiTilesLinq()
+ {
+ int toRet = 0;
+
+ foreach (StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds))
+ {
+ for (int i = 0; i < tiles.Length; ++i)
+ {
+ toRet = tiles[i].ID;
+ }
+ }
+
+ return toRet;
+ }
+
+ public IEnumerable SelectMultiTilesLinq(Sector s, Rectangle2D bounds)
+ {
+ foreach (var o in s.Multis.Where(o => o != null && !o.Deleted))
+ {
+ var c = o.Components;
+
+ int x, y, xo, yo;
+ StaticTile[] t, r;
+
+ for (x = bounds.Start.X; x < bounds.End.X; x++)
+ {
+ xo = x - (o.X + c.Min.X);
+
+ if (xo < 0 || xo >= c.Width)
+ {
+ continue;
+ }
+
+ for (y = bounds.Start.Y; y < bounds.End.Y; y++)
+ {
+ yo = y - (o.Y + c.Min.Y);
+
+ if (yo < 0 || yo >= c.Height)
+ {
+ continue;
+ }
+
+ t = c.Tiles[xo][yo];
+
+ if (t.Length <= 0)
+ {
+ continue;
+ }
+
+ r = new StaticTile[t.Length];
+
+ for (var i = 0; i < t.Length; i++)
+ {
+ r[i] = t[i];
+ r[i].Z += o.Z;
+ }
+
+ yield return r;
+ }
+ }
+ }
+ }
+
+ public IEnumerable SelectMultiTilesNew(Sector s, Rectangle2D bounds)
+ {
+ List multis = s.Multis;
+
+ for (int l = multis.Count - 1; l >= 0; --l)
+ {
+ if (multis[l] is not { Deleted: false } o)
+ {
+ continue;
+ }
+
+ MultiComponentList c = o.Components;
+
+ int x, y, xo, yo;
+ StaticTile[] t, r;
+
+ for (x = bounds.Start.X; x < bounds.End.X; x++)
+ {
+ xo = x - (o.X + c.Min.X);
+
+ if (xo < 0 || xo >= c.Width)
+ {
+ continue;
+ }
+
+ for (y = bounds.Start.Y; y < bounds.End.Y; y++)
+ {
+ yo = y - (o.Y + c.Min.Y);
+
+ if (yo < 0 || yo >= c.Height)
+ {
+ continue;
+ }
+
+ t = c.Tiles[xo][yo];
+
+ if (t.Length <= 0)
+ {
+ continue;
+ }
+
+ r = new StaticTile[t.Length];
+
+ for (var i = 0; i < t.Length; i++)
+ {
+ r[i] = t[i];
+ r[i].Z += o.Z;
+ }
+
+ yield return r;
+ }
+ }
+ }
+ }
+ }
+
+ public class BItem : IPoint3D, IEntity
+ {
+ public object Parent { get; set; } = null;
+
+ public bool Deleted { get; set; } = false;
+
+ public int Z { get; set; } = 1;
+
+ public int X { get; set; } = 1;
+
+ public int Y { get; set; } = 1;
+
+ public Serial Serial => throw new NotImplementedException();
+
+ public Point3D Location { get; }
+
+ public Map Map { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public Region Region => throw new NotImplementedException();
+
+ public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public int Hue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public Direction Direction { get => throw new System.NotImplementedException(); set => throw new NotImplementedException(); }
+ public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ public int TypeRef => throw new NotImplementedException();
+
+ int IPoint3D.Z => throw new NotImplementedException();
+
+ int IPoint2D.X => throw new NotImplementedException();
+
+ int IPoint2D.Y => throw new NotImplementedException();
+
+ DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+
+ int ISerializable.TypeRef => throw new NotImplementedException();
+
+ Serial ISerializable.Serial => throw new NotImplementedException();
+
+ bool ISerializable.Deleted => throw new NotImplementedException();
+
+ public BItem(Point3D location)
+ {
+ Location = location;
+ }
+
+ public void Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ProcessDelta()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnStatsQuery(Server.Mobile m)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void InvalidateProperties()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int CompareTo(IEntity other)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void MoveToWorld(Point3D location, Map map)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point2D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool InRange(Point3D p, int range)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveBItem(BItem BItem)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.BeforeSerialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Deserialize(IGenericReader reader)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Serialize(IGenericWriter writer)
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.Delete()
+ {
+ throw new NotImplementedException();
+ }
+
+ void ISerializable.SetTypeRef(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RemoveItem(Item item)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class BaseMulti : BItem
+ {
+ public MultiComponentList Components = MultiComponentList.Empty;
+
+ public BaseMulti(Point3D location) : base(location)
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ for (int j = 0; j < 20; ++j)
+ {
+ for (int z = 0; z < 20; ++z)
+ {
+ Components.Add(123, i, j, z);
+ }
+ }
+ }
+ }
+ }
+
+ public class Sector
+ {
+ public List Multis { get; set; } = new List();
+ }
+}
diff --git a/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs b/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs
deleted file mode 100644
index 4c47b7189..000000000
--- a/Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs
+++ /dev/null
@@ -1,665 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Server;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Benchmarks
-{
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class MapSelectors
- {
- static readonly Sector sector = new Sector();
- static Server.Rectangle2D bounds = new Server.Rectangle2D(0, 0, 100, 100);
-
- public static void Init()
- {
- for (int i = 0; i < 50; ++i)
- {
- sector.Multis.Add(new BaseMulti());
- }
- for (int i = 0; i < 1000; ++i)
- {
- sector.BItems.Add(new BItem());
- }
- for (int i = 0; i < 1000; ++i)
- {
- sector.Mobiles.Add(new Mobile());
- }
- }
-
- #region MultiTiles
- [Benchmark]
- public void SelectMultiTilesNew()
- {
- foreach(StaticTile[] tiles in SelectMultiTiles(sector, bounds))
- {
- for(int i = 0; i < tiles.Length; ++i)
- {
- int id = tiles[i].ID;
- }
- }
- }
-
- [Benchmark]
- public void SelectMultiTilesLinq()
- {
- foreach(StaticTile[] tiles in SelectMultiTilesLinq(sector, bounds))
- {
- for(int i = 0; i < tiles.Length; ++i)
- {
- int id = tiles[i].ID;
- }
- }
- }
-
- public IEnumerable SelectMultiTilesLinq(Sector s, Server.Rectangle2D bounds)
- {
- foreach (var o in s.Multis.Where(o => o != null && !o.Deleted))
- {
- var c = o.Components;
-
- int x, y, xo, yo;
- StaticTile[] t, r;
-
- for (x = bounds.Start.X; x < bounds.End.X; x++)
- {
- xo = x - (o.X + c.Min.X);
-
- if (xo < 0 || xo >= c.Width)
- {
- continue;
- }
-
- for (y = bounds.Start.Y; y < bounds.End.Y; y++)
- {
- yo = y - (o.Y + c.Min.Y);
-
- if (yo < 0 || yo >= c.Height)
- {
- continue;
- }
-
- t = c.Tiles[xo][yo];
-
- if (t.Length <= 0)
- {
- continue;
- }
-
- r = new StaticTile[t.Length];
-
- for (var i = 0; i < t.Length; i++)
- {
- r[i] = t[i];
- r[i].Z += o.Z;
- }
-
- yield return r;
- }
- }
- }
- }
-
- public IEnumerable SelectMultiTiles(Sector s, Server.Rectangle2D bounds)
- {
- for (int l = s.Multis.Count - 1; l >= 0; --l)
- {
- BaseMulti o = s.Multis[l];
- if (o != null && !o.Deleted)
- {
- MultiComponentList c = o.Components;
-
- int x, y, xo, yo;
- StaticTile[] t, r;
-
- for (x = bounds.Start.X; x < bounds.End.X; x++)
- {
- xo = x - (o.X + c.Min.X);
-
- if (xo < 0 || xo >= c.Width)
- {
- continue;
- }
-
- for (y = bounds.Start.Y; y < bounds.End.Y; y++)
- {
- yo = y - (o.Y + c.Min.Y);
-
- if (yo < 0 || yo >= c.Height)
- {
- continue;
- }
-
- t = c.Tiles[xo][yo];
-
- if (t.Length <= 0)
- {
- continue;
- }
-
- r = new StaticTile[t.Length];
-
- for (var i = 0; i < t.Length; i++)
- {
- r[i] = t[i];
- r[i].Z += o.Z;
- }
-
- yield return r;
- }
- }
- }
- }
- }
-
- #endregion
-
- #region Multis
- [Benchmark]
- public void SelectMultisNew()
- {
- SelectMultis(sector, bounds);
- }
-
- [Benchmark]
- public void SelectMultisLinq()
- {
- SelectMultisLinq(sector, bounds);
- }
-
- public IEnumerable SelectMultisLinq(Sector s, Server.Rectangle2D bounds)
- {
- return s.Multis.Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
- }
-
- public IEnumerable SelectMultis(Sector s, Server.Rectangle2D bounds)
- {
- List entities = new List(s.Multis.Count);
- for (int i = s.Multis.Count - 1; i >= 0; --i)
- {
- BaseMulti BItem = s.Multis[i];
- if (BItem != null && !BItem.Deleted && bounds.Contains(BItem.Location))
- entities.Add(BItem);
- }
- return entities;
- }
- #endregion
-
- #region BItems
- [Benchmark]
- public void SelectBItemsNew()
- {
- SelectBItems(sector, bounds);
- }
-
- [Benchmark]
- public void SelectBItemsLinq()
- {
- SelectBItemsLinq(sector, bounds);
- }
-
- public IEnumerable SelectBItemsLinq(Sector s, Server.Rectangle2D bounds) where T : BItem
- {
- return s.BItems.OfType().Where(o => o != null && !o.Deleted && o.Parent == null && bounds.Contains(o.Location));
- }
-
- public IEnumerable SelectBItems(Sector s, Server.Rectangle2D bounds) where T : BItem
- {
- List entities = new List(s.BItems.Count);
- Type type = typeof(T);
- for (int i = s.BItems.Count - 1; i >= 0; --i)
- {
- BItem BItem = s.BItems[i];
- if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location) && type.IsAssignableFrom(BItem.GetType()))
- entities.Add(BItem as T);
- }
- return entities;
- }
- #endregion
-
- #region Mobiles
- [Benchmark]
- public void SelectMobilesNew()
- {
- SelectMobiles(sector, bounds);
- }
-
- [Benchmark]
- public void SelectMobilesLinq()
- {
- SelectMobilesLinq(sector, bounds);
- }
-
- public IEnumerable SelectMobilesLinq(Sector s, Server.Rectangle2D bounds) where T : Mobile
- {
- return s.Mobiles.OfType().Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
- }
-
- public IEnumerable SelectMobiles(Sector s, Server.Rectangle2D bounds) where T : Mobile
- {
- List entities = new List(s.Mobiles.Count);
- Type type = typeof(T);
- for (int i = s.Mobiles.Count - 1; i >= 0; --i)
- {
- Mobile mob = s.Mobiles[i];
- if (mob != null && !mob.Deleted && bounds.Contains(mob.Location) && type.IsAssignableFrom(mob.GetType()))
- entities.Add(mob as T);
- }
- return entities;
- }
- #endregion
-
- #region Entities
- [Benchmark]
- public void SelectEntitiesNew()
- {
- SelectEntities(sector, bounds);
- }
-
- [Benchmark]
- public void SelectEntitiesLinq()
- {
- SelectEntitiesLinq(sector, bounds);
- }
-
- public IEnumerable SelectEntitiesLinq(Sector s, Server.Rectangle2D bounds)
- {
- return Enumerable.Empty()
- .Union(s.Mobiles.Where(o => o != null && !o.Deleted))
- .Union(s.BItems.Where(o => o != null && !o.Deleted && o.Parent == null))
- .Where(o => bounds.Contains(o.Location));
- }
-
- private readonly List entities = new (10);
- public IEnumerable SelectEntities(Sector s, Server.Rectangle2D bounds)
- {
- entities.Clear();
- entities.Capacity = s.Mobiles.Count + s.BItems.Count;
- for (int i = s.Mobiles.Count - 1, j = s.BItems.Count - 1; i >= 0 || j >= 0; --i, --j)
- {
- if (j >= 0)
- {
- BItem BItem = s.BItems[j];
- if (BItem != null && !BItem.Deleted && BItem.Parent == null && bounds.Contains(BItem.Location))
- entities.Add(BItem);
- }
- if (i >= 0)
- {
- Mobile mob = s.Mobiles[i];
- if (mob != null && !mob.Deleted && bounds.Contains(mob.Location))
- entities.Add(mob);
- }
- }
- return entities;
- }
- #endregion
- }
- public class BItem : Server.IPoint3D, IEntity
- {
- public object Parent { get; set; } = null;
-
- public bool Deleted { get; set; } = false;
-
- public int Z { get; set; } = 1;
-
- public int X { get; set; } = 1;
-
- public int Y { get; set; } = 1;
-
- public Serial Serial => throw new System.NotImplementedException();
-
- public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
-
- public Region Region => throw new System.NotImplementedException();
-
- public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- public int TypeRef => throw new NotImplementedException();
-
- Point3D IEntity.Location => throw new NotImplementedException();
-
- Map IEntity.Map => throw new NotImplementedException();
-
- int IPoint3D.Z => throw new NotImplementedException();
-
- int IPoint2D.X => throw new NotImplementedException();
-
- int IPoint2D.Y => throw new NotImplementedException();
-
- DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
- DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
- long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
- BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- int ISerializable.TypeRef => throw new NotImplementedException();
-
- Serial ISerializable.Serial => throw new NotImplementedException();
-
- bool ISerializable.Deleted => throw new NotImplementedException();
-
- public BItem()
- {
-
- }
-
- public void Delete()
- {
- throw new System.NotImplementedException();
- }
-
- public void ProcessDelta()
- {
- throw new System.NotImplementedException();
- }
-
- public void OnStatsQuery(Server.Mobile m)
- {
- throw new System.NotImplementedException();
- }
-
- public void InvalidateProperties()
- {
- throw new System.NotImplementedException();
- }
-
- public int CompareTo(object obj)
- {
- throw new System.NotImplementedException();
- }
-
- public int CompareTo(IEntity other)
- {
- throw new System.NotImplementedException();
- }
-
- public void MoveToWorld(Point3D location, Map map)
- {
- throw new NotImplementedException();
- }
-
- public bool InRange(Point2D p, int range)
- {
- throw new NotImplementedException();
- }
-
- public bool InRange(Point3D p, int range)
- {
- throw new NotImplementedException();
- }
-
- public void RemoveBItem(BItem BItem)
- {
- throw new NotImplementedException();
- }
-
- public void BeforeSerialize()
- {
- throw new NotImplementedException();
- }
-
- public void Deserialize(IGenericReader reader)
- {
- throw new NotImplementedException();
- }
-
- public void Serialize(IGenericWriter writer)
- {
- throw new NotImplementedException();
- }
-
- public void SetTypeRef(Type type)
- {
- throw new NotImplementedException();
- }
-
- void IEntity.MoveToWorld(Point3D location, Map map)
- {
- throw new NotImplementedException();
- }
-
- void IEntity.ProcessDelta()
- {
- throw new NotImplementedException();
- }
-
- bool IEntity.InRange(Point2D p, int range)
- {
- throw new NotImplementedException();
- }
-
- bool IEntity.InRange(Point3D p, int range)
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.BeforeSerialize()
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.Deserialize(IGenericReader reader)
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.Serialize(IGenericWriter writer)
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.Delete()
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.SetTypeRef(Type type)
- {
- throw new NotImplementedException();
- }
-
- public void RemoveItem(Item item)
- {
- throw new NotImplementedException();
- }
- }
-
- public class Mobile : Server.IPoint3D, IEntity
- {
- public bool Deleted { get; set; } = false;
-
- public int Z { get; set; } = 1;
-
- public int X { get; set; } = 1;
-
- public int Y { get; set; } = 1;
-
- public Serial Serial => throw new System.NotImplementedException();
-
- public Point3D Location { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public Map Map { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
-
- public Region Region => throw new System.NotImplementedException();
-
- public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public int Hue { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public Direction Direction { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
- public DateTime Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- public int TypeRef => throw new NotImplementedException();
-
- Point3D IEntity.Location => throw new NotImplementedException();
-
- Map IEntity.Map => throw new NotImplementedException();
-
- int IPoint3D.Z => throw new NotImplementedException();
-
- int IPoint2D.X => throw new NotImplementedException();
-
- int IPoint2D.Y => throw new NotImplementedException();
-
- DateTime ISerializable.Created { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
- DateTime ISerializable.LastSerialized { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
- long ISerializable.SavePosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
- BufferWriter ISerializable.SaveBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- int ISerializable.TypeRef => throw new NotImplementedException();
-
- Serial ISerializable.Serial => throw new NotImplementedException();
-
- bool ISerializable.Deleted => throw new NotImplementedException();
-
- public Mobile()
- {
-
- }
-
- public void Delete()
- {
- throw new System.NotImplementedException();
- }
-
- public void ProcessDelta()
- {
- throw new System.NotImplementedException();
- }
-
- public void OnStatsQuery(Server.Mobile m)
- {
- throw new System.NotImplementedException();
- }
-
- public void InvalidateProperties()
- {
- throw new System.NotImplementedException();
- }
-
- public int CompareTo(object obj)
- {
- throw new System.NotImplementedException();
- }
-
- public int CompareTo(IEntity other)
- {
- throw new System.NotImplementedException();
- }
-
- public void MoveToWorld(Point3D location, Map map)
- {
- throw new NotImplementedException();
- }
-
- public bool InRange(Point2D p, int range)
- {
- throw new NotImplementedException();
- }
-
- public bool InRange(Point3D p, int range)
- {
- throw new NotImplementedException();
- }
-
- public void RemoveBItem(BItem BItem)
- {
- throw new NotImplementedException();
- }
-
- public void BeforeSerialize()
- {
- throw new NotImplementedException();
- }
-
- public void Deserialize(IGenericReader reader)
- {
- throw new NotImplementedException();
- }
-
- public void Serialize(IGenericWriter writer)
- {
- throw new NotImplementedException();
- }
-
- public void SetTypeRef(Type type)
- {
- throw new NotImplementedException();
- }
-
- void IEntity.MoveToWorld(Point3D location, Map map)
- {
- throw new NotImplementedException();
- }
-
- void IEntity.ProcessDelta()
- {
- throw new NotImplementedException();
- }
-
- bool IEntity.InRange(Point2D p, int range)
- {
- throw new NotImplementedException();
- }
-
- bool IEntity.InRange(Point3D p, int range)
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.BeforeSerialize()
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.Deserialize(IGenericReader reader)
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.Serialize(IGenericWriter writer)
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.Delete()
- {
- throw new NotImplementedException();
- }
-
- void ISerializable.SetTypeRef(Type type)
- {
- throw new NotImplementedException();
- }
-
- public void RemoveItem(Item item)
- {
- throw new NotImplementedException();
- }
- }
-
- public class BaseMulti : BItem
- {
- public MultiComponentList Components = MultiComponentList.Empty;
-
- public BaseMulti()
- {
- for (int i = 0; i < 20; ++i)
- for (int j = 0; j < 20; ++j)
- for (int z = 0; z < 20; ++z)
- Components.Add(123, i, j, z);
- }
-
- }
-
- public class Sector
- {
- public List BItems { get; set; } = new List();
- public List Mobiles { get; set; } = new List();
- public List Multis { get; set; } = new List();
- }
-}
diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs
index bfdadb1bc..e86c18d19 100644
--- a/Projects/Benchmarks/Program.cs
+++ b/Projects/Benchmarks/Program.cs
@@ -1,5 +1,9 @@
using BenchmarkDotNet.Running;
-using Benchmarks.Benchmarks.Rng;
+using Benchmarks.EntitiesSelectors;
+using Benchmarks.ItemSelectors;
+using Benchmarks.MobileSelectors;
+using Benchmarks.MultiSelectors;
+using Benchmarks.MultiTilesSelectors;
namespace Benchmarks
{
@@ -15,10 +19,14 @@ namespace Benchmarks
// var textEncoding = BenchmarkRunner.Run();
// var logging = BenchmarkRunner.Run();
// var gumpPacket = BenchmarkRunner.Run();
- // MapSelectors.Init();
- // var mapSelectors = BenchmarkRunner.Run();
// var rngTest = BenchmarkRunner.Run();
- var doubleRngText = BenchmarkRunner.Run();
+ //var doubleRngText = BenchmarkRunner.Run();
+
+ //var mapEntitiesSelectors = BenchmarkRunner.Run();
+ //var mapMobilesSelectors = BenchmarkRunner.Run();
+ //var mapMultiTilesSelectors = BenchmarkRunner.Run();
+ //var mapMultiSelectors = BenchmarkRunner.Run();
+ var mapItemsSelectors = BenchmarkRunner.Run();
}
}
}
From fc51b60cc13c42d721a7719f2d20c93ed7789bd3 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Mon, 10 Jan 2022 23:14:55 -0800
Subject: [PATCH 002/178] fix: Adds server access with protected accounts
(#915)
Adds a configuration file to specify protected accounts:
_Distribution/Configuration/server-access.json_
```json
{
"newPasswordOnReset": false,
"protectedAccounts": ["admin"]
}
```
Protected accounts are unbanned and reset to `AccessLevel.Owner` upon login.
The option `newPasswordOnReset` will create a new password for a protected account if it needs to be reset. The password is a random GUID and logged to the console.
_**Note:**_ If your player character was accidentally modified, simply make a new character to fix the old one.
---
.../UOContent/Accounting/AccountHandler.cs | 9 +-
Projects/UOContent/Misc/AccountPrompt.cs | 3 +
Projects/UOContent/Misc/PacketThrottles.cs | 2 +-
Projects/UOContent/Misc/ServerAccess.cs | 99 +++++++++++++++++++
4 files changed, 108 insertions(+), 5 deletions(-)
create mode 100644 Projects/UOContent/Misc/ServerAccess.cs
diff --git a/Projects/UOContent/Accounting/AccountHandler.cs b/Projects/UOContent/Accounting/AccountHandler.cs
index 642660d05..583091ed7 100644
--- a/Projects/UOContent/Accounting/AccountHandler.cs
+++ b/Projects/UOContent/Accounting/AccountHandler.cs
@@ -241,13 +241,15 @@ namespace Server.Misc
{
res = DeleteResultType.CharBeingPlayed;
}
- else if (RestrictDeletion && Core.Now < m.Created + DeleteDelay)
+ else if (acct.AccessLevel == AccessLevel.Player && RestrictDeletion && Core.Now < m.Created + DeleteDelay)
{
res = DeleteResultType.CharTooYoung;
}
- else if (m.AccessLevel == AccessLevel.Player &&
+ // Don't need to check current location, if netstate is null, they're logged out
+ else if (
+ m.AccessLevel == AccessLevel.Player &&
Region.Find(m.LogoutLocation, m.LogoutMap).IsPartOf()
- ) // Don't need to check current location, if netstate is null, they're logged out
+ )
{
res = DeleteResultType.BadRequest;
}
@@ -265,7 +267,6 @@ namespace Server.Misc
state.SendCharacterDeleteResult(res);
state.SendCharacterListUpdate(acct);
-
}
public static bool CanCreate(IPAddress ip) =>
diff --git a/Projects/UOContent/Misc/AccountPrompt.cs b/Projects/UOContent/Misc/AccountPrompt.cs
index 0e537c0d5..1483f022e 100644
--- a/Projects/UOContent/Misc/AccountPrompt.cs
+++ b/Projects/UOContent/Misc/AccountPrompt.cs
@@ -27,6 +27,9 @@ namespace Server.Misc
a.AccessLevel = AccessLevel.Owner;
Console.WriteLine("Account created.");
+
+ ServerAccess.AddProtectedAccount(a, true);
+ Console.WriteLine("Added {0} to the protected accounts list.", a.Username);
}
else
{
diff --git a/Projects/UOContent/Misc/PacketThrottles.cs b/Projects/UOContent/Misc/PacketThrottles.cs
index d2b666ed9..dda06aab8 100644
--- a/Projects/UOContent/Misc/PacketThrottles.cs
+++ b/Projects/UOContent/Misc/PacketThrottles.cs
@@ -10,7 +10,7 @@ namespace Server.Network
{
// Delay in milliseconds
private static readonly int[] Delays = new int[0x100];
- private static string ThrottlesConfiguration = "Configuration/throttles.json";
+ private const string ThrottlesConfiguration = "Configuration/throttles.json";
public static void Initialize()
{
diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs
new file mode 100644
index 000000000..433055b86
--- /dev/null
+++ b/Projects/UOContent/Misc/ServerAccess.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.Json.Serialization;
+using Server.Accounting;
+using Server.Json;
+using Server.Logging;
+
+namespace Server.Misc;
+
+public static class ServerAccess
+{
+ private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerAccess));
+ private const string _serverAccessConfigurationPath = "Configuration/server-access.json";
+ public static ServerAccessConfiguration ServerAccessConfiguration { get; private set; }
+
+ public static void SaveConfiguration()
+ {
+ var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath);
+ JsonConfig.Serialize(path, ServerAccessConfiguration);
+ }
+
+ public static void AddProtectedAccount(Account acct, bool save = false)
+ {
+ ServerAccessConfiguration.ProtectedAccounts.Add(acct.Username.ToLower());
+
+ if (save)
+ {
+ SaveConfiguration();
+ }
+ }
+
+ public static void RemoveProtectedAccount(Account acct, bool save = false)
+ {
+ ServerAccessConfiguration.ProtectedAccounts.Remove(acct.Username.ToLower());
+
+ if (save)
+ {
+ SaveConfiguration();
+ }
+ }
+
+ public static void Configure()
+ {
+ var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath);
+
+ if (!File.Exists(path))
+ {
+ return;
+ }
+
+ ServerAccessConfiguration = JsonConfig.Deserialize(path);
+ var protectedAccounts = string.Join(", ", ServerAccessConfiguration.ProtectedAccounts);
+ logger.Information("Protected accounts registered: {0}", protectedAccounts);
+ }
+
+ public static void Initialize()
+ {
+ EventSink.AccountLogin += EventSink_ResetProtectedAccount;
+ }
+
+ public static void EventSink_ResetProtectedAccount(AccountLoginEventArgs e)
+ {
+ var username = e.Username.ToLower();
+ if (!ServerAccessConfiguration.ProtectedAccounts.Contains(username))
+ {
+ return;
+ }
+
+ var account = Accounts.GetAccount(username);
+ if (account is not { Banned: true, AccessLevel: >= AccessLevel.Owner })
+ {
+ return;
+ }
+
+ account.Banned = false;
+ account.AccessLevel = AccessLevel.Owner;
+
+ logger.Warning("Protected account \"{0}\" has been reset.", username);
+
+ if (ServerAccessConfiguration.NewPasswordOnReset)
+ {
+ var password = Guid.NewGuid().ToString();
+ logger.Warning("Protected account \"{0}\" password reset to \"{1}\"", username, password);
+ account.SetPassword(password);
+ }
+
+ e.Accepted = true;
+ }
+}
+
+public record ServerAccessConfiguration
+{
+ [JsonPropertyName("newPasswordOnReset")]
+ public bool NewPasswordOnReset { get; init; }
+
+ [JsonPropertyName("protectedAccounts")]
+ public HashSet ProtectedAccounts { get; init; }
+}
From 1989488638c73817a87a619a7cadf3299b0a5ea0 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Mon, 10 Jan 2022 23:32:12 -0800
Subject: [PATCH 003/178] fix: Fixes server access for owners (#916)
* Removes new password on reset option.
* Fixes a bug with the feature that would allow an exploit.
---
Projects/UOContent/Misc/ServerAccess.cs | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs
index 433055b86..c8278def4 100644
--- a/Projects/UOContent/Misc/ServerAccess.cs
+++ b/Projects/UOContent/Misc/ServerAccess.cs
@@ -5,6 +5,7 @@ using System.Text.Json.Serialization;
using Server.Accounting;
using Server.Json;
using Server.Logging;
+using Server.Network;
namespace Server.Misc;
@@ -67,33 +68,26 @@ public static class ServerAccess
return;
}
- var account = Accounts.GetAccount(username);
- if (account is not { Banned: true, AccessLevel: >= AccessLevel.Owner })
+ var acct = Accounts.GetAccount(username);
+ if (acct == null || !acct.Banned && acct.AccessLevel >= AccessLevel.Owner || !acct.CheckPassword(e.Password))
{
return;
}
- account.Banned = false;
- account.AccessLevel = AccessLevel.Owner;
+ acct.Banned = false;
+ acct.AccessLevel = AccessLevel.Owner;
logger.Warning("Protected account \"{0}\" has been reset.", username);
- if (ServerAccessConfiguration.NewPasswordOnReset)
+ if (e.RejectReason is ALRReason.Blocked or ALRReason.BadPass or ALRReason.BadComm)
{
- var password = Guid.NewGuid().ToString();
- logger.Warning("Protected account \"{0}\" password reset to \"{1}\"", username, password);
- account.SetPassword(password);
+ e.Accepted = true;
}
-
- e.Accepted = true;
}
}
public record ServerAccessConfiguration
{
- [JsonPropertyName("newPasswordOnReset")]
- public bool NewPasswordOnReset { get; init; }
-
[JsonPropertyName("protectedAccounts")]
public HashSet ProtectedAccounts { get; init; }
}
From cf5cc247db098d31c8f9927ca5236aa5b159f193 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sun, 16 Jan 2022 22:53:48 -0800
Subject: [PATCH 004/178] fix: Fixes server access NPE error (#919)
---
Projects/UOContent/Misc/ServerAccess.cs | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/Projects/UOContent/Misc/ServerAccess.cs b/Projects/UOContent/Misc/ServerAccess.cs
index c8278def4..9b43d604a 100644
--- a/Projects/UOContent/Misc/ServerAccess.cs
+++ b/Projects/UOContent/Misc/ServerAccess.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json.Serialization;
@@ -18,12 +17,15 @@ public static class ServerAccess
public static void SaveConfiguration()
{
var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath);
- JsonConfig.Serialize(path, ServerAccessConfiguration);
+
+ JsonConfig.Serialize(path, ServerAccessConfiguration ??= new ServerAccessConfiguration());
}
public static void AddProtectedAccount(Account acct, bool save = false)
{
- ServerAccessConfiguration.ProtectedAccounts.Add(acct.Username.ToLower());
+ var username = acct.Username.ToLower();
+ ServerAccessConfiguration.ProtectedAccounts.Add(username);
+ logger.Information("Protected account added: {0}", username);
if (save)
{
@@ -33,7 +35,9 @@ public static class ServerAccess
public static void RemoveProtectedAccount(Account acct, bool save = false)
{
- ServerAccessConfiguration.ProtectedAccounts.Remove(acct.Username.ToLower());
+ var username = acct.Username.ToLower();
+ ServerAccessConfiguration.ProtectedAccounts.Remove(username);
+ logger.Information("Protected account removed: {0}", username);
if (save)
{
@@ -47,6 +51,7 @@ public static class ServerAccess
if (!File.Exists(path))
{
+ SaveConfiguration();
return;
}
@@ -89,5 +94,5 @@ public static class ServerAccess
public record ServerAccessConfiguration
{
[JsonPropertyName("protectedAccounts")]
- public HashSet ProtectedAccounts { get; init; }
+ public HashSet ProtectedAccounts { get; set; } = new();
}
From 6fef622715d19b521c60d5343bb02b5c7eb06bf6 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sun, 30 Jan 2022 14:02:46 -0800
Subject: [PATCH 005/178] fix: Fixes en-us forced pricing culture throwing when
bulding in VS (#921)
* fix: Fixes en-us forced pricing culture throwing when bulding in VS
* Fixes value
---
Directory.Build.props | 1 +
1 file changed, 1 insertion(+)
diff --git a/Directory.Build.props b/Directory.Build.props
index d0e008643..500f44bb9 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -28,6 +28,7 @@
NO_LOCAL_INIT
MUO
$(SolutionDir)
+ false
true
From 01a41732f116974e3d0016349833965978da395a Mon Sep 17 00:00:00 2001
From: Stefano Merotta <97297186+stefanomerotta@users.noreply.github.com>
Date: Fri, 4 Feb 2022 18:33:12 +0100
Subject: [PATCH 006/178] fix: Fixes missing EJ houses in catalog (#925)
---
.gitignore | 1 +
Projects/UOContent/Multis/Houses/HousePlacementTool.cs | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index 325476c99..ae6dbf334 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,4 @@
.DS_Store
/packages/*
+/Distribution/Configuration/server-access.json
diff --git a/Projects/UOContent/Multis/Houses/HousePlacementTool.cs b/Projects/UOContent/Multis/Houses/HousePlacementTool.cs
index 56817bf22..19eafcb53 100644
--- a/Projects/UOContent/Multis/Houses/HousePlacementTool.cs
+++ b/Projects/UOContent/Multis/Houses/HousePlacementTool.cs
@@ -103,8 +103,9 @@ namespace Server.Items
{
case 1: // Classic Houses
{
- // TODO: Add flag to use ClassicHouses or EJ
- m_From.SendGump(new HousePlacementListGump(m_From, HousePlacementEntry.HousesEJ));
+ var entry = Core.EJ ? HousePlacementEntry.HousesEJ : HousePlacementEntry.ClassicHouses;
+ m_From.SendGump(new HousePlacementListGump(m_From, entry));
+
break;
}
case 2: // 2-Story Customizable Houses
@@ -318,7 +319,7 @@ namespace Server.Items
{
m_Table = new Dictionary();
- FillTable(ClassicHouses);
+ FillTable(Core.EJ ? HousesEJ : ClassicHouses);
FillTable(TwoStoryFoundations);
FillTable(ThreeStoryFoundations);
}
From 48f1fe338485d5047aafe1e01b6136f74cd9596c Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sat, 12 Feb 2022 17:58:42 -0800
Subject: [PATCH 007/178] fix: Moves codegen to its own repo (#918)
- [X] Replace serialization generator with nuget
- [X] Replace schema migration with dotnet bool
- [X] Add ability to run migrations in VS/Rider using a project build
---
.config/dotnet-tools.json | 12 +
Directory.Build.props | 2 +-
ModernUO.sln | 22 +-
.../Run Schema Migrations.csproj | 13 +
.../EntitySerializationGenerator.cs | 91 ----
.../SerializationGenerator/IsExternalInit.cs | 4 -
.../SerializableEntityGeneration.Class.cs | 436 ------------------
...zableEntityGeneration.DeserializeMethod.cs | 213 ---------
.../SerializableEntityGeneration.Property.cs | 82 ----
...SerializableEntityGeneration.SerialCtor.cs | 52 ---
...lizableEntityGeneration.SerializeMethod.cs | 112 -----
.../SerializableFieldSaveFlagMethods.cs | 11 -
...alizationEntityGeneration.ContentStruct.cs | 127 -----
.../IPostDeserializeMethod.cs | 31 --
.../ISerializableMigrationRule.cs | 57 ---
.../Rules/ArrayMigrationRule.cs | 135 ------
.../Rules/DictionaryMigrationRule.cs | 250 ----------
.../Rules/EnumMigrationRule.cs | 73 ---
.../Rules/HashSetMigrationRule.cs | 171 -------
.../Rules/KeyValuePairMigrationRule.cs | 225 ---------
.../Rules/ListMigrationRule.cs | 172 -------
.../Rules/MigrationRule.cs | 36 --
.../Rules/PrimitiveTypeMigrationRule.cs | 149 ------
.../Rules/PrimitiveUOTypeMigrationRule.cs | 80 ----
.../Rules/RawSerializableMigrationRule.cs | 82 ----
.../SerializableInterfaceMigrationRule.cs | 75 ---
...rializationMethodSignatureMigrationRule.cs | 85 ----
.../Rules/TimerMigrationRule.cs | 136 ------
.../SerializableMetadata.cs | 32 --
.../SerializableMetadataComparer.cs | 27 --
.../SerializableMigrationRulesEngine.cs | 133 ------
.../SerializableMigrationSchema.cs | 112 -----
.../SerializableProperty.cs | 40 --
.../SerializablePropertyComparer.cs | 42 --
.../SerializationGenerator.csproj | 31 --
.../SerializerSyntaxReceiver.cs | 133 ------
.../SourceGeneration/Helpers.cs | 65 ---
.../SourceGeneration.Arguments.cs | 125 -----
.../SourceGeneration.Attribute.cs | 102 ----
.../SourceGeneration.Class.cs | 72 ---
.../SourceGeneration/SourceGeneration.Enum.cs | 50 --
.../SourceGeneration.InstanceModifier.cs | 39 --
.../SourceGeneration.Method.cs | 62 ---
.../SourceGeneration.Namespace.cs | 33 --
.../SourceGeneration.Property.cs | 144 ------
.../SymbolMetadata/SymbolMetadata.Builtin.cs | 69 ---
.../SymbolMetadata/SymbolMetadata.UO.cs | 228 ---------
Projects/SerializationGenerator/Utility.cs | 28 --
.../SerializationSchemaGenerator/.gitignore | 1 -
.../Application.cs | 103 -----
.../SerializationSchemaGenerator.csproj | 23 -
.../SourceCodeAnalysis.cs | 49 --
.../SyntaxVisitor.cs | 52 ---
Projects/Server/Server.csproj | 10 +-
Projects/UOContent/UOContent.csproj | 12 +-
publish.cmd | 24 +-
56 files changed, 48 insertions(+), 4727 deletions(-)
create mode 100644 .config/dotnet-tools.json
create mode 100644 Projects/Schema Migrations/Run Schema Migrations.csproj
delete mode 100755 Projects/SerializationGenerator/EntitySerializationGenerator.cs
delete mode 100644 Projects/SerializationGenerator/IsExternalInit.cs
delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs
delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs
delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs
delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs
delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs
delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs
delete mode 100644 Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs
delete mode 100644 Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs
delete mode 100755 Projects/SerializationGenerator/SerializationGenerator.csproj
delete mode 100755 Projects/SerializationGenerator/SerializerSyntaxReceiver.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/Helpers.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs
delete mode 100644 Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs
delete mode 100644 Projects/SerializationGenerator/Utility.cs
delete mode 100644 Projects/SerializationSchemaGenerator/.gitignore
delete mode 100644 Projects/SerializationSchemaGenerator/Application.cs
delete mode 100755 Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
delete mode 100644 Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs
delete mode 100644 Projects/SerializationSchemaGenerator/SyntaxVisitor.cs
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 000000000..e0dbc85fc
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "modernuoschemagenerator": {
+ "version": "1.0.2",
+ "commands": [
+ "ModernUOSchemaGenerator"
+ ]
+ }
+ }
+}
diff --git a/Directory.Build.props b/Directory.Build.props
index 500f44bb9..4a52a9154 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -59,7 +59,7 @@
- 3.4.244
+ 3.4.255
all
diff --git a/ModernUO.sln b/ModernUO.sln
index 75eb761a4..3251fb4a4 100644
--- a/ModernUO.sln
+++ b/ModernUO.sln
@@ -12,9 +12,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UOContent.Tests", "Projects
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Projects\Benchmarks\Benchmarks.csproj", "{38B7E4A1-FDDD-486C-98EE-BA7B13712528}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationGenerator", "Projects\SerializationGenerator\SerializationGenerator.csproj", "{07DDB8CF-F926-44F4-A584-FF2997D2C9D0}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationSchemaGenerator", "Projects\SerializationSchemaGenerator\SerializationSchemaGenerator.csproj", "{A30150A3-796C-4C6D-B3E4-B7BEB0021701}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Run Schema Migrations", "Projects\Schema Migrations\Run Schema Migrations.csproj", "{75256276-FEAB-416C-9DB8-533FE816A0EF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -53,18 +51,12 @@ Global
{38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.Build.0 = Debug|x64
{38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.ActiveCfg = Release|x64
{38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.Build.0 = Release|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.ActiveCfg = Analyze|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.Build.0 = Analyze|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.ActiveCfg = Debug|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.Build.0 = Debug|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.ActiveCfg = Release|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.Build.0 = Release|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.ActiveCfg = Analyze|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.Build.0 = Analyze|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.ActiveCfg = Debug|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.Build.0 = Debug|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.ActiveCfg = Release|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.Build.0 = Release|x64
+ {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.ActiveCfg = Analyze|x64
+ {75256276-FEAB-416C-9DB8-533FE816A0EF}.Analyze|x64.Build.0 = Analyze|x64
+ {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.ActiveCfg = Debug|x64
+ {75256276-FEAB-416C-9DB8-533FE816A0EF}.Debug|x64.Build.0 = Debug|x64
+ {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.ActiveCfg = Release|x64
+ {75256276-FEAB-416C-9DB8-533FE816A0EF}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Projects/Schema Migrations/Run Schema Migrations.csproj b/Projects/Schema Migrations/Run Schema Migrations.csproj
new file mode 100644
index 000000000..39947e2f9
--- /dev/null
+++ b/Projects/Schema Migrations/Run Schema Migrations.csproj
@@ -0,0 +1,13 @@
+
+
+ Schema_Migrations
+
+
+
+
+
+
+
+
+
+
diff --git a/Projects/SerializationGenerator/EntitySerializationGenerator.cs b/Projects/SerializationGenerator/EntitySerializationGenerator.cs
deleted file mode 100755
index e5b1e0f0d..000000000
--- a/Projects/SerializationGenerator/EntitySerializationGenerator.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: EntityJsonGenerator.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 . *
- *************************************************************************/
-
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- [Generator]
- public class EntitySerializationGenerator : ISourceGenerator
- {
- public void Initialize(GeneratorInitializationContext context)
- {
- context.RegisterForSyntaxNotifications(() => new SerializerSyntaxReceiver());
- }
-
- public void Execute(GeneratorExecutionContext context)
- {
- if (context.SyntaxContextReceiver is not SerializerSyntaxReceiver receiver)
- {
- return;
- }
-
- var jsonOptions = SerializableMigrationSchema.GetJsonSerializerOptions();
- // List of types that _will_ become ISerializable
- var serializableList = receiver.SerializableList;
- var embeddedSerializableList = receiver.EmbeddedSerializableList;
-
- foreach (var (classSymbol, (serializableAttr, fieldsList)) in receiver.ClassAndFields)
- {
- if (serializableAttr == null)
- {
- continue;
- }
-
- string classSource = context.GenerateSerializationPartialClass(
- classSymbol,
- serializableAttr,
- false,
- fieldsList.ToImmutableArray(),
- jsonOptions,
- serializableList,
- embeddedSerializableList
- );
-
- if (classSource != null)
- {
- context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
- }
- }
-
- foreach (var (classSymbol, (embeddedSerializableAttr, fieldsList)) in receiver.EmbeddedClassAndFields)
- {
- if (embeddedSerializableAttr == null)
- {
- continue;
- }
-
- string classSource = context.GenerateSerializationPartialClass(
- classSymbol,
- embeddedSerializableAttr,
- true,
- fieldsList.ToImmutableArray(),
- jsonOptions,
- serializableList,
- embeddedSerializableList
- );
-
- if (classSource != null)
- {
- context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
- }
- }
- }
- }
-}
diff --git a/Projects/SerializationGenerator/IsExternalInit.cs b/Projects/SerializationGenerator/IsExternalInit.cs
deleted file mode 100644
index eb2da113f..000000000
--- a/Projects/SerializationGenerator/IsExternalInit.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace System.Runtime.CompilerServices
-{
- internal static class IsExternalInit {}
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs
deleted file mode 100644
index 7611d5799..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs
+++ /dev/null
@@ -1,436 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.Class.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static string GenerateSerializationPartialClass(
- this GeneratorExecutionContext context,
- INamedTypeSymbol classSymbol,
- AttributeData serializableAttr,
- bool embedded,
- ImmutableArray fieldsAndProperties,
- JsonSerializerOptions jsonSerializerOptions,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes
- )
- {
- var version = (int)serializableAttr.ConstructorArguments[0].Value!;
-
- var migrations = context.GetMigrationsByAnalyzerConfig(
- classSymbol,
- version,
- jsonSerializerOptions
- );
-
- return context.Compilation.GenerateSerializationPartialClass(
- classSymbol,
- serializableAttr,
- null, // Do not generate schema
- embedded,
- null,
- migrations.ToImmutableArray(),
- fieldsAndProperties,
- serializableTypes,
- embeddedSerializableTypes
- );
- }
-
- public static string GenerateSerializationPartialClass(
- this Compilation compilation,
- INamedTypeSymbol classSymbol,
- AttributeData serializableAttr,
- string? migrationPath,
- bool embedded,
- JsonSerializerOptions? jsonSerializerOptions,
- ImmutableArray fieldsAndProperties,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes
- )
- {
- var version = (int)serializableAttr.ConstructorArguments[0].Value!;
-
- var migrations = SerializableMigrationSchema.GetMigrations(
- classSymbol,
- version,
- migrationPath,
- jsonSerializerOptions
- );
-
- return compilation.GenerateSerializationPartialClass(
- classSymbol,
- serializableAttr,
- migrationPath,
- embedded,
- jsonSerializerOptions,
- migrations.ToImmutableArray(),
- fieldsAndProperties,
- serializableTypes,
- embeddedSerializableTypes
- );
- }
-
- public static string GenerateSerializationPartialClass(
- this Compilation compilation,
- INamedTypeSymbol classSymbol,
- AttributeData serializableAttr,
- string? migrationPath,
- bool embedded,
- JsonSerializerOptions? jsonSerializerOptions,
- ImmutableArray migrations,
- ImmutableArray fieldsAndProperties,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes
- )
- {
- var serializableFieldAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
- var serializableFieldAttrAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTR_ATTRIBUTE);
- var serializableInterface =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_INTERFACE);
- var parentSerializableAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
- var serializableFieldSaveFlagAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE);
- var serializableFieldDefaultAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE);
-
- // If we have a parent that is or derives from ISerializable, then we are in override
- var isOverride = classSymbol.BaseType.ContainsInterface(serializableInterface);
-
- if (!(embedded || isOverride || classSymbol.ContainsInterface(serializableInterface)))
- {
- return null;
- }
-
- var isRawSerializable = classSymbol.HasRawSerializableInterface(compilation, ImmutableArray.Empty);
-
- var version = (int)serializableAttr.ConstructorArguments[0].Value!;
- var encodedVersion = (bool)serializableAttr.ConstructorArguments[1].Value!;
-
- // Let's find out if we need to do serialization flags
- var serializableFieldSaveFlags = new SortedDictionary();
- foreach (var m in classSymbol.GetMembers().OfType())
- {
- var getSaveFlagAttribute = m.GetAttribute(serializableFieldSaveFlagAttribute);
- var getDefaultValueAttribute = m.GetAttribute(serializableFieldDefaultAttribute);
-
- if (getSaveFlagAttribute == null && getDefaultValueAttribute == null)
- {
- continue;
- }
-
- var attrCtorArgs = getSaveFlagAttribute?.ConstructorArguments ?? getDefaultValueAttribute.ConstructorArguments;
- var order = (int)attrCtorArgs[0].Value!;
-
- serializableFieldSaveFlags.TryGetValue(order, out var saveFlagMethods);
-
- serializableFieldSaveFlags[order] = new SerializableFieldSaveFlagMethods
- {
- DetermineFieldShouldSerialize = getSaveFlagAttribute != null ? m : saveFlagMethods?.DetermineFieldShouldSerialize,
- GetFieldDefaultValue = getDefaultValueAttribute != null ? m : saveFlagMethods?.GetFieldDefaultValue
- };
- }
-
- var namespaceName = classSymbol.ContainingNamespace.ToDisplayString();
- var className = classSymbol.Name;
-
- StringBuilder source = new StringBuilder();
-
- source.AppendLine("#pragma warning disable\n");
- source.GenerateNamespaceStart(namespaceName);
-
- var interfaces = !embedded || isRawSerializable
- ? Array.Empty()
- : new ITypeSymbol[] { compilation.GetTypeByMetadataName(SymbolMetadata.RAW_SERIALIZABLE_INTERFACE) };
-
- var indent = " ";
-
- source.RecursiveGenerateClassStart(classSymbol, interfaces.ToImmutableArray(), ref indent);
-
- source.GenerateClassField(
- indent,
- Accessibility.Private,
- InstanceModifier.Const,
- "int",
- "_version",
- version.ToString()
- );
- source.AppendLine();
-
- var parentFieldOrProperty = embedded ? fieldsAndProperties.FirstOrDefault(
- fieldOrPropertySymbol => fieldOrPropertySymbol.GetAttributes()
- .FirstOrDefault(
- attr =>
- SymbolEqualityComparer.Default.Equals(attr.AttributeClass, parentSerializableAttribute)
- ) != null
- ) : null;
-
- var serializablePropertySet = new SortedDictionary(new SerializablePropertyComparer());
-
- foreach (var fieldOrPropertySymbol in fieldsAndProperties)
- {
- var allAttributes = fieldOrPropertySymbol.GetAttributes();
-
- var serializableFieldAttr = allAttributes
- .FirstOrDefault(
- attr =>
- SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttribute)
- );
-
- if (serializableFieldAttr == null)
- {
- continue;
- }
-
- foreach (var attr in allAttributes)
- {
- if (!SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttrAttribute))
- {
- continue;
- }
-
- if (attr.AttributeClass == null)
- {
- continue;
- }
-
- var ctorArgs = attr.ConstructorArguments;
- var attrTypeArg = ctorArgs[0];
-
- if (attrTypeArg.Kind == TypedConstantKind.Primitive && attrTypeArg.Value is string attrStr)
- {
- source.AppendLine($"{indent}{attrStr}");
- }
- else
- {
- var attrType = (ITypeSymbol)attrTypeArg.Value;
- source.GenerateAttribute(indent, attrType?.Name, ctorArgs[1].Values);
- }
- }
-
- var attrCtorArgs = serializableFieldAttr.ConstructorArguments;
-
- var order = (int)attrCtorArgs[0].Value!;
- var getterAccessor = Helpers.GetAccessibility(attrCtorArgs[1].Value?.ToString());
- var setterAccessor = Helpers.GetAccessibility(attrCtorArgs[2].Value?.ToString());
- var virtualProperty = (bool)attrCtorArgs[3].Value!;
-
- if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol)
- {
- source.GenerateSerializableProperty(
- compilation,
- indent,
- fieldSymbol,
- getterAccessor,
- setterAccessor,
- virtualProperty,
- parentFieldOrProperty
- );
- source.AppendLine();
- }
-
- serializableFieldSaveFlags.TryGetValue(order, out var serializableFieldSaveFlagMethods);
-
- var serializableProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- fieldOrPropertySymbol,
- order,
- allAttributes,
- serializableTypes,
- embeddedSerializableTypes,
- classSymbol,
- serializableFieldSaveFlagMethods
- );
-
- serializablePropertySet.Add(serializableProperty, fieldOrPropertySymbol);
- }
-
- var serializableFields = serializablePropertySet.Keys.ToImmutableArray();
- var serializableProperties = serializablePropertySet.Select(
- kvp => kvp.Key with
- {
- Name = (kvp.Value as IFieldSymbol)?.GetPropertyName() ?? ((IPropertySymbol)kvp.Value).Name
- }
- ).ToImmutableArray();
-
- // If we are not inheriting ISerializable, then we need to define some stuff
- if (!(isOverride || embedded))
- {
- // long ISerializable.SavePosition { get; set; } = -1;
- source.GenerateAutoProperty(
- Accessibility.NotApplicable,
- "long",
- "ISerializable.SavePosition",
- Accessibility.NotApplicable,
- Accessibility.NotApplicable,
- indent,
- defaultValue: "-1"
- );
-
- // BufferWriter ISerializable.SaveBuffer { get; set; }
- source.GenerateAutoProperty(
- Accessibility.NotApplicable,
- "BufferWriter",
- "ISerializable.SaveBuffer",
- Accessibility.NotApplicable,
- Accessibility.NotApplicable,
- indent
- );
- }
-
- if (!embedded)
- {
- // Serial constructor
- source.GenerateSerialCtor(compilation, className, indent, isOverride);
- source.AppendLine();
- }
-
- if (version > 0)
- {
- for (var i = 0; i < migrations.Length; i++)
- {
- var migration = migrations[i];
- if (migration.Version < version)
- {
- source.GenerateMigrationContentStruct(compilation, indent, migration, classSymbol);
- source.AppendLine();
- }
- }
- }
-
- // Serialize Method
- source.GenerateSerializeMethod(
- compilation,
- indent,
- isOverride,
- encodedVersion,
- serializableFields,
- serializableProperties,
- serializableFieldSaveFlags
- );
- source.AppendLine();
-
- // Deserialize Method
- source.GenerateDeserializeMethod(
- compilation,
- classSymbol,
- indent,
- isOverride,
- version,
- encodedVersion,
- migrations,
- serializableFields,
- serializableProperties,
- parentFieldOrProperty,
- serializableFieldSaveFlags
- );
-
- // Serialize SaveFlag enum class
- if (serializableFieldSaveFlags.Count > 0)
- {
- source.AppendLine();
- source.GenerateEnumStart(
- "SaveFlag",
- $"{indent} ",
- true,
- Accessibility.Private
- );
-
- source.GenerateEnumValue($"{indent} ", true, "None", -1);
- int index = 0;
- foreach (var (order, _) in serializableFieldSaveFlags)
- {
- source.GenerateEnumValue($"{indent} ", true, serializableProperties[order].Name, index++);
- }
-
- source.GenerateEnumEnd($"{indent} ");
- }
-
- source.RecursiveGenerateClassEnd(classSymbol, ref indent);
- source.GenerateNamespaceEnd();
-
- if (migrationPath != null)
- {
- // Write the migration file
- var newMigration = new SerializableMetadata
- {
- Version = version,
- Type = classSymbol.ToDisplayString(),
- Properties = serializableProperties.Length > 0 ? serializableProperties : null
- };
-
- WriteMigration(migrationPath, newMigration, jsonSerializerOptions);
- }
-
- return source.ToString();
- }
-
- private static void WriteMigration(string migrationPath, SerializableMetadata metadata, JsonSerializerOptions options)
- {
- Directory.CreateDirectory(migrationPath);
- var filePath = Path.Combine(migrationPath, $"{metadata.Type}.v{metadata.Version}.json");
- File.WriteAllText(filePath, JsonSerializer.Serialize(metadata, options));
- }
-
- private static void RecursiveGenerateClassStart(
- this StringBuilder source,
- INamedTypeSymbol classSymbol,
- ImmutableArray interfaces,
- ref string indent
- )
- {
- var containingSymbolList = new List();
-
- do
- {
- containingSymbolList.Add(classSymbol);
- classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol;
- } while (classSymbol != null);
-
- containingSymbolList.Reverse();
-
- for (var i = 0; i < containingSymbolList.Count; i++)
- {
- var symbol = containingSymbolList[i];
- source.GenerateClassStart(symbol, indent, i == containingSymbolList.Count - 1 ? interfaces : ImmutableArray.Empty);
- indent += " ";
- }
- }
-
- private static void RecursiveGenerateClassEnd(this StringBuilder source, INamedTypeSymbol classSymbol, ref string indent)
- {
- do
- {
- indent = indent.Substring(0, indent.Length - 4);
- source.GenerateClassEnd(indent);
-
- classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol;
- } while (classSymbol != null);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs
deleted file mode 100644
index 59048a125..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs
+++ /dev/null
@@ -1,213 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.DeserializeMethod.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 . *
- *************************************************************************/
-
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateDeserializeMethod(
- this StringBuilder source,
- Compilation compilation,
- INamedTypeSymbol classSymbol,
- string indent,
- bool isOverride,
- int version,
- bool encodedVersion,
- ImmutableArray migrations,
- ImmutableArray fields,
- ImmutableArray properties,
- ISymbol parentFieldOrProperty,
- SortedDictionary serializableFieldSaveFlagMethodsDictionary
- )
- {
- var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE);
-
- source.GenerateMethodStart(
- indent,
- "Deserialize",
- Accessibility.Public,
- isOverride,
- "void",
- ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader"))
- );
-
- var bodyIndent = $"{indent} ";
- var innerIndent = $"{bodyIndent} ";
-
- if (isOverride)
- {
- source.AppendLine($"{bodyIndent}base.Deserialize(reader);");
- source.AppendLine();
- }
-
- var afterDeserialization = classSymbol
- .GetMembers()
- .OfType()
- .Select(
- m =>
- {
- if (!m.ReturnsVoid || m.Parameters.Length != 0)
- {
- return (m, null);
- }
-
- return (m, m.GetAttributes()
- .FirstOrDefault(
- attr => SymbolEqualityComparer.Default.Equals(
- attr.AttributeClass,
- compilation.GetTypeByMetadataName(SymbolMetadata.AFTERDESERIALIZATION_ATTRIBUTE)
- )
- ));
- }
- ).Where(m => m.Item2 != null).ToList();
-
- // Version
- source.AppendLine($"{bodyIndent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();");
-
- if (version > 0)
- {
- var parent = parentFieldOrProperty?.Name ?? "this";
- var nextVersion = 0;
-
- for (var i = 0; i < migrations.Length; i++)
- {
- var migrationVersion = migrations[i].Version;
- if (migrationVersion == nextVersion)
- {
- nextVersion++;
- }
-
- source.AppendLine();
- source.AppendLine($"{bodyIndent}if (version == {migrationVersion})");
- source.AppendLine($"{bodyIndent}{{");
- source.AppendLine($"{bodyIndent} MigrateFrom(new V{migrationVersion}Content(reader, this));");
- source.AppendLine($"{bodyIndent} {parent}.MarkDirty();");
- source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization);
- source.AppendLine($"{bodyIndent} return;");
- source.AppendLine($"{bodyIndent}}}");
- }
-
- if (nextVersion < version)
- {
- source.AppendLine();
- source.AppendLine($"{bodyIndent}if (version < _version)");
- source.AppendLine($"{bodyIndent}{{");
- source.AppendLine($"{bodyIndent} Deserialize(reader, version);");
- source.AppendLine($"{bodyIndent} {parent}.MarkDirty();");
- source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization);
- source.AppendLine($"{bodyIndent} return;");
- source.AppendLine($"{bodyIndent}}}");
- }
- }
-
- if (serializableFieldSaveFlagMethodsDictionary.Count > 0)
- {
- source.AppendLine();
- source.AppendLine($"{bodyIndent}var saveFlags = reader.ReadEnum();");
- }
-
- for (var i = 0; i < properties.Length; i++)
- {
- var field = fields[i];
- var property = properties[i];
- var rule = SerializableMigrationRulesEngine.Rules[property.Rule];
-
- if (serializableFieldSaveFlagMethodsDictionary.TryGetValue(
- property.Order,
- out var serializableFieldSaveFlagMethods
- ))
- {
- source.AppendLine();
- // Special case
- if (property.Type == "bool")
- {
- source.AppendLine($"{bodyIndent}{field.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;");
- }
- else
- {
- source.AppendLine($"{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{");
- rule.GenerateDeserializationMethod(
- source,
- innerIndent,
- field,
- parentFieldOrProperty?.Name ?? "this"
- );
- (rule as IPostDeserializeMethod)?.PostDeserializeMethod(
- source,
- innerIndent,
- field,
- compilation,
- classSymbol
- );
-
- if (serializableFieldSaveFlagMethods.GetFieldDefaultValue != null)
- {
- source.AppendLine($"{bodyIndent}}}\n{bodyIndent}else\n{bodyIndent}{{");
- source.AppendLine(
- $"{bodyIndent} {field.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();"
- );
- }
-
- source.AppendLine($"{bodyIndent}}}");
- }
- }
- else
- {
- source.AppendLine();
- rule.GenerateDeserializationMethod(
- source,
- bodyIndent,
- field,
- parentFieldOrProperty?.Name ?? "this"
- );
- (rule as IPostDeserializeMethod)?.PostDeserializeMethod(
- source,
- bodyIndent,
- field,
- compilation,
- classSymbol
- );
- }
- }
-
- source.GenerateAfterDeserialization($"{bodyIndent}", afterDeserialization);
- source.GenerateMethodEnd(indent);
- }
-
- private static void GenerateAfterDeserialization(
- this StringBuilder source, string indent, IList<(IMethodSymbol, AttributeData?)> afterDeserialization
- )
- {
- foreach (var (method, attr) in afterDeserialization)
- {
- if ((bool)attr.ConstructorArguments[0].Value!)
- {
- source.AppendLine($"{indent}{method.Name}();");
- }
- else
- {
- source.AppendLine($"{indent}Timer.DelayCall({method.Name});");
- }
- }
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs
deleted file mode 100644
index d2457bb90..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.Property.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 . *
- *************************************************************************/
-
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateSerializableProperty(
- this StringBuilder source,
- Compilation compilation,
- string indent,
- IFieldSymbol fieldSymbol,
- Accessibility getter,
- Accessibility? setter,
- bool isVirtual,
- ISymbol? parentFieldOrProperty
- )
- {
- var fieldName = fieldSymbol.Name;
-
- var invalidatePropertiesAttribute = fieldSymbol
- .GetAttributes()
- .OfType()
- .FirstOrDefault(
- attr => attr.AttributeClass?.Equals(
- compilation.GetTypeByMetadataName(SymbolMetadata.INVALIDATEPROPERTIES_ATTRIBUTE),
- SymbolEqualityComparer.Default
- ) ?? false
- );
-
- var propertyIndent = $"{indent} ";
- var innerIndent = $"{propertyIndent} ";
-
- var propertyAccessor = setter > getter ? setter : getter;
- var getterAccessor = getter == propertyAccessor ? Accessibility.NotApplicable : getter;
-
- source.GeneratePropertyStart(indent, propertyAccessor.Value, isVirtual, fieldSymbol);
-
- // Getter
- source.GeneratePropertyGetterReturnsField(propertyIndent, fieldSymbol, getterAccessor);
-
- if (setter != null && setter != Accessibility.NotApplicable)
- {
- var setterAccessor = setter == propertyAccessor ? Accessibility.NotApplicable : setter;
-
- var parentSymbol = parentFieldOrProperty?.Name ?? "this";
-
- // Setter
- source.GeneratePropertySetterStart(propertyIndent, false, setterAccessor.Value);
- source.AppendLine($"{innerIndent}if (value != {fieldName})");
- source.AppendLine($"{innerIndent}{{");
- source.AppendLine($"{innerIndent} {fieldName} = value;");
- source.AppendLine($"{innerIndent} {parentSymbol}.MarkDirty();");
-
- if (invalidatePropertiesAttribute != null)
- {
- source.AppendLine($"{innerIndent} InvalidateProperties();");
- }
- source.AppendLine($"{innerIndent}}}");
- source.GeneratePropertyGetSetEnd(propertyIndent, false);
- }
-
- source.GeneratePropertyEnd(indent);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs
deleted file mode 100644
index 7b7ebcb7f..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.SerialCtor.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 . *
- *************************************************************************/
-
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- private static readonly ImmutableArray _baseParameters = new[] { "serial" }.ToImmutableArray();
- public static void GenerateSerialCtor(
- this StringBuilder source,
- Compilation compilation,
- string className,
- string indent,
- bool isOverride
- )
- {
- var serialType = (ITypeSymbol)compilation.GetTypeByMetadataName("Server.Serial");
-
- source.GenerateConstructorStart(
- indent,
- className,
- Accessibility.Public,
- new []{ (serialType, "serial") }.ToImmutableArray(),
- isOverride ? _baseParameters : ImmutableArray.Empty
- );
-
- if (!isOverride)
- {
- source.AppendLine($"{indent} Serial = serial;");
- source.AppendLine($"{indent} SetTypeRef(typeof({className}));");
- }
-
- source.GenerateMethodEnd(indent);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs
deleted file mode 100644
index 6aff93f5e..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.SerializeMethod.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 . *
- *************************************************************************/
-
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateSerializeMethod(
- this StringBuilder source,
- Compilation compilation,
- string indent,
- bool isOverride,
- bool encodedVersion,
- ImmutableArray fields,
- ImmutableArray properties,
- SortedDictionary serializableFieldSaveFlagMethodsDictionary
- )
- {
- var genericWriterInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_WRITER_INTERFACE);
-
- source.GenerateMethodStart(
- indent,
- "Serialize",
- Accessibility.Public,
- isOverride,
- "void",
- ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer"))
- );
-
- var bodyIndent = $"{indent} ";
- var innerIndent = $"{bodyIndent} ";
-
- if (isOverride)
- {
- source.AppendLine($"{bodyIndent}base.Serialize(writer);");
- source.AppendLine();
- }
-
- // Version
- source.AppendLine($"{bodyIndent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);");
-
- // Let's collect the flags
- if (serializableFieldSaveFlagMethodsDictionary.Count > 0)
- {
- source.AppendLine($"\n{bodyIndent}var saveFlags = SaveFlag.None;");
-
- foreach (var (order, saveFlagMethods) in serializableFieldSaveFlagMethodsDictionary)
- {
- source.AppendLine($"{bodyIndent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{bodyIndent}{{");
-
- var propertyName = properties[order].Name;
- source.AppendLine($"{innerIndent}saveFlags |= SaveFlag.{propertyName};");
-
- source.AppendLine($"{bodyIndent}}}");
- }
-
- source.AppendLine($"{bodyIndent}writer.WriteEnum(saveFlags);");
- }
-
- for (var i = 0; i < properties.Length; i++)
- {
- var field = fields[i];
- var property = properties[i];
- if (serializableFieldSaveFlagMethodsDictionary.ContainsKey(property.Order))
- {
- // Special case
- if (property.Type != "bool")
- {
- source.AppendLine($"\n{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{");
- SerializableMigrationRulesEngine.Rules[property.Rule]
- .GenerateSerializationMethod(
- source,
- innerIndent,
- field
- );
- source.AppendLine($"{bodyIndent}}}");
- }
- }
- else
- {
- source.AppendLine();
- SerializableMigrationRulesEngine.Rules[property.Rule]
- .GenerateSerializationMethod(
- source,
- bodyIndent,
- field
- );
- }
- }
-
- source.GenerateMethodEnd(indent);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs
deleted file mode 100644
index 55a087914..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public record SerializableFieldSaveFlagMethods
- {
- public IMethodSymbol? DetermineFieldShouldSerialize { get; init; }
-
- public IMethodSymbol? GetFieldDefaultValue { get; init; }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
deleted file mode 100644
index 56544ed60..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializationEntityGeneration.ContentStruct.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 . *
- *************************************************************************/
-
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateMigrationContentStruct(
- this StringBuilder source,
- Compilation compilation,
- string indent,
- SerializableMetadata migration,
- INamedTypeSymbol classSymbol
- )
- {
- source.AppendLine($"{indent}ref struct V{migration.Version}Content");
- source.AppendLine($"{indent}{{");
- var properties = migration.Properties ?? ImmutableArray.Empty;
-
- foreach (var serializableProperty in properties)
- {
- SerializableMigrationRulesEngine.Rules[serializableProperty.Rule].GenerateMigrationProperty(
- source, compilation, $"{indent} ", serializableProperty
- );
- }
-
- var innerIndent = $"{indent} ";
-
- var usesSaveFlags = properties.Any(p => p.UsesSaveFlag == true);
-
- if (usesSaveFlags)
- {
- source.AppendLine();
- source.GenerateEnumStart(
- $"V{migration.Version}SaveFlag",
- $"{indent} ",
- true,
- Accessibility.Private
- );
-
- source.GenerateEnumValue(innerIndent, true, "None", -1);
- int index = 0;
- foreach (var property in properties)
- {
- if (property.UsesSaveFlag == true)
- {
- source.GenerateEnumValue(innerIndent, true, property.Name, index++);
- }
- }
-
- source.GenerateEnumEnd($"{indent} ");
- }
-
- source.AppendLine($"{indent} internal V{migration.Version}Content(IGenericReader reader, {classSymbol.ToDisplayString()} entity)");
- source.AppendLine($"{indent} {{");
-
- if (usesSaveFlags)
- {
- source.AppendLine($"{innerIndent}var saveFlags = reader.ReadEnum();");
- }
-
- if (properties.Length > 0)
- {
- foreach (var property in properties)
- {
- if (property.UsesSaveFlag == true)
- {
- source.AppendLine();
- // Special case
- if (property.Type == "bool")
- {
- source.AppendLine($"{innerIndent}{property.Name} = (saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0;");
- }
- else
- {
- source.AppendLine($"{innerIndent}if ((saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0)\n{innerIndent}{{");
-
- SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod(
- source,
- $"{innerIndent} ",
- property,
- "entity",
- true
- );
-
- source.AppendLine($"{innerIndent}}}\n{innerIndent}else\n{innerIndent}{{");
- source.AppendLine($"{innerIndent} {property.Name} = default;");
- source.AppendLine($"{innerIndent}}}");
- }
- }
- else
- {
- SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod(
- source,
- innerIndent,
- property,
- "entity",
- true
- );
- }
- }
- }
-
- source.AppendLine($"{indent} }}");
-
- source.AppendLine($"{indent}}}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs b/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs
deleted file mode 100644
index 0a48c0117..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: IPostDeserializeMethod.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 . *
- *************************************************************************/
-
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration
-{
- public interface IPostDeserializeMethod
- {
- public void PostDeserializeMethod(
- StringBuilder source,
- string indent,
- SerializableProperty property,
- Compilation compilation,
- INamedTypeSymbol classSymbol
- );
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
deleted file mode 100644
index a64453e33..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableMigrationRule.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 . *
- *************************************************************************/
-
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration
-{
- public interface ISerializableMigrationRule
- {
- string RuleName { get; }
-
- void GenerateMigrationProperty(
- StringBuilder source,
- Compilation compilation,
- string indent,
- SerializableProperty serializableProperty
- );
-
- bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- );
-
- void GenerateDeserializationMethod(
- StringBuilder source,
- string indent,
- SerializableProperty property,
- string? parentReference,
- bool isMigration = false
- );
-
- void GenerateSerializationMethod(
- StringBuilder source,
- string indent,
- SerializableProperty property
- );
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
deleted file mode 100644
index 99a1e911e..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: ArrayMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration;
-
-public class ArrayMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(ArrayMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not IArrayTypeSymbol arrayTypeSymbol)
- {
- ruleArguments = null;
- return false;
- }
-
- var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "ArrayEntry",
- arrayTypeSymbol.ElementType,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var length = serializableArrayType.RuleArguments?.Length?? 0;
- ruleArguments = new string[length + 2];
- ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString();
- ruleArguments[1] = serializableArrayType.Rule;
- if (length > 0)
- {
- Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length);
- }
-
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
- var ruleArguments = property.RuleArguments;
- var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
- var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
- Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
-
- var propertyIndex = $"{property.Name}Index";
- source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableArrayElement = new SerializableProperty
- {
- Name = $"{property.Name}[{propertyIndex}]",
- Type = ruleArguments[0],
- Rule = arrayElementRule.RuleName,
- RuleArguments = arrayElementRuleArguments
- };
-
- arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference);
-
- source.AppendLine($"{indent}}}");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
- var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
- Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyIndex = $"{propertyVarPrefix}Index";
- var propertyLength = $"{propertyVarPrefix}Length";
- source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;");
- source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableArrayElement = new SerializableProperty
- {
- Name = $"{property.Name}![{propertyIndex}]",
- Type = ruleArguments[0],
- Rule = arrayElementRule.RuleName,
- RuleArguments = arrayElementRuleArguments
- };
-
- arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement);
-
- source.AppendLine($"{indent}}}");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
deleted file mode 100644
index caf0d1dc8..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: DictionaryMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class DictionaryMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(DictionaryMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation))
- {
- ruleArguments = null;
- return false;
- }
-
- var keySymbolType = namedTypeSymbol.TypeArguments[0];
-
- var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "KeyEntry",
- keySymbolType,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var valueSymbolType = namedTypeSymbol.TypeArguments[1];
-
- var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "ValueEntry",
- valueSymbolType,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var extraOptions = "";
- if (attributes.Any(a => a.IsTidy(compilation)))
- {
- extraOptions += "@Tidy";
- }
-
- var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0;
- var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0;
- var index = 0;
-
- ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength];
- ruleArguments[index++] = extraOptions;
- ruleArguments[index++] = keySymbolType.ToDisplayString();
- ruleArguments[index++] = serializableKeyProperty.Rule;
- ruleArguments[index++] = keyArgumentsLength.ToString();
-
- if (keyArgumentsLength > 0)
- {
- Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
- index += keyArgumentsLength;
- }
-
- ruleArguments[index++] = valueSymbolType.ToDisplayString();
- ruleArguments[index++] = serializableValueProperty.Rule;
- ruleArguments[index++] = valueArgumentsLength.ToString();
-
- if (valueArgumentsLength > 0)
- {
- Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
- }
-
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var index = 1;
- var keyType = ruleArguments![index++];
-
- var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
- var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (keyRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
- index += keyRuleArguments.Length;
- }
-
- var valueType = ruleArguments[index++];
- var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
- var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (valueRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
- }
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyIndex = $"{propertyVarPrefix}Index";
- var propertyKeyEntry = $"{propertyVarPrefix}Key";
- var propertyValueEntry = $"{propertyVarPrefix}Value";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};");
- source.AppendLine($"{indent}{valueType} {propertyValueEntry};");
- source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
- source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableKeyElement = new SerializableProperty
- {
- Name = propertyKeyEntry,
- Type = keyType,
- Rule = keyElementRule.RuleName,
- RuleArguments = keyRuleArguments
- };
-
- keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference);
-
- var serializableValueElement = new SerializableProperty
- {
- Name = propertyValueEntry,
- Type = valueType,
- Rule = valueElementRule.RuleName,
- RuleArguments = valueRuleArguments
- };
-
- valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference);
- source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});");
-
- source.AppendLine($"{indent}}}");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var index = 0;
- var shouldTidy = ruleArguments![index++].Contains("@Tidy");
- var keyType = ruleArguments![index++];
-
- var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]];
- var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (keyRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
- index += keyRuleArguments.Length;
- }
-
- var valueType = ruleArguments[index++];
- var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
- var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (valueRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
- }
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyKeyEntry = $"{propertyVarPrefix}Key";
- var propertyValueEntry = $"{propertyVarPrefix}Value";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- if (shouldTidy)
- {
- source.AppendLine($"{indent}{property.Name}?.Tidy();");
- }
- source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
- source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
- source.AppendLine($"{indent}if ({propertyCount} > 0)");
- source.AppendLine($"{indent}{{");
- source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)");
- source.AppendLine($"{indent} {{");
-
- var serializableKeyElement = new SerializableProperty
- {
- Name = propertyKeyEntry,
- Type = keyType,
- Rule = keyElementRule.RuleName,
- RuleArguments = keyRuleArguments
- };
-
- keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement);
-
- var serializableValueElement = new SerializableProperty
- {
- Name = propertyValueEntry,
- Type = valueType,
- Rule = valueElementRule.RuleName,
- RuleArguments = valueRuleArguments
- };
-
- valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement);
-
- source.AppendLine($"{indent} }}");
- source.AppendLine($"{indent}}}");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs
deleted file mode 100644
index 5e8d7fd45..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: EnumMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class EnumMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(EnumMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = Array.Empty();
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs
deleted file mode 100644
index 20fe03d08..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs
+++ /dev/null
@@ -1,171 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: HashSetMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class HashSetMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(HashSetMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation))
- {
- ruleArguments = null;
- return false;
- }
-
- var setTypeSymbol = namedTypeSymbol.TypeArguments[0];
-
- var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "SetEntry",
- setTypeSymbol,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var extraOptions = "";
- if (attributes.Any(a => a.IsTidy(compilation)))
- {
- extraOptions += "@Tidy";
- }
-
- var length = serializableSetType.RuleArguments?.Length ?? 0;
- ruleArguments = new string[length + 3];
- ruleArguments[0] = extraOptions;
- ruleArguments[1] = setTypeSymbol.ToDisplayString();
- ruleArguments[2] = serializableSetType.Rule;
-
- if (length > 0)
- {
- Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length);
- }
-
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
- var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyIndex = $"{propertyVarPrefix}Index";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
- source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
- source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableSetElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = setElementRule.RuleName,
- RuleArguments = setElementRuleArguments
- };
-
- setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference);
- source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});");
-
- source.AppendLine($"{indent}}}");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
- var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- if (shouldTidy)
- {
- source.AppendLine($"{indent}{property.Name}?.Tidy();");
- }
- source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
- source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
- source.AppendLine($"{indent}if ({propertyCount} > 0)");
- source.AppendLine($"{indent}{{");
- source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
- source.AppendLine($"{indent} {{");
-
- var serializableSetElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = setElementRule.RuleName,
- RuleArguments = setElementRuleArguments
- };
-
- setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement);
-
- source.AppendLine($"{indent} }}");
- source.AppendLine($"{indent}}}");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
deleted file mode 100644
index 5b7c4fbef..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: KeyValuePairMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class KeyValuePairMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(KeyValuePairMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation))
- {
- ruleArguments = null;
- return false;
- }
-
- var keySymbolType = namedTypeSymbol.TypeArguments[0];
-
- var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "key",
- keySymbolType,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var valueSymbolType = namedTypeSymbol.TypeArguments[1];
-
- var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "value",
- valueSymbolType,
- 1,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0;
- var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0;
- var index = 0;
-
- // Key
- ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength];
- ruleArguments[index++] = ""; // Extra options
- ruleArguments[index++] = keySymbolType.ToDisplayString();
- ruleArguments[index++] = keySerializedProperty.Rule;
- ruleArguments[index++] = keyArgumentsLength.ToString();
- if (keyArgumentsLength > 0)
- {
- Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
- index += keyArgumentsLength;
- }
-
- // Value
- ruleArguments[index++] = valueSymbolType.ToDisplayString();
- ruleArguments[index++] = valueSerializedProperty.Rule;
-
- if (valueArgumentsLength > 0)
- {
- Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
- }
-
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var index = 1; // skip extra options
- var keyType = ruleArguments![index++];
- var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
- var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (keyRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
- index += keyRuleArguments.Length;
- }
-
- var serializableKeyProperty = new SerializableProperty
- {
- Name = "key",
- Type = keyType,
- Rule = keyRule.RuleName,
- RuleArguments = keyRuleArguments
- };
-
- keyRule.GenerateDeserializationMethod(
- source,
- indent,
- serializableKeyProperty,
- parentReference
- );
-
- var valueType = ruleArguments[index++];
- var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
- var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (valueRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
- }
-
- var serializableValueProperty = new SerializableProperty
- {
- Name = "value",
- Type = valueType,
- Rule = valueRule.RuleName,
- RuleArguments = valueRuleArguments
- };
-
- valueRule.GenerateDeserializationMethod(
- source,
- indent,
- serializableValueProperty,
- parentReference
- );
-
- source.AppendLine(
- $"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);"
- );
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var index = 1; // skip extra options
- var keyType = ruleArguments![index++];
- var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
- var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (keyRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
- index += keyRuleArguments.Length;
- }
-
- var serializableKeyProperty = new SerializableProperty
- {
- Name = $"{property.Name}.Key",
- Type = keyType,
- Rule = keyRule.RuleName,
- RuleArguments = keyRuleArguments
- };
-
- keyRule.GenerateSerializationMethod(
- source,
- indent,
- serializableKeyProperty
- );
-
- var valueType = ruleArguments[index++];
- var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
- var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
-
- if (valueRuleArguments.Length > 0)
- {
- Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
- }
-
- var serializableValueProperty = new SerializableProperty
- {
- Name = $"{property.Name}.Value",
- Type = valueType,
- Rule = valueRule.RuleName,
- RuleArguments = valueRuleArguments
- };
-
- valueRule.GenerateSerializationMethod(
- source,
- indent,
- serializableValueProperty
- );
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs
deleted file mode 100644
index 53d2d2c44..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs
+++ /dev/null
@@ -1,172 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: ListMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class ListMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(ListMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation))
- {
- ruleArguments = null;
- return false;
- }
-
- var listTypeSymbol = namedTypeSymbol.TypeArguments[0];
-
- var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "ListEntry",
- listTypeSymbol,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var extraOptions = "";
- if (attributes.Any(a => a.IsTidy(compilation)))
- {
- extraOptions += "@Tidy";
- }
-
- var length = serializableListType.RuleArguments?.Length ?? 0;
- ruleArguments = new string[length + 3];
- ruleArguments[0] = extraOptions;
- ruleArguments[1] = listTypeSymbol.ToDisplayString();
- ruleArguments[2] = serializableListType.Rule;
-
- if (length > 0)
- {
- Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length);
- }
-
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]];
-
- var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyIndex = $"{propertyVarPrefix}Index";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
- source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
- source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableListElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = listElementRule.RuleName,
- RuleArguments = listElementRuleArguments
- };
-
- listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference);
- source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});");
-
- source.AppendLine($"{indent}}}");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
- var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- if (shouldTidy)
- {
- source.AppendLine($"{indent}{property.Name}?.Tidy();");
- }
- source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
- source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
- source.AppendLine($"{indent}if ({propertyCount} > 0)");
- source.AppendLine($"{indent}{{");
- source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
- source.AppendLine($"{indent} {{");
-
- var serializableListElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = listElementRule.RuleName,
- RuleArguments = listElementRuleArguments
- };
-
- listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement);
-
- source.AppendLine($"{indent} }}");
- source.AppendLine($"{indent}}}");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs
deleted file mode 100644
index 848812b54..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/MigrationRule.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public abstract class MigrationRule : ISerializableMigrationRule
-{
- public abstract string RuleName { get; }
-
- public virtual void GenerateMigrationProperty(
- StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty
- )
- {
- var propertyType = serializableProperty.Type;
- var type = compilation.GetTypeByMetadataName(propertyType)?.IsValueType == true
- || SymbolMetadata.IsPrimitiveFromTypeDisplayString(propertyType) && propertyType != "bool"
- ? $"{propertyType}{(serializableProperty.UsesSaveFlag == true ? "?" : "")}" : propertyType;
-
- source.AppendLine($"{indent}internal readonly {type} {serializableProperty.Name};");
- }
-
- public abstract bool GenerateRuleState(
- Compilation compilation, ISymbol symbol, ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes, ISymbol? parentSymbol, out string[] ruleArguments
- );
-
- public abstract void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- );
-
- public abstract void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property);
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs
deleted file mode 100644
index 70b34ce06..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: PrimitiveTypeMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class PrimitiveTypeMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(PrimitiveTypeMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
- {
- ruleArguments = Array.Empty();
- return true;
- }
-
- if (
- symbol is not ITypeSymbol {
- SpecialType: not (not
- SpecialType.System_Boolean and not
- SpecialType.System_SByte and not
- SpecialType.System_Int16 and not
- SpecialType.System_Int32 and not
- SpecialType.System_Int64 and not
- SpecialType.System_Byte and not
- SpecialType.System_UInt16 and not
- SpecialType.System_UInt32 and not
- SpecialType.System_UInt64 and not
- SpecialType.System_Single and not
- SpecialType.System_Double and not
- SpecialType.System_String and not
- SpecialType.System_Decimal and not
- SpecialType.System_DateTime)
- } typeSymbol
- )
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = typeSymbol.SpecialType switch
- {
- SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) =>
- new[] { "EncodedInt" },
- SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) =>
- new[] { "DeltaTime" },
- SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) =>
- new[] { "InternString" },
- _ => new[] { "" }
- };
-
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
-
- const string ipAddress = SymbolMetadata.IPADDRESS_CLASS;
- const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT;
- const string date = "System.DateTime";
-
- var readMethod = property.Type switch
- {
- "bool" => "ReadBool",
- "sbyte" => "ReadSByte",
- "short" => "ReadShort",
- "int" when argument == "EncodedInt" => "ReadEncodedInt",
- "int" => "ReadInt",
- "long" => "ReadLong",
- "byte" => "ReadByte",
- "ushort" => "ReadUShort",
- "uint" => "ReadUInt",
- "ulong" => "ReadULong",
- "float" => "ReadFloat",
- "double" => "ReadDouble",
- "string" => "ReadString",
- "decimal" => "ReadDecimal",
- date when argument == "DeltaTime" => "ReadDeltaTime",
- date => "ReadDateTime",
- ipAddress => "ReadIPAddress",
- timeSpan => "ReadTimeSpan"
- };
-
- var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : "";
-
- source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
-
- var writeMethod = property.Type switch
- {
- "System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime",
- "int" when argument == "EncodedInt" => "WriteEncodedInt",
- _ => "Write"
- };
-
- source.AppendLine($"{indent}writer.{writeMethod}({propertyName});");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs
deleted file mode 100644
index ec2ea15d3..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: PrimitiveUOTypeMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class PrimitiveUOTypeMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(PrimitiveUOTypeMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- ruleArguments = symbol switch
- {
- _ when symbol.IsPoint2D(compilation) => new[] { "Point2D" },
- _ when symbol.IsPoint3D(compilation) => new[] { "Point3D" },
- _ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" },
- _ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" },
- _ when symbol.IsRace(compilation) => new[] { "Race" },
- _ when symbol.IsMap(compilation) => new[] { "Map" },
- _ when symbol.IsBitArray(compilation) => new[] { "BitArray" },
- _ => null
- };
-
- return ruleArguments != null;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName} = reader.Read{property.RuleArguments?[0] ?? ""}();");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}writer.Write({propertyName});");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs
deleted file mode 100644
index 8f0944f1d..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: RawSerializableMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class RawSerializableMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(RawSerializableMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not ITypeSymbol typeSymbol)
- {
- ruleArguments = null;
- return false;
- }
-
- if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = new[] { "" };
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});");
- source.AppendLine($"{indent}{propertyName}.Deserialize(reader);");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs
deleted file mode 100644
index 2326af110..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableInterfaceMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class SerializableInterfaceMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(SerializableInterfaceMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes))
- {
- ruleArguments = Array.Empty();
- return true;
- }
-
- ruleArguments = null;
- return false;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}writer.Write({propertyName});");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs
deleted file mode 100644
index 4e9859170..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializationMethodSignatureMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class SerializationMethodSignatureMigrationRule : MigrationRule
-{
- public override string RuleName => nameof(SerializationMethodSignatureMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true)
- {
- ruleArguments = null;
- return false;
- }
-
- if (symbol is not INamedTypeSymbol namedTypeSymbol ||
- !namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" };
- return true;
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var argument = property.RuleArguments?.Length >= 1 &&
- property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : "";
-
- source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs
deleted file mode 100644
index 7d97dfd6e..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: TimerMigrationRule.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration;
-
-public class TimerMigrationRule : MigrationRule, IPostDeserializeMethod
-{
- public override string RuleName => nameof(TimerMigrationRule);
-
- public override bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
- ? new[] { "@TimerDrift" }
- : new[] { "" };
-
- return true;
- }
-
- public override void GenerateMigrationProperty(
- StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty
- )
- {
- source.AppendLine($"{indent}internal readonly System.DateTime {serializableProperty.Name}Next;");
- source.AppendLine($"{indent}internal readonly System.TimeSpan {serializableProperty.Name}Delay;");
- }
-
- public override void GenerateDeserializationMethod(
- StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
- )
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var ruleArguments = property.RuleArguments;
- var driftTimer = ruleArguments![0].Contains("@TimerDrift");
-
- var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()";
- var useVar = isMigration ? "" : "var ";
- source.AppendLine($"{indent}{useVar}{propertyName}Next = {readTimer};");
- source.AppendLine($"{indent}{useVar}{propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;");
- }
-
- public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var ruleArguments = property.RuleArguments;
- var driftTimer = ruleArguments![0].Contains("@TimerDrift");
-
- var writerMethod = driftTimer ? "WriteDeltaTime" : "Write";
- source.AppendLine($"{indent}writer.{writerMethod}({propertyName}?.Next ?? System.DateTime.MinValue);");
- }
-
- public void PostDeserializeMethod(
- StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
- )
- {
- var deserializeTimerMethod = classSymbol
- .GetMembers()
- .OfType()
- .FirstOrDefault(
- m =>
- {
- if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
- {
- return false;
- }
-
- return m.GetAttributes()
- .FirstOrDefault(
- attr =>
- {
- if (!SymbolEqualityComparer.Default.Equals(
- attr.AttributeClass,
- compilation.GetTypeByMetadataName(
- SymbolMetadata.DESERIALIZE_TIMER_FIELD_ATTRIBUTE
- )
- ))
- {
- return false;
- }
-
- var order = (int)attr.ConstructorArguments[0].Value!;
- return order == property.Order;
- }
- ) != null;
- }
- ) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself.");
-
- source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);");
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs
deleted file mode 100644
index a7a8a6b81..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadata.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableMigration.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 . *
- *************************************************************************/
-
-using System.Collections.Immutable;
-using System.Text.Json.Serialization;
-
-namespace SerializableMigration
-{
- public record SerializableMetadata
- {
- [JsonPropertyName("version")]
- public int Version { get; init; }
-
- [JsonPropertyName("type")]
- public string Type { get; init; }
-
- [JsonPropertyName("properties")]
- public ImmutableArray? Properties { get; init; }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs
deleted file mode 100644
index 13fd600b2..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Collections.Generic;
-
-namespace SerializableMigration
-{
- public class SerializableMetadataComparer : IComparer
- {
- public int Compare(SerializableMetadata x, SerializableMetadata y)
- {
- if (ReferenceEquals(x, y))
- {
- return 0;
- }
-
- if (ReferenceEquals(null, y))
- {
- return 1;
- }
-
- if (ReferenceEquals(null, x))
- {
- return -1;
- }
-
- return x.Version.CompareTo(y.Version);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs
deleted file mode 100644
index 1fe3e32f5..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableMigrationRulesEngine.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 . *
- *************************************************************************/
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public static class SerializableMigrationRulesEngine
- {
- public static readonly Dictionary Rules = new();
-
- static SerializableMigrationRulesEngine()
- {
- var rules = new ISerializableMigrationRule[]
- {
- new EnumMigrationRule(),
- new ListMigrationRule(),
- new ArrayMigrationRule(),
- new HashSetMigrationRule(),
- new DictionaryMigrationRule(),
- new KeyValuePairMigrationRule(),
- new PrimitiveTypeMigrationRule(),
- new PrimitiveUOTypeMigrationRule(),
- new SerializableInterfaceMigrationRule(),
- new SerializationMethodSignatureMigrationRule(),
- new RawSerializableMigrationRule(),
- new TimerMigrationRule()
- };
-
- foreach (var rule in rules)
- {
- Rules.Add(rule.RuleName, rule);
- }
- }
-
- public static SerializableProperty? GenerateSerializableProperty(
- Compilation compilation,
- ISymbol fieldOrPropertySymbol,
- int order,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods
- )
- {
- string propertyName;
- ITypeSymbol propertyType;
-
- if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol)
- {
- propertyName = fieldSymbol.Name;
- propertyType = fieldSymbol.Type;
- }
- else if (fieldOrPropertySymbol is IPropertySymbol propertySymbol)
- {
- propertyName = fieldOrPropertySymbol.Name;
- propertyType = propertySymbol.Type;
- }
- else
- {
- return null;
- }
-
- return GenerateSerializableProperty(
- compilation,
- propertyName,
- propertyType,
- order,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- serializableFieldSaveFlagMethods
- );
- }
-
- public static SerializableProperty GenerateSerializableProperty(
- Compilation compilation,
- string propertyName,
- ISymbol propertyType,
- int order,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods
- )
- {
- foreach (var rule in Rules.Values)
- {
- if (rule.GenerateRuleState(
- compilation,
- propertyType,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- out var ruleArguments
- ))
- {
- return new SerializableProperty
- {
- Name = propertyName,
- Type = propertyType.ToDisplayString(),
- Order = order,
- UsesSaveFlag = serializableFieldSaveFlagMethods?.DetermineFieldShouldSerialize != null ? true : null,
- Rule = rule.RuleName,
- RuleArguments = ruleArguments.Length > 0 ? ruleArguments : null
- };
- }
- }
-
- throw new Exception($"No rule found for property {propertyName} of type {propertyType} ({Rules.Count})");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
deleted file mode 100644
index 2f8613456..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableMigrationSchema.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 . *
- *************************************************************************/
-
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using System.Text.RegularExpressions;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration
-{
- public static class SerializableMigrationSchema
- {
- public static JsonSerializerOptions GetJsonSerializerOptions() =>
- new()
- {
- WriteIndented = true,
- AllowTrailingCommas = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
- ReadCommentHandling = JsonCommentHandling.Skip
- };
-
- private static Dictionary _cache = new();
-
- private static readonly Regex _fileRegex = new(@"\S+\.v\d+\.json$");
-
- public static List GetMigrations(
- INamedTypeSymbol typeSymbol,
- int version,
- string migrationPath,
- JsonSerializerOptions options
- )
- {
- var typeName = typeSymbol.ToDisplayString();
- var migrations = new SortedSet(new SerializableMetadataComparer());
-
- var migrationFiles = Directory.GetFiles(migrationPath, $"{typeName}.v*.json");
-
- foreach (var file in migrationFiles)
- {
- var fi = new FileInfo(file);
- if (!_cache.TryGetValue(fi.Name, out var migration))
- {
- var text = File.ReadAllText(file, Encoding.UTF8);
- migration = JsonSerializer.Deserialize(text, options);
- _cache[fi.Name] = migration;
- }
-
- if (typeName == migration!.Type && version > migration.Version)
- {
- migrations.Add(migration);
- }
- }
-
- return migrations.ToList();
- }
-
- public static List GetMigrationsByAnalyzerConfig(
- this GeneratorExecutionContext context,
- INamedTypeSymbol typeSymbol,
- int version,
- JsonSerializerOptions options
- )
- {
- var typeName = typeSymbol.ToDisplayString();
- var migrations = new SortedSet(new SerializableMetadataComparer());
-
- foreach (var additionalText in context.AdditionalFiles)
- {
- var fi = new FileInfo(additionalText.Path);
- if (!_fileRegex.IsMatch(fi.Name))
- {
- continue;
- }
-
- if (!_cache.TryGetValue(fi.Name, out var migration))
- {
- var text = additionalText.GetText(context.CancellationToken)?.ToString();
- if (text == null)
- {
- continue;
- }
-
- migration = JsonSerializer.Deserialize(text, options);
- _cache[fi.Name] = migration;
- }
-
- if (typeName == migration!.Type && version > migration.Version)
- {
- migrations.Add(migration);
- }
- }
-
- return migrations.ToList();
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs
deleted file mode 100644
index 1f6f0c55e..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableProperty.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 . *
- *************************************************************************/
-
-using System.Text.Json.Serialization;
-
-namespace SerializableMigration
-{
- public record SerializableProperty
- {
- [JsonPropertyName("name")]
- public string Name { get; init; }
-
- [JsonPropertyName("type")]
- public string Type { get; init; }
-
- [JsonPropertyName("usesSaveFlag")]
- public bool? UsesSaveFlag { get; init; }
-
- [JsonPropertyName("rule")]
- public string Rule { get; init; }
-
- [JsonPropertyName("ruleArguments")]
- public string[]? RuleArguments { get; init; }
-
- [JsonIgnore]
- public int Order { get; init; }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs
deleted file mode 100644
index d4b736978..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializablePropertyComparer.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 . *
- *************************************************************************/
-
-using System.Collections.Generic;
-
-namespace SerializableMigration
-{
- public class SerializablePropertyComparer : IComparer
- {
- public int Compare(SerializableProperty x, SerializableProperty y)
- {
- if (Equals(x, y))
- {
- return 0;
- }
-
- if (Equals(null, y))
- {
- return 1;
- }
-
- if (Equals(null, x))
- {
- return -1;
- }
-
- return x.Order.CompareTo(y.Order);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj
deleted file mode 100755
index 10448f42f..000000000
--- a/Projects/SerializationGenerator/SerializationGenerator.csproj
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
- netstandard2.0
- preview
- analyzers
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(GetTargetPathDependsOn);GetDependencyTargetPaths
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs b/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs
deleted file mode 100755
index fea02e69d..000000000
--- a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SyntaxReceiver.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 . *
- *************************************************************************/
-
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-namespace SerializationGenerator
-{
- public class SerializerSyntaxReceiver : ISyntaxContextReceiver
- {
-#pragma warning disable RS1024
- public Dictionary)> ClassAndFields { get; } = new(SymbolEqualityComparer.Default);
- public Dictionary)> EmbeddedClassAndFields { get; } = new(SymbolEqualityComparer.Default);
-#pragma warning restore RS1024
-
- public ImmutableArray SerializableList => ClassAndFields.Keys.ToImmutableArray();
-
- public ImmutableArray EmbeddedSerializableList => EmbeddedClassAndFields.Keys.ToImmutableArray();
-
- public void OnVisitSyntaxNode(SyntaxNode node, SemanticModel semanticModel)
- {
- var compilation = semanticModel.Compilation;
-
- if (node is ClassDeclarationSyntax { AttributeLists: { Count: > 0 } } classDeclarationSyntax)
- {
- if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol)
- {
- return;
- }
-
- if (classSymbol.IsEmbeddedSerializable(compilation, out var attrData))
- {
- if (EmbeddedClassAndFields.TryGetValue(classSymbol, out var value))
- {
- var (_, fieldsList) = value;
- EmbeddedClassAndFields[classSymbol] = (attrData, fieldsList);
- }
- else
- {
- EmbeddedClassAndFields.Add(classSymbol, (attrData, new List()));
- }
- }
- else if (classSymbol.WillBeSerializable(compilation, out attrData))
- {
- if (ClassAndFields.TryGetValue(classSymbol, out var value))
- {
- var (_, fieldsList) = value;
- ClassAndFields[classSymbol] = (attrData, fieldsList);
- }
- else
- {
- ClassAndFields.Add(classSymbol, (attrData, new List()));
- }
- }
-
- return;
- }
-
- if (node is FieldDeclarationSyntax { AttributeLists: { Count: > 0 } } fieldDeclarationSyntax)
- {
- foreach (var variable in fieldDeclarationSyntax.Declaration.Variables)
- {
- if (semanticModel.GetDeclaredSymbol(variable) is IFieldSymbol fieldSymbol)
- {
- AddFieldOrProperty(fieldSymbol, compilation);
- }
- }
-
- return;
- }
-
- if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax)
- {
- if (semanticModel.GetDeclaredSymbol(propertyDeclarationSyntax) is IPropertySymbol propertySymbol)
- {
- AddFieldOrProperty(propertySymbol, compilation);
- }
- }
- }
-
- public void OnVisitSyntaxNode(GeneratorSyntaxContext context) =>
- OnVisitSyntaxNode(context.Node, context.SemanticModel);
-
- private void AddFieldOrProperty(ISymbol symbol, Compilation compilation)
- {
- var serializableFieldAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
- var parentAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
-
- if (symbol.GetAttribute(serializableFieldAttr) == null && symbol.GetAttribute(parentAttr) == null)
- {
- return;
- }
-
- var classSymbol = symbol.ContainingType;
- if (ClassAndFields.TryGetValue(classSymbol, out var value))
- {
- var (_, fieldsList) = value;
- fieldsList.Add(symbol);
- return;
- }
-
- if (EmbeddedClassAndFields.TryGetValue(classSymbol, out value))
- {
- var (_, fieldsList) = value;
- fieldsList.Add(symbol);
- return;
- }
-
- if (classSymbol.WillBeSerializable(compilation, out var attrData))
- {
- ClassAndFields.Add(classSymbol, (attrData, new List { symbol }));
- }
- else if (classSymbol.IsEmbeddedSerializable(compilation, out attrData))
- {
- EmbeddedClassAndFields.Add(classSymbol, (attrData, new List { symbol }));
- }
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs b/Projects/SerializationGenerator/SourceGeneration/Helpers.cs
deleted file mode 100644
index f1a9a88e5..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: Helpers.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 . *
- *************************************************************************/
-
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-
-namespace SerializationGenerator
-{
- public static class Helpers
- {
- public static bool ContainsInterface(this ITypeSymbol symbol, ISymbol interfaceSymbol) =>
- symbol.Interfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default)) ||
- symbol.AllInterfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default));
-
- public static ImmutableArray GetAllMethods(this ITypeSymbol symbol, string name)
- {
- var methods = symbol.GetMembers(name).OfType().ToImmutableArray();
- if (symbol.ContainingSymbol is not ITypeSymbol typeSymbol)
- {
- return methods;
- }
-
- var list = new List();
- list.AddRange(methods.ToList());
- list.AddRange(GetAllMethods(typeSymbol, name).ToList());
-
- return list.ToImmutableArray();
- }
-
- public static string ToFriendlyString(this Accessibility accessibility) => SyntaxFacts.GetText(accessibility);
-
- public static Accessibility GetAccessibility(string? value) =>
- value switch
- {
- "private" => Accessibility.Private,
- "protected" => Accessibility.Protected,
- "internal" => Accessibility.Internal,
- "public" => Accessibility.Public,
- "protected internal" => Accessibility.ProtectedOrInternal,
- "private protected" => Accessibility.ProtectedAndInternal,
- _ => Accessibility.NotApplicable
- };
-
- public static bool CanBeConstructedFrom(this ITypeSymbol? symbol, ISymbol classSymbol) =>
- symbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.ConstructedFrom.Equals(
- classSymbol,
- SymbolEqualityComparer.Default
- ) || symbol != null && CanBeConstructedFrom(symbol.BaseType, classSymbol);
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs
deleted file mode 100644
index 53dc5823c..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Arguments.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 . *
- *************************************************************************/
-
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static void GetTypesFromTypedConstant(TypedConstant arg, List list)
- {
- if (arg.Kind == TypedConstantKind.Type)
- {
- list.Add((ITypeSymbol)arg.Value);
- }
- else if (arg.Kind == TypedConstantKind.Array)
- {
- for (var i = 0; i < arg.Values.Length; i++)
- {
- GetTypesFromTypedConstant(arg.Values[i], list);
- }
- }
- }
-
- public static void GenerateSignatureArguments(this StringBuilder source, ImmutableArray<(ITypeSymbol, string)> parameters)
- {
- for (var i = 0; i < parameters.Length; i++)
- {
- var (t, v) = parameters[i];
- source.AppendFormat("{0} {1}", t.ToDisplayString(), v);
- if (i < parameters.Length - 1)
- {
- source.Append(", ");
- }
- }
- }
-
- public static void GenerateNamedArgument(this StringBuilder source, KeyValuePair namedArg)
- {
- source.AppendFormat("{0} = ", namedArg.Key);
- source.GenerateTypedConstant(namedArg.Value);
- }
-
- public static void GenerateTypedConstants(this StringBuilder source, ImmutableArray