This commit is contained in:
Leath Cooper 2024-10-19 16:10:11 -04:00
parent 3fc55e4db3
commit c9ae5e3bd2
7 changed files with 135 additions and 8 deletions

View file

@ -41,4 +41,7 @@ public static partial class EventSink
public static event Action ServerStarted; public static event Action ServerStarted;
public static void InvokeServerStarted() => ServerStarted?.Invoke(); public static void InvokeServerStarted() => ServerStarted?.Invoke();
public static event Action<string, int> IncomingMessage;
public static void InvokeIncomingMessage(string message, int hue) => IncomingMessage?.Invoke(message, hue);
} }

View file

@ -0,0 +1,97 @@
using System;
using System.Text.Json.Serialization;
using System.Threading;
using NATS.Client;
using NATS.Client.Core;
using NATS.Client.JetStream;
using NATS.Client.JetStream.Models;
using NATS.Net;
namespace Server;
[JsonSerializable(typeof(BroadcastMessage))]
internal partial class BroadcastJsonContext : JsonSerializerContext;
public record BroadcastMessage
{
[JsonPropertyName("hue")]
public int Hue { get; set; } = 0x482;
[JsonPropertyName("message")]
public string? Message { get; set; }
}
public static class MessageBus
{
private static NatsClient natsClient;
private static INatsJSContext jetstreamContext;
private static INatsJSConsumer incomingBroadcastsConsumer;
private static CancellationTokenSource cancellationTokenSource;
private static NatsJsonContextSerializer<BroadcastMessage> broadcastSerializer =
new (BroadcastJsonContext.Default);
public static void Start()
{
natsClient = new NatsClient();
jetstreamContext = natsClient.CreateJetStreamContext();
StartBroadcasts();
}
private static async void StartBroadcasts()
{
await jetstreamContext.CreateStreamAsync(
new StreamConfig(name: "INCOMING_NOTIFICATIONS", subjects: ["incoming.notifications.>"])
);
incomingBroadcastsConsumer = await jetstreamContext.CreateOrUpdateConsumerAsync(
"INCOMING_NOTIFICATIONS",
new ConsumerConfig("incoming_broadcasts_consumer")
{
FilterSubject = "incoming.notifications.broadcast"
}
);
cancellationTokenSource = new CancellationTokenSource();
await foreach (var msg in incomingBroadcastsConsumer.ConsumeAsync(
cancellationToken: cancellationTokenSource.Token,
serializer: broadcastSerializer
))
{
if (msg.Data == null)
{
Console.WriteLine($"Message Received w/ null Data");
continue;
}
Console.WriteLine($"Message Received {msg.Data}");
EventSink.InvokeIncomingMessage(msg.Data.Message, msg.Data.Hue);
await msg.AckAsync(cancellationToken: cancellationTokenSource.Token);
}
}
public static async void SendBroadcast(string message, int hue)
{
await natsClient.PublishAsync(
subject: "incoming.notifications.broadcast",
data: new BroadcastMessage()
{
Message = message,
Hue = hue,
},
serializer: broadcastSerializer
);
}
public static async void Publish<T>(string subject, T data, INatsSerializer<T> serializer = null)
{
await natsClient.PublishAsync<T>(subject, data);
}
public static void Kill()
{
cancellationTokenSource.Cancel();
}
}

View file

@ -233,6 +233,8 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
SetLastMoved(); SetLastMoved();
World.AddEntity(this); World.AddEntity(this);
MessageBus.Publish("items.created", $"{Serial}:{itemID}");
} }
public Item(Serial serial) => Serial = serial; public Item(Serial serial) => Serial = serial;
@ -1072,6 +1074,8 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
{ {
writer.WriteEncodedInt(info.m_SavedFlags); writer.WriteEncodedInt(info.m_SavedFlags);
} }
MessageBus.Publish("items.serialize", $"{Serial}:{ItemID}");
} }
public void MoveToWorld(WorldLocation worldLocation) public void MoveToWorld(WorldLocation worldLocation)
@ -3036,6 +3040,8 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
// if (version < 9) // if (version < 9)
VerifyCompactInfo(); VerifyCompactInfo();
MessageBus.Publish("items.deserialize", $"{Serial}:{ItemID}");
} }
private void FixHolding_Sandbox() private void FixHolding_Sandbox()

View file

@ -189,9 +189,11 @@ public static class Core
if (fi.Directory != null && Directory.Exists(fi.Directory.FullName)) if (fi.Directory != null && Directory.Exists(fi.Directory.FullName))
{ {
fullPath = fi.Directory.EnumerateFiles( fullPath = fi.Directory.EnumerateFiles(
fi.Name, fi.Name,
new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive } new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive }
).FirstOrDefault()?.FullName; )
.FirstOrDefault()
?.FullName;
} }
} }
@ -317,6 +319,7 @@ public static class Core
process.Start(); process.Start();
} }
logger.Information("Restart done"); logger.Information("Restart done");
} }
catch (Exception e) catch (Exception e)
@ -380,13 +383,15 @@ public static class Core
Utility.PopColor(); Utility.PopColor();
Utility.PushColor(ConsoleColor.DarkGray); Utility.PushColor(ConsoleColor.DarkGray);
Console.WriteLine(@"Copyright 2019-2023 ModernUO Development Team Console.WriteLine(
@"Copyright 2019-2023 ModernUO Development Team
This program comes with ABSOLUTELY NO WARRANTY; This program comes with ABSOLUTELY NO WARRANTY;
This is free software, and you are welcome to redistribute it under certain conditions. This is free software, and you are welcome to redistribute it under certain conditions.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
".TrimMultiline()); ".TrimMultiline()
);
Utility.PopColor(); Utility.PopColor();
Console.CancelKeyPress += Console_CancelKeyPressed; Console.CancelKeyPress += Console_CancelKeyPressed;
@ -426,6 +431,8 @@ public static class Core
TileMatrixLoader.LoadTileMatrix(); TileMatrixLoader.LoadTileMatrix();
MessageBus.Start();
RegionJsonSerializer.LoadRegions(); RegionJsonSerializer.LoadRegions();
World.Load(); World.Load();
@ -433,6 +440,7 @@ public static class Core
TcpServer.Start(); TcpServer.Start();
PingServer.Start(); PingServer.Start();
EventSink.InvokeServerStarted(); EventSink.InvokeServerStarted();
RunEventLoop(); RunEventLoop();
} }
@ -561,7 +569,8 @@ public static class Core
if (World.DirtyTrackingEnabled) if (World.DirtyTrackingEnabled)
{ {
var manualDirtyCheckingAttribute = type.GetCustomAttribute<ManualDirtyCheckingAttribute>(false); var manualDirtyCheckingAttribute = type.GetCustomAttribute<ManualDirtyCheckingAttribute>(false);
var codeGennedAttribute = type.GetCustomAttribute<ModernUO.Serialization.SerializationGeneratorAttribute>(false); var codeGennedAttribute =
type.GetCustomAttribute<ModernUO.Serialization.SerializationGeneratorAttribute>(false);
if (manualDirtyCheckingAttribute == null && codeGennedAttribute == null) if (manualDirtyCheckingAttribute == null && codeGennedAttribute == null)
{ {

View file

@ -35,6 +35,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.HighPerformance" Version="8.3.2" /> <PackageReference Include="CommunityToolkit.HighPerformance" Version="8.3.2" />
<PackageReference Include="LibDeflate.Bindings" Version="1.0.2.120" /> <PackageReference Include="LibDeflate.Bindings" Version="1.0.2.120" />
<PackageReference Include="NATS.Net" Version="2.5.1" />
<PackageReference Include="PollGroup" Version="1.5.1" /> <PackageReference Include="PollGroup" Version="1.5.1" />
<PackageReference Include="System.IO.Hashing" Version="8.0.0" /> <PackageReference Include="System.IO.Hashing" Version="8.0.0" />

View file

@ -638,8 +638,10 @@ namespace Server.Commands
[Description("Broadcasts a message to everyone online.")] [Description("Broadcasts a message to everyone online.")]
public static void BroadcastMessage_OnCommand(CommandEventArgs e) public static void BroadcastMessage_OnCommand(CommandEventArgs e)
{ {
BroadcastMessage(AccessLevel.Player, 0x482, $"Staff message from {e.Mobile.Name}:"); MessageBus.SendBroadcast($"Staff message from {e.Mobile.Name}:", 0x482);
BroadcastMessage(AccessLevel.Player, 0x482, e.ArgString); MessageBus.SendBroadcast($"{e.ArgString}", 0x21);
// BroadcastMessage(AccessLevel.Player, 0x482, $"Staff message from {e.Mobile.Name}:");
// BroadcastMessage(AccessLevel.Player, 0x482, e.ArgString);
} }
public static void BroadcastMessage(AccessLevel ac, int hue, string message) public static void BroadcastMessage(AccessLevel ac, int hue, string message)

View file

@ -1,3 +1,5 @@
using System;
namespace Server.Misc namespace Server.Misc
{ {
public static class Broadcasts public static class Broadcasts
@ -6,6 +8,13 @@ namespace Server.Misc
{ {
EventSink.ServerCrashed += EventSink_Crashed; EventSink.ServerCrashed += EventSink_Crashed;
EventSink.Shutdown += EventSink_Shutdown; EventSink.Shutdown += EventSink_Shutdown;
EventSink.IncomingMessage += EventSink_IncomingMessage;
}
public static void EventSink_IncomingMessage(string message, int hue)
{
Console.WriteLine("Incoming Message");
World.Broadcast(hue, true, message);
} }
public static void EventSink_Crashed(ServerCrashedEventArgs e) public static void EventSink_Crashed(ServerCrashedEventArgs e)