fix: Fixes NPE in BuffTable and standardizes BuffIcon packets (#1785)
This commit is contained in:
parent
50d3779d9b
commit
6747168db0
4 changed files with 97 additions and 86 deletions
|
|
@ -20,7 +20,7 @@ namespace UOContent.Tests
|
||||||
).Compile();
|
).Compile();
|
||||||
|
|
||||||
var ns = PacketTestUtilities.CreateTestNetState();
|
var ns = PacketTestUtilities.CreateTestNetState();
|
||||||
BuffInfo.SendAddBuffPacket(ns, (Serial)mob, iconID, titleCliloc, secondaryCliloc, args, (int)timeSpan.TotalMilliseconds);
|
ns.SendAddBuffPacket((Serial)mob, iconID, titleCliloc, secondaryCliloc, args, (int)timeSpan.TotalMilliseconds);
|
||||||
|
|
||||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||||
AssertThat.Equal(result, expected);
|
AssertThat.Equal(result, expected);
|
||||||
|
|
@ -34,7 +34,7 @@ namespace UOContent.Tests
|
||||||
var expected = new RemoveBuffPacket(m, buffIcon).Compile();
|
var expected = new RemoveBuffPacket(m, buffIcon).Compile();
|
||||||
|
|
||||||
var ns = PacketTestUtilities.CreateTestNetState();
|
var ns = PacketTestUtilities.CreateTestNetState();
|
||||||
BuffInfo.SendRemoveBuffPacket(ns, m, buffIcon);
|
ns.SendRemoveBuffPacket(m, buffIcon);
|
||||||
|
|
||||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||||
AssertThat.Equal(result, expected);
|
AssertThat.Equal(result, expected);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using Server.Mobiles;
|
using Server.Mobiles;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
||||||
|
|
@ -137,84 +136,6 @@ namespace Server
|
||||||
{
|
{
|
||||||
(m as PlayerMobile)?.RemoveBuff(b);
|
(m as PlayerMobile)?.RemoveBuff(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAddBuffPacket(NetState ns, Serial m) => SendAddBuffPacket(
|
|
||||||
ns,
|
|
||||||
m,
|
|
||||||
ID,
|
|
||||||
TitleCliloc,
|
|
||||||
SecondaryCliloc,
|
|
||||||
Args,
|
|
||||||
TimeStart == 0 ? 0 : Math.Max(TimeStart + (long)TimeLength.TotalMilliseconds - Core.TickCount, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
public static void SendAddBuffPacket(
|
|
||||||
NetState ns, Serial mob, BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args,
|
|
||||||
long ticks
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (ns.CannotSendPackets())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasArgs = args != null;
|
|
||||||
var length = hasArgs ? args.ToString()!.Length * 2 + 52 : 46;
|
|
||||||
var writer = new SpanWriter(stackalloc byte[length]);
|
|
||||||
writer.Write((byte)0xDF); // Packet ID
|
|
||||||
writer.Write((ushort)length);
|
|
||||||
writer.Write(mob);
|
|
||||||
writer.Write((short)iconID);
|
|
||||||
writer.Write((short)0x1); // command (0 = remove, 1 = add, 2 = data)
|
|
||||||
writer.Write(0);
|
|
||||||
|
|
||||||
writer.Write((short)iconID);
|
|
||||||
writer.Write((short)0x1); // command (0 = remove, 1 = add, 2 = data)
|
|
||||||
writer.Write(0);
|
|
||||||
|
|
||||||
// Truncate to whole seconds - The packet should be delayed by the partial seconds and then sent "on the second"
|
|
||||||
writer.Write((short)(ticks / 1000));
|
|
||||||
writer.Clear(3);
|
|
||||||
writer.Write(titleCliloc);
|
|
||||||
writer.Write(secondaryCliloc);
|
|
||||||
|
|
||||||
if (hasArgs)
|
|
||||||
{
|
|
||||||
writer.Write(0);
|
|
||||||
writer.Write((short)0x1);
|
|
||||||
writer.Write((ushort)0);
|
|
||||||
writer.WriteLE('\t');
|
|
||||||
writer.WriteLittleUniNull(args);
|
|
||||||
writer.Write((short)0x1);
|
|
||||||
writer.Write((ushort)0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
writer.Clear(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
ns.Send(writer.Span);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendRemoveBuffPacket(NetState ns, Serial mob) => SendRemoveBuffPacket(ns, mob, ID);
|
|
||||||
|
|
||||||
public static void SendRemoveBuffPacket(NetState ns, Serial mob, BuffIcon iconID)
|
|
||||||
{
|
|
||||||
if (ns.CannotSendPackets())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var writer = new SpanWriter(stackalloc byte[15]);
|
|
||||||
writer.Write((byte)0xDF); // Packet ID
|
|
||||||
writer.Write((ushort)15);
|
|
||||||
writer.Write(mob);
|
|
||||||
writer.Write((short)iconID);
|
|
||||||
writer.Write((short)0x0); // command (0 = remove, 1 = add, 2 = data)
|
|
||||||
writer.Write(0);
|
|
||||||
|
|
||||||
ns.Send(writer.Span);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum BuffIcon : short
|
public enum BuffIcon : short
|
||||||
|
|
|
||||||
|
|
@ -4492,13 +4492,32 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
public void ResetRecipes() => _acquiredRecipes = null;
|
public void ResetRecipes() => _acquiredRecipes = null;
|
||||||
|
|
||||||
|
public void SendAddBuffPacket(BuffInfo buffInfo)
|
||||||
|
{
|
||||||
|
if (buffInfo == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetState.SendAddBuffPacket(
|
||||||
|
Serial,
|
||||||
|
buffInfo.ID,
|
||||||
|
buffInfo.TitleCliloc,
|
||||||
|
buffInfo.SecondaryCliloc,
|
||||||
|
buffInfo.Args,
|
||||||
|
buffInfo.TimeStart == 0
|
||||||
|
? 0
|
||||||
|
: Math.Max(buffInfo.TimeStart + (long)buffInfo.TimeLength.TotalMilliseconds - Core.TickCount, 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public void ResendBuffs()
|
public void ResendBuffs()
|
||||||
{
|
{
|
||||||
if (BuffInfo.Enabled && m_BuffTable != null && NetState?.BuffIcon == true)
|
if (BuffInfo.Enabled && m_BuffTable != null && NetState?.BuffIcon == true)
|
||||||
{
|
{
|
||||||
foreach (var info in m_BuffTable.Values)
|
foreach (var info in m_BuffTable.Values)
|
||||||
{
|
{
|
||||||
info.SendAddBuffPacket(NetState, Serial);
|
SendAddBuffPacket(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4525,15 +4544,15 @@ namespace Server.Mobiles
|
||||||
Timer.DelayCall(TimeSpan.FromMilliseconds(msecs), (buffInfo, pm) =>
|
Timer.DelayCall(TimeSpan.FromMilliseconds(msecs), (buffInfo, pm) =>
|
||||||
{
|
{
|
||||||
// They are still online, we still have the buff icon in the table, and it is the same buff icon
|
// They are still online, we still have the buff icon in the table, and it is the same buff icon
|
||||||
if (pm.NetState != null && pm.m_BuffTable.TryGetValue(buffInfo.ID, out var checkBuff) && checkBuff == buffInfo)
|
if (pm.NetState != null && pm.m_BuffTable?.GetValueOrDefault(buffInfo.ID) == buffInfo)
|
||||||
{
|
{
|
||||||
buffInfo.SendAddBuffPacket(pm.NetState, pm.Serial);
|
pm.SendAddBuffPacket(buffInfo);
|
||||||
}
|
}
|
||||||
}, b, this);
|
}, b, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
b.SendAddBuffPacket(NetState, Serial);
|
SendAddBuffPacket(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4557,7 +4576,7 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
if (NetState?.BuffIcon == true)
|
if (NetState?.BuffIcon == true)
|
||||||
{
|
{
|
||||||
BuffInfo.SendRemoveBuffPacket(NetState, Serial, b);
|
NetState.SendRemoveBuffPacket(Serial, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_BuffTable.Count <= 0)
|
if (m_BuffTable.Count <= 0)
|
||||||
|
|
|
||||||
71
Projects/UOContent/Network/BuffIconPackets.cs
Normal file
71
Projects/UOContent/Network/BuffIconPackets.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
using System.Buffers;
|
||||||
|
|
||||||
|
namespace Server.Network;
|
||||||
|
|
||||||
|
public static class BuffIconPackets
|
||||||
|
{
|
||||||
|
public static void SendAddBuffPacket(
|
||||||
|
this NetState ns, Serial mob, BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args, long ticks
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (ns.CannotSendPackets())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasArgs = args != null;
|
||||||
|
var length = hasArgs ? args.ToString()!.Length * 2 + 52 : 46;
|
||||||
|
var writer = new SpanWriter(stackalloc byte[length]);
|
||||||
|
writer.Write((byte)0xDF); // Packet ID
|
||||||
|
writer.Write((ushort)length);
|
||||||
|
writer.Write(mob);
|
||||||
|
writer.Write((short)iconID);
|
||||||
|
writer.Write((short)0x1); // command (0 = remove, 1 = add, 2 = data)
|
||||||
|
writer.Write(0);
|
||||||
|
|
||||||
|
writer.Write((short)iconID);
|
||||||
|
writer.Write((short)0x1); // command (0 = remove, 1 = add, 2 = data)
|
||||||
|
writer.Write(0);
|
||||||
|
|
||||||
|
// Truncate to whole seconds - The packet should be delayed by the partial seconds and then sent "on the second"
|
||||||
|
writer.Write((short)(ticks / 1000));
|
||||||
|
writer.Clear(3);
|
||||||
|
writer.Write(titleCliloc);
|
||||||
|
writer.Write(secondaryCliloc);
|
||||||
|
|
||||||
|
if (hasArgs)
|
||||||
|
{
|
||||||
|
writer.Write(0);
|
||||||
|
writer.Write((short)0x1);
|
||||||
|
writer.Write((ushort)0);
|
||||||
|
writer.WriteLE('\t');
|
||||||
|
writer.WriteLittleUniNull(args);
|
||||||
|
writer.Write((short)0x1);
|
||||||
|
writer.Write((ushort)0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.Clear(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
ns.Send(writer.Span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendRemoveBuffPacket(this NetState ns, Serial mob, BuffIcon iconID)
|
||||||
|
{
|
||||||
|
if (ns.CannotSendPackets())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var writer = new SpanWriter(stackalloc byte[15]);
|
||||||
|
writer.Write((byte)0xDF); // Packet ID
|
||||||
|
writer.Write((ushort)15);
|
||||||
|
writer.Write(mob);
|
||||||
|
writer.Write((short)iconID);
|
||||||
|
writer.Write((short)0x0); // command (0 = remove, 1 = add, 2 = data)
|
||||||
|
writer.Write(0);
|
||||||
|
|
||||||
|
ns.Send(writer.Span);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue