diff --git a/Directory.Build.props b/Directory.Build.props
index 69268aa70..352e3d34c 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -9,6 +9,7 @@
x64
9
true
+ true
NU1603
win-x64;debian.10-x64;debian.9-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;osx-x64
Debug;Release;Analyze
diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj
index afd521a92..1d9434d67 100644
--- a/Projects/Benchmarks/Benchmarks.csproj
+++ b/Projects/Benchmarks/Benchmarks.csproj
@@ -1,10 +1,15 @@
-
- Exe
-
-
-
-
-
-
+
+ Exe
+ net5.0
+ x64
+ x64
+ 9
+ true
+
+
+
+
+
+
diff --git a/Projects/Benchmarks/Directory.Build.props b/Projects/Benchmarks/Directory.Build.props
new file mode 100644
index 000000000..b9b7c8ad8
--- /dev/null
+++ b/Projects/Benchmarks/Directory.Build.props
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Projects/Benchmarks/Packets/BenchmarkPacketBroadcast.cs b/Projects/Benchmarks/Packets/BenchmarkPacketBroadcast.cs
new file mode 100644
index 000000000..933206cf3
--- /dev/null
+++ b/Projects/Benchmarks/Packets/BenchmarkPacketBroadcast.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Buffers;
+using System.Runtime.InteropServices;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using Server;
+using Server.Network;
+
+namespace Benchmarks
+{
+ [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ public class BenchmarkPacketBroadcast
+ {
+ public static int SendUnicodeMessage(
+ ArraySegment[] buffer,
+ Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, string text
+ )
+ {
+ name = name?.Trim() ?? "";
+ text = text?.Trim() ?? "";
+ lang = lang?.Trim() ?? "ENU";
+
+ if (hue == 0)
+ {
+ hue = 0x3B2;
+ }
+
+ var writer = new CircularBufferWriter(buffer);
+ writer.Write((byte)0xAE);
+ writer.Write((ushort)(50 + text.Length * 2));
+ writer.Write(serial);
+ writer.Write((short)graphic);
+ writer.Write((byte)type);
+ writer.Write((short)hue);
+ writer.Write((short)font);
+ writer.WriteAscii(lang, 4);
+ writer.WriteAscii(name, 30);
+ writer.WriteBigUniNull(text);
+
+ return writer.Position;
+ }
+
+ public static int CreateUnicodeMessage(
+ ref Span buffer,
+ Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, string text
+ )
+ {
+ name = name?.Trim() ?? "";
+ text = text?.Trim() ?? "";
+ lang = lang?.Trim() ?? "ENU";
+
+ if (hue == 0)
+ {
+ hue = 0x3B2;
+ }
+
+ var writer = new SpanWriter(buffer);
+ writer.Write((byte)0xAE);
+ writer.Write((ushort)(50 + text.Length * 2));
+ writer.Write(serial);
+ writer.Write((short)graphic);
+ writer.Write((byte)type);
+ writer.Write((short)hue);
+ writer.Write((short)font);
+ writer.WriteAscii(lang, 4);
+ writer.WriteAscii(name, 30);
+ writer.WriteBigUniNull(text);
+
+ return writer.Position;
+ }
+
+ private Pipe[] _pipes = new Pipe[512];
+ private IntPtr[] _pointers = new IntPtr[512];
+
+ [IterationSetup]
+ public void SetUp()
+ {
+ for (var i = 0; i < _pipes.Length; i++)
+ {
+ _pipes[i] = new Pipe(new byte[8192]);
+ _pointers[i] = Marshal.AllocHGlobal(8192);
+ }
+ }
+
+ [IterationCleanup]
+ public void CleanUp()
+ {
+ for (var i = 0; i < _pipes.Length; i++)
+ {
+ _pipes[i] = null;
+ Marshal.FreeHGlobal(_pointers[i]);
+ }
+ }
+
+ [Benchmark]
+ public int TestCircularBuffer()
+ {
+ var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
+ foreach (var pipe in _pipes)
+ {
+ var result = pipe.Writer.TryGetMemory();
+ var length = SendUnicodeMessage(
+ result.Buffer,
+ Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text
+ );
+ pipe.Writer.Advance((uint)length);
+ }
+
+ return _pipes.Length;
+ }
+
+ [Benchmark]
+ public int TestSpanWriterFromBuffer()
+ {
+ var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
+ foreach (var pipe in _pipes)
+ {
+ var result = pipe.Writer.TryGetMemory();
+
+ Span buffer = result.Buffer[0];
+
+ var length = CreateUnicodeMessage(
+ ref buffer,
+ Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text
+ );
+ pipe.Writer.Advance((uint)length);
+ }
+
+ return _pipes.Length;
+ }
+
+ [Benchmark]
+ public int TestSpanWriter()
+ {
+ var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
+ var length = CreateUnicodeMessage(
+ ref buffer,
+ Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text
+ );
+
+ buffer = buffer.Slice(0, length);
+
+ foreach (var pipe in _pipes)
+ {
+ var result = pipe.Writer.TryGetMemory();
+ result.CopyFrom(buffer);
+ pipe.Writer.Advance((uint)buffer.Length);
+ }
+
+ return _pipes.Length;
+ }
+
+ [Benchmark]
+ public int TestSpanWriterAllocH()
+ {
+ var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
+
+ foreach (var pointer in _pointers)
+ {
+ Span buffer;
+ unsafe
+ {
+ buffer = new Span(pointer.ToPointer(), 8192);
+ }
+
+ CreateUnicodeMessage(
+ ref buffer,
+ Serial.MinusOne,
+ -1,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ "ENU",
+ "System",
+ text
+ );
+ }
+
+ return _pipes.Length;
+ }
+ }
+}
diff --git a/Projects/Benchmarks/Packets/BenchmarkPacketConstruction.cs b/Projects/Benchmarks/Packets/BenchmarkPacketConstruction.cs
index 1a38d7631..3809ed9a0 100644
--- a/Projects/Benchmarks/Packets/BenchmarkPacketConstruction.cs
+++ b/Projects/Benchmarks/Packets/BenchmarkPacketConstruction.cs
@@ -1,4 +1,5 @@
using System;
+using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
@@ -8,7 +9,7 @@ using Server.Network;
namespace Benchmarks
{
- [MemoryDiagnoser, SimpleJob(RuntimeMoniker.NetCoreApp31)]
+ [SimpleJob(RuntimeMoniker.NetCoreApp50)]
public class BenchmarkPacketConstruction
{
public List m_States;
@@ -150,7 +151,7 @@ namespace Benchmarks
w.Write((ushort)buyState.Hue);
}
- return w.Pos;
+ return w.Position;
}
}
}
diff --git a/Projects/Benchmarks/Packets/SpanWriter.cs b/Projects/Benchmarks/Packets/SpanWriter.cs
deleted file mode 100644
index 18cb03a1d..000000000
--- a/Projects/Benchmarks/Packets/SpanWriter.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Buffers.Binary;
-using System.Runtime.CompilerServices;
-using Server;
-
-namespace Benchmarks
-{
- public ref struct SpanWriter
- {
- public Span Span;
- public int Pos;
-
- public SpanWriter(Span span)
- {
- Span = span;
- Pos = 0;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Write(Serial serial)
- {
- BinaryPrimitives.WriteUInt32BigEndian(Span.Slice(Pos), serial);
- Pos += 4;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Write(ushort value)
- {
- BinaryPrimitives.WriteUInt16BigEndian(Span.Slice(Pos), value);
- Pos += 2;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Write(byte value) => Span[Pos++] = value;
- }
-}
diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs
index c9b023050..a9bf8cccb 100644
--- a/Projects/Benchmarks/Program.cs
+++ b/Projects/Benchmarks/Program.cs
@@ -2,12 +2,13 @@ using BenchmarkDotNet.Running;
namespace Benchmarks
{
- public class Program
+ public static class Program
{
- static void Main(string[] args)
+ private static void Main(string[] args)
{
- var featureFlags = BenchmarkRunner.Run();
- var packetConstruction = BenchmarkRunner.Run();
+ // var featureFlags = BenchmarkRunner.Run();
+ // var packetConstruction = BenchmarkRunner.Run();
+ var broadcast = BenchmarkRunner.Run();
}
}
}
diff --git a/Projects/Server/Network/Packets/MessagePackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MessagePackets.cs
similarity index 54%
rename from Projects/Server/Network/Packets/MessagePackets.cs
rename to Projects/Server.Tests/Tests/Network/Packets/Outgoing/MessagePackets.cs
index ab896f8ae..dd7cd8c5d 100644
--- a/Projects/Server/Network/Packets/MessagePackets.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MessagePackets.cs
@@ -1,36 +1,7 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2020 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: MessagePackets.cs *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- *************************************************************************/
-
-using System;
-
namespace Server.Network
{
- [Flags]
- public enum AffixType : byte
- {
- Append = 0x00,
- Prepend = 0x01,
- System = 0x02
- }
-
public sealed class MessageLocalized : Packet
{
- private static readonly MessageLocalized[] m_Cache_IntLoc = new MessageLocalized[15000];
- private static readonly MessageLocalized[] m_Cache_CliLoc = new MessageLocalized[100000];
- private static readonly MessageLocalized[] m_Cache_CliLocCmp = new MessageLocalized[5000];
-
public MessageLocalized(
Serial serial, int graphic, MessageType type, int hue, int font, int number, string name, string args
) : base(0xC1)
@@ -54,56 +25,6 @@ namespace Server.Network
Stream.WriteAsciiFixed(name, 30);
Stream.WriteLittleUniNull(args);
}
-
- public static MessageLocalized InstantiateGeneric(int number)
- {
- MessageLocalized[] cache = null;
- var index = 0;
-
- if (number >= 3000000)
- {
- cache = m_Cache_IntLoc;
- index = number - 3000000;
- }
- else if (number >= 1000000)
- {
- cache = m_Cache_CliLoc;
- index = number - 1000000;
- }
- else if (number >= 500000)
- {
- cache = m_Cache_CliLocCmp;
- index = number - 500000;
- }
-
- MessageLocalized p;
-
- if (cache != null && index < cache.Length)
- {
- p = cache[index];
-
- if (p == null)
- {
- cache[index] = p = new MessageLocalized(
- Serial.MinusOne,
- -1,
- MessageType.Regular,
- 0x3B2,
- 3,
- number,
- "System",
- ""
- );
- p.SetStatic();
- }
- }
- else
- {
- p = new MessageLocalized(Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, number, "System", "");
- }
-
- return p;
- }
}
public sealed class MessageLocalizedAffix : Packet
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MessageTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MessageTests.cs
index cb1cafa74..190a4aa53 100644
--- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MessageTests.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MessageTests.cs
@@ -19,7 +19,7 @@ namespace Server.Tests.Network
var name = "Stuff";
var args = "Arguments";
- var data = new MessageLocalized(
+ var expected = new MessageLocalized(
serial,
graphic,
messageType,
@@ -30,21 +30,20 @@ namespace Server.Tests.Network
args
).Compile();
- Span expectedData = stackalloc byte[50 + args.Length * 2];
- var pos = 0;
- expectedData.Write(ref pos, (byte)0xC1); // Packet ID
- expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
+ using var ns = PacketTestUtilities.CreateTestNetState();
+ ns.SendMessageLocalized(
+ serial,
+ graphic,
+ messageType,
+ hue,
+ font,
+ number,
+ name,
+ args
+ );
- expectedData.Write(ref pos, serial);
- expectedData.Write(ref pos, (ushort)graphic);
- expectedData.Write(ref pos, (byte)messageType);
- expectedData.Write(ref pos, (ushort)hue);
- expectedData.Write(ref pos, (ushort)font);
- expectedData.Write(ref pos, number);
- expectedData.WriteAsciiFixed(ref pos, name, 30);
- expectedData.WriteLittleUniNull(ref pos, args);
-
- AssertThat.Equal(data, expectedData);
+ var result = ns.SendPipe.Reader.TryRead();
+ AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
[Fact]
@@ -61,7 +60,7 @@ namespace Server.Tests.Network
var affixType = AffixType.System;
var affix = "Affix";
- var data = new MessageLocalizedAffix(
+ var expected = new MessageLocalizedAffix(
serial,
graphic,
messageType,
@@ -74,23 +73,22 @@ namespace Server.Tests.Network
args
).Compile();
- Span expectedData = stackalloc byte[52 + affix.Length + args.Length * 2];
- var pos = 0;
- expectedData.Write(ref pos, (byte)0xCC); // Packet ID
- expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
+ using var ns = PacketTestUtilities.CreateTestNetState();
+ ns.SendMessageLocalizedAffix(
+ serial,
+ graphic,
+ messageType,
+ hue,
+ font,
+ number,
+ name,
+ affixType,
+ affix,
+ args
+ );
- expectedData.Write(ref pos, serial);
- expectedData.Write(ref pos, (ushort)graphic);
- expectedData.Write(ref pos, (byte)messageType);
- expectedData.Write(ref pos, (ushort)hue);
- expectedData.Write(ref pos, (ushort)font);
- expectedData.Write(ref pos, number);
- expectedData.Write(ref pos, (byte)affixType);
- expectedData.WriteAsciiFixed(ref pos, name, 30);
- expectedData.WriteAsciiNull(ref pos, affix);
- expectedData.WriteBigUniNull(ref pos, args);
-
- AssertThat.Equal(data, expectedData);
+ var result = ns.SendPipe.Reader.TryRead();
+ AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
[Fact]
@@ -104,7 +102,7 @@ namespace Server.Tests.Network
var name = "Stuff";
var text = "Some Text";
- var data = new AsciiMessage(
+ var expected = new AsciiMessage(
serial,
graphic,
messageType,
@@ -114,20 +112,21 @@ namespace Server.Tests.Network
text
).Compile();
- Span expectedData = stackalloc byte[45 + text.Length];
- var pos = 0;
- expectedData.Write(ref pos, (byte)0x1C); // Packet ID
- expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
+ using var ns = PacketTestUtilities.CreateTestNetState();
+ ns.SendMessage(
+ serial,
+ graphic,
+ messageType,
+ hue,
+ font,
+ true,
+ null,
+ name,
+ text
+ );
- expectedData.Write(ref pos, serial);
- expectedData.Write(ref pos, (ushort)graphic);
- expectedData.Write(ref pos, (byte)messageType);
- expectedData.Write(ref pos, (ushort)hue);
- expectedData.Write(ref pos, (ushort)font);
- expectedData.WriteAsciiFixed(ref pos, name, 30);
- expectedData.WriteAsciiNull(ref pos, text);
-
- AssertThat.Equal(data, expectedData);
+ var result = ns.SendPipe.Reader.TryRead();
+ AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
[Fact]
@@ -142,7 +141,7 @@ namespace Server.Tests.Network
var name = "Stuff";
var text = "Some Text";
- var data = new UnicodeMessage(
+ var expected = new UnicodeMessage(
serial,
graphic,
messageType,
@@ -153,21 +152,21 @@ namespace Server.Tests.Network
text
).Compile();
- Span expectedData = stackalloc byte[50 + text.Length * 2];
- var pos = 0;
- expectedData.Write(ref pos, (byte)0xAE); // Packet ID
- expectedData.Write(ref pos, (ushort)expectedData.Length); // Length
+ using var ns = PacketTestUtilities.CreateTestNetState();
+ ns.SendMessage(
+ serial,
+ graphic,
+ messageType,
+ hue,
+ font,
+ false,
+ lang,
+ name,
+ text
+ );
- expectedData.Write(ref pos, serial);
- expectedData.Write(ref pos, (ushort)graphic);
- expectedData.Write(ref pos, (byte)messageType);
- expectedData.Write(ref pos, (ushort)hue);
- expectedData.Write(ref pos, (ushort)font);
- expectedData.WriteAsciiFixed(ref pos, lang, 4);
- expectedData.WriteAsciiFixed(ref pos, name, 30);
- expectedData.WriteBigUniNull(ref pos, text);
-
- AssertThat.Equal(data, expectedData);
+ var result = ns.SendPipe.Reader.TryRead();
+ AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
[Fact]
@@ -176,16 +175,13 @@ namespace Server.Tests.Network
Serial serial = 0x1;
Serial serial2 = 0x2;
- var data = new FollowMessage(serial, serial2).Compile();
+ var expected = new FollowMessage(serial, serial2).Compile();
- Span expectedData = stackalloc byte[9];
- var pos = 0;
+ using var ns = PacketTestUtilities.CreateTestNetState();
+ ns.SendFollowMessage(serial, serial2);
- expectedData.Write(ref pos, (byte)0x15); // Packet ID
- expectedData.Write(ref pos, serial);
- expectedData.Write(ref pos, serial2);
-
- AssertThat.Equal(data, expectedData);
+ var result = ns.SendPipe.Reader.TryRead();
+ AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
}
}
diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs
index 950bfdf58..66f02ca66 100644
--- a/Projects/Server/Items/Item.cs
+++ b/Projects/Server/Items/Item.cs
@@ -2332,19 +2332,14 @@ namespace Server
MoveToWorld(location, m_Map);
}
- public void LabelTo(Mobile to, int number)
+ public void LabelTo(Mobile to, int number, string args = "")
{
- to.Send(new MessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", ""));
- }
-
- public void LabelTo(Mobile to, int number, string args)
- {
- to.Send(new MessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", args));
+ to.NetState.SendMessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", args);
}
public void LabelTo(Mobile to, string text)
{
- to.Send(new UnicodeMessage(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, "ENU", "", text));
+ to.NetState.SendMessage(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, false, "ENU", "", text);
}
public void LabelTo(Mobile to, string format, params object[] args)
@@ -2352,14 +2347,9 @@ namespace Server
LabelTo(to, string.Format(format, args));
}
- public void LabelToAffix(Mobile to, int number, AffixType type, string affix)
+ public void LabelToAffix(Mobile to, int number, AffixType type, string affix, string args = "")
{
- to.Send(new MessageLocalizedAffix(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", type, affix, ""));
- }
-
- public void LabelToAffix(Mobile to, int number, AffixType type, string affix, string args)
- {
- to.Send(new MessageLocalizedAffix(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", type, affix, args));
+ to.NetState.SendMessageLocalizedAffix(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", type, affix, args);
}
public virtual void LabelLootTypeTo(Mobile to)
@@ -3433,71 +3423,61 @@ namespace Server
return;
}
- Packet p = null;
var worldLoc = GetWorldLocation();
-
var eable = m_Map.GetClientsInRange(worldLoc, GetMaxUpdateRange());
+ var length = OutgoingMessagePackets.GetMaxMessageLength(text);
+
+ Span buffer = stackalloc byte[length];
+ length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ Serial, m_ItemID, type, hue, 3, ascii, "ENU", Name, text
+ );
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
+
foreach (var state in eable)
{
var m = state.Mobile;
if (m.CanSee(this) && m.InRange(worldLoc, GetUpdateRange(m)))
{
- if (p == null)
- {
- if (ascii)
- {
- p = new AsciiMessage(Serial, m_ItemID, type, hue, 3, Name, text);
- }
- else
- {
- p = new UnicodeMessage(Serial, m_ItemID, type, hue, 3, "ENU", Name, text);
- }
-
- p.Acquire();
- }
-
- state.Send(p);
+ state.Send(buffer);
}
}
- Packet.Release(p);
-
eable.Free();
}
- public void PublicOverheadMessage(MessageType type, int hue, int number)
- {
- PublicOverheadMessage(type, hue, number, "");
- }
-
- public void PublicOverheadMessage(MessageType type, int hue, int number, string args)
+ public void PublicOverheadMessage(MessageType type, int hue, int number, string args = "")
{
if (m_Map == null)
{
return;
}
- Packet p = null;
var worldLoc = GetWorldLocation();
-
var eable = m_Map.GetClientsInRange(worldLoc, GetMaxUpdateRange());
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedLength(args)];
+
+ var length = OutgoingMessagePackets.CreateMessageLocalized(
+ ref buffer,
+ Serial, m_ItemID, type, hue, 3, number, Name, args
+ );
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
+
foreach (var state in eable)
{
var m = state.Mobile;
if (m.CanSee(this) && m.InRange(worldLoc, GetUpdateRange(m)))
{
- p ??= Packet.Acquire(new MessageLocalized(Serial, m_ItemID, type, hue, 3, number, Name, args));
-
- state.Send(p);
+ state.Send(buffer);
}
}
- Packet.Release(p);
-
eable.Free();
}
@@ -3994,24 +3974,14 @@ namespace Server
public Point3D GetWorldTop() => RootParent?.Location ??
new Point3D(m_Location.m_X, m_Location.m_Y, m_Location.m_Z + ItemData.CalcHeight);
- public void SendLocalizedMessageTo(Mobile to, int number)
+ public void SendLocalizedMessageTo(Mobile to, int number, string args = "")
{
if (Deleted || !to.CanSee(this))
{
return;
}
- to.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", ""));
- }
-
- public void SendLocalizedMessageTo(Mobile to, int number, string args)
- {
- if (Deleted || !to.CanSee(this))
- {
- return;
- }
-
- to.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", args));
+ to.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", args);
}
public void SendLocalizedMessageTo(Mobile to, int number, AffixType affixType, string affix, string args)
@@ -4021,19 +3991,17 @@ namespace Server
return;
}
- to.Send(
- new MessageLocalizedAffix(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x3B2,
- 3,
- number,
- "",
- affixType,
- affix,
- args
- )
+ to.NetState.SendMessageLocalizedAffix(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ number,
+ "",
+ affixType,
+ affix,
+ args
);
}
@@ -4254,17 +4222,15 @@ namespace Server
if (opl.Header > 0)
{
- from.Send(
- new MessageLocalized(
- Serial,
- m_ItemID,
- MessageType.Label,
- 0x3B2,
- 3,
- opl.Header,
- Name,
- opl.HeaderArgs
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ m_ItemID,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ opl.Header,
+ Name,
+ opl.HeaderArgs
);
}
}
@@ -4292,39 +4258,35 @@ namespace Server
{
if (m_Amount <= 1)
{
- ns.Send(new MessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, LabelNumber, "", ""));
+ ns.SendMessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, LabelNumber);
}
else
{
- ns.Send(
- new MessageLocalizedAffix(
- Serial,
- m_ItemID,
- MessageType.Label,
- 0x3B2,
- 3,
- LabelNumber,
- "",
- AffixType.Append,
- $" : {m_Amount}",
- ""
- )
- );
- }
- }
- else
- {
- ns.Send(
- new UnicodeMessage(
+ ns.SendMessageLocalizedAffix(
Serial,
m_ItemID,
MessageType.Label,
0x3B2,
3,
- "ENU",
+ LabelNumber,
"",
- Name + (m_Amount > 1 ? $" : {m_Amount}" : "")
- )
+ AffixType.Append,
+ $" : {m_Amount}"
+ );
+ }
+ }
+ else
+ {
+ ns.SendMessage(
+ Serial,
+ m_ItemID,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ false,
+ "ENU",
+ "",
+ $"{Name}{(m_Amount > 1 ? $" : {m_Amount}" : "")}"
);
}
}
diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs
index 51f453389..0116bf67e 100644
--- a/Projects/Server/Mobiles/Mobile.cs
+++ b/Projects/Server/Mobiles/Mobile.cs
@@ -1434,7 +1434,7 @@ namespace Server
m_Warmode = value;
Delta(MobileDelta.Flags);
- m_NetState?.SendSetWarMode(value);
+ m_NetState.SendSetWarMode(value);
if (!m_Warmode)
{
@@ -3718,7 +3718,7 @@ namespace Server
hue = Notoriety.GetHue(Notoriety.Compute(from, this));
}
- from.Send(new MessageLocalized(Serial, Body, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs));
+ from.NetState.SendMessageLocalized(Serial, Body, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs);
}
}
@@ -6114,11 +6114,22 @@ namespace Server
ProcessDelta();
- Packet regp = null;
- Packet mutp = null;
+ Span regBuffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
+ Span mutBuffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(mutatedText)];
+
+ var length = OutgoingMessagePackets.CreateMessage(
+ ref regBuffer,
+ Serial, Body, type, hue, 3, false, m_Language, Name, text
+ );
+ regBuffer = regBuffer.Slice(0, length); // Adjust to the actual size
+
+ length = OutgoingMessagePackets.CreateMessage(
+ ref mutBuffer,
+ Serial, Body, type, hue, 3, false, m_Language, Name, mutatedText
+ );
+ mutBuffer = mutBuffer.Slice(0, length); // Adjust to the actual size
// TODO: Should this be sorted like onSpeech is below?
-
for (var i = 0; i < hears.Count; ++i)
{
var heard = hears[i];
@@ -6126,36 +6137,15 @@ namespace Server
if (mutatedArgs == null || !CheckHearsMutatedSpeech(heard, mutateContext))
{
heard.OnSpeech(regArgs);
-
- var ns = heard.NetState;
-
- if (ns != null)
- {
- regp ??= Packet.Acquire(new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, text));
-
- ns.Send(regp);
- }
+ heard.NetState?.Send(regBuffer);
}
else
{
heard.OnSpeech(mutatedArgs);
-
- var ns = heard.NetState;
-
- if (ns != null)
- {
- mutp ??= Packet.Acquire(
- new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, mutatedText)
- );
-
- ns.Send(mutp);
- }
+ heard.NetState?.Send(mutBuffer);
}
}
- Packet.Release(regp);
- Packet.Release(mutp);
-
if (onSpeech.Count > 1)
{
onSpeech.Sort(LocationComparer.GetInstance(this));
@@ -6459,7 +6449,7 @@ namespace Server
if (amount > 0)
{
- ourState?.SendDamage(Serial, amount);
+ ourState.SendDamage(Serial, amount);
if (theirState != null && theirState != ourState)
{
@@ -6534,7 +6524,7 @@ namespace Server
{
if (damaged.CanSeeVisibleDamage)
{
- ourState?.SendDamage(Serial, amount);
+ ourState.SendDamage(Serial, amount);
}
if (theirState != null && theirState != ourState && damager.CanSeeVisibleDamage)
@@ -6569,19 +6559,16 @@ namespace Server
if (message && amount > 0)
{
- m_NetState?.Send(
- new MessageLocalizedAffix(
- Serial.MinusOne,
- -1,
- MessageType.Label,
- 0x3B2,
- 3,
- 1008158,
- "",
- AffixType.Append | AffixType.System,
- amount.ToString(),
- ""
- )
+ m_NetState.SendMessageLocalizedAffix(
+ Serial.MinusOne,
+ -1,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ 1008158,
+ "",
+ AffixType.Append | AffixType.System,
+ amount.ToString()
);
}
}
@@ -7291,13 +7278,13 @@ namespace Server
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendSound(int soundID)
{
- m_NetState?.SendSoundEffect(soundID, this);
+ m_NetState.SendSoundEffect(soundID, this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendSound(int soundID, IPoint3D p)
{
- m_NetState?.SendSoundEffect(soundID, p);
+ m_NetState.SendSoundEffect(soundID, p);
}
/**
@@ -8769,11 +8756,8 @@ namespace Server
public void SayTo(Mobile to, bool ascii, string format, params object[] args) =>
SayTo(to, ascii, string.Format(format, args));
- public void SayTo(Mobile to, int number) =>
- to.Send(new MessageLocalized(Serial, Body, MessageType.Regular, SpeechHue, 3, number, Name, ""));
-
- public void SayTo(Mobile to, int number, string args) =>
- to.Send(new MessageLocalized(Serial, Body, MessageType.Regular, SpeechHue, 3, number, Name, args));
+ public void SayTo(Mobile to, int number, string args = "") =>
+ to.NetState.SendMessageLocalized(Serial, Body, MessageType.Regular, SpeechHue, 3, number, Name, args);
public void Say(bool ascii, string text) => PublicOverheadMessage(MessageType.Regular, SpeechHue, ascii, text);
@@ -9578,15 +9562,7 @@ namespace Server
public Direction GetDirectionTo(Point2D p) => GetDirectionTo(p.m_X, p.m_Y);
public Direction GetDirectionTo(Point3D p) => GetDirectionTo(p.m_X, p.m_Y);
- public Direction GetDirectionTo(IPoint2D p)
- {
- if (p == null)
- {
- return Direction.North;
- }
-
- return GetDirectionTo(p.X, p.Y);
- }
+ public Direction GetDirectionTo(IPoint2D p) => p == null ? Direction.North : GetDirectionTo(p.X, p.Y);
public void PublicOverheadMessage(MessageType type, int hue, bool ascii, string text, bool noLineOfSight = true)
{
@@ -9595,11 +9571,15 @@ namespace Server
return;
}
- var p = ascii
- ? (Packet)new AsciiMessage(Serial, Body, type, hue, 3, Name, text)
- : new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, text);
+ var length = OutgoingMessagePackets.GetMaxMessageLength(text);
- p.Acquire();
+ Span buffer = stackalloc byte[length];
+ length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ Serial, Body, type, hue, 3, ascii, Language, Name, text
+ );
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
var eable = m_Map.GetClientsInRange(m_Location);
@@ -9607,12 +9587,10 @@ namespace Server
{
if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this)))
{
- state.Send(p);
+ state.Send(buffer);
}
}
- Packet.Release(p);
-
eable.Free();
}
@@ -9623,7 +9601,13 @@ namespace Server
return;
}
- var p = Packet.Acquire(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args));
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedLength(args)];
+
+ var length = OutgoingMessagePackets.CreateMessageLocalized(
+ ref buffer,
+ Serial, Body, type, hue, 3, number, Name, args
+ );
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
var eable = m_Map.GetClientsInRange(m_Location);
@@ -9631,12 +9615,10 @@ namespace Server
{
if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this)))
{
- state.Send(p);
+ state.Send(buffer);
}
}
- Packet.Release(p);
-
eable.Free();
}
@@ -9650,20 +9632,13 @@ namespace Server
return;
}
- var p = Packet.Acquire(
- new MessageLocalizedAffix(
- Serial,
- Body,
- type,
- hue,
- 3,
- number,
- Name,
- affixType,
- affix,
- args
- )
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedAffixLength(affix, args)];
+
+ var length = OutgoingMessagePackets.CreateMessageLocalizedAffix(
+ ref buffer,
+ Serial, Body, type, hue, 3, number, Name, affixType, affix, args
);
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
var eable = m_Map.GetClientsInRange(m_Location);
@@ -9671,59 +9646,29 @@ namespace Server
{
if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this)))
{
- state.Send(p);
+ state.Send(buffer);
}
}
- Packet.Release(p);
-
eable.Free();
}
public void PrivateOverheadMessage(MessageType type, int hue, bool ascii, string text, NetState state)
{
- if (state == null)
- {
- return;
- }
-
- if (ascii)
- {
- state.Send(new AsciiMessage(Serial, Body, type, hue, 3, Name, text));
- }
- else
- {
- state.Send(new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, text));
- }
+ state.SendMessage(Serial, Body, type, hue, 3, ascii, m_Language, Name, text);
}
public void PrivateOverheadMessage(MessageType type, int hue, int number, NetState state) =>
PrivateOverheadMessage(type, hue, number, "", state);
public void PrivateOverheadMessage(MessageType type, int hue, int number, string args, NetState state) =>
- state?.Send(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args));
+ state.SendMessageLocalized(Serial, Body, type, hue, 3, number, Name, args);
- public void LocalOverheadMessage(MessageType type, int hue, bool ascii, string text)
- {
- var ns = m_NetState;
-
- if (ns == null)
- {
- return;
- }
-
- if (ascii)
- {
- ns.Send(new AsciiMessage(Serial, Body, type, hue, 3, Name, text));
- }
- else
- {
- ns.Send(new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, text));
- }
- }
+ public void LocalOverheadMessage(MessageType type, int hue, bool ascii, string text) =>
+ m_NetState.SendMessage(Serial, Body, type, hue, 3, ascii, m_Language, Name, text);
public void LocalOverheadMessage(MessageType type, int hue, int number, string args = "") =>
- m_NetState?.Send(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args));
+ m_NetState.SendMessageLocalized(Serial, Body, type, hue, 3, number, Name, args);
public void NonlocalOverheadMessage(MessageType type, int hue, int number, string args = "")
{
@@ -9732,7 +9677,13 @@ namespace Server
return;
}
- var p = Packet.Acquire(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args));
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedLength(args)];
+
+ var length = OutgoingMessagePackets.CreateMessageLocalized(
+ ref buffer,
+ Serial, Body, type, hue, 3, number, Name, args
+ );
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
var eable = m_Map.GetClientsInRange(m_Location);
@@ -9740,12 +9691,10 @@ namespace Server
{
if (state != m_NetState && state.Mobile.CanSee(this))
{
- state.Send(p);
+ state.Send(buffer);
}
}
- Packet.Release(p);
-
eable.Free();
}
@@ -9756,11 +9705,15 @@ namespace Server
return;
}
- var p = ascii
- ? (Packet)new AsciiMessage(Serial, Body, type, hue, 3, Name, text)
- : new UnicodeMessage(Serial, Body, type, hue, 3, Language, Name, text);
+ var length = OutgoingMessagePackets.GetMaxMessageLength(text);
- p.Acquire();
+ Span buffer = stackalloc byte[length];
+ length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ Serial, Body, type, hue, 3, ascii, Language, Name, text
+ );
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
var eable = m_Map.GetClientsInRange(m_Location);
@@ -9768,45 +9721,28 @@ namespace Server
{
if (state != m_NetState && state.Mobile.CanSee(this))
{
- state.Send(p);
+ state.Send(buffer);
}
}
- Packet.Release(p);
-
eable.Free();
}
- public void SendLocalizedMessage(int number) => m_NetState?.Send(MessageLocalized.InstantiateGeneric(number));
-
- public void SendLocalizedMessage(int number, string args, int hue = 0x3B2)
- {
- if (hue == 0x3B2 && string.IsNullOrEmpty(args))
- {
- m_NetState?.Send(MessageLocalized.InstantiateGeneric(number));
- }
- else
- {
- m_NetState?.Send(
- new MessageLocalized(Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", args)
- );
- }
- }
+ public void SendLocalizedMessage(int number, string args = "", int hue = 0x3B2) =>
+ m_NetState.SendMessageLocalized(Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", args);
public void SendLocalizedMessage(int number, bool append, string affix, string args = "", int hue = 0x3B2) =>
- m_NetState?.Send(
- new MessageLocalizedAffix(
- Serial.MinusOne,
- -1,
- MessageType.Regular,
- hue,
- 3,
- number,
- "System",
- (append ? AffixType.Append : AffixType.Prepend) | AffixType.System,
- affix,
- args
- )
+ m_NetState.SendMessageLocalizedAffix(
+ Serial.MinusOne,
+ -1,
+ MessageType.Regular,
+ hue,
+ 3,
+ number,
+ "System",
+ (append ? AffixType.Append : AffixType.Prepend) | AffixType.System,
+ affix,
+ args
);
public void SendMessage(string text) => SendMessage(0x3B2, text);
@@ -9815,7 +9751,7 @@ namespace Server
SendMessage(0x3B2, string.Format(format, args));
public void SendMessage(int hue, string text) =>
- m_NetState?.Send(new UnicodeMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "ENU", "System", text));
+ m_NetState.SendMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, false, "ENU", "System", text);
public void SendMessage(int hue, string format, params object[] args) =>
SendMessage(hue, string.Format(format, args));
@@ -9826,7 +9762,7 @@ namespace Server
SendAsciiMessage(0x3B2, string.Format(format, args));
public void SendAsciiMessage(int hue, string text) =>
- m_NetState?.Send(new AsciiMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "System", text));
+ m_NetState.SendMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, true, null, "System", text);
public void SendAsciiMessage(int hue, string format, params object[] args) =>
SendAsciiMessage(hue, string.Format(format, args));
diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs
index 0fefc26e1..7684de8c8 100644
--- a/Projects/Server/Network/NetState/NetState.cs
+++ b/Projects/Server/Network/NetState/NetState.cs
@@ -353,7 +353,7 @@ namespace Server.Network
public void LaunchBrowser(string url)
{
- Send(new MessageLocalized(Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231, "", ""));
+ this.SendMessageLocalized(Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231);
Send(new LaunchBrowser(url));
}
diff --git a/Projects/Server/Network/PacketUtilities.cs b/Projects/Server/Network/PacketUtilities.cs
index 0fda88dce..65d3e4301 100644
--- a/Projects/Server/Network/PacketUtilities.cs
+++ b/Projects/Server/Network/PacketUtilities.cs
@@ -15,11 +15,13 @@
using System.Buffers;
using System.IO;
+using System.Runtime.CompilerServices;
namespace Server.Network
{
public static class PacketUtilities
{
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WritePacketLength(this CircularBufferWriter writer)
{
var length = writer.Position;
@@ -27,5 +29,14 @@ namespace Server.Network
writer.Write((ushort)length);
writer.Seek(length, SeekOrigin.Begin);
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WritePacketLength(this SpanWriter writer)
+ {
+ var length = writer.Position;
+ writer.Seek(1, SeekOrigin.Begin);
+ writer.Write((ushort)length);
+ writer.Seek(length, SeekOrigin.Begin);
+ }
}
}
diff --git a/Projects/Server/Network/Packets/OutgoingEffectPackets.cs b/Projects/Server/Network/Packets/OutgoingEffectPackets.cs
index e54554b78..4765e3d9b 100644
--- a/Projects/Server/Network/Packets/OutgoingEffectPackets.cs
+++ b/Projects/Server/Network/Packets/OutgoingEffectPackets.cs
@@ -25,6 +25,19 @@ namespace Server.Network
public const int HuedEffectLength = 36;
public const int BoltEffectLength = 36;
+ public static void SendSoundEffect(this NetState ns, int soundID, IPoint3D target)
+ {
+ if (ns == null)
+ {
+ return;
+ }
+
+ Span buffer = stackalloc byte[SoundPacketLength];
+ CreateSoundEffect(ref buffer, soundID, target);
+
+ ns.Send(buffer);
+ }
+
public static void CreateSoundEffect(ref Span buffer, int soundID, IPoint3D target)
{
var writer = new SpanWriter(buffer);
@@ -37,25 +50,6 @@ namespace Server.Network
writer.Write((short)target.Z);
}
- public static void SendSoundEffect(this NetState ns, int soundID, IPoint3D target)
- {
- if (ns == null || !ns.GetSendBuffer(out var buffer))
- {
- return;
- }
-
- var writer = new CircularBufferWriter(buffer);
- writer.Write((byte)0x54); // Packet ID
- writer.Write((byte)1); // flags
- writer.Write((short)soundID);
- writer.Write((short)0); // volume
- writer.Write((short)target.X);
- writer.Write((short)target.Y);
- writer.Write((short)target.Z);
-
- ns.Send(ref buffer, writer.Position);
- }
-
public static void CreateParticleEffect(
ref Span buffer,
EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint,
diff --git a/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs b/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs
index 0a73bd30c..119cd4b43 100644
--- a/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs
+++ b/Projects/Server/Network/Packets/OutgoingEquipmentPackets.cs
@@ -36,11 +36,7 @@ namespace Server.Network
{
public static void SendDisplayEquipmentInfo(
this NetState ns,
- Serial serial,
- int number,
- string crafterName,
- bool unidentified,
- List attrs
+ Serial serial, int number, string crafterName, bool unidentified, List attrs
)
{
if (ns == null || !ns.GetSendBuffer(out var buffer))
diff --git a/Projects/Server/Network/Packets/OutgoingMenuPackets.cs b/Projects/Server/Network/Packets/OutgoingMenuPackets.cs
index 0b02f44c8..2f5969c63 100644
--- a/Projects/Server/Network/Packets/OutgoingMenuPackets.cs
+++ b/Projects/Server/Network/Packets/OutgoingMenuPackets.cs
@@ -72,11 +72,9 @@ namespace Server.Network
}
}
- var length = writer.Position;
- writer.Seek(1, SeekOrigin.Begin);
- writer.Write((ushort)length);
+ writer.WritePacketLength();
- ns.Send(ref buffer, length);
+ ns.Send(ref buffer, writer.Position);
}
public static void SendDisplayQuestionMenu(this NetState ns, QuestionMenu menu)
@@ -129,11 +127,9 @@ namespace Server.Network
}
}
- var length = writer.Position;
- writer.Seek(1, SeekOrigin.Begin);
- writer.Write((ushort)length);
+ writer.WritePacketLength();
- ns.Send(ref buffer, length);
+ ns.Send(ref buffer, writer.Position);
}
public static void SendDisplayContextMenu(this NetState ns, ContextMenu menu)
@@ -209,11 +205,9 @@ namespace Server.Network
}
}
- var length = writer.Position;
- writer.Seek(1, SeekOrigin.Begin);
- writer.Write((ushort)length);
+ writer.WritePacketLength();
- ns.Send(ref buffer, length);
+ ns.Send(ref buffer, writer.Position);
}
}
}
diff --git a/Projects/Server/Network/Packets/OutgoingMessagePackets.cs b/Projects/Server/Network/Packets/OutgoingMessagePackets.cs
new file mode 100644
index 000000000..692cc0578
--- /dev/null
+++ b/Projects/Server/Network/Packets/OutgoingMessagePackets.cs
@@ -0,0 +1,235 @@
+/*************************************************************************
+ * ModernUO *
+ * Copyright 2019-2020 - ModernUO Development Team *
+ * Email: hi@modernuo.com *
+ * File: OutgoingMessagePackets.cs *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
+ *************************************************************************/
+
+using System;
+using System.Buffers;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+namespace Server.Network
+{
+ [Flags]
+ public enum AffixType : byte
+ {
+ Append = 0x00,
+ Prepend = 0x01,
+ System = 0x02
+ }
+
+ public static class OutgoingMessagePackets
+ {
+ public static void SendMessageLocalized(
+ this NetState ns,
+ Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = ""
+ )
+ {
+ if (ns == null)
+ {
+ return;
+ }
+
+ Span buffer = stackalloc byte[GetMaxMessageLocalizedLength(args)];
+ var length = CreateMessageLocalized(
+ ref buffer,
+ serial, graphic, type, hue, font, number, name, args
+ );
+
+ ns.Send(buffer.Slice(0, length));
+ }
+
+ public static int GetMaxMessageLocalizedLength(string args) => 50 + (args?.Length ?? 0) * 2;
+
+ public static int CreateMessageLocalized(
+ ref Span buffer,
+ Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = ""
+ )
+ {
+ name = name?.Trim() ?? "";
+ args = args?.Trim() ?? "";
+
+ if (hue == 0)
+ {
+ hue = 0x3B2;
+ }
+
+ var writer = new SpanWriter(buffer);
+ writer.Write((byte)0xC1);
+ writer.Seek(2, SeekOrigin.Current);
+ writer.Write(serial);
+ writer.Write((short)graphic);
+ writer.Write((byte)type);
+ writer.Write((short)hue);
+ writer.Write((short)font);
+ writer.Write(number);
+ writer.WriteAscii(name, 30);
+ writer.WriteLittleUniNull(args);
+
+ writer.WritePacketLength();
+
+ return writer.Position;
+ }
+
+ public static void SendMessageLocalizedAffix(
+ this NetState ns,
+ Serial serial, int graphic, MessageType type, int hue, int font, int number, string name,
+ AffixType affixType, string affix = "", string args = ""
+ )
+ {
+ if (ns == null)
+ {
+ return;
+ }
+
+ Span buffer = stackalloc byte[GetMaxMessageLocalizedAffixLength(affix, args)];
+ var length = CreateMessageLocalizedAffix(
+ ref buffer,
+ serial, graphic, type, hue, font, number, name, affixType, affix, args
+ );
+
+ ns.Send(buffer.Slice(0, length));
+ }
+
+ public static int GetMaxMessageLocalizedAffixLength(string affix, string args) =>
+ 52 + (affix?.Length ?? 0) + (args?.Length ?? 0) * 2;
+
+ public static int CreateMessageLocalizedAffix(
+ ref Span buffer,
+ Serial serial, int graphic, MessageType type, int hue, int font, int number, string name,
+ AffixType affixType, string affix = "", string args = ""
+ )
+ {
+ name = name?.Trim() ?? "";
+ affix = affix?.Trim() ?? "";
+ args = args?.Trim() ?? "";
+
+ if (hue == 0)
+ {
+ hue = 0x3B2;
+ }
+
+ var writer = new SpanWriter(buffer);
+ writer.Write((byte)0xCC);
+ writer.Seek(2, SeekOrigin.Current);
+ writer.Write(serial);
+ writer.Write((short)graphic);
+ writer.Write((byte)type);
+ writer.Write((short)hue);
+ writer.Write((short)font);
+ writer.Write(number);
+ writer.Write((byte)affixType);
+ writer.WriteAscii(name, 30);
+ writer.WriteAsciiNull(affix);
+ writer.WriteBigUniNull(args);
+
+ writer.WritePacketLength();
+
+ return writer.Position;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void SendMessage(
+ this NetState ns,
+ Serial serial, int graphic, MessageType type, int hue, int font, bool ascii, string lang, string name, string text
+ )
+ {
+ if (ns == null)
+ {
+ return;
+ }
+
+ Span buffer = stackalloc byte[GetMaxMessageLength(text)];
+ var length = CreateMessage(
+ ref buffer,
+ serial,
+ graphic,
+ type,
+ hue,
+ font,
+ ascii,
+ lang,
+ name,
+ text
+ );
+
+ ns.Send(buffer.Slice(0, length));
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GetMaxMessageLength(string text) => 50 + (text?.Length ?? 0) * 2;
+
+ public static int CreateMessage(
+ ref Span buffer,
+ Serial serial,
+ int graphic,
+ MessageType type,
+ int hue,
+ int font,
+ bool ascii,
+ string lang,
+ string name,
+ string text
+ )
+ {
+ name = name?.Trim() ?? "";
+ text = text?.Trim() ?? "";
+ lang = lang?.Trim() ?? "ENU";
+
+ if (hue == 0)
+ {
+ hue = 0x3B2;
+ }
+
+ var writer = new SpanWriter(buffer);
+ writer.Write((byte)(ascii ? 0x1C : 0xAE)); // Packet ID
+ writer.Seek(2, SeekOrigin.Current);
+ writer.Write(serial);
+ writer.Write((short)graphic);
+ writer.Write((byte)type);
+ writer.Write((short)hue);
+ writer.Write((short)font);
+ if (ascii)
+ {
+ writer.WriteAscii(name, 30);
+ writer.WriteAsciiNull(text);
+ }
+ else
+ {
+ writer.WriteAscii(lang, 4);
+ writer.WriteAscii(name, 30);
+ writer.WriteBigUniNull(text);
+ }
+
+ writer.WritePacketLength();
+
+ return writer.Position;
+ }
+
+ public static void SendFollowMessage(this NetState ns, Serial s1, Serial s2)
+ {
+ if (ns == null || !ns.GetSendBuffer(out var buffer))
+ {
+ return;
+ }
+
+ var writer = new CircularBufferWriter(buffer);
+ writer.Write((byte)0x15); // Packet ID
+ writer.Write(s1);
+ writer.Write(s2);
+
+ ns.Send(ref buffer, 9);
+ }
+ }
+}
diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs
index f7b3012ed..708b8fc5a 100644
--- a/Projects/Server/World/World.cs
+++ b/Projects/Server/World/World.cs
@@ -152,28 +152,23 @@ namespace Server
public static void Broadcast(int hue, bool ascii, string text)
{
- Packet p;
+ var length = OutgoingMessagePackets.GetMaxMessageLength(text);
- if (ascii)
- {
- p = new AsciiMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "System", text);
- }
- else
- {
- p = new UnicodeMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "ENU", "System", text);
- }
+ Span buffer = stackalloc byte[length];
+ length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ Serial.MinusOne, -1, MessageType.Regular, hue, 3, ascii, "ENU", "System", text
+ );
- p.Acquire();
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
foreach (var ns in TcpServer.Instances)
{
if (ns.Mobile != null)
{
- ns.Send(p);
+ ns.Send(buffer);
}
}
-
- p.Release();
}
public static void Broadcast(int hue, bool ascii, string format, params object[] args)
diff --git a/Projects/UOContent/Engines/ConPVP/Games/CTF.cs b/Projects/UOContent/Engines/ConPVP/Games/CTF.cs
index 49a78f60a..e9410a79e 100644
--- a/Projects/UOContent/Engines/ConPVP/Games/CTF.cs
+++ b/Projects/UOContent/Engines/ConPVP/Games/CTF.cs
@@ -291,17 +291,16 @@ namespace Server.Engines.ConPVP
{
if (Location == m_TeamInfo.Origin && Map == m_TeamInfo.Game.Facet)
{
- from.Send(
- new UnicodeMessage(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x3B2,
- 3,
- "ENU",
- Name,
- "Touch me not for I am chaste."
- )
+ from.NetState.SendMessage(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ false,
+ "ENU",
+ Name,
+ "Touch me not for I am chaste."
);
}
else
diff --git a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs
index b3f2fa69c..6f6de1a20 100644
--- a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs
+++ b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs
@@ -487,38 +487,47 @@ namespace Server.Engines.Doom
public static void PlayerSendASCII(Mobile player, int index)
{
- player.Send(
- new AsciiMessage(
- Serial.MinusOne,
- 0xFFFF,
- MessageType.Label,
- MsgParams[index][0],
- MsgParams[index][1],
- null,
- Msgs[index]
- )
+ player.NetState.SendMessage(
+ Serial.MinusOne,
+ 0xFFFF,
+ MessageType.Label,
+ MsgParams[index][0],
+ MsgParams[index][1],
+ true,
+ null,
+ null,
+ Msgs[index]
);
}
/* I cant find any better way to send "speech" using fonts other than default */
public static void POHMessage(Mobile from, int index)
{
- Packet p = new AsciiMessage(
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(Msgs[index])];
+
+ var length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
from.Serial,
from.Body,
MessageType.Regular,
MsgParams[index][0],
MsgParams[index][1],
+ true,
+ null,
from.Name,
Msgs[index]
);
- p.Acquire();
- foreach (var state in from.Map.GetClientsInRange(from.Location))
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
+
+ var eable = from.Map.GetClientsInRange(from.Location);
+
+ foreach (var state in eable)
{
- state.Send(p);
+ state.Send(buffer);
}
- Packet.Release(p);
+ eable.Free();
}
public override void Serialize(IGenericWriter writer)
diff --git a/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrap.cs b/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrap.cs
index 7d2ff0f9e..0d4b2c107 100644
--- a/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrap.cs
+++ b/Projects/UOContent/Engines/Factions/Items/Traps/BaseFactionTrap.cs
@@ -192,9 +192,7 @@ namespace Server.Factions
public void PrivateOverheadLocalizedMessage(Mobile to, int number, int hue, string name, string args)
{
- var ns = to?.NetState;
-
- ns?.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number, name, args));
+ to?.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number, name, args);
}
public virtual bool CheckDecay()
diff --git a/Projects/UOContent/Engines/MLQuests/Mobiles/SirHelper.cs b/Projects/UOContent/Engines/MLQuests/Mobiles/SirHelper.cs
index 518f5a71a..08b164330 100644
--- a/Projects/UOContent/Engines/MLQuests/Mobiles/SirHelper.cs
+++ b/Projects/UOContent/Engines/MLQuests/Mobiles/SirHelper.cs
@@ -90,37 +90,35 @@ namespace Server.Engines.MLQuests.Mobiles
{
base.OnThink();
- if (m_NextShout <= DateTime.UtcNow)
+ if (m_NextShout > DateTime.UtcNow)
{
- Packet shoutPacket = null;
-
- foreach (var state in GetClientsInRange(12))
- {
- var m = state.Mobile;
-
- if (m.CanSee(this) && m.InLOS(this) && m.CanBeginAction(this))
- {
- shoutPacket ??= Packet.Acquire(
- new MessageLocalized(
- Serial,
- Body,
- MessageType.Regular,
- 946,
- 3,
- 1078099,
- Name,
- ""
- )
- ); // Double Click On Me For Help!
-
- state.Send(shoutPacket);
- }
- }
-
- Packet.Release(shoutPacket);
-
- m_NextShout = DateTime.UtcNow + m_ShoutDelay;
+ return;
}
+
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedLength("")];
+ var packetCreated = false;
+
+ foreach (var state in GetClientsInRange(12))
+ {
+ var m = state.Mobile;
+
+ if (m.CanSee(this) && m.InLOS(this) && m.CanBeginAction(this))
+ {
+ if (!packetCreated)
+ {
+ // Double Click On Me For Help!
+ var length = OutgoingMessagePackets.CreateMessageLocalized(
+ ref buffer,
+ Serial, Body, MessageType.Regular, 946, 3, 1078099, Name
+ );
+ packetCreated = true;
+ }
+
+ state.Send(buffer);
+ }
+ }
+
+ m_NextShout = DateTime.UtcNow + m_ShoutDelay;
}
private void EndLock(Mobile m)
diff --git a/Projects/UOContent/Engines/Party/Party.cs b/Projects/UOContent/Engines/Party/Party.cs
index 861d37847..45efc269e 100644
--- a/Projects/UOContent/Engines/Party/Party.cs
+++ b/Projects/UOContent/Engines/Party/Party.cs
@@ -239,22 +239,25 @@ namespace Server.Engines.PartySystem
return;
}
- // : joined the party.
- SendToAll(
- new MessageLocalizedAffix(
- Serial.MinusOne,
- -1,
- MessageType.Label,
- 0x3B2,
- 3,
- 1008094,
- "",
- AffixType.Prepend | AffixType.System,
- from.Name,
- ""
- )
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedAffixLength(from.Name, "")];
+ var length = OutgoingMessagePackets.CreateMessageLocalizedAffix(
+ ref buffer,
+ Serial.MinusOne,
+ -1,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ 1008094,
+ "",
+ AffixType.Prepend | AffixType.System,
+ from.Name
);
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
+
+ // : joined the party.
+ SendToAll(ref buffer, true);
+
from.SendLocalizedMessage(1005445); // You have been added to the party.
Candidates.Remove(from);
@@ -288,32 +291,31 @@ namespace Server.Engines.PartySystem
if (m == Leader)
{
Disband();
+ return;
}
- else
+
+ for (var i = 0; i < Members.Count; ++i)
{
- for (var i = 0; i < Members.Count; ++i)
+ if (Members[i].Mobile == m)
{
- if (Members[i].Mobile == m)
- {
- Members.RemoveAt(i);
+ Members.RemoveAt(i);
- m.Party = null;
- m.Send(new PartyEmptyList(m));
+ m.Party = null;
+ m.Send(new PartyEmptyList(m));
- m.SendLocalizedMessage(1005451); // You have been removed from the party.
+ m.SendLocalizedMessage(1005451); // You have been removed from the party.
- SendToAll(new PartyRemoveMember(m, this));
- SendToAll(1005452); // A player has been removed from your party.
+ SendToAll(new PartyRemoveMember(m, this));
+ SendToAll(1005452); // A player has been removed from your party.
- break;
- }
+ break;
}
+ }
- if (Members.Count == 1)
- {
- SendToAll(1005450); // The last person has left the party...
- Disband();
- }
+ if (Members.Count == 1)
+ {
+ SendToAll(1005450); // The last person has left the party...
+ Disband();
}
}
@@ -357,19 +359,16 @@ namespace Server.Engines.PartySystem
}
// : You are invited to join the party. Type /accept to join or /decline to decline the offer.
- target.Send(
- new MessageLocalizedAffix(
- Serial.MinusOne,
- -1,
- MessageType.Label,
- 0x3B2,
- 3,
- 1008089,
- "",
- AffixType.Prepend | AffixType.System,
- from.Name,
- ""
- )
+ target.NetState.SendMessageLocalizedAffix(
+ Serial.MinusOne,
+ -1,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ 1008089,
+ "",
+ AffixType.Prepend | AffixType.System,
+ from.Name
);
from.SendLocalizedMessage(1008090); // You have invited them to join the party.
@@ -380,19 +379,17 @@ namespace Server.Engines.PartySystem
DeclineTimer.Start(target, from);
}
- public void SendToAll(int number)
+ public void SendToAll(int number, string args = "", int hue = 0x3B2)
{
- SendToAll(number, "", 0x3B2);
- }
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedLength(args)];
+ var length = OutgoingMessagePackets.CreateMessageLocalized(
+ ref buffer,
+ Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", args
+ );
- public void SendToAll(int number, string args)
- {
- SendToAll(number, args, 0x3B2);
- }
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
- public void SendToAll(int number, string args, int hue)
- {
- SendToAll(new MessageLocalized(Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", args));
+ SendToAll(ref buffer, true);
}
public void SendPublicMessage(Mobile from, string text)
@@ -431,7 +428,20 @@ namespace Server.Engines.PartySystem
private void SendToStaffMessage(Mobile from, string text)
{
- Packet p = null;
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
+ var length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ from.Serial,
+ from.Body,
+ MessageType.Regular,
+ from.SpeechHue,
+ 3,
+ false,
+ from.Language,
+ from.Name,
+ text
+ );
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
foreach (var ns in from.GetClientsInRange(8))
{
@@ -440,27 +450,9 @@ namespace Server.Engines.PartySystem
if (mob?.AccessLevel >= AccessLevel.GameMaster && mob.AccessLevel > from.AccessLevel &&
mob.Party != this && !m_Listeners.Contains(mob))
{
- if (p == null)
- {
- p = Packet.Acquire(
- new UnicodeMessage(
- from.Serial,
- from.Body,
- MessageType.Regular,
- from.SpeechHue,
- 3,
- from.Language,
- from.Name,
- text
- )
- );
- }
-
- ns.Send(p);
+ ns.Send(buffer);
}
}
-
- Packet.Release(p);
}
private void SendToStaffMessage(Mobile from, string format, params object[] args)
@@ -477,7 +469,17 @@ namespace Server.Engines.PartySystem
Members[i].Mobile.Send(p);
}
- if (p is MessageLocalized || p is MessageLocalizedAffix || p is UnicodeMessage || p is AsciiMessage)
+ p.Release();
+ }
+
+ public void SendToAll(ref Span span, bool isSpeech)
+ {
+ for (var i = 0; i < Members.Count; ++i)
+ {
+ Members[i].Mobile.NetState?.Send(span);
+ }
+
+ if (isSpeech)
{
for (var i = 0; i < m_Listeners.Count; ++i)
{
@@ -485,12 +487,10 @@ namespace Server.Engines.PartySystem
if (mob.Party != this)
{
- mob.Send(p);
+ mob.NetState?.Send(span);
}
}
}
-
- p.Release();
}
private class RejoinTimer : Timer
@@ -511,20 +511,22 @@ namespace Server.Engines.PartySystem
m_Mobile.SendLocalizedMessage(1005437); // You have rejoined the party.
m_Mobile.Send(new PartyMemberList(p));
- var message = Packet.Acquire(
- new MessageLocalizedAffix(
- Serial.MinusOne,
- -1,
- MessageType.Label,
- 0x3B2,
- 3,
- 1008087,
- "",
- AffixType.Prepend | AffixType.System,
- m_Mobile.Name,
- ""
- )
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLocalizedAffixLength(m_Mobile.Name, "")];
+ var length = OutgoingMessagePackets.CreateMessageLocalizedAffix(
+ ref buffer,
+ Serial.MinusOne,
+ -1,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ 1008087,
+ "",
+ AffixType.Prepend | AffixType.System,
+ m_Mobile.Name
);
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
+
var attrs = Packet.Acquire(new MobileAttributesN(m_Mobile));
foreach (var mi in p.Members)
@@ -533,7 +535,7 @@ namespace Server.Engines.PartySystem
if (m != m_Mobile)
{
- m.Send(message);
+ m.NetState?.Send(buffer);
m.Send(new MobileStatusCompact(m_Mobile.CanBeRenamedBy(m), m_Mobile));
m.Send(attrs);
m_Mobile.Send(new MobileStatusCompact(m.CanBeRenamedBy(m_Mobile), m));
@@ -541,7 +543,6 @@ namespace Server.Engines.PartySystem
}
}
- Packet.Release(message);
Packet.Release(attrs);
}
}
diff --git a/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs b/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs
index 7e40799a8..c59401bf6 100644
--- a/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs
+++ b/Projects/UOContent/Engines/Quests/Collector/Items/Obsidian.cs
@@ -189,17 +189,13 @@ namespace Server.Engines.Quests.Collector
{
if (!IsChildOf(from.Backpack))
{
- from.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x2C,
- 3,
- 500309,
- "",
- ""
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x2C,
+ 3,
+ 500309
); // Nothing Happens.
}
else
@@ -286,33 +282,30 @@ namespace Server.Engines.Quests.Collector
targObsidian.StatueName = RandomName(from);
}
- from.Send(
- new AsciiMessage(
- targObsidian.Serial,
- targObsidian.ItemID,
- MessageType.Regular,
- 0x59,
- 3,
- m_Obsidian.Name,
- "Something Happened."
- )
+ from.NetState.SendMessage(
+ targObsidian.Serial,
+ targObsidian.ItemID,
+ MessageType.Regular,
+ 0x59,
+ 3,
+ true,
+ null,
+ m_Obsidian.Name,
+ "Something Happened."
);
return;
}
}
- from.Send(
- new MessageLocalized(
- m_Obsidian.Serial,
- m_Obsidian.ItemID,
- MessageType.Regular,
- 0x2C,
- 3,
- 500309,
- m_Obsidian.Name,
- ""
- )
+ from.NetState.SendMessageLocalized(
+ m_Obsidian.Serial,
+ m_Obsidian.ItemID,
+ MessageType.Regular,
+ 0x2C,
+ 3,
+ 500309,
+ m_Obsidian.Name
); // Nothing Happens.
}
}
diff --git a/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs b/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs
index dfc9138da..139b18fcf 100644
--- a/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs
+++ b/Projects/UOContent/Engines/Quests/Core/Items/EnchantedSextant.cs
@@ -102,18 +102,15 @@ namespace Server.Items
banks = m_IlshenarBanks;
moongates = PMList.Ilshenar;
#else
- from.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Label,
- 0x482,
- 3,
- 1061684,
- "",
- ""
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ 0x482,
+ 3,
+ 1061684
); // The magic of the sextant fails...
+
return;
#endif
}
@@ -176,7 +173,7 @@ namespace Server.Items
moonMsg = 1048018; // You are next to a Moongate at the moment.
}
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, moonMsg, "", ""));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, moonMsg);
int bankMsg;
if (bankDistance == double.MaxValue)
@@ -196,7 +193,7 @@ namespace Server.Items
bankMsg = 1048019; // You are next to a Bank at the moment.
}
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, 0x5AA, 3, bankMsg, "", ""));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x5AA, 3, bankMsg);
}
public override void Serialize(IGenericWriter writer)
diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs
index 50077499c..8dded19d2 100644
--- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs
+++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs
@@ -89,32 +89,26 @@ namespace Server.Engines.Quests.Haven
if (ItemID == 0x2006) // Corpse form
{
- from.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Label,
- hue,
- 3,
- 1049144,
- "",
- Name
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ hue,
+ 3,
+ 1049144,
+ "",
+ Name
); // the remains of ~1_NAME~ the apprentice
}
else
{
- from.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Label,
- hue,
- 3,
- 1049145,
- "",
- ""
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ hue,
+ 3,
+ 1049145
); // the remains of a wizard's apprentice
}
}
diff --git a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs
index 968530315..ee0a3795c 100644
--- a/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs
+++ b/Projects/UOContent/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs
@@ -127,32 +127,26 @@ namespace Server.Engines.Quests.Haven
if (ItemID == 0x2006) // Corpse form
{
- from.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Label,
- hue,
- 3,
- 1049318,
- "",
- Name
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ hue,
+ 3,
+ 1049318,
+ "",
+ Name
); // the remains of ~1_NAME~ the militia fighter
}
else
{
- from.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Label,
- hue,
- 3,
- 1049319,
- "",
- ""
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ hue,
+ 3,
+ 1049319
); // the remains of a militia fighter
}
}
diff --git a/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs b/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs
index 0578ea900..9603bab33 100644
--- a/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs
+++ b/Projects/UOContent/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs
@@ -48,7 +48,7 @@ namespace Server.Engines.Quests.Hag
{
var hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this));
- from.Send(new AsciiMessage(Serial, ItemID, MessageType.Label, hue, 3, "", "a charred corpse"));
+ from.NetState.SendMessage(Serial, ItemID, MessageType.Label, hue, 3, true, null, "", "a charred corpse");
}
public override void Open(Mobile from, bool checkSelfLoot)
diff --git a/Projects/UOContent/Items/Armor/BaseArmor.cs b/Projects/UOContent/Items/Armor/BaseArmor.cs
index 58752d49d..5229dbd50 100644
--- a/Projects/UOContent/Items/Armor/BaseArmor.cs
+++ b/Projects/UOContent/Items/Armor/BaseArmor.cs
@@ -2036,7 +2036,7 @@ namespace Server.Items
return;
}
- from.NetState?.SendDisplayEquipmentInfo(Serial, number, m_Crafter?.RawName, false, attrs);
+ from.NetState.SendDisplayEquipmentInfo(Serial, number, m_Crafter?.RawName, false, attrs);
}
[Flags]
diff --git a/Projects/UOContent/Items/Clothing/BaseClothing.cs b/Projects/UOContent/Items/Clothing/BaseClothing.cs
index 8e7bdf614..17288493f 100644
--- a/Projects/UOContent/Items/Clothing/BaseClothing.cs
+++ b/Projects/UOContent/Items/Clothing/BaseClothing.cs
@@ -880,7 +880,7 @@ namespace Server.Items
return;
}
- from.NetState?.SendDisplayEquipmentInfo(Serial, number, m_Crafter?.RawName, false, attrs);
+ from.NetState.SendDisplayEquipmentInfo(Serial, number, m_Crafter?.RawName, false, attrs);
}
public virtual void AddEquipInfoAttributes(Mobile from, List attrs)
diff --git a/Projects/UOContent/Items/Containers/LockableContainer.cs b/Projects/UOContent/Items/Containers/LockableContainer.cs
index 54d0e3d92..c541abaa2 100644
--- a/Projects/UOContent/Items/Containers/LockableContainer.cs
+++ b/Projects/UOContent/Items/Containers/LockableContainer.cs
@@ -279,7 +279,7 @@ namespace Server.Items
inaccessible = true;
}
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", ""));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number);
}
return inaccessible;
diff --git a/Projects/UOContent/Items/Containers/TrappableContainer.cs b/Projects/UOContent/Items/Containers/TrappableContainer.cs
index 05b97f8eb..ac9398ae9 100644
--- a/Projects/UOContent/Items/Containers/TrappableContainer.cs
+++ b/Projects/UOContent/Items/Containers/TrappableContainer.cs
@@ -51,7 +51,7 @@ namespace Server.Items
return;
}
- to.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number, "", ""));
+ to.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number);
}
private void SendMessageTo(Mobile to, string text, int hue)
@@ -61,7 +61,7 @@ namespace Server.Items
return;
}
- to.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, hue, 3, "ENU", "", text));
+ to.NetState.SendMessage(Serial, ItemID, MessageType.Regular, hue, 3, false, "ENU", "", text);
}
public virtual bool ExecuteTrap(Mobile from)
diff --git a/Projects/UOContent/Items/Guilds/Guildstone.cs b/Projects/UOContent/Items/Guilds/Guildstone.cs
index a6578b217..458ca8c73 100644
--- a/Projects/UOContent/Items/Guilds/Guildstone.cs
+++ b/Projects/UOContent/Items/Guilds/Guildstone.cs
@@ -276,17 +276,13 @@ namespace Server.Items
}
else if (from.AccessLevel < AccessLevel.GameMaster && !Guild.IsMember(from))
{
- from.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x3B2,
- 3,
- 501158,
- "",
- ""
- )
+ from.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ 501158
); // You are not a member ...
}
else
diff --git a/Projects/UOContent/Items/Maps/TreasureMap.cs b/Projects/UOContent/Items/Maps/TreasureMap.cs
index dd7170e4e..b0c7587ea 100644
--- a/Projects/UOContent/Items/Maps/TreasureMap.cs
+++ b/Projects/UOContent/Items/Maps/TreasureMap.cs
@@ -519,7 +519,7 @@ namespace Server.Items
if (m_Completed)
{
- list.Add(1041507, m_CompletedBy == null ? "someone" : m_CompletedBy.Name); // completed by ~1_val~
+ list.Add(1041507, m_CompletedBy?.RawName ?? "someone"); // completed by ~1_val~
}
}
@@ -527,19 +527,16 @@ namespace Server.Items
{
if (m_Completed)
{
- from.Send(
- new MessageLocalizedAffix(
- Serial,
- ItemID,
- MessageType.Label,
- 0x3B2,
- 3,
- 1048030,
- "",
- AffixType.Append,
- $" completed by {(m_CompletedBy == null ? "someone" : m_CompletedBy.Name)}",
- ""
- )
+ from.NetState.SendMessageLocalizedAffix(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ 1048030,
+ "",
+ AffixType.Append,
+ $" completed by {m_CompletedBy?.RawName ?? "someone"}"
);
}
else if (m_Decoder != null)
diff --git a/Projects/UOContent/Items/Misc/BankCheck.cs b/Projects/UOContent/Items/Misc/BankCheck.cs
index 32c9535a1..5683d9d5f 100644
--- a/Projects/UOContent/Items/Misc/BankCheck.cs
+++ b/Projects/UOContent/Items/Misc/BankCheck.cs
@@ -153,19 +153,16 @@ namespace Server.Items
public override void OnSingleClick(Mobile from)
{
- from.Send(
- new MessageLocalizedAffix(
- Serial,
- ItemID,
- MessageType.Label,
- 0x3B2,
- 3,
- 1041361,
- "",
- AffixType.Append,
- $" {m_Worth}",
- ""
- )
+ from.NetState.SendMessageLocalizedAffix(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ 1041361,
+ "",
+ AffixType.Append,
+ $" {m_Worth}"
); // A bank check:
}
diff --git a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs
index c04c52b6e..fbac6fe2b 100644
--- a/Projects/UOContent/Items/Misc/Corpses/Corpse.cs
+++ b/Projects/UOContent/Items/Misc/Corpses/Corpse.cs
@@ -1168,7 +1168,7 @@ namespace Server.Items
if (opl.Header > 0)
{
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs);
}
}
@@ -1180,16 +1180,16 @@ namespace Server.Items
{
if (m_CorpseName != null)
{
- from.Send(new AsciiMessage(Serial, ItemID, MessageType.Label, hue, 3, "", m_CorpseName));
+ from.NetState.SendMessage(Serial, ItemID, MessageType.Label, hue, 3, true, null, "", m_CorpseName);
}
else
{
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name);
}
}
else // Bone form
{
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name);
}
}
diff --git a/Projects/UOContent/Items/Misc/Key.cs b/Projects/UOContent/Items/Misc/Key.cs
index 2f33ebe5b..058f4f49d 100644
--- a/Projects/UOContent/Items/Misc/Key.cs
+++ b/Projects/UOContent/Items/Misc/Key.cs
@@ -249,14 +249,14 @@ namespace Server.Items
{
desc = "(blank)";
}
- else if ((desc = m_Description) == null || (desc = desc.Trim()).Length <= 0)
+ else
{
- desc = "";
+ desc = m_Description?.Trim() ?? "";
}
if (desc.Length > 0)
{
- from.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", "", desc));
+ from.NetState.SendMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, false, "ENU", "", desc);
}
}
diff --git a/Projects/UOContent/Items/Misc/PowerGenerator.cs b/Projects/UOContent/Items/Misc/PowerGenerator.cs
index 5d0710ef9..35d8899d8 100644
--- a/Projects/UOContent/Items/Misc/PowerGenerator.cs
+++ b/Projects/UOContent/Items/Misc/PowerGenerator.cs
@@ -216,18 +216,18 @@ namespace Server.Items
public void DoDamage(Mobile to)
{
- to.Send(
- new UnicodeMessage(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x3B2,
- 3,
- "",
- "",
- "The generator shoots an arc of electricity at you!"
- )
+ to.NetState.SendMessage(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ false,
+ "ENU",
+ "",
+ "The generator shoots an arc of electricity at you!"
);
+
to.BoltEffect(0);
to.LocalOverheadMessage(MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *");
to.NonlocalOverheadMessage(MessageType.Regular, 0xC9, true, $"* {to.Name} spasms from electric shock *");
diff --git a/Projects/UOContent/Items/Misc/Teleporter.cs b/Projects/UOContent/Items/Misc/Teleporter.cs
index 31a905caa..16f53cfb0 100644
--- a/Projects/UOContent/Items/Misc/Teleporter.cs
+++ b/Projects/UOContent/Items/Misc/Teleporter.cs
@@ -429,32 +429,28 @@ namespace Server.Items
{
if (m_MessageString != null)
{
- m.Send(
- new UnicodeMessage(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x3B2,
- 3,
- "ENU",
- null,
- m_MessageString
- )
+ m.NetState.SendMessage(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ false,
+ "ENU",
+ null,
+ m_MessageString
);
}
else if (m_MessageNumber != 0)
{
- m.Send(
- new MessageLocalized(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x3B2,
- 3,
- m_MessageNumber,
- null,
- ""
- )
+ m.NetState.SendMessageLocalized(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ m_MessageNumber,
+ null
);
}
diff --git a/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs b/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs
index c1450e397..3363c4741 100644
--- a/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs
+++ b/Projects/UOContent/Items/Resources/Tailor/BoltOfCloth.cs
@@ -61,10 +61,8 @@ namespace Server.Items
public override void OnSingleClick(Mobile from)
{
var number = Amount == 1 ? 1049122 : 1049121;
-
- from.Send(
- new MessageLocalized(Serial, ItemID, MessageType.Label, 0x3B2, 3, number, "", (Amount * 50).ToString())
- );
+ var amount = (Amount * 50).ToString();
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, 0x3B2, 3, number, "", amount);
}
}
}
diff --git a/Projects/UOContent/Items/Resources/Tailor/Cloth.cs b/Projects/UOContent/Items/Resources/Tailor/Cloth.cs
index b18f2b427..998c7d3fb 100644
--- a/Projects/UOContent/Items/Resources/Tailor/Cloth.cs
+++ b/Projects/UOContent/Items/Resources/Tailor/Cloth.cs
@@ -62,7 +62,7 @@ namespace Server.Items
{
var number = Amount == 1 ? 1049124 : 1049123;
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", Amount.ToString()));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", Amount.ToString());
}
}
}
diff --git a/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs b/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs
index 51aaffc55..78d97416b 100644
--- a/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs
+++ b/Projects/UOContent/Items/Resources/Tailor/UncutCloth.cs
@@ -62,7 +62,7 @@ namespace Server.Items
{
var number = Amount == 1 ? 1049124 : 1049123;
- from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", Amount.ToString()));
+ from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", Amount.ToString());
}
}
}
diff --git a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs
index bc415b404..9d4158dc7 100644
--- a/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs
+++ b/Projects/UOContent/Items/Skill Items/Magical/Spellbook.cs
@@ -696,7 +696,7 @@ namespace Server.Items
else if (Parent is Mobile)
{
// What will happen if the client doesn't know about our parent?
- to.NetState?.SendEquipUpdate(this);
+ to.NetState.SendEquipUpdate(this);
}
if (ns.HighSeas)
diff --git a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs
index 3b150ae58..98296973a 100644
--- a/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs
+++ b/Projects/UOContent/Items/Skill Items/Musical Instruments/BaseInstrument.cs
@@ -469,7 +469,7 @@ namespace Server.Items
return;
}
- from.NetState?.SendDisplayEquipmentInfo(Serial, number, m_Crafter?.RawName, false, attrs);
+ from.NetState.SendDisplayEquipmentInfo(Serial, number, m_Crafter?.RawName, false, attrs);
}
public override void Serialize(IGenericWriter writer)
diff --git a/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs b/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs
index b313ee557..46b5004a5 100644
--- a/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs
+++ b/Projects/UOContent/Items/Skill Items/Tinkering/Spyglass.cs
@@ -22,33 +22,28 @@ namespace Server.Items
1008155
); // You peer into the heavens, seeking the moons...
- from.Send(
- new MessageLocalizedAffix(
- from.Serial,
- from.Body,
- MessageType.Regular,
- 0x3B2,
- 3,
- 1008146 + (int)Clock.GetMoonPhase(Map.Trammel, from.X, from.Y),
- "",
- AffixType.Prepend,
- "Trammel : ",
- ""
- )
+ from.NetState.SendMessageLocalizedAffix(
+ from.Serial,
+ from.Body,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ 1008146 + (int)Clock.GetMoonPhase(Map.Trammel, from.X, from.Y),
+ "",
+ AffixType.Prepend,
+ "Trammel : "
);
- from.Send(
- new MessageLocalizedAffix(
- from.Serial,
- from.Body,
- MessageType.Regular,
- 0x3B2,
- 3,
- 1008146 + (int)Clock.GetMoonPhase(Map.Felucca, from.X, from.Y),
- "",
- AffixType.Prepend,
- "Felucca : ",
- ""
- )
+
+ from.NetState.SendMessageLocalizedAffix(
+ from.Serial,
+ from.Body,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ 1008146 + (int)Clock.GetMoonPhase(Map.Felucca, from.X, from.Y),
+ "",
+ AffixType.Prepend,
+ "Felucca : "
);
if (from is PlayerMobile player)
diff --git a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs
index 142664a06..e4af5f581 100644
--- a/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs
+++ b/Projects/UOContent/Items/Special/Solen Items/BagOfSending.cs
@@ -260,16 +260,16 @@ namespace Server.Items
}
else if (item is BagOfSending || item is Container)
{
- from.Send(
- new AsciiMessage(
- m_Bag.Serial,
- m_Bag.ItemID,
- MessageType.Regular,
- 0x3B2,
- 3,
- "",
- "You cannot send a container through the bag of sending."
- )
+ from.NetState.SendMessage(
+ m_Bag.Serial,
+ m_Bag.ItemID,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ true,
+ null,
+ "",
+ "You cannot send a container through the bag of sending."
);
}
else if (item.LootType == LootType.Cursed)
diff --git a/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs b/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs
index e6f638a6a..ed6b6971a 100644
--- a/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs
+++ b/Projects/UOContent/Items/Special/Solen Items/BallOfSummoning.cs
@@ -226,16 +226,16 @@ namespace Server.Items
else if (from.Map == Map.Ilshenar || from.Region.IsPartOf() ||
from.Region.IsPartOf() || from.Region.IsPartOf())
{
- from.Send(
- new AsciiMessage(
- Serial,
- ItemID,
- MessageType.Regular,
- 0x22,
- 3,
- "",
- "You cannot summon your pet to this location."
- )
+ from.NetState.SendMessage(
+ Serial,
+ ItemID,
+ MessageType.Regular,
+ 0x22,
+ 3,
+ true,
+ null,
+ "",
+ "You cannot summon your pet to this location."
);
}
else if (Core.ML && from is PlayerMobile mobile && DateTime.UtcNow < mobile.LastPetBallTime.AddSeconds(15.0))
diff --git a/Projects/UOContent/Items/Special/Solen Items/MessageHelper.cs b/Projects/UOContent/Items/Special/Solen Items/MessageHelper.cs
index 441689886..21bb8170c 100644
--- a/Projects/UOContent/Items/Special/Solen Items/MessageHelper.cs
+++ b/Projects/UOContent/Items/Special/Solen Items/MessageHelper.cs
@@ -11,12 +11,12 @@ namespace Server
public static void SendLocalizedMessageTo(Item from, Mobile to, int number, string args, int hue)
{
- to.Send(new MessageLocalized(from.Serial, from.ItemID, MessageType.Regular, hue, 3, number, "", args));
+ to.NetState.SendMessageLocalized(from.Serial, from.ItemID, MessageType.Regular, hue, 3, number, "", args);
}
public static void SendMessageTo(Item from, Mobile to, string text, int hue)
{
- to.Send(new UnicodeMessage(from.Serial, from.ItemID, MessageType.Regular, hue, 3, "ENU", "", text));
+ to.NetState.SendMessage(from.Serial, from.ItemID, MessageType.Regular, hue, 3, false, "ENU", "", text);
}
}
}
diff --git a/Projects/UOContent/Items/Wands/BaseWand.cs b/Projects/UOContent/Items/Wands/BaseWand.cs
index 022282a72..305556d6d 100644
--- a/Projects/UOContent/Items/Wands/BaseWand.cs
+++ b/Projects/UOContent/Items/Wands/BaseWand.cs
@@ -268,7 +268,7 @@ namespace Server.Items
return;
}
- from.NetState?.SendDisplayEquipmentInfo(Serial, number, Crafter?.RawName, false, attrs);
+ from.NetState.SendDisplayEquipmentInfo(Serial, number, Crafter?.RawName, false, attrs);
}
public void Cast(Spell spell)
diff --git a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs
index ce47d2c01..bec5b60df 100644
--- a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs
+++ b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs
@@ -83,7 +83,7 @@ namespace Server.Items
if (canSwing && attacker.HarmfulCheck(defender))
{
attacker.DisruptiveAction();
- attacker.NetState?.SendSwing(attacker.Serial, defender.Serial);
+ attacker.NetState.SendSwing(attacker.Serial, defender.Serial);
if (OnFired(attacker, defender))
{
diff --git a/Projects/UOContent/Misc/Guild.cs b/Projects/UOContent/Misc/Guild.cs
index 09e9d26bd..c7e5c0aca 100644
--- a/Projects/UOContent/Misc/Guild.cs
+++ b/Projects/UOContent/Misc/Guild.cs
@@ -343,38 +343,31 @@ namespace Server.Guilds
public void AllianceChat(Mobile from, int hue, string text)
{
- Packet p = null;
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
+ var length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ from.Serial,
+ from.Body,
+ MessageType.Alliance,
+ hue,
+ 3,
+ false,
+ from.Language,
+ from.Name,
+ text
+ );
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
+
for (var i = 0; i < m_Members.Count; i++)
{
var g = m_Members[i];
for (var j = 0; j < g.Members.Count; j++)
{
- var m = g.Members[j];
-
- var state = m.NetState;
-
- if (state != null)
- {
- p ??= Packet.Acquire(
- new UnicodeMessage(
- from.Serial,
- from.Body,
- MessageType.Alliance,
- hue,
- 3,
- from.Language,
- from.Name,
- text
- )
- );
-
- state.Send(p);
- }
+ g.Members[j].NetState?.Send(buffer);
}
}
-
- Packet.Release(p);
}
public void AllianceChat(Mobile from, string text)
@@ -1512,24 +1505,18 @@ namespace Server.Guilds
public void GuildChat(Mobile from, int hue, string text)
{
- Packet p = null;
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
+ var length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ from.Serial, from.Body, MessageType.Guild, hue, 3, false, from.Language, from.Name, text
+ );
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
+
for (var i = 0; i < Members.Count; i++)
{
- var m = Members[i];
-
- var state = m.NetState;
-
- if (state != null)
- {
- p ??= Packet.Acquire(
- new UnicodeMessage(from.Serial, from.Body, MessageType.Guild, hue, 3, from.Language, from.Name, text)
- );
-
- state.Send(p);
- }
+ Members[i].NetState?.Send(buffer);
}
-
- Packet.Release(p);
}
public void GuildChat(Mobile from, string text)
diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs
index 931f9a57c..f78ce3e40 100644
--- a/Projects/UOContent/Mobiles/PlayerMobile.cs
+++ b/Projects/UOContent/Mobiles/PlayerMobile.cs
@@ -2851,7 +2851,21 @@ namespace Server.Mobiles
private static void SendToStaffMessage(Mobile from, string text)
{
- Packet p = null;
+ Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
+ var length = OutgoingMessagePackets.CreateMessage(
+ ref buffer,
+ from.Serial,
+ from.Body,
+ MessageType.Regular,
+ from.SpeechHue,
+ 3,
+ false,
+ from.Language,
+ from.Name,
+ text
+ );
+
+ buffer = buffer.Slice(0, length); // Adjust to the actual size
foreach (var ns in from.GetClientsInRange(8))
{
@@ -2859,24 +2873,9 @@ namespace Server.Mobiles
if (mob?.AccessLevel >= AccessLevel.GameMaster && mob.AccessLevel > from.AccessLevel)
{
- p ??= Packet.Acquire(
- new UnicodeMessage(
- from.Serial,
- from.Body,
- MessageType.Regular,
- from.SpeechHue,
- 3,
- from.Language,
- from.Name,
- text
- )
- );
-
- ns.Send(p);
+ ns.Send(buffer);
}
}
-
- Packet.Release(p);
}
private static void SendToStaffMessage(Mobile from, string format, params object[] args)
diff --git a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs
index fa0533f85..ea4e117f9 100644
--- a/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs
+++ b/Projects/UOContent/Mobiles/Vendors/BaseVendor.cs
@@ -1021,13 +1021,13 @@ namespace Server.Mobiles
AddItem(pack);
}
- from.NetState?.SendEquipUpdate(pack);
+ from.NetState.SendEquipUpdate(pack);
pack = FindItemOnLayer(Layer.ShopSell);
if (pack != null)
{
- from.NetState?.SendEquipUpdate(pack);
+ from.NetState.SendEquipUpdate(pack);
}
pack = FindItemOnLayer(Layer.ShopResale);
@@ -1038,7 +1038,7 @@ namespace Server.Mobiles
AddItem(pack);
}
- from.NetState?.SendEquipUpdate(pack);
+ from.NetState.SendEquipUpdate(pack);
}
public virtual void VendorSell(Mobile from)
diff --git a/Projects/UOContent/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs b/Projects/UOContent/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs
index 23b68e00a..731f1bbbb 100644
--- a/Projects/UOContent/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs
+++ b/Projects/UOContent/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs
@@ -48,19 +48,16 @@ namespace Server.Mobiles
public virtual void SayPriceTo(Mobile m)
{
- m.Send(
- new MessageLocalizedAffix(
- Serial,
- Body,
- MessageType.Regular,
- SpeechHue,
- 3,
- 1008052,
- Name,
- AffixType.Append,
- JoinCost.ToString(),
- ""
- )
+ m.NetState.SendMessageLocalizedAffix(
+ Serial,
+ Body,
+ MessageType.Regular,
+ SpeechHue,
+ 3,
+ 1008052,
+ Name,
+ AffixType.Append,
+ JoinCost.ToString()
);
}
diff --git a/Projects/UOContent/Multis/HouseFoundation.cs b/Projects/UOContent/Multis/HouseFoundation.cs
index 5be269f0a..cd45eca4a 100644
--- a/Projects/UOContent/Multis/HouseFoundation.cs
+++ b/Projects/UOContent/Multis/HouseFoundation.cs
@@ -1980,7 +1980,7 @@ namespace Server.Multis
public void SendGeneralInfoTo(NetState state)
{
- state?.Send(new DesignStateGeneral(Foundation, this));
+ state.Send(new DesignStateGeneral(Foundation, this));
}
public void SendDetailedInfoTo(NetState state)
diff --git a/Projects/UOContent/Skills/Tracking/QuestArrow.cs b/Projects/UOContent/Skills/Tracking/QuestArrow.cs
index c41bd37d3..8267dd22a 100644
--- a/Projects/UOContent/Skills/Tracking/QuestArrow.cs
+++ b/Projects/UOContent/Skills/Tracking/QuestArrow.cs
@@ -35,7 +35,7 @@ namespace Server
return;
}
- Mobile.NetState?.SendSetArrow(x, y, Target.Serial);
+ Mobile.NetState.SendSetArrow(x, y, Target.Serial);
}
public void Stop()
@@ -51,7 +51,7 @@ namespace Server
}
Mobile.ClearQuestArrow();
- Mobile.NetState?.SendCancelArrow(x, y, Target.Serial);
+ Mobile.NetState.SendCancelArrow(x, y, Target.Serial);
Running = false;
OnStop();
diff --git a/Projects/UOContent/SpecialSystems/Engines/TestCenter.cs b/Projects/UOContent/SpecialSystems/Engines/TestCenter.cs
index ba2c444e0..355a2f4bb 100644
--- a/Projects/UOContent/SpecialSystems/Engines/TestCenter.cs
+++ b/Projects/UOContent/SpecialSystems/Engines/TestCenter.cs
@@ -226,17 +226,18 @@ namespace Server.Misc
if (sb.Length + 1 + v.Length >= 256)
{
- sender.Send(
- new AsciiMessage(
- Server.Serial.MinusOne,
- -1,
- MessageType.Label,
- 0x35,
- 3,
- "System",
- sb.ToString()
- )
+ sender.SendMessage(
+ Server.Serial.MinusOne,
+ -1,
+ MessageType.Label,
+ 0x35,
+ 3,
+ true,
+ null,
+ "System",
+ sb.ToString()
);
+
sb = new StringBuilder();
sb.Append(v);
}
@@ -249,16 +250,16 @@ namespace Server.Misc
if (sb.Length > 0)
{
- sender.Send(
- new AsciiMessage(
- Server.Serial.MinusOne,
- -1,
- MessageType.Label,
- 0x35,
- 3,
- "System",
- sb.ToString()
- )
+ sender.SendMessage(
+ Server.Serial.MinusOne,
+ -1,
+ MessageType.Label,
+ 0x35,
+ 3,
+ true,
+ null,
+ "System",
+ sb.ToString()
);
}
diff --git a/Projects/UOContent/Spells/Sixth/Mark.cs b/Projects/UOContent/Spells/Sixth/Mark.cs
index c36a205f2..aa1c4a7a9 100644
--- a/Projects/UOContent/Spells/Sixth/Mark.cs
+++ b/Projects/UOContent/Spells/Sixth/Mark.cs
@@ -26,17 +26,14 @@ namespace Server.Spells.Sixth
{
if (!(item is RecallRune rune))
{
- Caster.Send(
- new MessageLocalized(
- Caster.Serial,
- Caster.Body,
- MessageType.Regular,
- 0x3B2,
- 3,
- 501797,
- Caster.Name,
- ""
- )
+ Caster.NetState.SendMessageLocalized(
+ Caster.Serial,
+ Caster.Body,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ 501797,
+ Caster.Name
); // I cannot mark that object.
}
else if (!Caster.CanSee(rune))
diff --git a/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs b/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs
index aead21c64..2a43e6ea4 100644
--- a/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs
+++ b/Projects/UOContent/Spells/Targeting/RecallSpellTarget.cs
@@ -51,17 +51,14 @@ namespace Server.Spells
}
else
{
- from.Send(
- new MessageLocalized(
- from.Serial,
- from.Body,
- MessageType.Regular,
- 0x3B2,
- 3,
- 502357,
- from.Name,
- ""
- )
+ from.NetState.SendMessageLocalized(
+ from.Serial,
+ from.Body,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ 502357,
+ from.Name
); // I can not recall from that object.
}
}
@@ -71,17 +68,14 @@ namespace Server.Spells
}
else
{
- from.Send(
- new MessageLocalized(
- from.Serial,
- from.Body,
- MessageType.Regular,
- 0x3B2,
- 3,
- 502357,
- from.Name,
- ""
- )
+ from.NetState.SendMessageLocalized(
+ from.Serial,
+ from.Body,
+ MessageType.Regular,
+ 0x3B2,
+ 3,
+ 502357,
+ from.Name
); // I can not recall from that object.
}
}