fix(core): Fixes map issues at New Haven (#509)

- [X] Fixes map issues at New Haven by turning off static diffs
- [X] Some code cleanup and reformatting of tile matrix, tile matrix patch, and tile data
- [X] Adds NetState.Flush for generating spawners so it doesn't feel like the server is frozen
- [X] Reverts NativeReader changes from a while back.
- [X] Adds more string reading for BufferReader.


Notes:
BufferReader is still `little endian` compared to `SpanReader` which is `big endian` (for packets). To that end, the RunUO deserialization `ReadString()` was made obsolete since it is ambiguous, and contains extra fields other than simply reading a string. Furthermore, we shouldn't be using UTF8 (for now) since it is slow.
This commit is contained in:
Kamron Batman 2021-02-14 16:06:49 -08:00 committed by GitHub
parent d070efeab3
commit ea5d09a7d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 724 additions and 482 deletions

View file

@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
@ -8,61 +9,121 @@ namespace Server
{
private static readonly INativeReader m_NativeReader;
static NativeReader()
{
if (Core.Unix)
{
m_NativeReader = new NativeReaderUnix();
}
else
{
m_NativeReader = new NativeReaderWin32();
}
}
static NativeReader() => m_NativeReader = Core.Unix ? (INativeReader)new NativeReaderUnix() : new NativeReaderWin32();
public static unsafe void Read(IntPtr p, void* buffer, int length)
{
m_NativeReader.Read(p, buffer, length);
}
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 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 void Read(IntPtr p, void* buffer, int length);
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
{
public unsafe void Read(IntPtr p, void* buffer, int length)
internal class UnsafeNativeMethods
{
uint lpNumberOfBytesRead = 0;
UnsafeNativeMethods.ReadFile(p, buffer, (uint)length, ref lpNumberOfBytesRead, null);
[DllImport("kernel32")]
internal static extern unsafe bool ReadFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, NativeOverlapped* lpOverlapped);
}
internal static class UnsafeNativeMethods
{
/*[DllImport("kernel32")]
internal unsafe static extern int _lread(IntPtr hFile, void* lpBuffer, int wBytes);*/
public unsafe int Read(FileStream source, void* buffer, int length) => InternalRead(source, buffer, 0, length);
[DllImport("kernel32")]
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 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 = 0U;
if (!UnsafeNativeMethods.ReadFile(source.SafeFileHandle!.DangerousGetHandle(), (byte*)buffer + bufferIndex, (uint)length, ref byteCount, null))
{
return -1;
}
if (byteCount > 0)
{
source.Seek(byteCount, SeekOrigin.Current);
}
return (int)byteCount;
}
}
public sealed class NativeReaderUnix : INativeReader
{
public unsafe void Read(IntPtr p, void* buffer, int length)
{
_ = UnsafeNativeMethods.read(p, buffer, length);
}
internal static class UnsafeNativeMethods
internal class UnsafeNativeMethods
{
[DllImport("libc")]
internal static extern unsafe int read(IntPtr p, void* buffer, int length);
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, 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;
}
}
}