From d9a9e90c14f31a7cf9a3ed573a6e6f0feb24f799 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 22 Aug 2021 08:05:03 -0700 Subject: [PATCH] fix(codegen): Codegens bulletin boards. (#712) --- .../Tests/Items/Bulletin Boards/Packets.cs | 4 +- .../Items/Bulletin Boards/BulletinBoard.cs | 116 ++++++---------- .../Bulletin Boards/BulletinBoardPackets.cs | 8 +- .../Items/Bulletin Boards/BulletinEquip.cs | 20 ++- .../Items/Bulletin Boards/BulletinMessage.cs | 130 +++++------------- .../Server.Items.BaseBulletinBoard.v0.json | 14 ++ .../Server.Items.BulletinBoard.v0.json | 4 + .../Server.Items.BulletinMessage.v2.json | 84 +++++++++++ 8 files changed, 200 insertions(+), 180 deletions(-) create mode 100644 Projects/UOContent/Migrations/Server.Items.BaseBulletinBoard.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BulletinBoard.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.BulletinMessage.v2.json diff --git a/Projects/UOContent.Tests/Tests/Items/Bulletin Boards/Packets.cs b/Projects/UOContent.Tests/Tests/Items/Bulletin Boards/Packets.cs index 18dd53e0b..2776a3a4f 100644 --- a/Projects/UOContent.Tests/Tests/Items/Bulletin Boards/Packets.cs +++ b/Projects/UOContent.Tests/Tests/Items/Bulletin Boards/Packets.cs @@ -101,8 +101,8 @@ namespace Server.Network { var eq = msg.PostedEquip[i]; - Stream.Write((short)eq.itemID); - Stream.Write((short)eq.hue); + Stream.Write((short)eq._itemID); + Stream.Write((short)eq._hue); } len = msg.Lines.Length; diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs index 9eaa54a5a..21c57f33e 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinBoard.cs @@ -1,6 +1,6 @@ using System; -using System.Collections.Generic; using System.Runtime.CompilerServices; +using Server.Collections; using Server.Network; namespace Server.Items @@ -25,56 +25,38 @@ namespace Server.Items [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CheckCreateTime(DateTime time) => time + ThreadCreateTime < Core.Now; - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CheckDeletionTime(DateTime time) => time + ThreadDeletionTime < Core.Now; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CheckReplyTime(DateTime time) => time + ThreadReplyTime < Core.Now; } + [Serializable(0, false)] [Flippable(0x1E5E, 0x1E5F)] - public class BulletinBoard : BaseBulletinBoard + public partial class BulletinBoard : BaseBulletinBoard { [Constructible] public BulletinBoard() : base(0x1E5E) { } - - public BulletinBoard(Serial serial) : base(serial) - { - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } } - public abstract class BaseBulletinBoard : Item + [Serializable(0, false)] + public abstract partial class BaseBulletinBoard : Item { + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private string _boardName; + public BaseBulletinBoard(int itemID) : base(itemID) { BoardName = "bulletin board"; Movable = false; } - public BaseBulletinBoard(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public string BoardName { get; set; } - + [AfterDeserialization(false)] public virtual void Cleanup() { var items = Items; @@ -86,7 +68,7 @@ namespace Server.Items continue; } - if (!(items[i] is BulletinMessage msg)) + if (items[i] is not BulletinMessage msg || msg.Deleted) { continue; } @@ -94,14 +76,24 @@ namespace Server.Items if (msg.Thread == null && BulletinBoardSystem.CheckDeletionTime(msg.LastPostTime)) { msg.Delete(); - RecurseDelete(msg); // A root-level thread has expired + var queue = PooledRefQueue.Create(); + var thread = msg; + + do + { + BFSDelete(thread, ref queue); + if (queue.Count > 0) + { + thread = (BulletinMessage)queue.Dequeue(); + } + } while (thread != null); + queue.Dispose(); } } } - private void RecurseDelete(BulletinMessage msg) + private void BFSDelete(BulletinMessage msg, ref PooledRefQueue queue) { - var found = new List(); var items = Items; for (var i = items.Count - 1; i >= 0; --i) @@ -111,7 +103,7 @@ namespace Server.Items continue; } - if (!(items[i] is BulletinMessage check)) + if (items[i] is not BulletinMessage check || check.Deleted) { continue; } @@ -119,24 +111,20 @@ namespace Server.Items if (check.Thread == msg) { check.Delete(); - found.Add(check); + queue.Enqueue(check); } } - - for (var i = 0; i < found.Count; ++i) - { - RecurseDelete((BulletinMessage)found[i]); - } } - public virtual bool GetLastPostTime(Mobile poster, bool onlyCheckRoot, ref DateTime lastPostTime) + public virtual bool GetLastPostTime(Mobile poster, bool onlyCheckRoot, out DateTime lastPostTime) { + lastPostTime = DateTime.MinValue; var items = Items; var wasSet = false; for (var i = 0; i < items.Count; ++i) { - if (!(items[i] is BulletinMessage msg) || msg.Poster != poster) + if (items[i] is not BulletinMessage msg || msg.Poster != poster) { continue; } @@ -158,19 +146,18 @@ namespace Server.Items public override void OnDoubleClick(Mobile from) { - if (CheckRange(from)) - { - Cleanup(); - - var state = from.NetState; - - state.SendBBDisplayBoard(this); - state.SendContainerContent(from, this); - } - else + if (!CheckRange(from)) { from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. + return; } + + Cleanup(); + + var state = from.NetState; + + state.SendBBDisplayBoard(this); + state.SendContainerContent(from, this); } public virtual bool CheckRange(Mobile from) => @@ -185,30 +172,5 @@ namespace Server.Items AddItem(new BulletinMessage(from, thread, subject, lines)); } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(BoardName); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - BoardName = reader.ReadString(); - break; - } - } - } } } diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs index 6332e217b..b6d30c2a0 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinBoardPackets.cs @@ -112,9 +112,7 @@ namespace Server.Network thread = thread.Thread; } - var lastPostTime = DateTime.MinValue; - - if (board.GetLastPostTime(from, thread == null, ref lastPostTime)) + if (board.GetLastPostTime(from, thread == null, out var lastPostTime)) { if (thread == null) { @@ -259,8 +257,8 @@ namespace Server.Network for (var i = 0; i < equipLength; i++) { var eq = msg.PostedEquip[i]; - writer.Write((short)eq.itemID); - writer.Write((short)eq.hue); + writer.Write((short)eq._itemID); + writer.Write((short)eq._hue); } writer.Write((byte)linesLength); diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinEquip.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinEquip.cs index 13877cb2c..df2f4ef9e 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinEquip.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinEquip.cs @@ -2,13 +2,25 @@ namespace Server.Items { public struct BulletinEquip { - public int itemID; - public int hue; + public int _itemID; + public int _hue; public BulletinEquip(int itemID, int hue) { - this.itemID = itemID; - this.hue = hue; + _itemID = itemID; + _hue = hue; + } + + public BulletinEquip(IGenericReader reader) + { + _itemID = reader.ReadInt(); + _hue = reader.ReadInt(); + } + + public void Serialize(IGenericWriter writer) + { + writer.Write(_itemID); + writer.Write(_hue); } } } diff --git a/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs b/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs index ba44aaee4..3a2ff59f7 100644 --- a/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs +++ b/Projects/UOContent/Items/Bulletin Boards/BulletinMessage.cs @@ -4,7 +4,8 @@ using Server.Targeting; namespace Server.Items { - public class BulletinMessage : Item + [Serializable(2, false)] + public partial class BulletinMessage : Item { public BulletinMessage(Mobile poster, BulletinMessage thread, string subject, string[] lines) : base(0xEB0) { @@ -35,29 +36,35 @@ namespace Server.Items PostedEquip = list.ToArray(); } - public BulletinMessage(Serial serial) : base(serial) - { - } + [SerializableField(0)] + private Mobile _poster; - public Mobile Poster { get; private set; } + [SerializableField(1)] + private string _subject; - public BulletinMessage Thread { get; private set; } + [SerializableField(2)] + private DateTime _time; - public string Subject { get; private set; } + [SerializableField(3)] + private DateTime _lastPostTime; - public DateTime Time { get; private set; } + [SerializableField(4)] + private BulletinMessage _thread; - public DateTime LastPostTime { get; set; } + [SerializableField(5)] + private string _postedName; - public string PostedName { get; private set; } + [SerializableField(6)] + private int _postedBody; - public int PostedBody { get; private set; } + [SerializableField(7)] + private int _postedHue; - public int PostedHue { get; private set; } + [SerializableField(8)] + private BulletinEquip[] _postedEquip; - public BulletinEquip[] PostedEquip { get; private set; } - - public string[] Lines { get; private set; } + [SerializableField(9)] + private string[] _lines; // TODO: Memoize public string GetTimeAsString() => Time.ToString("MMM dd, yyyy"); @@ -66,95 +73,34 @@ namespace Server.Items public override bool IsAccessibleTo(Mobile check) => false; - public override void Serialize(IGenericWriter writer) + private void Deserialize(IGenericReader reader, int version) { - base.Serialize(writer); + Poster = reader.ReadEntity(); + Subject = reader.ReadString(); + Time = reader.ReadDateTime(); + LastPostTime = reader.ReadDateTime(); + reader.ReadBool(); // Has thread + Thread = reader.ReadEntity(); + PostedName = reader.ReadString(); + PostedBody = reader.ReadInt(); + PostedHue = reader.ReadInt(); - writer.Write(1); // version - - writer.Write(Poster); - writer.Write(Subject); - writer.Write(Time); - writer.Write(LastPostTime); - writer.Write(Thread != null); - writer.Write(Thread); - writer.Write(PostedName); - writer.Write(PostedBody); - writer.Write(PostedHue); - - writer.Write(PostedEquip.Length); + PostedEquip = new BulletinEquip[reader.ReadInt()]; for (var i = 0; i < PostedEquip.Length; ++i) { - writer.Write(PostedEquip[i].itemID); - writer.Write(PostedEquip[i].hue); + PostedEquip[i]._itemID = reader.ReadInt(); + PostedEquip[i]._hue = reader.ReadInt(); } - writer.Write(Lines.Length); + Lines = new string[reader.ReadInt()]; for (var i = 0; i < Lines.Length; ++i) { - writer.Write(Lines[i]); + Lines[i] = reader.ReadString(); } - } - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - case 0: - { - Poster = reader.ReadEntity(); - Subject = reader.ReadString(); - Time = reader.ReadDateTime(); - LastPostTime = reader.ReadDateTime(); - var hasThread = reader.ReadBool(); - Thread = reader.ReadEntity(); - PostedName = reader.ReadString(); - PostedBody = reader.ReadInt(); - PostedHue = reader.ReadInt(); - - PostedEquip = new BulletinEquip[reader.ReadInt()]; - - for (var i = 0; i < PostedEquip.Length; ++i) - { - PostedEquip[i].itemID = reader.ReadInt(); - PostedEquip[i].hue = reader.ReadInt(); - } - - Lines = new string[reader.ReadInt()]; - - for (var i = 0; i < Lines.Length; ++i) - { - Lines[i] = reader.ReadString(); - } - - if (hasThread && Thread == null) - { - Delete(); - } - - if (version == 0) - { - ValidationQueue.Add(this); - } - - break; - } - } - } - - public void Validate() - { - if ((Parent as BulletinBoard)?.Items.Contains(this) == false) - { - Delete(); - } + // Moved validation/cleanup to the BB itself } } } diff --git a/Projects/UOContent/Migrations/Server.Items.BaseBulletinBoard.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseBulletinBoard.v0.json new file mode 100644 index 000000000..c5fa8a39f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BaseBulletinBoard.v0.json @@ -0,0 +1,14 @@ +{ + "version": 0, + "type": "Server.Items.BaseBulletinBoard", + "properties": [ + { + "name": "BoardName", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BulletinBoard.v0.json b/Projects/UOContent/Migrations/Server.Items.BulletinBoard.v0.json new file mode 100644 index 000000000..3bbf83354 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BulletinBoard.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.BulletinBoard" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.BulletinMessage.v2.json b/Projects/UOContent/Migrations/Server.Items.BulletinMessage.v2.json new file mode 100644 index 000000000..80e08325f --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.BulletinMessage.v2.json @@ -0,0 +1,84 @@ +{ + "version": 2, + "type": "Server.Items.BulletinMessage", + "properties": [ + { + "name": "Poster", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Subject", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Time", + "type": "System.DateTime", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "LastPostTime", + "type": "System.DateTime", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Thread", + "type": "Server.Items.BulletinMessage", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "PostedName", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "PostedBody", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "PostedHue", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "PostedEquip", + "type": "Server.Items.BulletinEquip[]", + "rule": "ArrayMigrationRule", + "ruleArguments": [ + "Server.Items.BulletinEquip", + "SerializationMethodSignatureMigrationRule", + "" + ] + }, + { + "name": "Lines", + "type": "string[]", + "rule": "ArrayMigrationRule", + "ruleArguments": [ + "string", + "PrimitiveTypeMigrationRule", + "" + ] + } + ] +} \ No newline at end of file