Merge branch 'main' into webSupport
This commit is contained in:
commit
f0471f35f8
61 changed files with 2614 additions and 1641 deletions
1
.github/workflows/update-docs.yml
vendored
1
.github/workflows/update-docs.yml
vendored
|
|
@ -3,6 +3,7 @@ name: Updates Docs
|
|||
on:
|
||||
repository_dispatch:
|
||||
types: [docs]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update-docs:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<PublicRelease>true</PublicRelease>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<NoWarn>NU1603</NoWarn>
|
||||
<RuntimeIdentifiers>win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;linuxmint.17-x64;linuxmint.18-x64;linuxmint.19-x64;osx-x64</RuntimeIdentifiers>
|
||||
<Configurations>Debug;Release;Analyze</Configurations>
|
||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
|
|
|
|||
665
Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs
Normal file
665
Projects/Benchmarks/Benchmarks/Map/MapSelectors.cs
Normal file
|
|
@ -0,0 +1,665 @@
|
|||
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<StaticTile[]> 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<StaticTile[]> 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<BaseMulti> SelectMultisLinq(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
return s.Multis.Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<BaseMulti> SelectMultis(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
List<BaseMulti> entities = new List<BaseMulti>(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<BItem>(sector, bounds);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SelectBItemsLinq()
|
||||
{
|
||||
SelectBItemsLinq<BItem>(sector, bounds);
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectBItemsLinq<T>(Sector s, Server.Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
return s.BItems.OfType<T>().Where(o => o != null && !o.Deleted && o.Parent == null && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectBItems<T>(Sector s, Server.Rectangle2D bounds) where T : BItem
|
||||
{
|
||||
List<T> entities = new List<T>(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<Mobile>(sector, bounds);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SelectMobilesLinq()
|
||||
{
|
||||
SelectMobilesLinq<Mobile>(sector, bounds);
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectMobilesLinq<T>(Sector s, Server.Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
return s.Mobiles.OfType<T>().Where(o => o != null && !o.Deleted && bounds.Contains(o.Location));
|
||||
}
|
||||
|
||||
public IEnumerable<T> SelectMobiles<T>(Sector s, Server.Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
List<T> entities = new List<T>(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<Server.IEntity> SelectEntitiesLinq(Sector s, Server.Rectangle2D bounds)
|
||||
{
|
||||
return Enumerable.Empty<IEntity>()
|
||||
.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<Server.IEntity> entities = new (10);
|
||||
public IEnumerable<Server.IEntity> 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<BItem> BItems { get; set; } = new List<BItem>();
|
||||
public List<Mobile> Mobiles { get; set; } = new List<Mobile>();
|
||||
public List<BaseMulti> Multis { get; set; } = new List<BaseMulti>();
|
||||
}
|
||||
}
|
||||
28
Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs
Normal file
28
Projects/Benchmarks/Benchmarks/Rng/BenchmarkDoubleVsFixed.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using Server.Random;
|
||||
|
||||
namespace Benchmarks.Benchmarks.Rng
|
||||
{
|
||||
[MemoryDiagnoser]
|
||||
[SimpleJob(RuntimeMoniker.Net60)]
|
||||
public class BenchmarkDoubleVsFixed
|
||||
{
|
||||
private Xoshiro256PlusPlus _xoshiro256PlusPlus;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
_xoshiro256PlusPlus = new Xoshiro256PlusPlus();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public bool NextDouble() => 50.1 < _xoshiro256PlusPlus.NextDouble() * 100;
|
||||
|
||||
[Benchmark]
|
||||
public bool NextFixedInt() => 501 < _xoshiro256PlusPlus.Next(1000);
|
||||
|
||||
[Benchmark]
|
||||
public bool NextHighResDouble() => 50.1 < _xoshiro256PlusPlus.NextDoubleHighRes() * 100;
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,10 @@ namespace Benchmarks
|
|||
// var textEncoding = BenchmarkRunner.Run<BenchmarkTextEncoding>();
|
||||
// var logging = BenchmarkRunner.Run<BenchmarkConsoleLogging>();
|
||||
// var gumpPacket = BenchmarkRunner.Run<OutgoingGumpPacketBenchmarks>();
|
||||
var rngTest = BenchmarkRunner.Run<BenchmarkXoshiro>();
|
||||
// MapSelectors.Init();
|
||||
// var mapSelectors = BenchmarkRunner.Run<MapSelectors>();
|
||||
// var rngTest = BenchmarkRunner.Run<BenchmarkXoshiro>();
|
||||
var doubleRngText = BenchmarkRunner.Run<BenchmarkDoubleVsFixed>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,9 @@ namespace SerializationGenerator
|
|||
|
||||
foreach (var serializableProperty in properties)
|
||||
{
|
||||
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};");
|
||||
SerializableMigrationRulesEngine.Rules[serializableProperty.Rule].GenerateMigrationProperty(
|
||||
source, compilation, $"{indent} ", serializableProperty
|
||||
);
|
||||
}
|
||||
|
||||
var innerIndent = $"{indent} ";
|
||||
|
|
@ -100,7 +97,8 @@ namespace SerializationGenerator
|
|||
source,
|
||||
$"{innerIndent} ",
|
||||
property,
|
||||
"entity"
|
||||
"entity",
|
||||
true
|
||||
);
|
||||
|
||||
source.AppendLine($"{innerIndent}}}\n{innerIndent}else\n{innerIndent}{{");
|
||||
|
|
@ -114,7 +112,8 @@ namespace SerializationGenerator
|
|||
source,
|
||||
innerIndent,
|
||||
property,
|
||||
"entity"
|
||||
"entity",
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@ namespace SerializableMigration
|
|||
{
|
||||
string RuleName { get; }
|
||||
|
||||
void GenerateMigrationProperty(
|
||||
StringBuilder source,
|
||||
Compilation compilation,
|
||||
string indent,
|
||||
SerializableProperty serializableProperty
|
||||
);
|
||||
|
||||
bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
|
|
@ -37,7 +44,8 @@ namespace SerializableMigration
|
|||
StringBuilder source,
|
||||
string indent,
|
||||
SerializableProperty property,
|
||||
string? parentReference
|
||||
string? parentReference,
|
||||
bool isMigration = false
|
||||
);
|
||||
|
||||
void GenerateSerializationMethod(
|
||||
|
|
|
|||
|
|
@ -18,117 +18,118 @@ using System.Collections.Immutable;
|
|||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class ArrayMigrationRule : MigrationRule
|
||||
{
|
||||
public class ArrayMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(ArrayMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(ArrayMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not IArrayTypeSymbol arrayTypeSymbol)
|
||||
{
|
||||
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;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
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)
|
||||
{
|
||||
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}}}");
|
||||
Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length);
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
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)
|
||||
{
|
||||
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}}}");
|
||||
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}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,230 +20,231 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class DictionaryMigrationRule : MigrationRule
|
||||
{
|
||||
public class DictionaryMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(DictionaryMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(DictionaryMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation))
|
||||
{
|
||||
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;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
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)))
|
||||
{
|
||||
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}}}");
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
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)
|
||||
{
|
||||
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}}}");
|
||||
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}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,54 +19,55 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class EnumMigrationRule : MigrationRule
|
||||
{
|
||||
public class EnumMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(EnumMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(EnumMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
|
||||
{
|
||||
if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
|
||||
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}.");
|
||||
}
|
||||
|
||||
public 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}{property.Name} = reader.ReadEnum<{property.Type}>();");
|
||||
}
|
||||
|
||||
source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});");
|
||||
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});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,151 +20,152 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class HashSetMigrationRule : MigrationRule
|
||||
{
|
||||
public class HashSetMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(HashSetMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(HashSetMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation))
|
||||
{
|
||||
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;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
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)))
|
||||
{
|
||||
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}}}");
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
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)
|
||||
{
|
||||
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}}}");
|
||||
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}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,206 +19,207 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class KeyValuePairMigrationRule : MigrationRule
|
||||
{
|
||||
public class KeyValuePairMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(KeyValuePairMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(KeyValuePairMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation))
|
||||
{
|
||||
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;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
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)
|
||||
{
|
||||
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);"
|
||||
);
|
||||
Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
|
||||
index += keyArgumentsLength;
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
// Value
|
||||
ruleArguments[index++] = valueSymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = valueSerializedProperty.Rule;
|
||||
|
||||
if (valueArgumentsLength > 0)
|
||||
{
|
||||
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
|
||||
);
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,152 +20,153 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class ListMigrationRule : MigrationRule
|
||||
{
|
||||
public class ListMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(ListMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(ListMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation))
|
||||
{
|
||||
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;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
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)))
|
||||
{
|
||||
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}}}");
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
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)
|
||||
{
|
||||
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}}}");
|
||||
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}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
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<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> 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);
|
||||
}
|
||||
|
|
@ -20,129 +20,130 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class PrimitiveTypeMigrationRule : MigrationRule
|
||||
{
|
||||
public class PrimitiveTypeMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(PrimitiveTypeMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(PrimitiveTypeMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
|
||||
{
|
||||
if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
|
||||
{
|
||||
ruleArguments = Array.Empty<string>();
|
||||
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[] { "" }
|
||||
};
|
||||
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
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
|
||||
)
|
||||
{
|
||||
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});");
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
ruleArguments = typeSymbol.SpecialType switch
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
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[] { "" }
|
||||
};
|
||||
|
||||
var propertyName = property.Name;
|
||||
var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
|
||||
return true;
|
||||
}
|
||||
|
||||
var writeMethod = property.Type switch
|
||||
{
|
||||
"System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime",
|
||||
"int" when argument == "EncodedInt" => "WriteEncodedInt",
|
||||
_ => "Write"
|
||||
};
|
||||
|
||||
source.AppendLine($"{indent}writer.{writeMethod}({propertyName});");
|
||||
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});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,61 +19,62 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class PrimitiveUOTypeMigrationRule : MigrationRule
|
||||
{
|
||||
public class PrimitiveUOTypeMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(PrimitiveUOTypeMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(PrimitiveUOTypeMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
ruleArguments = symbol switch
|
||||
{
|
||||
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
|
||||
};
|
||||
_ 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;
|
||||
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}.");
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
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] ?? ""}();");
|
||||
}
|
||||
|
||||
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}.");
|
||||
}
|
||||
|
||||
public 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});");
|
||||
}
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}writer.Write({propertyName});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,63 +19,64 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class RawSerializableMigrationRule : MigrationRule
|
||||
{
|
||||
public class RawSerializableMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(RawSerializableMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(RawSerializableMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not ITypeSymbol typeSymbol)
|
||||
{
|
||||
if (symbol is not ITypeSymbol typeSymbol)
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = new[] { "" };
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
|
||||
{
|
||||
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);");
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public 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}.");
|
||||
}
|
||||
ruleArguments = new[] { "" };
|
||||
return true;
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
|
||||
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);");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,56 +19,57 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class SerializableInterfaceMigrationRule : MigrationRule
|
||||
{
|
||||
public class SerializableInterfaceMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(SerializableInterfaceMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(SerializableInterfaceMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes))
|
||||
{
|
||||
if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes))
|
||||
{
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();");
|
||||
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}.");
|
||||
}
|
||||
|
||||
public 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} = reader.ReadEntity<{property.Type}>();");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}writer.Write({propertyName});");
|
||||
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});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,66 +19,67 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class SerializationMethodSignatureMigrationRule : MigrationRule
|
||||
{
|
||||
public class SerializationMethodSignatureMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(SerializationMethodSignatureMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(SerializationMethodSignatureMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true)
|
||||
{
|
||||
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;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol ||
|
||||
!namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent))
|
||||
{
|
||||
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});");
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public 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}.");
|
||||
}
|
||||
ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" };
|
||||
return true;
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
|
||||
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);");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,107 +20,117 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class TimerMigrationRule : MigrationRule, IPostDeserializeMethod
|
||||
{
|
||||
public class TimerMigrationRule : ISerializableMigrationRule, IPostDeserializeMethod
|
||||
public override string RuleName => nameof(TimerMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(TimerMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
|
||||
{
|
||||
if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
|
||||
? new[] { "@TimerDrift" }
|
||||
: new[] { "" };
|
||||
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
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)
|
||||
{
|
||||
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()";
|
||||
source.AppendLine($"{indent}var {propertyName}Next = {readTimer};");
|
||||
source.AppendLine($"{indent}var {propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;");
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
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)
|
||||
{
|
||||
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);");
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void PostDeserializeMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
|
||||
)
|
||||
{
|
||||
var deserializeTimerMethod = classSymbol
|
||||
.GetMembers()
|
||||
.OfType<IMethodSymbol>()
|
||||
.FirstOrDefault(
|
||||
m =>
|
||||
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<IMethodSymbol>()
|
||||
.FirstOrDefault(
|
||||
m =>
|
||||
{
|
||||
if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
|
||||
{
|
||||
if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return m.GetAttributes()
|
||||
.FirstOrDefault(
|
||||
attr =>
|
||||
{
|
||||
if (!SymbolEqualityComparer.Default.Equals(
|
||||
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;
|
||||
{
|
||||
return false;
|
||||
}
|
||||
) != 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);");
|
||||
}
|
||||
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);");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
||||
<PackageReference Include="Zlib.Bindings" Version="1.7.2" />
|
||||
<PackageReference Include="Zlib.Bindings" Version="1.8.0" />
|
||||
<ProjectReference Include="..\Server\Server.csproj" />
|
||||
<ProjectReference Include="..\UOContent\UOContent.csproj" />
|
||||
<DataFiles Include="$(SolutionDir)\Distribution\Data\**" />
|
||||
|
|
|
|||
|
|
@ -26,65 +26,20 @@ namespace Server
|
|||
|
||||
public int Length => Arguments.Length;
|
||||
|
||||
public string GetString(int index)
|
||||
{
|
||||
if (index < 0 || index >= Arguments.Length)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public string GetString(int index) => index < 0 || index >= Arguments.Length ? "" : Arguments[index];
|
||||
|
||||
return Arguments[index];
|
||||
}
|
||||
public int GetInt32(int index) => index < 0 || index >= Arguments.Length ? 0 : Utility.ToInt32(Arguments[index]);
|
||||
|
||||
public int GetInt32(int index)
|
||||
{
|
||||
if (index < 0 || index >= Arguments.Length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public uint GetUInt32(int index) =>
|
||||
index < 0 || index >= Arguments.Length ? 0 : Utility.ToUInt32(Arguments[index]);
|
||||
|
||||
return Utility.ToInt32(Arguments[index]);
|
||||
}
|
||||
public bool GetBoolean(int index) => index >= 0 && index < Arguments.Length && Utility.ToBoolean(Arguments[index]);
|
||||
|
||||
public uint GetUInt32(int index)
|
||||
{
|
||||
if (index < 0 || index >= Arguments.Length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public double GetDouble(int index) =>
|
||||
index < 0 || index >= Arguments.Length ? 0.0 : Utility.ToDouble(Arguments[index]);
|
||||
|
||||
return Utility.ToUInt32(Arguments[index]);
|
||||
}
|
||||
|
||||
public bool GetBoolean(int index)
|
||||
{
|
||||
if (index < 0 || index >= Arguments.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Utility.ToBoolean(Arguments[index]);
|
||||
}
|
||||
|
||||
public double GetDouble(int index)
|
||||
{
|
||||
if (index < 0 || index >= Arguments.Length)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return Utility.ToDouble(Arguments[index]);
|
||||
}
|
||||
|
||||
public TimeSpan GetTimeSpan(int index)
|
||||
{
|
||||
if (index < 0 || index >= Arguments.Length)
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
|
||||
return Utility.ToTimeSpan(Arguments[index]);
|
||||
}
|
||||
public TimeSpan GetTimeSpan(int index) =>
|
||||
index < 0 || index >= Arguments.Length ? TimeSpan.Zero : Utility.ToTimeSpan(Arguments[index]);
|
||||
}
|
||||
|
||||
public static partial class EventSink
|
||||
|
|
@ -137,27 +92,7 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
public record CommandInfo
|
||||
{
|
||||
public CommandInfo(AccessLevel accessLevel, string name, string[] aliases, string usage, string description)
|
||||
{
|
||||
AccessLevel = accessLevel;
|
||||
Name = name;
|
||||
Aliases = aliases;
|
||||
Usage = usage;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public AccessLevel AccessLevel { get; }
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string[] Aliases { get; }
|
||||
|
||||
public string Usage { get; }
|
||||
|
||||
public string Description { get; }
|
||||
}
|
||||
public record CommandInfo(AccessLevel AccessLevel, string Name, string[] Aliases, string Usage, string Description);
|
||||
|
||||
public class CommandInfoSorter : IComparer<CommandInfo>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ namespace Server.Items
|
|||
|
||||
public override bool IsChildVisibleTo(Mobile m, Item child) =>
|
||||
child is VirtualCheck
|
||||
? !AccountGold.Enabled || m.NetState?.NewSecureTrading != true
|
||||
? AccountGold.Enabled && m.NetState is not { NewSecureTrading: true }
|
||||
: base.IsChildVisibleTo(m, child);
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
|
@ -54,49 +55,97 @@ namespace Server
|
|||
|
||||
public static IEnumerable<NetState> SelectClients(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
return s.Clients.Where(o => o?.Mobile?.Deleted == false && bounds.Contains(o.Mobile.Location));
|
||||
var clients = new List<NetState>(s.Clients.Count);
|
||||
foreach (var client in s.Clients)
|
||||
{
|
||||
var m = client.Mobile;
|
||||
|
||||
if (m?.Deleted == false && bounds.Contains(m.Location))
|
||||
{
|
||||
clients.Add(client);
|
||||
}
|
||||
}
|
||||
|
||||
return clients;
|
||||
}
|
||||
|
||||
public static IEnumerable<IEntity> SelectEntities(Sector s, Rectangle2D bounds) =>
|
||||
SelectEntities(s, true, true, bounds);
|
||||
|
||||
public static IEnumerable<IEntity> SelectEntities(Sector s, bool items, bool mobiles, Rectangle2D bounds)
|
||||
public static IEnumerable<IEntity> SelectEntities(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
var eable = Enumerable.Empty<IEntity>();
|
||||
if (mobiles)
|
||||
var entities = new List<IEntity>(s.Mobiles.Count + s.Items.Count);
|
||||
for (int i = s.Mobiles.Count - 1, j = s.Items.Count - 1; i >= 0 || j >= 0; --i, --j)
|
||||
{
|
||||
eable = eable.Union(s.Mobiles.Where(o => o?.Deleted == false));
|
||||
}
|
||||
if (j >= 0)
|
||||
{
|
||||
Item item = s.Items[j];
|
||||
if (item is { Deleted: false, Parent: null } && bounds.Contains(item.Location))
|
||||
{
|
||||
entities.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (items)
|
||||
{
|
||||
eable = eable.Union(s.Items.Where(o => o?.Deleted == false && o.Parent == null));
|
||||
if (i >= 0)
|
||||
{
|
||||
Mobile mob = s.Mobiles[i];
|
||||
if (mob is { Deleted: false } && bounds.Contains(mob.Location))
|
||||
{
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eable.Where(o => bounds.Contains(o.Location));
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> SelectMobiles<T>(Sector s, Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
return s.Mobiles.OfType<T>().Where(o => !o.Deleted && bounds.Contains(o.Location));
|
||||
var entities = new List<T>(s.Mobiles.Count);
|
||||
for (int i = s.Mobiles.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (s.Mobiles[i] is T { Deleted: false } mob && bounds.Contains(mob.Location))
|
||||
{
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> SelectItems<T>(Sector s, Rectangle2D bounds) where T : Item
|
||||
{
|
||||
return s.Items.OfType<T>()
|
||||
.Where(o => o.Deleted == false && o.Parent == null && bounds.Contains(o.Location));
|
||||
var entities = new List<T>(s.Items.Count);
|
||||
for (int i = s.Items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (s.Items[i] is T { Deleted: false, Parent: null } item && bounds.Contains(item.Location))
|
||||
{
|
||||
entities.Add(item);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<BaseMulti> SelectMultis(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
return s.Multis.Where(o => o?.Deleted == false && bounds.Contains(o.Location));
|
||||
var entities = new List<BaseMulti>(s.Multis.Count);
|
||||
for (int i = s.Multis.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BaseMulti multi = s.Multis[i];
|
||||
if (multi is { Deleted: false } && bounds.Contains(multi.Location))
|
||||
{
|
||||
entities.Add(multi);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<StaticTile[]> SelectMultiTiles(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
foreach (var o in s.Multis.Where(o => o?.Deleted == false))
|
||||
for (int l = s.Multis.Count - 1; l >= 0; --l)
|
||||
{
|
||||
var c = o.Components;
|
||||
BaseMulti o = s.Multis[l];
|
||||
if (o?.Deleted != false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
MultiComponentList c = o.Components;
|
||||
|
||||
int x, y, xo, yo;
|
||||
StaticTile[] t, r;
|
||||
|
|
@ -143,10 +192,8 @@ namespace Server
|
|||
public static Map.PooledEnumerable<NetState> GetClients(Map map, Rectangle2D bounds) =>
|
||||
Map.PooledEnumerable<NetState>.Instantiate(map, bounds, ClientSelector ?? SelectClients);
|
||||
|
||||
public static Map.PooledEnumerable<IEntity> GetEntities(
|
||||
Map map, Rectangle2D bounds, bool items = true,
|
||||
bool mobiles = true
|
||||
) => Map.PooledEnumerable<IEntity>.Instantiate(map, bounds, EntitySelector ?? SelectEntities);
|
||||
public static Map.PooledEnumerable<IEntity> GetEntities(Map map, Rectangle2D bounds) =>
|
||||
Map.PooledEnumerable<IEntity>.Instantiate(map, bounds, EntitySelector ?? SelectEntities);
|
||||
|
||||
public static Map.PooledEnumerable<Mobile> GetMobiles(Map map, Rectangle2D bounds) =>
|
||||
GetMobiles<Mobile>(map, bounds);
|
||||
|
|
@ -272,9 +319,6 @@ namespace Server
|
|||
public const int SectorShift = 4;
|
||||
public const int SectorActiveRange = 2;
|
||||
|
||||
private static readonly Queue<List<Item>> m_FixPool = new(128);
|
||||
private static readonly List<Item> m_EmptyFixItems = new();
|
||||
|
||||
private static ILogger _logger;
|
||||
private static ILogger Logger => _logger ??= LogFactory.GetLogger(typeof(Map));
|
||||
|
||||
|
|
@ -389,9 +433,55 @@ namespace Server
|
|||
|
||||
public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID);
|
||||
|
||||
public static string[] GetMapNames() => Maps.Where(m => m != null).Select(m => m.Name).ToArray();
|
||||
public static string[] GetMapNames()
|
||||
{
|
||||
var mapCount = 0;
|
||||
for (var i = 0; i < Maps.Length; i++)
|
||||
{
|
||||
var map = Maps[i];
|
||||
if (map != null)
|
||||
{
|
||||
mapCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map[] GetMapValues() => Maps.Where(m => m != null).ToArray();
|
||||
var mapNames = new string[mapCount];
|
||||
for (int i = 0, mIndex = 0; i < Maps.Length; i++)
|
||||
{
|
||||
var map = Maps[i];
|
||||
if (map != null)
|
||||
{
|
||||
mapNames[mIndex++] = map.Name;
|
||||
}
|
||||
}
|
||||
|
||||
return mapNames;
|
||||
}
|
||||
|
||||
public static Map[] GetMapValues()
|
||||
{
|
||||
var mapCount = 0;
|
||||
for (var i = 0; i < Maps.Length; i++)
|
||||
{
|
||||
var map = Maps[i];
|
||||
if (map != null)
|
||||
{
|
||||
mapCount++;
|
||||
}
|
||||
}
|
||||
|
||||
var mapValues = new Map[mapCount];
|
||||
for (int i = 0, mIndex = 0; i < Maps.Length; i++)
|
||||
{
|
||||
var map = Maps[i];
|
||||
if (map != null)
|
||||
{
|
||||
mapValues[mIndex++] = map;
|
||||
}
|
||||
}
|
||||
|
||||
return mapValues;
|
||||
}
|
||||
|
||||
public static Map Parse(string value)
|
||||
{
|
||||
|
|
@ -498,54 +588,31 @@ namespace Server
|
|||
public IPooledEnumerable<StaticTile[]> GetMultiTilesAt(int x, int y) =>
|
||||
PooledEnumeration.GetMultiTiles(this, new Rectangle2D(x, y, 1, 1));
|
||||
|
||||
private static List<Item> AcquireFixItems(Map map, int x, int y)
|
||||
private static void AcquireFixItems(Map map, int x, int y, Item[] pool, out int length)
|
||||
{
|
||||
length = 0;
|
||||
if (map == null || map == Internal || x < 0 || x > map.Width || y < 0 || y > map.Height)
|
||||
{
|
||||
return m_EmptyFixItems;
|
||||
}
|
||||
|
||||
List<Item> pool = null;
|
||||
|
||||
lock (m_FixPool)
|
||||
{
|
||||
if (m_FixPool.Count > 0)
|
||||
{
|
||||
pool = m_FixPool.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
pool ??= new List<Item>(128); // Arbitrary limit
|
||||
|
||||
var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0);
|
||||
|
||||
pool.AddRange(
|
||||
eable.Where(item => item.ItemID <= TileData.MaxItemValue && item is not BaseMulti)
|
||||
.OrderBy(item => item.Z)
|
||||
.Take(pool.Capacity)
|
||||
);
|
||||
|
||||
eable.Free();
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
private static void FreeFixItems(List<Item> pool)
|
||||
{
|
||||
if (pool == m_EmptyFixItems)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pool.Clear();
|
||||
|
||||
lock (m_FixPool)
|
||||
var eable = map.GetItemsInRange(new Point3D(x, y, 0), 0);
|
||||
foreach (var item in eable)
|
||||
{
|
||||
if (m_FixPool.Count < 128)
|
||||
if (item is not BaseMulti && item.ItemID <= TileData.MaxItemValue)
|
||||
{
|
||||
m_FixPool.Enqueue(pool);
|
||||
if (length == 128)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pool[length++] = item;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
Array.Sort(pool, 0, length, ZComparer.Default);
|
||||
}
|
||||
|
||||
public void FixColumn(int x, int y)
|
||||
|
|
@ -555,9 +622,10 @@ namespace Server
|
|||
|
||||
GetAverageZ(x, y, out _, out var landAvg, out _);
|
||||
|
||||
var items = AcquireFixItems(this, x, y);
|
||||
var items = ArrayPool<Item>.Shared.Rent(128);
|
||||
AcquireFixItems(this, x, y, items, out var length);
|
||||
|
||||
for (var i = 0; i < items.Count; i++)
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var toFix = items[i];
|
||||
|
||||
|
|
@ -592,7 +660,7 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < items.Count; ++j)
|
||||
for (var j = 0; j < length; ++j)
|
||||
{
|
||||
if (j == i)
|
||||
{
|
||||
|
|
@ -622,7 +690,7 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
FreeFixItems(items);
|
||||
ArrayPool<Item>.Shared.Return(items);
|
||||
}
|
||||
|
||||
/* This could probably be re-implemented if necessary (perhaps via an ITile interface?).
|
||||
|
|
@ -1031,15 +1099,11 @@ namespace Server
|
|||
|
||||
public IPooledEnumerable<IEntity> GetObjectsInRange(Point3D p) => GetObjectsInRange(p, Core.GlobalMaxUpdateRange);
|
||||
|
||||
public IPooledEnumerable<IEntity> GetObjectsInRange(Point3D p, int range, bool items = true, bool mobiles = true) =>
|
||||
GetObjectsInBounds(
|
||||
new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1),
|
||||
items,
|
||||
mobiles
|
||||
);
|
||||
public IPooledEnumerable<IEntity> GetObjectsInRange(Point3D p, int range) =>
|
||||
GetObjectsInBounds(new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1));
|
||||
|
||||
public IPooledEnumerable<IEntity> GetObjectsInBounds(Rectangle2D bounds, bool items = true, bool mobiles = true) =>
|
||||
PooledEnumeration.GetEntities(this, bounds, items, mobiles);
|
||||
public IPooledEnumerable<IEntity> GetObjectsInBounds(Rectangle2D bounds) =>
|
||||
PooledEnumeration.GetEntities(this, bounds);
|
||||
|
||||
public IPooledEnumerable<NetState> GetClientsInRange(Point3D p) => GetClientsInRange(p, Core.GlobalMaxUpdateRange);
|
||||
|
||||
|
|
@ -1188,6 +1252,13 @@ namespace Server
|
|||
public bool CanSpawnMobile(int x, int y, int z) =>
|
||||
Region.Find(new Point3D(x, y, z), this).AllowSpawn() && CanFit(x, y, z, 16);
|
||||
|
||||
private class ZComparer : IComparer<Item>
|
||||
{
|
||||
public static readonly ZComparer Default = new();
|
||||
|
||||
public int Compare(Item x, Item y) => x!.Z.CompareTo(y!.Z);
|
||||
}
|
||||
|
||||
public Sector GetSector(Point3D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift);
|
||||
|
||||
public Sector GetSector(Point2D p) => InternalGetSector(p.m_X >> SectorShift, p.m_Y >> SectorShift);
|
||||
|
|
@ -1529,9 +1600,7 @@ namespace Server
|
|||
{
|
||||
public static readonly NullEnumerable<T> Instance = new();
|
||||
|
||||
private readonly IEnumerable<T> m_Empty;
|
||||
|
||||
private NullEnumerable() => m_Empty = Enumerable.Empty<T>();
|
||||
private readonly IEnumerable<T> m_Empty = Enumerable.Empty<T>();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => m_Empty.GetEnumerator();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Toolkit.HighPerformance" Version="7.1.2" />
|
||||
<PackageReference Include="PollGroup" Version="1.1.0" />
|
||||
<PackageReference Include="Zlib.Bindings" Version="1.7.2" />
|
||||
<PackageReference Include="Zlib.Bindings" Version="1.8.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SerializationGenerator\SerializationGenerator.csproj">
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Batch"), Description("Allows multiple commands to be run at the same time.")]
|
||||
[Usage("Batch")]
|
||||
[Description("Allows multiple commands to be run at the same time.")]
|
||||
public static void Batch_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.SendGump(new BatchGump(e.Mobile, new Batch()));
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("DragEffects", AccessLevel.Developer, DragEffects_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("DragEffects [enable=false]"), Description("Enables or disables the item drag and drop effects.")]
|
||||
[Usage("DragEffects [enable=false]")]
|
||||
[Description("Enables or disables the item drag and drop effects.")]
|
||||
public static void DragEffects_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length == 0)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Dupe [amount]"), Description("Dupes a targeted item.")]
|
||||
[Usage("Dupe [amount]")]
|
||||
[Description("Dupes a targeted item.")]
|
||||
private static void Dupe_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var amount = 1;
|
||||
|
|
@ -26,7 +27,8 @@ namespace Server.Commands
|
|||
e.Mobile.SendMessage("What do you wish to dupe?");
|
||||
}
|
||||
|
||||
[Usage("DupeInBag <count>"), Description("Dupes an item at it's current location (count) number of times.")]
|
||||
[Usage("DupeInBag <count>")]
|
||||
[Description("Dupes an item at it's current location (count) number of times.")]
|
||||
private static void DupeInBag_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var amount = 1;
|
||||
|
|
|
|||
|
|
@ -43,13 +43,18 @@ namespace Server.Commands.Generic
|
|||
return;
|
||||
}
|
||||
|
||||
var eable = map.GetObjectsInBounds(rect, items, mobiles);
|
||||
var eable = map.GetObjectsInBounds(rect);
|
||||
|
||||
var objs = new List<object>();
|
||||
|
||||
foreach (var obj in eable)
|
||||
{
|
||||
if ((!mobiles || obj is not Mobile || BaseCommand.IsAccessible(from, obj)) && ext.IsValid(obj))
|
||||
if (!mobiles && obj is Mobile || !items && obj is Item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BaseCommand.IsAccessible(from, obj) && ext.IsValid(obj))
|
||||
{
|
||||
objs.Add(obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register(command, access, handler);
|
||||
}
|
||||
|
||||
[Usage("SpeedBoost [true|false]"), Description("Enables a speed boost for the invoker. Disable with parameters.")]
|
||||
[Usage("SpeedBoost [true|false]")]
|
||||
[Description("Enables a speed boost for the invoker. Disable with parameters.")]
|
||||
private static void SpeedBoost_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
|
|
@ -97,7 +98,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("Where"), Description("Tells the commanding player his coordinates, region, and facet.")]
|
||||
[Usage("Where")]
|
||||
[Description("Tells the commanding player his coordinates, region, and facet.")]
|
||||
public static void Where_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
|
|
@ -127,9 +129,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("DropHolding"), Description(
|
||||
"Drops the item, if any, that a targeted player is holding. The item is placed into their backpack, or if that's full, at their feet."
|
||||
)]
|
||||
[Usage("DropHolding")]
|
||||
[Description("Drops the item, if any, that a targeted player is holding. The item is placed into their backpack, or if that's full, at their feet.")]
|
||||
public static void DropHolding_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.BeginTarget(-1, false, TargetFlags.None, DropHolding_OnTarget);
|
||||
|
|
@ -274,7 +275,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("GetFollowers"), Description("Teleports all pets of a targeted player to your location.")]
|
||||
[Usage("GetFollowers")]
|
||||
[Description("Teleports all pets of a targeted player to your location.")]
|
||||
public static void GetFollowers_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.BeginTarget(-1, false, TargetFlags.None, GetFollowers_OnTarget);
|
||||
|
|
@ -374,9 +376,8 @@ namespace Server.Commands
|
|||
e.Mobile.Target = new ViewEqTarget();
|
||||
}
|
||||
|
||||
[Usage("Sound <index> [toAll=true]"), Description(
|
||||
"Plays a sound to players within 12 tiles of you. The (toAll) argument specifies to everyone, or just those who can see you."
|
||||
)]
|
||||
[Usage("Sound <index> [toAll=true]")]
|
||||
[Description("Plays a sound to players within 12 tiles of you. The (toAll) argument specifies to everyone, or just those who can see you.")]
|
||||
public static void Sound_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length == 1)
|
||||
|
|
@ -423,7 +424,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("Echo <text>"), Description("Relays (text) as a system message.")]
|
||||
[Usage("Echo <text>")]
|
||||
[Description("Relays (text) as a system message.")]
|
||||
public static void Echo_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var toEcho = e.ArgString.Trim();
|
||||
|
|
@ -438,19 +440,22 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("Bank"), Description("Opens the bank box of a given target.")]
|
||||
[Usage("Bank")]
|
||||
[Description("Opens the bank box of a given target.")]
|
||||
public static void Bank_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.Target = new BankTarget();
|
||||
}
|
||||
|
||||
[Usage("Client"), Description("Opens the client gump menu for a given player.")]
|
||||
[Usage("Client")]
|
||||
[Description("Opens the client gump menu for a given player.")]
|
||||
private static void Client_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.Target = new ClientTarget();
|
||||
}
|
||||
|
||||
[Usage("Move"), Description("Repositions a targeted item or mobile.")]
|
||||
[Usage("Move")]
|
||||
[Description("Repositions a targeted item or mobile.")]
|
||||
private static void Move_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.Target = new PickMoveTarget();
|
||||
|
|
@ -473,9 +478,8 @@ namespace Server.Commands
|
|||
return validMap;
|
||||
}
|
||||
|
||||
[Usage("Go [name | serial | (x y [z]) | (deg min (N | S) deg min (E | W))]"), Description(
|
||||
"With no arguments, this command brings up the go menu. With one argument, (name), you are moved to that regions \"go location.\" Or, if a numerical value is specified for one argument, (serial), you are moved to that object. Two or three arguments, (x y [z]), will move your character to that location. When six arguments are specified, (deg min (N | S) deg min (E | W)), your character will go to an approximate of those sextant coordinates."
|
||||
)]
|
||||
[Usage("Go [name | serial | (x y [z]) | (deg min (N | S) deg min (E | W))]")]
|
||||
[Description("With no arguments, this command brings up the go menu. With one argument, (name), you are moved to that regions \"go location.\" Or, if a numerical value is specified for one argument, (serial), you are moved to that object. Two or three arguments, (x y [z]), will move your character to that location. When six arguments are specified, (deg min (N | S) deg min (E | W)), your character will go to an approximate of those sextant coordinates.")]
|
||||
private static void Go_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
|
|
@ -685,7 +689,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("Help"), Description("Lists all available commands.")]
|
||||
[Usage("Help")]
|
||||
[Description("Lists all available commands.")]
|
||||
public static void Help_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var m = e.Mobile;
|
||||
|
|
@ -732,13 +737,15 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("SMsg <text>"), Aliases("S", "SM"), Description("Broadcasts a message to all online staff.")]
|
||||
[Usage("SMsg <text>"), Aliases("S", "SM")]
|
||||
[Description("Broadcasts a message to all online staff.")]
|
||||
public static void StaffMessage_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BroadcastMessage(AccessLevel.Counselor, e.Mobile.SpeechHue, $"[{e.Mobile.Name}] {e.ArgString}");
|
||||
}
|
||||
|
||||
[Usage("BCast <text>"), Aliases("B", "BC"), Description("Broadcasts a message to everyone online.")]
|
||||
[Usage("BCast <text>"), Aliases("B", "BC")]
|
||||
[Description("Broadcasts a message to everyone online.")]
|
||||
public static void BroadcastMessage_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BroadcastMessage(AccessLevel.Player, 0x482, $"Staff message from {e.Mobile.Name}:");
|
||||
|
|
@ -758,7 +765,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("AutoPageNotify"), Aliases("APN"), Description("Toggles your auto-page-notify status.")]
|
||||
[Usage("AutoPageNotify"), Aliases("APN")]
|
||||
[Description("Toggles your auto-page-notify status.")]
|
||||
public static void APN_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var m = e.Mobile;
|
||||
|
|
@ -789,7 +797,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("Cast <name>"), Description("Casts a spell by name.")]
|
||||
[Usage("Cast <name>")]
|
||||
[Description("Casts a spell by name.")]
|
||||
public static void Cast_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length == 1)
|
||||
|
|
@ -816,19 +825,22 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("Stuck"), Description("Opens a menu of towns, used for teleporting stuck mobiles.")]
|
||||
[Usage("Stuck")]
|
||||
[Description("Opens a menu of towns, used for teleporting stuck mobiles.")]
|
||||
public static void Stuck_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.Target = new StuckMenuTarget();
|
||||
}
|
||||
|
||||
[Usage("Light <level>"), Description("Set your local lightlevel.")]
|
||||
[Usage("Light <level>")]
|
||||
[Description("Set your local lightlevel.")]
|
||||
public static void Light_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.LightLevel = e.GetInt32(0);
|
||||
}
|
||||
|
||||
[Usage("Stats"), Description("View some stats about the server.")]
|
||||
[Usage("Stats")]
|
||||
[Description("View some stats about the server.")]
|
||||
public static void Stats_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.SendMessage("Open Connections: {0}", TcpServer.Instances.Count);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ namespace Server.Commands
|
|||
FillTable();
|
||||
}
|
||||
|
||||
[Usage("HelpInfo [<command>]"), Description(
|
||||
"Gives information on a specified command, or when no argument specified, displays a gump containing all commands"
|
||||
)]
|
||||
[Usage("HelpInfo [<command>]")]
|
||||
[Description("Gives information on a specified command, or when no argument specified, displays a gump containing all commands")]
|
||||
private static void HelpInfo_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Length > 0)
|
||||
|
|
|
|||
|
|
@ -96,9 +96,8 @@ namespace Server.Gumps
|
|||
CommandSystem.Register("t", AccessLevel.GameMaster, Sciter_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("AddMenu [searchString]"), Description(
|
||||
"Opens an add menu, with an optional initial search string. This menu allows you to search for Items or Mobiles and add them interactively."
|
||||
)]
|
||||
[Usage("AddMenu [searchString]")]
|
||||
[Description("Opens an add menu, with an optional initial search string. This menu allows you to search for Items or Mobiles and add them interactively.")]
|
||||
private static void AddMenu_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var val = e.ArgString.Trim();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("Decorate", AccessLevel.Administrator, Decorate_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Decorate"), Description("Generates world decoration.")]
|
||||
[Usage("Decorate")]
|
||||
[Description("Generates world decoration.")]
|
||||
private static void Decorate_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
m_Mobile = e.Mobile;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("DecorateMag", AccessLevel.Administrator, DecorateMag_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("DecorateMag"), Description("Generates world decoration.")]
|
||||
[Usage("DecorateMag")]
|
||||
[Description("Generates world decoration.")]
|
||||
private static void DecorateMag_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
m_Mobile = e.Mobile;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("TelGenDelete", AccessLevel.Administrator, TelGenDelete_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("TelGenDelete"), Description("Destroys world/dungeon teleporters for all facets.")]
|
||||
[Usage("TelGenDelete")]
|
||||
[Description("Destroys world/dungeon teleporters for all facets.")]
|
||||
public static void TelGenDelete_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
|
|
@ -63,7 +64,8 @@ namespace Server.Commands
|
|||
from.SendMessage(WarningHue, $"{count} Teleporters Removed.");
|
||||
}
|
||||
|
||||
[Usage("TelGen"), Description("Generates world/dungeon teleporters for all facets.")]
|
||||
[Usage("TelGen")]
|
||||
[Description("Generates world/dungeon teleporters for all facets.")]
|
||||
public static void GenTeleporter_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("SetProfiles", AccessLevel.Administrator, SetProfiles_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("WriteProfiles"), Description("Generates a log files containing performance diagnostic information.")]
|
||||
[Usage("WriteProfiles")]
|
||||
[Description("Generates a log files containing performance diagnostic information.")]
|
||||
public static void WriteProfiles_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
try
|
||||
|
|
@ -86,7 +87,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("CountObjects"), Description("Generates a log file detailing all item and mobile types in the world.")]
|
||||
[Usage("CountObjects")]
|
||||
[Description("Generates a log file detailing all item and mobile types in the world.")]
|
||||
public static void CountObjects_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
using (var op = new StreamWriter("objects.log"))
|
||||
|
|
@ -140,7 +142,8 @@ namespace Server.Commands
|
|||
e.Mobile.SendMessage("Object table has been generated. See the file : objects.log");
|
||||
}
|
||||
|
||||
[Usage("TraceExpanded"), Description("Generates a log file describing all items using expanded memory.")]
|
||||
[Usage("TraceExpanded")]
|
||||
[Description("Generates a log file describing all items using expanded memory.")]
|
||||
public static void TraceExpanded_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var typeTable = new Dictionary<Type, int[]>();
|
||||
|
|
@ -251,7 +254,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("TraceInternal"), Description("Generates a log file describing all items in the 'internal' map.")]
|
||||
[Usage("TraceInternal")]
|
||||
[Description("Generates a log file describing all items in the 'internal' map.")]
|
||||
public static void TraceInternal_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var totalCount = 0;
|
||||
|
|
|
|||
80
Projects/UOContent/Commands/ResetStaffDress.cs
Normal file
80
Projects/UOContent/Commands/ResetStaffDress.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server.Commands;
|
||||
|
||||
public static class StaffDress
|
||||
{
|
||||
private static readonly Type[] _staffRobeTypes =
|
||||
{
|
||||
null,
|
||||
typeof(CounselorRobe),
|
||||
typeof(GMRobe),
|
||||
typeof(SeerRobe),
|
||||
typeof(AdminRobe),
|
||||
typeof(AdminRobe),
|
||||
typeof(AdminRobe)
|
||||
};
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("ResetStaffDress", AccessLevel.Counselor, StaffDress_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("ResetStaffDress")]
|
||||
[Description("Resets staff to proper GM")]
|
||||
public static void StaffDress_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is not PlayerMobile pm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pm.Race = Race.Human;
|
||||
pm.Karma = pm.Fame = pm.Kills = pm.ShortTermMurders = pm.BodyMod = 0;
|
||||
pm.Body = 987;
|
||||
pm.SolidHueOverride = pm.HueMod = -1;
|
||||
pm.FacialHairItemID = 0;
|
||||
pm.Blessed = true;
|
||||
pm.DisplayGuildTitle = false;
|
||||
pm.DisplayChampionTitle = false;
|
||||
if (pm.Mount != null)
|
||||
{
|
||||
pm.Mount.Rider = null;
|
||||
}
|
||||
|
||||
pm.NetState.SendSpeedControl(SpeedControlSetting.Mount);
|
||||
pm.ResetStaffAccess();
|
||||
|
||||
if (pm.AccessLevel < AccessLevel.Administrator)
|
||||
{
|
||||
pm.Hue = Race.Human.ClipSkinHue((pm.Hue + 1) & 0x3FFF);
|
||||
}
|
||||
|
||||
for (var i = pm.Items.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var item = pm.Items[i];
|
||||
|
||||
if (item.Layer is Layer.FacialHair)
|
||||
{
|
||||
item.Delete();
|
||||
}
|
||||
|
||||
if (item.Layer is not Layer.Backpack
|
||||
and not Layer.Bank
|
||||
and not Layer.Hair
|
||||
and not Layer.Mount
|
||||
and not Layer.ShopBuy
|
||||
and not Layer.ShopResale
|
||||
and not Layer.ShopSell)
|
||||
{
|
||||
pm.AddToBackpack(item);
|
||||
}
|
||||
}
|
||||
|
||||
pm.AddItem(_staffRobeTypes[(int)pm.AccessLevel].CreateInstance<BaseSuit>());
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("Time", AccessLevel.Player, Time_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Time"), Description("Returns the server's local time.")]
|
||||
[Usage("Time")]
|
||||
[Description("Returns the server's local time.")]
|
||||
private static void Time_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.SendMessage(Core.Now.ToString(CultureInfo.InvariantCulture));
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("SignGen", AccessLevel.Administrator, SignGen_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("SignGen"), Description("Generates world/shop signs on all facets.")]
|
||||
[Usage("SignGen")]
|
||||
[Description("Generates world/shop signs on all facets.")]
|
||||
public static void SignGen_OnCommand(CommandEventArgs c)
|
||||
{
|
||||
Parse(c.Mobile);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("SetAllSkills", AccessLevel.GameMaster, SetAllSkills_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("SetSkill <name> <value>"), Description("Sets a skill value by name of a targeted mobile.")]
|
||||
[Usage("SetSkill <name> <value>")]
|
||||
[Description("Sets a skill value by name of a targeted mobile.")]
|
||||
public static void SetSkill_OnCommand(CommandEventArgs arg)
|
||||
{
|
||||
if (arg.Length != 2)
|
||||
|
|
@ -32,7 +33,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("SetAllSkills <name> <value>"), Description("Sets all skill values of a targeted mobile.")]
|
||||
[Usage("SetAllSkills <name> <value>")]
|
||||
[Description("Sets all skill values of a targeted mobile.")]
|
||||
public static void SetAllSkills_OnCommand(CommandEventArgs arg)
|
||||
{
|
||||
if (arg.Length != 1)
|
||||
|
|
@ -45,7 +47,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("GetSkill <name>"), Description("Gets a skill value by name of a targeted mobile.")]
|
||||
[Usage("GetSkill <name>")]
|
||||
[Description("Gets a skill value by name of a targeted mobile.")]
|
||||
public static void GetSkill_OnCommand(CommandEventArgs arg)
|
||||
{
|
||||
if (arg.Length != 1)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("Skills", AccessLevel.Counselor, Skills_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Skills"), Description("Opens a menu where you can view or edit skills of a targeted mobile.")]
|
||||
[Usage("Skills")]
|
||||
[Description("Opens a menu where you can view or edit skills of a targeted mobile.")]
|
||||
private static void Skills_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.Target = new SkillsTarget();
|
||||
|
|
|
|||
101
Projects/UOContent/Commands/StaffAccess.cs
Normal file
101
Projects/UOContent/Commands/StaffAccess.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Server.Accounting;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Commands;
|
||||
|
||||
public static class StaffAccess
|
||||
{
|
||||
private static readonly Dictionary<string, AccessLevel> _accessLevelByString = new();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static string AccountTag(Serial serial) => $"OriginalStaffAccess:{serial}";
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("StaffAccess", AccessLevel.Player, StaffAccess_OnCommand);
|
||||
|
||||
foreach (var accessLevel in Enum.GetValues<AccessLevel>())
|
||||
{
|
||||
_accessLevelByString[accessLevel.ToString().ToLower()] = accessLevel;
|
||||
}
|
||||
|
||||
_accessLevelByString["gm"] = AccessLevel.GameMaster;
|
||||
_accessLevelByString["dev"] = AccessLevel.Developer;
|
||||
_accessLevelByString["admin"] = AccessLevel.Administrator;
|
||||
}
|
||||
|
||||
public static void ResetStaffAccess(this PlayerMobile m)
|
||||
{
|
||||
if (m.Account is not Account account)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var accountTag = AccountTag(m.Serial);
|
||||
var originalAccessLevelString = account.GetTag(accountTag);
|
||||
if (originalAccessLevelString == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var accessLevel = _accessLevelByString[originalAccessLevelString];
|
||||
account.RemoveTag(accountTag);
|
||||
m.AccessLevel = accessLevel;
|
||||
}
|
||||
|
||||
[Usage("StaffAccess <access level>")]
|
||||
[Description("Overrides your access level.")]
|
||||
public static void StaffAccess_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var m = e.Mobile;
|
||||
if (m.Account is not Account account)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var accountTag = AccountTag(m.Serial);
|
||||
var originalAccessLevelString = account.GetTag(accountTag);
|
||||
AccessLevel? originalAccessLevel = originalAccessLevelString != null ? _accessLevelByString[originalAccessLevelString] : null;
|
||||
if (originalAccessLevel == null && m.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var accessLevelArgument = e.GetString(0)?.Trim().ToLower();
|
||||
AccessLevel newAccessLevel = AccessLevel.Player;
|
||||
var validAccessLevel = !string.IsNullOrEmpty(accessLevelArgument) &&
|
||||
_accessLevelByString.TryGetValue(accessLevelArgument, out newAccessLevel);
|
||||
|
||||
if (!validAccessLevel && originalAccessLevel == null)
|
||||
{
|
||||
m.SendMessage("Invalid access level specified.");
|
||||
m.SendMessage("Usage: [staffaccess <access level>.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (originalAccessLevel != null && (!validAccessLevel || newAccessLevel == originalAccessLevel))
|
||||
{
|
||||
account.RemoveTag(accountTag);
|
||||
newAccessLevel = originalAccessLevel.Value;
|
||||
m.SendMessage("Restoring original staff access...");
|
||||
}
|
||||
|
||||
if ((originalAccessLevel ?? m.AccessLevel) < newAccessLevel)
|
||||
{
|
||||
m.SendMessage($"You cannot set your staff access to {newAccessLevel.ToString()}.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (originalAccessLevel == null)
|
||||
{
|
||||
// Save the original access level
|
||||
account.AddTag(accountTag, m.AccessLevel.ToString().ToLower());
|
||||
}
|
||||
|
||||
m.AccessLevel = newAccessLevel;
|
||||
m.SendMessage($"Staff access set to {newAccessLevel.ToString()}.");
|
||||
}
|
||||
}
|
||||
|
|
@ -48,14 +48,16 @@ namespace Server
|
|||
CommandSystem.Register("UnfreezeWorld", AccessLevel.Administrator, UnfreezeWorld_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Freeze"), Description("Makes a targeted area of dynamic items static.")]
|
||||
[Usage("Freeze")]
|
||||
[Description("Makes a targeted area of dynamic items static.")]
|
||||
public static void Freeze_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) => FreezeBox_Callback(from, map, start, end));
|
||||
}
|
||||
|
||||
[Usage("FreezeMap"), Description("Makes every dynamic item in your map static.")]
|
||||
[Usage("FreezeMap")]
|
||||
[Description("Makes every dynamic item in your map static.")]
|
||||
public static void FreezeMap_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
|
|
@ -75,7 +77,8 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("FreezeWorld"), Description("Makes every dynamic item on all maps static.")]
|
||||
[Usage("FreezeWorld")]
|
||||
[Description("Makes every dynamic item on all maps static.")]
|
||||
public static void FreezeWorld_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
SendWarning(
|
||||
|
|
@ -404,14 +407,16 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("Unfreeze"), Description("Makes a targeted area of static items dynamic.")]
|
||||
[Usage("Unfreeze")]
|
||||
[Description("Makes a targeted area of static items dynamic.")]
|
||||
public static void Unfreeze_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var from = e.Mobile;
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) => UnfreezeBox_Callback(from, map, start, end));
|
||||
}
|
||||
|
||||
[Usage("UnfreezeMap"), Description("Makes every static item in your map dynamic.")]
|
||||
[Usage("UnfreezeMap")]
|
||||
[Description("Makes every static item in your map dynamic.")]
|
||||
public static void UnfreezeMap_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
var map = e.Mobile.Map;
|
||||
|
|
@ -430,7 +435,8 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("UnfreezeWorld"), Description("Makes every static item on all maps dynamic.")]
|
||||
[Usage("UnfreezeWorld")]
|
||||
[Description("Makes every static item on all maps dynamic.")]
|
||||
public static void UnfreezeWorld_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
SendWarning(
|
||||
|
|
|
|||
|
|
@ -22,9 +22,8 @@ namespace Server.Commands
|
|||
(m as PlayerMobile)?.VisibilityList.Clear();
|
||||
}
|
||||
|
||||
[Usage("Vis"), Description(
|
||||
"Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden."
|
||||
)]
|
||||
[Usage("Vis")]
|
||||
[Description("Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden.")]
|
||||
public static void Vis_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile)
|
||||
|
|
@ -34,7 +33,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("VisList"), Description("Shows the names of everyone in your visibility list.")]
|
||||
[Usage("VisList")]
|
||||
[Description("Shows the names of everyone in your visibility list.")]
|
||||
public static void VisList_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile pm)
|
||||
|
|
@ -57,7 +57,8 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
[Usage("VisClear"), Description("Removes everyone from your visibility list.")]
|
||||
[Usage("VisClear")]
|
||||
[Description("Removes everyone from your visibility list.")]
|
||||
public static void VisClear_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile pm)
|
||||
|
|
|
|||
|
|
@ -24,25 +24,29 @@ namespace Server.Commands
|
|||
CommandSystem.Register("WipeMultis", AccessLevel.GameMaster, WipeMultis_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Wipe"), Description("Wipes all items and npcs in a targeted bounding box.")]
|
||||
[Usage("Wipe")]
|
||||
[Description("Wipes all items and npcs in a targeted bounding box.")]
|
||||
private static void WipeAll_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BeginWipe(e.Mobile, WipeType.Items | WipeType.Mobiles);
|
||||
}
|
||||
|
||||
[Usage("WipeItems"), Description("Wipes all items in a targeted bounding box.")]
|
||||
[Usage("WipeItems")]
|
||||
[Description("Wipes all items in a targeted bounding box.")]
|
||||
private static void WipeItems_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BeginWipe(e.Mobile, WipeType.Items);
|
||||
}
|
||||
|
||||
[Usage("WipeNPCs"), Description("Wipes all npcs in a targeted bounding box.")]
|
||||
[Usage("WipeNPCs")]
|
||||
[Description("Wipes all npcs in a targeted bounding box.")]
|
||||
private static void WipeNPCs_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BeginWipe(e.Mobile, WipeType.Mobiles);
|
||||
}
|
||||
|
||||
[Usage("WipeMultis"), Description("Wipes all multis in a targeted bounding box.")]
|
||||
[Usage("WipeMultis")]
|
||||
[Description("Wipes all multis in a targeted bounding box.")]
|
||||
private static void WipeMultis_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BeginWipe(e.Mobile, WipeType.Multis);
|
||||
|
|
|
|||
|
|
@ -273,9 +273,14 @@ namespace Server.Factions
|
|||
return false;
|
||||
}
|
||||
|
||||
var eable = mob.Map.GetObjectsInRange(mob.Location, range, items, mobs);
|
||||
var eable = mob.Map.GetObjectsInRange(mob.Location, range);
|
||||
foreach (var obj in eable)
|
||||
{
|
||||
if (!mobs && obj is Mobile || !items && obj is Item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type.IsInstanceOfType(obj))
|
||||
{
|
||||
eable.Free();
|
||||
|
|
|
|||
|
|
@ -102,14 +102,8 @@ namespace Server.Items
|
|||
banks = m_IlshenarBanks;
|
||||
moongates = PMList.Ilshenar;
|
||||
#else
|
||||
from.NetState.SendMessageLocalized(
|
||||
Serial,
|
||||
ItemID,
|
||||
MessageType.Label,
|
||||
0x482,
|
||||
3,
|
||||
1061684
|
||||
); // The magic of the sextant fails...
|
||||
// The magic of the sextant fails...
|
||||
from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, 1061684);
|
||||
|
||||
return;
|
||||
#endif
|
||||
|
|
@ -155,43 +149,23 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
|
||||
int moonMsg;
|
||||
if (moongateDistance == double.MaxValue)
|
||||
int moonMsg = moongateDistance switch
|
||||
{
|
||||
moonMsg = 1048021; // The sextant fails to find a Moongate nearby.
|
||||
}
|
||||
else if (moongateDistance > m_LongDistance)
|
||||
{
|
||||
moonMsg = 1046449 + (int)from.GetDirectionTo(closestMoongate); // A moongate is * from here
|
||||
}
|
||||
else if (moongateDistance > m_ShortDistance)
|
||||
{
|
||||
moonMsg = 1048010 + (int)from.GetDirectionTo(closestMoongate); // There is a Moongate * of here.
|
||||
}
|
||||
else
|
||||
{
|
||||
moonMsg = 1048018; // You are next to a Moongate at the moment.
|
||||
}
|
||||
double.MaxValue => 1048021, // The sextant fails to find a Moongate nearby.
|
||||
> m_LongDistance => 1046449 + (int)from.GetDirectionTo(closestMoongate), // A moongate is * from here
|
||||
> m_ShortDistance => 1048010 + (int)from.GetDirectionTo(closestMoongate), // There is a Moongate * of here.
|
||||
_ => 1048018 // You are next to a Moongate at the moment.
|
||||
};
|
||||
|
||||
from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, moonMsg);
|
||||
|
||||
int bankMsg;
|
||||
if (bankDistance == double.MaxValue)
|
||||
int bankMsg = bankDistance switch
|
||||
{
|
||||
bankMsg = 1048020; // The sextant fails to find a Bank nearby.
|
||||
}
|
||||
else if (bankDistance > m_LongDistance)
|
||||
{
|
||||
bankMsg = 1046462 + (int)from.GetDirectionTo(closestBank); // A town is * from here
|
||||
}
|
||||
else if (bankDistance > m_ShortDistance)
|
||||
{
|
||||
bankMsg = 1048002 + (int)from.GetDirectionTo(closestBank); // There is a city Bank * of here.
|
||||
}
|
||||
else
|
||||
{
|
||||
bankMsg = 1048019; // You are next to a Bank at the moment.
|
||||
}
|
||||
double.MaxValue => 1048020, // The sextant fails to find a Bank nearby.
|
||||
> m_LongDistance => 1046462 + (int)from.GetDirectionTo(closestBank), // A town is * from here
|
||||
> m_ShortDistance => 1048002 + (int)from.GetDirectionTo(closestBank), // There is a city Bank * of here.
|
||||
_ => 1048019 // You are next to a Bank at the moment.
|
||||
};
|
||||
|
||||
from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x5AA, 3, bankMsg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Server.Guilds
|
|||
m_List = list;
|
||||
}
|
||||
|
||||
public virtual bool WillFilter => m_Filter.Length >= 0;
|
||||
public virtual bool WillFilter => m_Filter.Length > 0;
|
||||
|
||||
public override void PopulateGump()
|
||||
{
|
||||
|
|
@ -55,7 +55,7 @@ namespace Server.Guilds
|
|||
}
|
||||
|
||||
m_List.Sort(m_Comparer);
|
||||
m_StartNumber = Math.Clamp(m_StartNumber, 0, m_List.Count - 1);
|
||||
m_StartNumber = Math.Max(Math.Min(m_StartNumber, m_List.Count - 1), 0);
|
||||
|
||||
AddBackground(130, 75, 385, 30, 0xBB8);
|
||||
AddTextEntry(135, 80, 375, 30, 0x481, 1, m_Filter);
|
||||
|
|
@ -109,8 +109,8 @@ namespace Server.Guilds
|
|||
else // descending, go from bottom of list to the top
|
||||
{
|
||||
for (var i = m_List.Count - 1 - m_StartNumber;
|
||||
i >= 0 && i >= m_List.Count - itemsPerPage - m_StartNumber;
|
||||
i--)
|
||||
i >= 0 && i >= m_List.Count - itemsPerPage - m_StartNumber;
|
||||
i--)
|
||||
{
|
||||
DrawEntry(m_List[i], i, itemNumber++);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ namespace Server.Items
|
|||
alchemyBonus = (int)(from.Skills.Alchemy.Value / (Core.AOS ? 5 : 10));
|
||||
}
|
||||
|
||||
var eable = map.GetObjectsInRange(loc, ExplosionRange, LeveledExplosion);
|
||||
var eable = map.GetObjectsInRange(loc, ExplosionRange);
|
||||
using var queue = PooledRefQueue<IEntity>.Create();
|
||||
|
||||
var toDamage = 0;
|
||||
|
|
@ -234,7 +234,7 @@ namespace Server.Items
|
|||
queue.Enqueue(entity);
|
||||
}
|
||||
}
|
||||
else if (entity is BaseExplosionPotion)
|
||||
else if (LeveledExplosion && entity is BaseExplosionPotion)
|
||||
{
|
||||
queue.Enqueue(entity);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ namespace Server.Items
|
|||
|
||||
public abstract class BaseWeapon : Item, IWeapon, IFactionItem, ICraftable, ISlayer, IDurability
|
||||
{
|
||||
private static bool _enableInstaHit;
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
_enableInstaHit = ServerConfiguration.GetSetting("melee.enableInstaHit", !Core.UOR);
|
||||
}
|
||||
|
||||
private WeaponAccuracyLevel m_AccuracyLevel;
|
||||
private WeaponAnimation m_Animation;
|
||||
private Mobile m_Crafter;
|
||||
|
|
@ -950,7 +957,10 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
|
||||
from.NextCombatTime = Core.TickCount + (int)GetDelay(from).TotalMilliseconds;
|
||||
if (!_enableInstaHit)
|
||||
{
|
||||
from.NextCombatTime = Core.TickCount + (int)GetDelay(from).TotalMilliseconds;
|
||||
}
|
||||
|
||||
if (UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular)
|
||||
{
|
||||
|
|
@ -989,45 +999,45 @@ namespace Server.Items
|
|||
|
||||
public override void OnRemoved(IEntity parent)
|
||||
{
|
||||
if (parent is Mobile m)
|
||||
if (parent is not Mobile m)
|
||||
{
|
||||
var weapon = m.Weapon as BaseWeapon;
|
||||
|
||||
var modName = Serial.ToString();
|
||||
|
||||
m.RemoveStatMod($"{modName}Str");
|
||||
m.RemoveStatMod($"{modName}Dex");
|
||||
m.RemoveStatMod($"{modName}Int");
|
||||
|
||||
if (weapon != null)
|
||||
{
|
||||
m.NextCombatTime = Core.TickCount + (int)weapon.GetDelay(m).TotalMilliseconds;
|
||||
}
|
||||
|
||||
if (UseSkillMod && m_SkillMod != null)
|
||||
{
|
||||
m_SkillMod.Remove();
|
||||
m_SkillMod = null;
|
||||
}
|
||||
|
||||
if (m_MageMod != null)
|
||||
{
|
||||
m_MageMod.Remove();
|
||||
m_MageMod = null;
|
||||
}
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
SkillBonuses.Remove();
|
||||
}
|
||||
|
||||
ImmolatingWeaponSpell.StopImmolating(this);
|
||||
ForceOfNature.Remove(m);
|
||||
|
||||
m.CheckStatTimers();
|
||||
|
||||
m.Delta(MobileDelta.WeaponDamage);
|
||||
return;
|
||||
}
|
||||
|
||||
var modName = Serial.ToString();
|
||||
|
||||
m.RemoveStatMod($"{modName}Str");
|
||||
m.RemoveStatMod($"{modName}Dex");
|
||||
m.RemoveStatMod($"{modName}Int");
|
||||
|
||||
if (!_enableInstaHit && m.Weapon is BaseWeapon weapon)
|
||||
{
|
||||
m.NextCombatTime = Core.TickCount + (long)weapon.GetDelay(m).TotalMilliseconds;
|
||||
}
|
||||
|
||||
if (UseSkillMod && m_SkillMod != null)
|
||||
{
|
||||
m_SkillMod.Remove();
|
||||
m_SkillMod = null;
|
||||
}
|
||||
|
||||
if (m_MageMod != null)
|
||||
{
|
||||
m_MageMod.Remove();
|
||||
m_MageMod = null;
|
||||
}
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
SkillBonuses.Remove();
|
||||
}
|
||||
|
||||
ImmolatingWeaponSpell.StopImmolating(this);
|
||||
ForceOfNature.Remove(m);
|
||||
|
||||
m.CheckStatTimers();
|
||||
|
||||
m.Delta(MobileDelta.WeaponDamage);
|
||||
}
|
||||
|
||||
public virtual SkillName GetUsedSkill(Mobile m, bool checkSkillAttrs)
|
||||
|
|
|
|||
|
|
@ -3,68 +3,64 @@ using Server.Misc;
|
|||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.SkillHandlers
|
||||
namespace Server.SkillHandlers;
|
||||
|
||||
public static class Snooping
|
||||
{
|
||||
public static class Snooping
|
||||
public static void Configure()
|
||||
{
|
||||
public static void Configure()
|
||||
Container.SnoopHandler = Container_Snoop;
|
||||
}
|
||||
|
||||
public static bool CheckSnoopAllowed(Mobile from, Mobile to)
|
||||
{
|
||||
var map = from.Map;
|
||||
|
||||
if (to.Player)
|
||||
{
|
||||
Container.SnoopHandler = Container_Snoop;
|
||||
return from.CanBeHarmful(to, false, true); // normal restrictions
|
||||
}
|
||||
|
||||
public static bool CheckSnoopAllowed(Mobile from, Mobile to)
|
||||
if ((map?.Rules & MapRules.HarmfulRestrictions) == 0)
|
||||
{
|
||||
var map = from.Map;
|
||||
|
||||
if (to.Player)
|
||||
{
|
||||
return from.CanBeHarmful(to, false, true); // normal restrictions
|
||||
}
|
||||
|
||||
if ((map?.Rules & MapRules.HarmfulRestrictions) == 0)
|
||||
{
|
||||
return true; // felucca you can snoop anybody
|
||||
}
|
||||
|
||||
var reg = to.Region.GetRegion<GuardedRegion>();
|
||||
|
||||
if (reg?.IsDisabled() != true)
|
||||
{
|
||||
return true; // not in town? we can snoop any npc
|
||||
}
|
||||
|
||||
return !to.Body.IsHuman || to is BaseCreature cret && (cret.AlwaysAttackable || cret.AlwaysMurderer);
|
||||
return true; // felucca you can snoop anybody
|
||||
}
|
||||
|
||||
public static void Container_Snoop(Container cont, Mobile from)
|
||||
var reg = to.Region.GetRegion<GuardedRegion>();
|
||||
|
||||
if (reg?.IsDisabled() != true)
|
||||
{
|
||||
if (from.AccessLevel <= AccessLevel.Player && !from.InRange(cont.GetWorldLocation(), 1))
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
return;
|
||||
}
|
||||
return true; // not in town? we can snoop any npc
|
||||
}
|
||||
|
||||
var root = cont.RootParent as Mobile;
|
||||
return !to.Body.IsHuman || to is BaseCreature cret && (cret.AlwaysAttackable || cret.AlwaysMurderer);
|
||||
}
|
||||
|
||||
if (root?.Alive == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
public static void Container_Snoop(Container cont, Mobile from)
|
||||
{
|
||||
if (from.AccessLevel <= AccessLevel.Player && !from.InRange(cont.GetWorldLocation(), 1))
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
return;
|
||||
}
|
||||
|
||||
if (root?.AccessLevel > AccessLevel.Player && from.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
from.SendLocalizedMessage(500209); // You can not peek into the container.
|
||||
return;
|
||||
}
|
||||
var root = cont.RootParent as Mobile;
|
||||
|
||||
if (root?.AccessLevel == AccessLevel.Player && !CheckSnoopAllowed(from, root))
|
||||
{
|
||||
from.SendLocalizedMessage(1001018); // You cannot perform negative acts on your target.
|
||||
return;
|
||||
}
|
||||
if (root?.Alive == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (root?.AccessLevel == AccessLevel.Player &&
|
||||
from.Skills.Snooping.Value < Utility.Random(100))
|
||||
if (root?.AccessLevel > AccessLevel.Player || !CheckSnoopAllowed(from, root))
|
||||
{
|
||||
from.SendLocalizedMessage(1001018); // You cannot perform negative acts on your target.
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
var snooping = from.Skills.Snooping.Value;
|
||||
if (root != null && snooping < 100.0 && snooping < Utility.RandomDouble() * 100)
|
||||
{
|
||||
var map = from.Map;
|
||||
|
||||
|
|
@ -86,28 +82,25 @@ namespace Server.SkillHandlers
|
|||
}
|
||||
}
|
||||
|
||||
if (from.AccessLevel == AccessLevel.Player)
|
||||
Titles.AwardKarma(from, -4, true);
|
||||
}
|
||||
|
||||
if (from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill(SkillName.Snooping, cont, 0.0, 100.0))
|
||||
{
|
||||
if ((cont as TrappableContainer)?.ExecuteTrap(from) == true)
|
||||
{
|
||||
Titles.AwardKarma(from, -4, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill(SkillName.Snooping, cont, 0.0, 100.0))
|
||||
{
|
||||
if (cont is TrappableContainer container && container.ExecuteTrap(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
cont.DisplayTo(from);
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(500210); // You failed to peek into the container.
|
||||
|
||||
cont.DisplayTo(from);
|
||||
}
|
||||
else
|
||||
if (from.Skills.Hiding.Value / 2 < Utility.RandomDouble() * 100)
|
||||
{
|
||||
from.SendLocalizedMessage(500210); // You failed to peek into the container.
|
||||
|
||||
if (from.Skills.Hiding.Value / 2 < Utility.Random(100))
|
||||
{
|
||||
from.RevealingAction();
|
||||
}
|
||||
from.RevealingAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,10 +52,10 @@ namespace Server.Misc
|
|||
return;
|
||||
}
|
||||
|
||||
var value = double.Parse(valueStr);
|
||||
|
||||
try
|
||||
{
|
||||
var value = double.Parse(valueStr);
|
||||
|
||||
if (name.InsensitiveEquals("str"))
|
||||
{
|
||||
ChangeStrength(from, (int)value);
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@
|
|||
<ProjectReference Include="..\Server\Server.csproj" Private="false" PrivateAssets="All" IncludeAssets="None">
|
||||
<IncludeInPackage>false</IncludeInPackage>
|
||||
</ProjectReference>
|
||||
<PackageReference Include="MailKit" Version="2.15.0" />
|
||||
<PackageReference Include="MailKit" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Toolkit.HighPerformance" Version="7.1.2" />
|
||||
<PackageReference Include="Zlib.Bindings" Version="1.7.2" />
|
||||
<PackageReference Include="Argon2.Bindings" Version="1.11.0" />
|
||||
<PackageReference Include="Zstd.Binaries" Version="1.2.0" />
|
||||
<PackageReference Include="Zlib.Bindings" Version="1.8.0" />
|
||||
<PackageReference Include="Argon2.Bindings" Version="1.12.0" />
|
||||
<PackageReference Include="Zstd.Binaries" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SerializationGenerator\SerializationGenerator.csproj">
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -19,16 +19,17 @@ ModernUO [
|
||||
[](https://www.debian.org/distrib/)
|
||||
[](https://ubuntu.com/download/server)
|
||||
[](https://linuxmint.com/download.php)
|
||||
[](https://www.centos.org/download/)
|
||||
[](https://getfedora.org/en/server/download/)
|
||||
[](https://getfedora.org/en/server/download/)
|
||||
[](https://access.redhat.com/downloads)
|
||||
|
||||
#### Running the server
|
||||
[](https://dotnet.microsoft.com/download/dotnet/6.0)
|
||||
[](https://dotnet.microsoft.com/download/dotnet/6.0)
|
||||
|
||||
#### Development
|
||||
[](https://git-scm.com/downloads)
|
||||
[](https://dotnet.microsoft.com/download/dotnet/6.0)
|
||||
[](https://dotnet.microsoft.com/download/dotnet/6.0)
|
||||
|
||||
#### Supported IDEs
|
||||
|
||||
|
|
@ -51,11 +52,12 @@ Rider 2021.3+ &
|
|||
- `win` - Windows 10/11/2016/2019/2022
|
||||
- `osx` - MacOS 10.15/11.0+/12.0+ (Catalina, Big Sur, Monterey)
|
||||
- `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04` - Ubuntu LTS
|
||||
- `linuxmint.17`, `linuxmint.18`, `linuxmint.19` - Linux Mint
|
||||
- `debian.10`, `debian.11` - Debian
|
||||
- `centos.7`, `centos.8` - CentOS
|
||||
- `fedora.32`, `fedora.33`, `fedora.34` - Fedora
|
||||
- `rhel.7`, `rhel.8` - Redhat
|
||||
- If blank, the operating system running the build is used
|
||||
- If blank, the operating system running the build is used. Linux Mint 20 is not supported directly yet, so build explicitly against `ubuntu.20.04` instead.
|
||||
|
||||
**Note:** Building in Visual Studio (or Rider) will not run the schema migration. The schema migration ensures future changes
|
||||
to the code will be backward compatible.
|
||||
|
|
@ -64,6 +66,9 @@ to the code will be backward compatible.
|
|||
- Follow the [publish](https://github.com/modernuo/ModernUO#publishing-builds) instructions
|
||||
- Run `ModernUO.exe` or `dotnet ModernUO.dll` from the `Distribution` directory on the server
|
||||
|
||||
**Note:** If you are running a version of linux that isn't listed above, then you may have to install the following using a package manager:
|
||||
* `libargon2-dev`, `libz-dev`, and `zstd`
|
||||
|
||||
## Thanks
|
||||
- RunUO Team & Community
|
||||
- ServUO Team & Community
|
||||
|
|
|
|||
|
|
@ -82,14 +82,26 @@ html .md-footer-meta.md-typeset a:hover {
|
|||
color: #e95420;
|
||||
}
|
||||
|
||||
.linuxmint {
|
||||
color: #87cF3e;
|
||||
}
|
||||
|
||||
.debian {
|
||||
color: #d70a53;
|
||||
}
|
||||
|
||||
.fedora {
|
||||
color: #3c6eb4;
|
||||
}
|
||||
|
||||
.centos {
|
||||
color: #212078;
|
||||
}
|
||||
|
||||
.redhat {
|
||||
color: #be0000;
|
||||
}
|
||||
|
||||
.codehilitetable .linenodiv pre, .highlighttable .linenodiv pre {
|
||||
color: var(--md-default-bg-color);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ The operating system to build the server against. If not specified then the serv
|
|||
|
||||
:fontawesome-brands-windows:{: .windows } `win`<br>
|
||||
:fontawesome-brands-apple:{: .apple } `osx`<br>
|
||||
:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`<br>
|
||||
:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.14.04` `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`<br>
|
||||
:brands-linuxmint:{: .linuxmint } `linuxmint.17` `linuxmint.18`, `linuxmint.19`, `ubuntu.20.04` for v20<br>
|
||||
:brands-debian:{: .debian } `debian.9`, `debian.10`<br>
|
||||
:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8`
|
||||
:fontawesome-brands-fedora:{: .fedora } `fedora.32`, `fedora.33`, `fedora.34`<br>
|
||||
:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8`<br>
|
||||
:fontawesome-brands-redhat:{: .redhat } `redhat.7`, `redhat.8`
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ title: Installation
|
|||
|
||||
=== "Windows"
|
||||
### Prerequisites
|
||||
1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
|
||||
1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0)
|
||||
1. Download and install from [here](https://git-scm.com/download/win)
|
||||
|
||||
!!! Tip
|
||||
|
|
@ -21,14 +21,14 @@ title: Installation
|
|||
```
|
||||
|
||||
=== "OSX"
|
||||
<h3>Prerequisites</h3>
|
||||
1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
|
||||
### Prerequisites
|
||||
1. Download and install the latest [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0).
|
||||
1. Using _terminal_, install [homebrew](https://brew.sh) and git:
|
||||
```bash
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
|
||||
brew install git
|
||||
```
|
||||
<h3>Install ModernUO</h3>
|
||||
### Install ModernUO
|
||||
1. Using _terminal_, navigate to the folder where you want to install ModernUO and run:
|
||||
```bash
|
||||
git clone https://github.com/modernuo/modernuo
|
||||
|
|
@ -36,8 +36,8 @@ title: Installation
|
|||
```
|
||||
|
||||
=== "Linux"
|
||||
<h3>Prerequisites</h3>
|
||||
1. Download and install the latest [.NET Core SDK](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux))
|
||||
### Prerequisites
|
||||
1. Download and install the latest [.NET 6 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux).
|
||||
1. Using _bash_, install git:
|
||||
```bash
|
||||
sudo apt update && sudo apt install git
|
||||
|
|
@ -46,7 +46,7 @@ title: Installation
|
|||
!!! Note
|
||||
The command to install git might be different for your flavor of linux. Consult your local Google search for answers.
|
||||
|
||||
<h3>Install ModernUO</h3>
|
||||
### Install ModernUO
|
||||
1. Using _bash_, navigate to the folder where you want to install ModernUO and run:
|
||||
```bash
|
||||
git clone https://github.com/modernuo/modernuo
|
||||
|
|
|
|||
1
docs/overrides/.icons/brands/linuxmint.svg
Normal file
1
docs/overrides/.icons/brands/linuxmint.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Linux Mint</title><path d="M0 1.693v4.193h1.828c1.276 0 1.502.865 1.502 2.058l.01 7.412c0 3.84 3.44 6.951 7.68 6.951h10.464c1.342 0 2.516-.83 2.516-2.108V8.706c0-3.84-3.44-6.95-7.683-6.95h-4.405v-.013L0 1.693zm5.723 2.566h2.102V14.82c0 1.413.984 2.51 2.139 2.51l7.17.03c1.496 0 2.661-1.01 2.661-2.206l-.012-5.607a1.2 1.2 0 0 0-.386-.91 1.224 1.224 0 0 0-.917-.384c-.374 0-.65.12-.918.384a1.2 1.2 0 0 0-.386.91v4.798h-2.223V9.548c0-.364-.124-.648-.389-.91a1.208 1.208 0 0 0-.917-.384c-.366 0-.647.12-.914.384-.265.262-.39.546-.39.91v4.798H10.12V9.548c0-.95.36-1.792 1.042-2.466a3.445 3.445 0 0 1 2.485-1.022c.937 0 1.752.345 2.413.97a3.448 3.448 0 0 1 2.42-.97c.954 0 1.803.348 2.485 1.022a3.385 3.385 0 0 1 1.041 2.466l.009 5.991c-.105 1.004-.539 1.894-1.28 2.637h-.002a4.367 4.367 0 0 1-3.174 1.314H9.574v-.038c-.976-.103-1.846-.519-2.57-1.217-.845-.825-1.281-1.846-1.281-3.01V4.26z"/></svg>
|
||||
|
After Width: | Height: | Size: 970 B |
|
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
title: Quick Start
|
||||
---
|
||||
|
||||
# Quick Start
|
||||
|
||||
If you are familiar with RunUO, then follow these steps to get your ModernUO server running in less than 10 minutes:
|
||||
|
||||
=== "Windows"
|
||||
1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
|
||||
1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
|
||||
1. Navigate to the _Distribution_ folder.
|
||||
1. Run `ModernUO.exe`
|
||||
|
||||
=== "OSX"
|
||||
1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
|
||||
1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
|
||||
1. Using _terminal_, navigate to the _Distribution_ folder.
|
||||
1. Run `dotnet ModernUO.dll`
|
||||
|
||||
=== "Linux"
|
||||
1. Download and install the [.NET 5 Runtime](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux))
|
||||
1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
|
||||
1. Using _bash_, navigate to the _Distribution_ folder.
|
||||
1. Run `dotnet ModernUO.dll`
|
||||
|
||||
!!! Note
|
||||
Follow the rest of the [Get Started](../installation) guide to learn how to connect, configure, and customize, your server.
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
site_name: ModernUO
|
||||
site_author: Kamron Batman
|
||||
site_url: https://modernuo.com
|
||||
edit_uri: edit/main/docs/
|
||||
|
||||
# Repository
|
||||
repo_name: modernuo/modernuo
|
||||
|
|
@ -41,14 +42,16 @@ markdown_extensions:
|
|||
- admonition
|
||||
- footnotes
|
||||
- meta
|
||||
- markdown.extensions.toc:
|
||||
- toc:
|
||||
toc_depth: "1-1"
|
||||
permalink: true
|
||||
- attr_list
|
||||
- pymdownx.highlight
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.superfences
|
||||
- pymdownx.snippets
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.caret
|
||||
- pymdownx.mark
|
||||
- pymdownx.tilde
|
||||
|
|
@ -67,6 +70,5 @@ markdown_extensions:
|
|||
nav:
|
||||
- Home: 'index.md'
|
||||
- 'Get Started':
|
||||
- 'quick-start.md'
|
||||
- 'installation.md'
|
||||
- 'building-server.md'
|
||||
|
|
|
|||
16
publish.cmd
16
publish.cmd
|
|
@ -12,7 +12,7 @@ elif [[ $(uname) = "Darwin" ]]; then
|
|||
os="-r osx-x64"
|
||||
elif [[ -f /etc/os-release ]]; then
|
||||
. /etc/os-release
|
||||
NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME)"
|
||||
NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME | tr -d [:blank:])"
|
||||
os="-r $NAME.$VERSION_ID-x64"
|
||||
fi
|
||||
|
||||
|
|
@ -32,8 +32,11 @@ dotnet clean --verbosity quiet
|
|||
echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
|
||||
dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
|
||||
|
||||
echo dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
|
||||
dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
|
||||
echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj
|
||||
dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj
|
||||
|
||||
echo dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
|
||||
dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
|
||||
|
||||
echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
|
||||
dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
|
||||
|
|
@ -65,8 +68,11 @@ dotnet clean --verbosity quiet
|
|||
echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
|
||||
dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
|
||||
|
||||
echo dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
|
||||
dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
|
||||
echo dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj
|
||||
dotnet build -c Release Projects/SerializationGenerator/SerializationGenerator.csproj
|
||||
|
||||
echo dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
|
||||
dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
|
||||
|
||||
echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
|
||||
dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue