diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MapPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MapPacketTests.cs index 9d61e4089..2fa148466 100644 --- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MapPacketTests.cs +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/MapPacketTests.cs @@ -6,16 +6,12 @@ namespace Server.Tests.Network { public class MapPatchesTests : IClassFixture { - [Theory] - [InlineData(ProtocolChanges.Version500a, ClientFlags.Malas | ClientFlags.Trammel | ClientFlags.Felucca)] - [InlineData(ProtocolChanges.Version7090, ClientFlags.TerMur | ClientFlags.Trammel | ClientFlags.Felucca)] - public void TestMapPatches(ProtocolChanges protocolChanges, ClientFlags flags) + [Fact] + public void TestMapPatches() { var ns = PacketTestUtilities.CreateTestNetState(); - ns.ProtocolChanges = protocolChanges; - ns.Flags = flags; - var expected = ns.ProtocolChanges >= ProtocolChanges.Version6000 ? Span.Empty : new MapPatches().Compile(); + var expected = new MapPatches().Compile(); ns.SendMapPatches(); diff --git a/Projects/Server/Configuration/ServerConfiguration.cs b/Projects/Server/Configuration/ServerConfiguration.cs index ff3fb58ce..820d72bd7 100644 --- a/Projects/Server/Configuration/ServerConfiguration.cs +++ b/Projects/Server/Configuration/ServerConfiguration.cs @@ -254,7 +254,7 @@ namespace Server if (string.IsNullOrWhiteSpace(input) || input.InsensitiveStartsWith("n")) { Utility.PushColor(ConsoleColor.Yellow); - Console.WriteLine("New Haven chosen with no map diffs."); + Console.WriteLine("Client >= 6.0.0.0 chosen."); Utility.PopColor(); return; } @@ -262,10 +262,9 @@ namespace Server if (input.InsensitiveStartsWith("y")) { SetSetting("maps.enablePre6000Trammel", true.ToString()); - SetSetting("maps.enableMapDiffPatches", true.ToString()); Utility.PushColor(ConsoleColor.Yellow); - Console.WriteLine("Old Haven chosen with map diffs."); + Console.WriteLine("Client <= 5.0.9.1 chosen."); Utility.PopColor(); return; } diff --git a/Projects/Server/Maps/MapLoader.cs b/Projects/Server/Maps/MapLoader.cs index d07382443..80294537d 100644 --- a/Projects/Server/Maps/MapLoader.cs +++ b/Projects/Server/Maps/MapLoader.cs @@ -47,9 +47,6 @@ namespace Server [CallPriority(2)] public static void Configure() { - // Set to true to support < 6.0.0 clients where map0.mul is both Felucca & Trammel - var pre6000Trammel = ServerConfiguration.GetOrUpdateSetting("maps.enablePre6000Trammel", false); - var failures = new List(); var count = 0; @@ -66,12 +63,6 @@ namespace Server foreach (var def in maps) { - if (def.Id == 1 && pre6000Trammel) - { - // Use Old Haven by changing file index to Felucca - def.FileIndex = 0; - } - try { RegisterMap(def); diff --git a/Projects/Server/NativeReader.cs b/Projects/Server/NativeReader.cs index 78cbd4fe8..ae6392775 100644 --- a/Projects/Server/NativeReader.cs +++ b/Projects/Server/NativeReader.cs @@ -11,25 +11,15 @@ namespace Server static NativeReader() => m_NativeReader = Core.Unix ? new NativeReaderUnix() : new NativeReaderWin32(); - public static unsafe int Read(FileStream source, void* buffer, int length) => - m_NativeReader.Read(source, buffer, length); + public static unsafe int Read(FileStream source, void* buffer, int length) => Read(source, buffer, 0, length); public static unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length) => m_NativeReader.Read(source, buffer, bufferIndex, length); - - public static unsafe int Read(FileStream source, int sourceIndex, void* buffer, int length) => - m_NativeReader.Read(source, sourceIndex, buffer, length); - - public static unsafe int Read(FileStream source, int sourceIndex, void* buffer, int bufferIndex, int length) => - m_NativeReader.Read(source, sourceIndex, buffer, bufferIndex, length); } public interface INativeReader { - unsafe int Read(FileStream source, void* buffer, int length); unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length); - unsafe int Read(FileStream source, int sourceIndex, void* buffer, int length); - unsafe int Read(FileStream source, int sourceIndex, void* buffer, int bufferIndex, int length); } public sealed class NativeReaderWin32 : INativeReader @@ -40,45 +30,18 @@ namespace Server internal static extern unsafe bool ReadFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, NativeOverlapped* lpOverlapped); } - public unsafe int Read(FileStream source, void* buffer, int length) => InternalRead(source, buffer, 0, length); - public unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length) => InternalRead(source, buffer, bufferIndex, length); - public unsafe int Read(FileStream source, int sourceIndex, void* buffer, int length) - { - if (source.Seek(sourceIndex, SeekOrigin.Begin) == sourceIndex) - { - return InternalRead(source, buffer, 0, length); - } - - return -1; - } - - public unsafe int Read(FileStream source, int sourceIndex, void* buffer, int bufferIndex, int length) - { - if (source.Seek(sourceIndex, SeekOrigin.Begin) == sourceIndex) - { - return InternalRead(source, buffer, bufferIndex, length); - } - - return -1; - } - - internal unsafe int InternalRead(FileStream source, void* buffer, int bufferIndex, int length) + internal static unsafe int InternalRead(FileStream source, void* buffer, int bufferIndex, int length) { var byteCount = 0U; - if (!UnsafeNativeMethods.ReadFile(source.SafeFileHandle!.DangerousGetHandle(), (byte*)buffer + bufferIndex, (uint)length, ref byteCount, null)) + if (UnsafeNativeMethods.ReadFile(source.SafeFileHandle!.DangerousGetHandle(), (byte*)buffer + bufferIndex, (uint)length, ref byteCount, null)) { - return -1; + return (int)byteCount; } - if (byteCount > 0) - { - source.Seek(byteCount, SeekOrigin.Current); - } - - return (int)byteCount; + return -1; } } @@ -90,40 +53,10 @@ namespace Server internal static extern unsafe int read(IntPtr ptr, void* buffer, int length); } - public unsafe int Read(FileStream source, void* buffer, int length) => InternalRead(source, buffer, 0, length); + public unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length) => + InternalRead(source, buffer, bufferIndex, length); - public unsafe int Read(FileStream source, void* buffer, int bufferIndex, int length) => InternalRead(source, buffer, bufferIndex, length); - - public unsafe int Read(FileStream source, int sourceIndex, void* buffer, int length) - { - if (source.Seek(sourceIndex, SeekOrigin.Begin) == sourceIndex) - { - return InternalRead(source, buffer, 0, length); - } - - return -1; - } - - public unsafe int Read(FileStream source, int sourceIndex, void* buffer, int bufferIndex, int length) - { - if (source.Seek(sourceIndex, SeekOrigin.Begin) == sourceIndex) - { - return InternalRead(source, buffer, bufferIndex, length); - } - - return -1; - } - - internal unsafe int InternalRead(FileStream source, void* buffer, int bufferIndex, int length) - { - var byteCount = UnsafeNativeMethods.read(source.Handle, (byte*)buffer + bufferIndex, length); - - if (byteCount > 0) - { - source.Seek(byteCount, SeekOrigin.Current); - } - - return byteCount; - } + internal unsafe int InternalRead(FileStream source, void* buffer, int bufferIndex, int length) => + UnsafeNativeMethods.read(source.SafeFileHandle.DangerousGetHandle(), (byte*)buffer + bufferIndex, length); } } diff --git a/Projects/Server/Network/Packets/OutgoingMapPackets.cs b/Projects/Server/Network/Packets/OutgoingMapPackets.cs index 6ae92f373..d0216d14d 100644 --- a/Projects/Server/Network/Packets/OutgoingMapPackets.cs +++ b/Projects/Server/Network/Packets/OutgoingMapPackets.cs @@ -14,68 +14,39 @@ *************************************************************************/ using System.Buffers; -using System.IO; using System.Runtime.CompilerServices; namespace Server.Network { public static class OutgoingMapPackets { + private static byte[] _mapPatchesPacket = new byte[41]; + public static void SendMapPatches(this NetState ns) { - if (ns == null || ns.ProtocolChanges >= ProtocolChanges.Version6000) + if (ns == null) { return; } - int count; + if (_mapPatchesPacket[0] == 0) + { + var writer = new SpanWriter(_mapPatchesPacket); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)41); // Length + writer.Write((ushort)0x18); // Subpacket + writer.Write(4); - if (ns.HasFlag(ClientFlags.TerMur)) - { - count = 6; - } - else if (ns.HasFlag(ClientFlags.Tokuno)) - { - count = 5; - } - else if (ns.HasFlag(ClientFlags.Malas)) - { - count = 4; - } - else if (ns.HasFlag(ClientFlags.Ilshenar)) - { - count = 3; - } - else if (ns.HasFlag(ClientFlags.Trammel)) - { - count = 2; - } - else if (ns.HasFlag(ClientFlags.Felucca)) - { - count = 1; - } - else - { - return; + for (int i = 0; i < 4; i++) + { + var map = Map.Maps[i]; + + writer.Write(map.Tiles.Patch.StaticBlocks); + writer.Write(map.Tiles.Patch.LandBlocks); + } } - var writer = new SpanWriter(stackalloc byte[9 + count * 8]); - writer.Write((byte)0xBF); // Packet ID - writer.Seek(2, SeekOrigin.Current); - writer.Write((ushort)0x18); // Subpacket - writer.Write(count); - - for (int i = 0; i < count; i++) - { - var map = Map.Maps[i]; - - writer.Write(map.Tiles.Patch.StaticBlocks); - writer.Write(map.Tiles.Patch.LandBlocks); - } - - writer.WritePacketLength(); - - ns.Send(writer.Span); + ns.Send(_mapPatchesPacket); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Projects/Server/TileData.cs b/Projects/Server/TileData.cs index a2289c2cd..3434d0455 100644 --- a/Projects/Server/TileData.cs +++ b/Projects/Server/TileData.cs @@ -262,7 +262,7 @@ namespace Server Load(); } - private unsafe static void Load() + private static unsafe void Load() { var filePath = Core.FindDataFile("tiledata.mul"); diff --git a/Projects/Server/TileMatrix/TileMatrix.cs b/Projects/Server/TileMatrix/TileMatrix.cs index a6a542799..aaea1f638 100644 --- a/Projects/Server/TileMatrix/TileMatrix.cs +++ b/Projects/Server/TileMatrix/TileMatrix.cs @@ -31,6 +31,14 @@ namespace Server public FileStream DataStream { get; } public BinaryReader IndexReader { get; } + private static bool Pre6000ClientSupport; + + public static void Configure() + { + // Set to true to support < 6.0.0 clients where map0.mul is both Felucca & Trammel + Pre6000ClientSupport = ServerConfiguration.GetOrUpdateSetting("maps.enablePre6000Trammel", false); + } + public TileMatrix(Map owner, int fileIndex, int mapID, int width, int height) { lock (_instances) @@ -63,11 +71,13 @@ namespace Server if (fileIndex != 0x7F) { + fileIndex = Pre6000ClientSupport && mapID == 1 ? 0 : fileIndex; + var mapPath = Core.FindDataFile($"map{fileIndex}.mul", false); if (mapPath != null) { - MapStream = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + MapStream = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.Read); } else { @@ -75,7 +85,7 @@ namespace Server if (mapPath != null) { - MapStream = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + MapStream = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.Read); _mapIndex = new UOPIndex(MapStream); } else @@ -88,7 +98,7 @@ namespace Server if (indexPath != null) { - IndexStream = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + IndexStream = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); IndexReader = new BinaryReader(IndexStream); } else @@ -100,7 +110,7 @@ namespace Server if (staticsPath != null) { - DataStream = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + DataStream = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.Read); } else { @@ -483,7 +493,7 @@ namespace Server public int Height => 0; - public bool Ignored => m_ID == 2 || m_ID == 0x1DB || m_ID >= 0x1AE && m_ID <= 0x1B5; + public bool Ignored => m_ID is 2 or 0x1DB or >= 0x1AE and <= 0x1B5; public LandTile(short id, sbyte z) { diff --git a/Projects/Server/TileMatrix/TileMatrixPatch.cs b/Projects/Server/TileMatrix/TileMatrixPatch.cs index ac6c86443..2e876a348 100644 --- a/Projects/Server/TileMatrix/TileMatrixPatch.cs +++ b/Projects/Server/TileMatrix/TileMatrixPatch.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using System.Runtime.CompilerServices; @@ -41,9 +42,8 @@ namespace Server public static void Configure() { - // Using this requires the old mapDif files to be present. Only needed to support Clients < 6.0.0.0 - PatchLandEnabled = ServerConfiguration.GetOrUpdateSetting("maps.enableMapDiffPatches", false); - PatchStaticsEnabled = ServerConfiguration.GetOrUpdateSetting("maps.enableStaticsDiffPatches", false); + PatchLandEnabled = ServerConfiguration.GetOrUpdateSetting("maps.enableMapDiffPatches", !Core.HS); + PatchStaticsEnabled = ServerConfiguration.GetOrUpdateSetting("maps.enableStaticsDiffPatches", true); } [MethodImpl(MethodImplOptions.Synchronized)] @@ -51,15 +51,14 @@ namespace Server { using var fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read); using var fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); - var indexReader = new BinaryReader(fsIndex); + using var indexReader = new BinaryReader(fsIndex); var count = (int)(indexReader.BaseStream.Length / 4); - for (var i = 0; i < count; ++i) + for (var i = 0; i < count; i++) { var blockID = indexReader.ReadInt32(); - var x = blockID / matrix.BlockHeight; - var y = blockID % matrix.BlockHeight; + var x = Math.DivRem(blockID, matrix.BlockHeight, out var y); fsData.Seek(4, SeekOrigin.Current); @@ -73,8 +72,6 @@ namespace Server matrix.SetLandBlock(x, y, tiles); } - indexReader.Close(); - return count; }