diff --git a/Directory.Build.props b/Directory.Build.props
index 636e59400..c207ac7cd 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -52,14 +52,7 @@
latest
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
- 3.3.1
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj
index 825ce1e4c..2e682976e 100644
--- a/Projects/Server.Tests/Server.Tests.csproj
+++ b/Projects/Server.Tests/Server.Tests.csproj
@@ -3,7 +3,7 @@
false
-
+
diff --git a/Projects/Server.Tests/Tests/Buffers/SpanWriterTests.cs b/Projects/Server.Tests/Tests/Buffers/SpanWriterTests.cs
new file mode 100644
index 000000000..0aeffe574
--- /dev/null
+++ b/Projects/Server.Tests/Tests/Buffers/SpanWriterTests.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Buffers;
+using Xunit;
+
+namespace Server.Tests
+{
+ public class SpanWriterTests
+ {
+ [Fact]
+ public unsafe void TestSpanWriterResizes()
+ {
+ Span smallStack = stackalloc byte[8];
+ using var writer = new SpanWriter(smallStack, true);
+ writer.Write(0x1024L);
+ writer.Write(0x1024L);
+
+ var span = writer.RawBuffer;
+ fixed (byte* spanPtr = span)
+ {
+ fixed (byte* stackPtr = smallStack)
+ {
+ Assert.True(spanPtr != stackPtr);
+ }
+ }
+
+ Assert.True(span.Length > smallStack.Length);
+ }
+
+ [Fact]
+ public unsafe void TestSpanWriterOnlyStackAlloc()
+ {
+ Span smallStack = stackalloc byte[8];
+ using var writer = new SpanWriter(smallStack, true);
+ writer.Write(0x1024L);
+
+ var span = writer.RawBuffer;
+ fixed (byte* spanPtr = span)
+ {
+ fixed (byte* stackPtr = smallStack)
+ {
+ Assert.True(spanPtr == stackPtr);
+ }
+ }
+
+ Assert.True(span.Length == smallStack.Length);
+ AssertThat.Equal(smallStack, stackalloc byte[] { 0, 0, 0, 0, 0, 0, 0x10, 0x24 });
+ }
+
+ [Fact]
+ public void TestSpanWriterNoResizeThrows()
+ {
+ Assert.Throws(
+ () =>
+ {
+ Span smallStack = stackalloc byte[8];
+ using var writer = new SpanWriter(smallStack);
+ writer.Write(0x1024L);
+ writer.Write(0x1024L);
+ }
+ );
+ }
+ }
+}
diff --git a/Projects/Server/Buffers/CircularBufferReader.cs b/Projects/Server/Buffers/CircularBufferReader.cs
index b4bd8242a..0bd6d5425 100644
--- a/Projects/Server/Buffers/CircularBufferReader.cs
+++ b/Projects/Server/Buffers/CircularBufferReader.cs
@@ -370,7 +370,7 @@ namespace Server.Network
Position = origin switch
{
SeekOrigin.Begin => offset,
- SeekOrigin.End => Length - offset,
+ SeekOrigin.End => Length + offset,
_ => Position + offset // Current
};
}
diff --git a/Projects/Server/Buffers/CircularBufferWriter.cs b/Projects/Server/Buffers/CircularBufferWriter.cs
index 11a8f0874..345a9d8e0 100644
--- a/Projects/Server/Buffers/CircularBufferWriter.cs
+++ b/Projects/Server/Buffers/CircularBufferWriter.cs
@@ -528,7 +528,7 @@ namespace System.Buffers
Position = origin switch
{
SeekOrigin.Begin => offset,
- SeekOrigin.End => Length - offset,
+ SeekOrigin.End => Length + offset,
_ => Position + offset // Current
};
}
diff --git a/Projects/Server/Buffers/SpanReader.cs b/Projects/Server/Buffers/SpanReader.cs
index 2f18bd794..754b9b350 100644
--- a/Projects/Server/Buffers/SpanReader.cs
+++ b/Projects/Server/Buffers/SpanReader.cs
@@ -14,6 +14,7 @@
*************************************************************************/
using System.Buffers.Binary;
+using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
@@ -176,12 +177,44 @@ namespace System.Buffers
public string ReadAscii() => ReadString(Encoding.ASCII);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public int Seek(int offset, SeekOrigin origin) =>
- Position = origin switch
+ public int Seek(int offset, SeekOrigin origin)
+ {
+ Debug.Assert(
+ origin != SeekOrigin.End || offset <= 0,
+ "Attempting to seek to a position beyond capacity using SeekOrigin.End"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.End || offset >= -_buffer.Length,
+ "Attempting to seek to a negative position using SeekOrigin.End"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Begin || offset >= 0,
+ "Attempting to seek to a negative position using SeekOrigin.Begin"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Begin || offset <= _buffer.Length,
+ "Attempting to seek to a position beyond the capacity using SeekOrigin.Begin"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Current || Position + offset >= 0,
+ "Attempting to seek to a negative position using SeekOrigin.Current"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Current || Position + offset <= _buffer.Length,
+ "Attempting to seek to a position beyond the capacity using SeekOrigin.Current"
+ );
+
+ return Position = Math.Max(0, origin switch
{
- SeekOrigin.Begin => offset,
- SeekOrigin.End => Length - offset,
- _ => Position + offset // Current
- };
+ SeekOrigin.Current => Position + offset,
+ SeekOrigin.End => _buffer.Length + offset,
+ _ => offset // Begin
+ });
+ }
}
}
diff --git a/Projects/Server/Buffers/SpanWriter.cs b/Projects/Server/Buffers/SpanWriter.cs
index ac88a392b..ae0e3ecd9 100644
--- a/Projects/Server/Buffers/SpanWriter.cs
+++ b/Projects/Server/Buffers/SpanWriter.cs
@@ -15,8 +15,10 @@
using System.Buffers.Binary;
using System.Data;
+using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Text;
using Server;
@@ -24,122 +26,173 @@ namespace System.Buffers
{
public ref struct SpanWriter
{
- private readonly Span _buffer;
+ private readonly bool _resize;
+ private byte[]? _arrayToReturnToPool;
+ private Span _buffer;
+ private int _position;
- public int Length => _buffer.Length;
+ public int Length { get; private set; }
+
+ public int Position
+ {
+ get => _position;
+ private set
+ {
+ _position = value;
+
+ if (value > Length)
+ {
+ Length = value;
+ }
+ }
+ }
+
+ public int Capacity => _buffer.Length;
public ReadOnlySpan Span => _buffer.Slice(0, Position);
- public int Position { get; private set; }
+ public Span RawBuffer => _buffer;
- public SpanWriter(Span span)
+ public SpanWriter(Span initialBuffer, bool resize = false)
{
- _buffer = span;
- Position = 0;
+ _resize = resize;
+ _buffer = initialBuffer;
+ _position = 0;
+ Length = 0;
+ _arrayToReturnToPool = null;
+ }
+
+ public SpanWriter(int initialCapacity, bool resize = false)
+ {
+ _resize = resize;
+ _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity);
+ _buffer = _arrayToReturnToPool;
+ _position = 0;
+ Length = 0;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private void Grow(int additionalCapacity)
+ {
+ var newSize = Math.Max(Length + additionalCapacity, _buffer.Length * 2);
+ byte[] poolArray = ArrayPool.Shared.Rent(newSize);
+
+ _buffer.Slice(0, Length).CopyTo(poolArray);
+
+ byte[]? toReturn = _arrayToReturnToPool;
+ _buffer = _arrayToReturnToPool = poolArray;
+ if (toReturn != null)
+ {
+ ArrayPool.Shared.Return(toReturn);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void GrowIfNeeded(int count)
+ {
+ if (_position + count > _buffer.Length)
+ {
+ if (!_resize)
+ {
+ throw new OutOfMemoryException();
+ }
+
+ Grow(count);
+ }
+ }
+
+ public ref byte GetPinnableReference() => ref MemoryMarshal.GetReference(_buffer);
+
+ public void EnsureCapacity(int capacity)
+ {
+ if (capacity > _buffer.Length)
+ {
+ if (!_resize)
+ {
+ throw new OutOfMemoryException();
+ }
+
+ Grow(capacity - Length);
+ }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void Write(bool value)
{
- if (Position >= Length)
- {
- throw new OutOfMemoryException();
- }
-
- _buffer[Position++] = *(byte*) & value;
+ GrowIfNeeded(1);
+ _buffer[Position++] = *(byte*)&value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(byte value)
{
+ GrowIfNeeded(1);
_buffer[Position++] = value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(sbyte value)
{
+ GrowIfNeeded(1);
_buffer[Position++] = (byte)value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(short value)
{
- if (!BinaryPrimitives.TryWriteInt16BigEndian(_buffer.Slice(Position), value))
- {
- throw new OutOfMemoryException();
- }
-
+ GrowIfNeeded(2);
+ BinaryPrimitives.WriteInt16BigEndian(_buffer.Slice(_position), value);
Position += 2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ushort value)
{
- if (!BinaryPrimitives.TryWriteUInt16BigEndian(_buffer.Slice(Position), value))
- {
- throw new OutOfMemoryException();
- }
-
+ GrowIfNeeded(2);
+ BinaryPrimitives.WriteUInt16BigEndian(_buffer.Slice(_position), value);
Position += 2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(int value)
{
- if (!BinaryPrimitives.TryWriteInt32BigEndian(_buffer.Slice(Position), value))
- {
- throw new OutOfMemoryException();
- }
-
+ GrowIfNeeded(4);
+ BinaryPrimitives.WriteInt32BigEndian(_buffer.Slice(_position), value);
Position += 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(uint value)
{
- if (!BinaryPrimitives.TryWriteUInt32BigEndian(_buffer.Slice(Position), value))
- {
- throw new OutOfMemoryException();
- }
-
+ GrowIfNeeded(4);
+ BinaryPrimitives.WriteUInt32BigEndian(_buffer.Slice(_position), value);
Position += 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(long value)
{
- if (!BinaryPrimitives.TryWriteInt64BigEndian(_buffer.Slice(Position), value))
- {
- throw new OutOfMemoryException();
- }
-
+ GrowIfNeeded(8);
+ BinaryPrimitives.WriteInt64BigEndian(_buffer.Slice(_position), value);
Position += 8;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ulong value)
{
- if (!BinaryPrimitives.TryWriteUInt64BigEndian(_buffer.Slice(Position), value))
- {
- throw new OutOfMemoryException();
- }
-
+ GrowIfNeeded(8);
+ BinaryPrimitives.WriteUInt64BigEndian(_buffer.Slice(_position), value);
Position += 8;
}
public void Write(ReadOnlySpan buffer)
{
- var size = buffer.Length;
- if (Position + size > Length)
- {
- throw new OutOfMemoryException();
- }
-
- buffer.Slice(0, size).CopyTo(_buffer.Slice(Position));
- Position += size;
+ var count = buffer.Length;
+ GrowIfNeeded(count);
+ buffer.CopyTo(_buffer.Slice(_position));
+ Position += count;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteString(string value, Encoding encoding, int fixedLength = -1) where T : struct, IEquatable
{
int sizeT = Unsafe.SizeOf();
@@ -156,12 +209,9 @@ namespace System.Buffers
var byteCount = fixedLength > -1 ? fixedLength * sizeT : encoding.GetByteCount(value);
- if (Position + byteCount > Length)
- {
- throw new OutOfMemoryException();
- }
+ GrowIfNeeded(byteCount);
- var bytesWritten = encoding.GetBytes(src, _buffer.Slice(Position));
+ var bytesWritten = encoding.GetBytes(src, _buffer.Slice(_position));
Position += bytesWritten;
if (fixedLength > -1)
@@ -194,7 +244,7 @@ namespace System.Buffers
public void WriteBigUniNull(string value)
{
WriteString(value, Utility.Unicode);
- Write((ushort)0);
+ Write((ushort)0); // '\0'
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -207,7 +257,7 @@ namespace System.Buffers
public void WriteUTF8Null(string value)
{
WriteString(value, Utility.UTF8);
- Write((byte)0);
+ Write((byte)0); // '\0'
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -217,38 +267,77 @@ namespace System.Buffers
public void WriteAsciiNull(string value)
{
WriteString(value, Encoding.ASCII);
- Write((byte)0);
+ Write((byte)0); // '\0'
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteAscii(string value, int fixedLength) => WriteString(value, Encoding.ASCII, fixedLength);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Clear()
+ public void Clear(int count)
{
- _buffer.Slice(Position).Clear();
- Position = Length;
+ GrowIfNeeded(count);
+ _buffer.Slice(_position, count).Clear();
+ Position += count;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Clear(int amount)
+ public int Seek(int offset, SeekOrigin origin)
{
- if (Position + amount > Length)
+ Debug.Assert(
+ origin != SeekOrigin.End || _resize || offset <= 0,
+ "Attempting to seek to a position beyond capacity using SeekOrigin.End without resize"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.End || offset >= -_buffer.Length,
+ "Attempting to seek to a negative position using SeekOrigin.End"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Begin || offset >= 0,
+ "Attempting to seek to a negative position using SeekOrigin.Begin"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Begin || _resize || offset <= _buffer.Length,
+ "Attempting to seek to a position beyond the capacity using SeekOrigin.Begin without resize"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Current || _position + offset >= 0,
+ "Attempting to seek to a negative position using SeekOrigin.Current"
+ );
+
+ Debug.Assert(
+ origin != SeekOrigin.Current || _resize || _position + offset <= _buffer.Length,
+ "Attempting to seek to a position beyond the capacity using SeekOrigin.Current without resize"
+ );
+
+ var newPosition = Math.Max(0, origin switch
{
- throw new OutOfMemoryException();
+ SeekOrigin.Current => _position + offset,
+ SeekOrigin.End => Length + offset,
+ _ => offset // Begin
+ });
+
+ if (newPosition >= _buffer.Length)
+ {
+ Grow(newPosition - _buffer.Length + 1);
}
- _buffer.Slice(Position, amount).Clear();
- Position += amount;
+ return _position = newPosition;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public int Seek(int offset, SeekOrigin origin) =>
- Position = origin switch
+ public void Dispose()
+ {
+ byte[] toReturn = _arrayToReturnToPool;
+ this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again
+ if (toReturn != null)
{
- SeekOrigin.Begin => offset,
- SeekOrigin.End => Length - offset,
- _ => Position + offset // Current
- };
+ ArrayPool.Shared.Return(toReturn);
+ }
+ }
}
}
diff --git a/Projects/UOContent.Tests/UOContent.Tests.csproj b/Projects/UOContent.Tests/UOContent.Tests.csproj
index aec2110e5..d2717dbd0 100644
--- a/Projects/UOContent.Tests/UOContent.Tests.csproj
+++ b/Projects/UOContent.Tests/UOContent.Tests.csproj
@@ -3,7 +3,7 @@
false
-
+
diff --git a/Projects/UOContent/Gumps/Guilds/New Guild System/War Declaration gump.cs b/Projects/UOContent/Gumps/Guilds/New Guild System/WarDeclarationGump.cs
similarity index 99%
rename from Projects/UOContent/Gumps/Guilds/New Guild System/War Declaration gump.cs
rename to Projects/UOContent/Gumps/Guilds/New Guild System/WarDeclarationGump.cs
index 20ebcc85c..04a992aef 100644
--- a/Projects/UOContent/Gumps/Guilds/New Guild System/War Declaration gump.cs
+++ b/Projects/UOContent/Gumps/Guilds/New Guild System/WarDeclarationGump.cs
@@ -45,7 +45,7 @@ namespace Server.Guilds
return;
}
- var playerRank = pm.GuildRank;
+ var playerRank = pm!.GuildRank;
switch (info.ButtonID)
{
diff --git a/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs b/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs
index 61ec8efce..9666e247b 100644
--- a/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs
+++ b/Projects/UOContent/Gumps/Props/SetPoint2DGump.cs
@@ -69,7 +69,7 @@ namespace Server.Gumps
m_Page = page;
m_List = list;
- var p = (Point2D)prop.GetValue(o, null);
+ var p = (Point2D)(prop?.GetValue(o, null) ?? new Point2D());
AddPage(0);
@@ -86,7 +86,7 @@ namespace Server.Gumps
var y = BorderSize + OffsetSize;
AddImageTiled(x, y, EntryWidth, EntryHeight, EntryGumpID);
- AddLabelCropped(x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, prop.Name);
+ AddLabelCropped(x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, prop?.Name);
x += EntryWidth + OffsetSize;
if (SetGumpID != 0)
diff --git a/Projects/UOContent/Gumps/Props/SetPoint3DGump.cs b/Projects/UOContent/Gumps/Props/SetPoint3DGump.cs
index 8ab7733d3..0b721b478 100644
--- a/Projects/UOContent/Gumps/Props/SetPoint3DGump.cs
+++ b/Projects/UOContent/Gumps/Props/SetPoint3DGump.cs
@@ -69,7 +69,7 @@ namespace Server.Gumps
m_Page = page;
m_List = list;
- var p = (Point3D)prop.GetValue(o, null);
+ var p = (Point3D)(prop?.GetValue(o, null) ?? new Point3D());
AddPage(0);
@@ -86,7 +86,7 @@ namespace Server.Gumps
var y = BorderSize + OffsetSize;
AddImageTiled(x, y, EntryWidth, EntryHeight, EntryGumpID);
- AddLabelCropped(x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, prop.Name);
+ AddLabelCropped(x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, prop?.Name);
x += EntryWidth + OffsetSize;
if (SetGumpID != 0)
diff --git a/Projects/UOContent/Gumps/Props/SetTimeSpanGump.cs b/Projects/UOContent/Gumps/Props/SetTimeSpanGump.cs
index 148a29f58..41dc268c7 100644
--- a/Projects/UOContent/Gumps/Props/SetTimeSpanGump.cs
+++ b/Projects/UOContent/Gumps/Props/SetTimeSpanGump.cs
@@ -68,7 +68,7 @@ namespace Server.Gumps
m_Page = page;
m_List = list;
- var ts = (TimeSpan)prop.GetValue(o, null);
+ var ts = (TimeSpan)(prop?.GetValue(o, null) ?? new TimeSpan());
AddPage(0);
@@ -81,7 +81,7 @@ namespace Server.Gumps
OffsetGumpID
);
- AddRect(0, prop.Name, 0, -1);
+ AddRect(0, prop?.Name, 0, -1);
AddRect(1, ts.ToString(), 0, -1);
AddRect(2, "Zero", 1, -1);
AddRect(3, "From H:M:S", 2, -1);
diff --git a/Projects/UOContent/Items/Skill Items/Specialized/GlassblowingBook.cs b/Projects/UOContent/Items/Skill Items/Specialized/GlassblowingBook.cs
index 7a5b0fda0..92c1d2ed2 100644
--- a/Projects/UOContent/Items/Skill Items/Specialized/GlassblowingBook.cs
+++ b/Projects/UOContent/Items/Skill Items/Specialized/GlassblowingBook.cs
@@ -29,24 +29,22 @@ namespace Server.Items
public override void OnDoubleClick(Mobile from)
{
- var pm = from as PlayerMobile;
-
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
- else if (pm == null || from.Skills.Alchemy.Base < 100.0)
+ else if (from is not PlayerMobile pm || from.Skills.Alchemy.Base < 100.0)
{
- pm.SendMessage("Only a Grandmaster Alchemist can learn from this book.");
+ from.SendMessage("Only a Grandmaster Alchemist can learn from this book.");
}
else if (pm.Glassblowing)
{
- pm.SendMessage("You have already learned this information.");
+ from.SendMessage("You have already learned this information.");
}
else
{
pm.Glassblowing = true;
- pm.SendMessage(
+ from.SendMessage(
"You have learned to make items from glass. You will need to find miners to mine find sand for you to make these items."
);
Delete();
diff --git a/Projects/UOContent/Items/Skill Items/Specialized/MasonryBook.cs b/Projects/UOContent/Items/Skill Items/Specialized/MasonryBook.cs
index ee337d1c8..a97f1b5a1 100644
--- a/Projects/UOContent/Items/Skill Items/Specialized/MasonryBook.cs
+++ b/Projects/UOContent/Items/Skill Items/Specialized/MasonryBook.cs
@@ -29,24 +29,22 @@ namespace Server.Items
public override void OnDoubleClick(Mobile from)
{
- var pm = from as PlayerMobile;
-
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
- else if (pm == null || from.Skills.Carpentry.Base < 100.0)
+ else if (from is not PlayerMobile pm || from.Skills.Carpentry.Base < 100.0)
{
- pm.SendMessage("Only a Grandmaster Carpenter can learn from this book.");
+ from.SendMessage("Only a Grandmaster Carpenter can learn from this book.");
}
else if (pm.Masonry)
{
- pm.SendMessage("You have already learned this information.");
+ from.SendMessage("You have already learned this information.");
}
else
{
pm.Masonry = true;
- pm.SendMessage(
+ from.SendMessage(
"You have learned to make items from stone. You will need miners to gather stones for you to make these items."
);
Delete();
diff --git a/Projects/UOContent/Items/Skill Items/Specialized/SandMiningBook.cs b/Projects/UOContent/Items/Skill Items/Specialized/SandMiningBook.cs
index 04099b6a3..dd2f6b773 100644
--- a/Projects/UOContent/Items/Skill Items/Specialized/SandMiningBook.cs
+++ b/Projects/UOContent/Items/Skill Items/Specialized/SandMiningBook.cs
@@ -29,24 +29,22 @@ namespace Server.Items
public override void OnDoubleClick(Mobile from)
{
- var pm = from as PlayerMobile;
-
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
- else if (pm == null || from.Skills.Mining.Base < 100.0)
+ else if (from is not PlayerMobile pm || from.Skills.Mining.Base < 100.0)
{
- pm.SendMessage("Only a Grandmaster Miner can learn from this book.");
+ from.SendMessage("Only a Grandmaster Miner can learn from this book.");
}
else if (pm.SandMining)
{
- pm.SendMessage("You have already learned this information.");
+ from.SendMessage("You have already learned this information.");
}
else
{
pm.SandMining = true;
- pm.SendMessage(
+ from.SendMessage(
"You have learned how to mine fine sand. Target sand areas when mining to look for fine sand."
);
Delete();
diff --git a/Projects/UOContent/Items/Special/SoulStone.cs b/Projects/UOContent/Items/Special/SoulStone.cs
index 3035fa8e3..3064645ad 100644
--- a/Projects/UOContent/Items/Special/SoulStone.cs
+++ b/Projects/UOContent/Items/Special/SoulStone.cs
@@ -156,10 +156,6 @@ namespace Server.Items
protected virtual bool CheckUse(Mobile from)
{
- // DateTime now = DateTime.UtcNow;
-
- var pm = from as PlayerMobile;
-
if (Deleted || !IsAccessibleTo(from))
{
return false;
@@ -235,11 +231,10 @@ namespace Server.Items
return false;
}
- if (pm.AcceleratedStart > DateTime.UtcNow)
+ if ((from as PlayerMobile)?.AcceleratedStart > DateTime.UtcNow)
{
- from.SendLocalizedMessage(
- 1078115
- ); // You may not use a soulstone while your character is under the effects of a Scroll of Alacrity.
+ // You may not use a soulstone while your character is under the effects of a Scroll of Alacrity.
+ from.SendLocalizedMessage(1078115);
return false;
}
@@ -748,8 +743,7 @@ namespace Server.Items
return;
}
- var pm = from as PlayerMobile;
- if (pm.AcceleratedStart > DateTime.UtcNow)
+ if ((from as PlayerMobile)?.AcceleratedStart > DateTime.UtcNow)
{
// Unable to Absorb Selected Skill from Soulstone
diff --git a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs
index 713f55f93..eeba762e7 100644
--- a/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs
+++ b/Projects/UOContent/Mobiles/Monsters/ML/Humanoid/Magic/MLDryad.cs
@@ -103,14 +103,12 @@ namespace Server.Mobiles
foreach (var m in GetMobilesInRange(RangePerception))
{
- var p = m as PlayerMobile;
-
- if (IsValidTarget(p))
+ if (m is PlayerMobile pm && IsValidTarget(pm))
{
- p.PeacedUntil = DateTime.UtcNow + duration;
- p.SendLocalizedMessage(1072065); // You gaze upon the dryad's beauty, and forget to continue battling!
- p.FixedParticles(0x376A, 1, 20, 0x7F5, EffectLayer.Waist);
- p.Combatant = null;
+ pm.PeacedUntil = DateTime.UtcNow + duration;
+ m.SendLocalizedMessage(1072065); // You gaze upon the dryad's beauty, and forget to continue battling!
+ m.FixedParticles(0x376A, 1, 20, 0x7F5, EffectLayer.Waist);
+ m.Combatant = null;
}
}
diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj
index e88d49329..5b3d08d91 100644
--- a/Projects/UOContent/UOContent.csproj
+++ b/Projects/UOContent/UOContent.csproj
@@ -28,7 +28,7 @@
false
-
+