Fixes publishing

This commit is contained in:
Kamron Batman 2019-10-04 22:02:19 -07:00
parent 6119774dc9
commit 58be0d416c
No known key found for this signature in database
GPG key ID: 5C9DFD15804B6BB8
53 changed files with 981 additions and 1225 deletions

View file

@ -19,6 +19,7 @@
***************************************************************************/
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Server.Network
@ -47,7 +48,7 @@ namespace Server.Network
// If our input exceeds this length, we may potentially overflow the buffer
private const int PossibleOverflow = (BufferSize * 8 - TerminalCodeLength) / MaximalCodeLength;
private static int[] _huffmanTable = {
private static readonly int[] _huffmanTable = {
0x2, 0x000, 0x5, 0x01F, 0x6, 0x022, 0x7, 0x034, 0x7, 0x075, 0x6, 0x028, 0x6, 0x03B, 0x7, 0x032,
0x8, 0x0E0, 0x8, 0x062, 0x7, 0x056, 0x8, 0x079, 0x9, 0x19D, 0x8, 0x097, 0x6, 0x02A, 0x7, 0x057,
0x8, 0x071, 0x8, 0x05B, 0x9, 0x1CC, 0x8, 0x0A7, 0x7, 0x025, 0x7, 0x04F, 0x8, 0x066, 0x8, 0x07D,
@ -88,23 +89,12 @@ namespace Server.Network
static Compression()
{
if (Core.Unix)
{
if (Core.Is64Bit)
Compressor = new CompressorUnix64();
Compressor = new UnixCompressor();
else
Compressor = new CompressorUnix32();
Compressor = new Compressor();
}
else if (Core.Is64Bit)
{
Compressor = new Compressor64();
}
else
{
Compressor = new Compressor32();
}
}
public static unsafe void Compress(byte[] input, int offset, int count, byte[] output, ref int length)
public static unsafe void Compress(ReadOnlySpan<byte> input, int offset, int count, Span<byte> output, out int length)
{
if (input == null) throw new ArgumentNullException(nameof(input));
@ -121,8 +111,6 @@ namespace Server.Network
fixed (int* pTable = _huffmanTable)
{
int* pEntry;
fixed (byte* pInputBuffer = input)
{
byte* pInput = pInputBuffer + offset, pInputEnd = pInput + count;
@ -131,6 +119,7 @@ namespace Server.Network
{
byte* pOutput = pOutputBuffer, pOutputEnd = pOutput + BufferSize;
int* pEntry;
while (pInput < pInputEnd)
{
pEntry = &pTable[*pInput++ << 1];
@ -192,183 +181,150 @@ namespace Server.Network
}
}
public static ZLibError Pack(byte[] dest, ref int destLength, byte[] source, int sourceLength)
public static int MaxPackSize(int sourceLength) => (int)Compressor.CompressBound((ulong)sourceLength);
public static unsafe ZLibError Pack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, int sourceLength)
{
return Compressor.Compress(dest, ref destLength, source, sourceLength);
ulong destLengthLong = (ulong)destLength;
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
{
ZLibError e = Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)sourceLength);
destLength = (int)destLengthLong;
return e;
}
}
public static unsafe ZLibError Pack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, ZLibQuality quality)
{
ulong destLengthLong = (ulong)destLength;
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
{
ZLibError e = Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)source.Length, quality);
destLength = (int)destLengthLong;
return e;
}
}
public static unsafe ZLibError Pack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, int sourceLength, ZLibQuality quality)
{
ulong destLengthLong = (ulong)destLength;
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
{
ZLibError e = Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)sourceLength, quality);
destLength = (int)destLengthLong;
return e;
}
}
public static ZLibError Pack(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
public static unsafe ZLibError Unpack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, int sourceLength)
{
return Compressor.Compress(dest, ref destLength, source, sourceLength, quality);
ulong destLengthLong = (ulong)destLength;
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
{
ZLibError e = Compressor.Decompress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)sourceLength);
destLength = (int)destLengthLong;
return e;
}
}
public static ulong MaxPackSize(ulong sourceLength) => Compressor.CompressBound(sourceLength);
public static unsafe ZLibError Pack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ulong sourceLength)
{
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
return Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), sourceLength);
}
public static ZLibError Unpack(byte[] dest, ref int destLength, byte[] source, int sourceLength)
public static unsafe ZLibError Pack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ZLibQuality quality)
{
return Compressor.Decompress(dest, ref destLength, source, sourceLength);
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
return Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), (ulong)source.Length, quality);
}
public static unsafe ZLibError Pack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ulong sourceLength, ZLibQuality quality)
{
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
return Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), sourceLength, quality);
}
public static unsafe ZLibError Unpack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ulong sourceLength)
{
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
return Compressor.Decompress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), sourceLength);
}
}
public interface ICompressor
{
string Version{ get; }
ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality);
ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
string Version { get; }
ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength, ZLibQuality quality);
ZLibError Decompress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
ulong CompressBound(ulong sourceLength);
}
public sealed class Compressor32 : ICompressor
{
public string Version => SafeNativeMethods.zlibVersion();
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
public class Compressor : ICompressor
{
return SafeNativeMethods.compress(dest, ref destLength, source, sourceLength);
}
public string Version => zlibVersion();
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
{
return SafeNativeMethods.compress2(dest, ref destLength, source, sourceLength, quality);
}
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
compress(dest, ref destLength, source, sourceLength);
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
{
return SafeNativeMethods.uncompress(dest, ref destLength, source, sourceLength);
}
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength,
ZLibQuality quality) => compress2(dest, ref destLength, source, sourceLength, quality);
internal class SafeNativeMethods
{
[DllImport("zlib32")]
internal static extern string zlibVersion();
public ZLibError Decompress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
uncompress(dest, ref destLength, source, sourceLength);
[DllImport("zlib32")]
internal static extern ZLibError compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
public ulong CompressBound(ulong sourceLength) => compressBound(sourceLength);
[DllImport("zlib32")]
internal static extern ZLibError compress2(byte[] dest, ref int destLength, byte[] source, int sourceLength,
[DllImport("zlib")]
private static extern string zlibVersion();
[DllImport("zlib")]
private static extern ZLibError compress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
[DllImport("zlib")]
private static extern ZLibError compress2(in int dest, ref ulong destLength, in int source, ulong sourceLength,
ZLibQuality quality);
[DllImport("zlib32")]
internal static extern ZLibError uncompress(byte[] dest, ref int destLen, byte[] source, int sourceLen);
}
[DllImport("zlib")]
private static extern ZLibError uncompress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
[DllImport("zlib")]
private static extern ulong compressBound(ulong sourceLen);
}
public sealed class Compressor64 : ICompressor
public class UnixCompressor : ICompressor
{
public string Version => SafeNativeMethods.zlibVersion();
public string Version => zlibVersion();
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
{
return SafeNativeMethods.compress(dest, ref destLength, source, sourceLength);
}
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
compress(dest, ref destLength, source, sourceLength);
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
{
return SafeNativeMethods.compress2(dest, ref destLength, source, sourceLength, quality);
}
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength,
ZLibQuality quality) => compress2(dest, ref destLength, source, sourceLength, quality);
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
{
return SafeNativeMethods.uncompress(dest, ref destLength, source, sourceLength);
}
public ZLibError Decompress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
uncompress(dest, ref destLength, source, sourceLength);
internal class SafeNativeMethods
{
[DllImport("zlib64")]
internal static extern string zlibVersion();
public ulong CompressBound(ulong sourceLength) => compressBound(sourceLength);
[DllImport("zlib64")]
internal static extern ZLibError compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
[DllImport("libz")]
private static extern string zlibVersion();
[DllImport("zlib64")]
internal static extern ZLibError compress2(byte[] dest, ref int destLength, byte[] source, int sourceLength,
[DllImport("libz")]
private static extern ZLibError compress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
[DllImport("libz")]
private static extern ZLibError compress2(in int dest, ref ulong destLength, in int source, ulong sourceLength,
ZLibQuality quality);
[DllImport("zlib64")]
internal static extern ZLibError uncompress(byte[] dest, ref int destLen, byte[] source, int sourceLen);
}
}
public sealed class CompressorUnix32 : ICompressor
{
public string Version => SafeNativeMethods.zlibVersion();
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
{
return SafeNativeMethods.compress(dest, ref destLength, source, sourceLength);
}
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
{
return SafeNativeMethods.compress2(dest, ref destLength, source, sourceLength, quality);
}
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
{
return SafeNativeMethods.uncompress(dest, ref destLength, source, sourceLength);
}
internal class SafeNativeMethods
{
[DllImport("libz")]
internal static extern string zlibVersion();
[DllImport("libz")]
private static extern ZLibError uncompress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
[DllImport("libz")]
internal static extern ZLibError compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
[DllImport("libz")]
internal static extern ZLibError compress2(byte[] dest, ref int destLength, byte[] source, int sourceLength,
ZLibQuality quality);
[DllImport("libz")]
internal static extern ZLibError uncompress(byte[] dest, ref int destLen, byte[] source, int sourceLen);
}
}
public sealed class CompressorUnix64 : ICompressor
{
public string Version => SafeNativeMethods.zlibVersion();
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
{
ulong destLengthLong = (ulong)destLength;
ZLibError z = SafeNativeMethods.compress(dest, ref destLengthLong, source, sourceLength);
destLength = (int)destLengthLong;
return z;
}
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
{
ulong destLengthLong = (ulong)destLength;
ZLibError z = SafeNativeMethods.compress2(dest, ref destLengthLong, source, sourceLength, quality);
destLength = (int)destLengthLong;
return z;
}
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
{
ulong destLengthLong = (ulong)destLength;
ZLibError z = SafeNativeMethods.uncompress(dest, ref destLengthLong, source, sourceLength);
destLength = (int)destLengthLong;
return z;
}
internal class SafeNativeMethods
{
[DllImport("libz")]
internal static extern string zlibVersion();
[DllImport("libz")]
internal static extern ZLibError compress(byte[] dest, ref ulong destLength, byte[] source, int sourceLength);
[DllImport("libz")]
internal static extern ZLibError compress2(byte[] dest, ref ulong destLength, byte[] source, int sourceLength,
ZLibQuality quality);
[DllImport("libz")]
internal static extern ZLibError uncompress(byte[] dest, ref ulong destLen, byte[] source, int sourceLen);
}
private static extern ulong compressBound(ulong sourceLen);
}
public enum ZLibError
@ -379,9 +335,7 @@ namespace Server.Network
DataError = -3,
StreamError = -2,
FileError = -1,
Okay = 0,
StreamEnd = 1,
NeedDictionary = 2
}
@ -389,10 +343,8 @@ namespace Server.Network
public enum ZLibQuality
{
Default = -1,
None = 0,
Speed = 1,
Size = 9
}
}
}

View file

@ -1,273 +1,273 @@
/***************************************************************************
* Packet.cs
* -------------------
* begin : August 2, 2019
* copyright : (C) The RunUO Software Team
* email : info@runuo.com
*
* $Id$
*
***************************************************************************/
/***************************************************************************
*
* 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 2 of the License, or
* (at your option) any later version.
*
***************************************************************************/
using Server.Diagnostics;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace Server.Network
{
public abstract class Packet
{
private const int CompressorBufferSize = 0x10000;
private const int BufferSize = 4096;
private byte[] m_CompiledBuffer;
private int m_CompiledLength;
private int m_Length;
private State m_State;
protected PacketWriter m_Stream;
protected Packet(int packetID)
{
PacketID = packetID;
if (Core.Profiling)
{
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
prof.Increment();
}
}
protected Packet(int packetID, int length)
{
PacketID = packetID;
m_Length = length;
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
m_Stream.Write((byte)packetID);
if (Core.Profiling)
{
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
prof.Increment();
}
}
public int PacketID { get; }
public PacketWriter UnderlyingStream => m_Stream;
public void EnsureCapacity(int length)
{
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
m_Stream.Write((byte)PacketID);
m_Stream.Write((short)0);
}
public static Packet SetStatic(Packet p)
{
p.SetStatic();
return p;
}
public static Packet Acquire(Packet p)
{
p.Acquire();
return p;
}
public static void Release(ref Packet p)
{
p?.Release();
p = null;
}
public static void Release(Packet p)
{
p?.Release();
}
public void SetStatic()
{
m_State |= State.Static | State.Acquired;
}
public void Acquire()
{
m_State |= State.Acquired;
}
public void OnSend()
{
Core.Set(); // Is this still needed if this is done async?
if ((m_State & (State.Acquired | State.Static)) == 0)
Free();
}
private void Free()
{
if (m_CompiledBuffer == null)
return;
if ((m_State & State.Buffered) != 0)
ArrayPool<byte>.Shared.Return(m_CompiledBuffer);
m_State &= ~(State.Static | State.Acquired | State.Buffered);
m_CompiledBuffer = null;
}
public void Release()
{
if ((m_State & State.Acquired) != 0)
Free();
}
public byte[] Compile(bool compress, out int length)
{
lock (this)
{
if (m_CompiledBuffer == null)
{
if ((m_State & State.Accessed) == 0)
{
m_State |= State.Accessed;
}
else
{
if ((m_State & State.Warned) == 0)
{
m_State |= State.Warned;
try
{
using (StreamWriter op = new StreamWriter("net_opt.log", true))
{
op.WriteLine("Redundant compile for packet {0}, use Acquire() and Release()", GetType());
op.WriteLine(new StackTrace());
}
}
catch
{
// ignored
}
}
m_CompiledBuffer = new byte[0];
m_CompiledLength = 0;
length = m_CompiledLength;
return m_CompiledBuffer;
}
InternalCompile(compress);
}
length = m_CompiledLength;
return m_CompiledBuffer;
}
}
private void InternalCompile(bool compress)
{
if (m_Length == 0)
{
long streamLen = m_Stream.Length;
m_Stream.Seek(1, SeekOrigin.Begin);
m_Stream.Write((ushort)streamLen);
}
else if (m_Stream.Length != m_Length)
{
int diff = (int)m_Stream.Length - m_Length;
Console.WriteLine("Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)", PacketID, diff >= 0 ? "+" : "",
diff);
}
MemoryStream ms = m_Stream.UnderlyingStream;
m_CompiledBuffer = ms.GetBuffer();
int length = (int)ms.Length;
if (compress)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(CompressorBufferSize);
Compression.Compress(m_CompiledBuffer, 0, length, buffer, ref length);
if (length <= 0)
{
Console.WriteLine("Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})",
PacketID, GetType().Name, length);
using (StreamWriter op = new StreamWriter("compression_overflow.log", true))
{
op.WriteLine("{0} Warning: Compression buffer overflowed on packet 0x{1:X2} ('{2}') (length={3})",
DateTime.UtcNow, PacketID, GetType().Name, length);
op.WriteLine(new StackTrace());
}
}
else
{
m_CompiledLength = length;
if ((m_State & State.Static) != 0)
{
m_CompiledBuffer = new byte[length];
Buffer.BlockCopy(buffer, 0, m_CompiledBuffer, 0, length);
ArrayPool<byte>.Shared.Return(buffer);
}
else
{
m_CompiledBuffer = buffer;
m_State |= State.Buffered;
}
}
}
else if (length > 0)
{
byte[] old = m_CompiledBuffer;
m_CompiledLength = length;
if ((m_State & State.Static) != 0)
m_CompiledBuffer = new byte[length];
else
{
m_CompiledBuffer = ArrayPool<byte>.Shared.Rent(length);
m_State |= State.Buffered;
}
Buffer.BlockCopy(old, 0, m_CompiledBuffer, 0, length);
}
PacketWriter.ReleaseInstance(m_Stream);
m_Stream = null;
}
[Flags]
private enum State
{
Inactive = 0x00,
Static = 0x01,
Acquired = 0x02,
Accessed = 0x04,
Buffered = 0x08,
Warned = 0x10
}
}
}
/***************************************************************************
* Packet.cs
* -------------------
* begin : August 2, 2019
* copyright : (C) The RunUO Software Team
* email : info@runuo.com
*
* $Id$
*
***************************************************************************/
/***************************************************************************
*
* 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 2 of the License, or
* (at your option) any later version.
*
***************************************************************************/
using Server.Diagnostics;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace Server.Network
{
public abstract class Packet
{
private const int CompressorBufferSize = 0x10000;
private const int BufferSize = 4096;
private byte[] m_CompiledBuffer;
private int m_CompiledLength;
private int m_Length;
private State m_State;
protected PacketWriter m_Stream;
protected Packet(int packetID)
{
PacketID = packetID;
if (Core.Profiling)
{
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
prof.Increment();
}
}
protected Packet(int packetID, int length)
{
PacketID = packetID;
m_Length = length;
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
m_Stream.Write((byte)packetID);
if (Core.Profiling)
{
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
prof.Increment();
}
}
public int PacketID { get; }
public PacketWriter UnderlyingStream => m_Stream;
public void EnsureCapacity(int length)
{
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
m_Stream.Write((byte)PacketID);
m_Stream.Write((short)0);
}
public static Packet SetStatic(Packet p)
{
p.SetStatic();
return p;
}
public static Packet Acquire(Packet p)
{
p.Acquire();
return p;
}
public static void Release(ref Packet p)
{
p?.Release();
p = null;
}
public static void Release(Packet p)
{
p?.Release();
}
public void SetStatic()
{
m_State |= State.Static | State.Acquired;
}
public void Acquire()
{
m_State |= State.Acquired;
}
public void OnSend()
{
Core.Set(); // Is this still needed if this is done async?
if ((m_State & (State.Acquired | State.Static)) == 0)
Free();
}
private void Free()
{
if (m_CompiledBuffer == null)
return;
if ((m_State & State.Buffered) != 0)
ArrayPool<byte>.Shared.Return(m_CompiledBuffer);
m_State &= ~(State.Static | State.Acquired | State.Buffered);
m_CompiledBuffer = null;
}
public void Release()
{
if ((m_State & State.Acquired) != 0)
Free();
}
public byte[] Compile(bool compress, out int length)
{
lock (this)
{
if (m_CompiledBuffer == null)
{
if ((m_State & State.Accessed) == 0)
{
m_State |= State.Accessed;
}
else
{
if ((m_State & State.Warned) == 0)
{
m_State |= State.Warned;
try
{
using (StreamWriter op = new StreamWriter("net_opt.log", true))
{
op.WriteLine("Redundant compile for packet {0}, use Acquire() and Release()", GetType());
op.WriteLine(new StackTrace());
}
}
catch
{
// ignored
}
}
m_CompiledBuffer = new byte[0];
m_CompiledLength = 0;
length = m_CompiledLength;
return m_CompiledBuffer;
}
InternalCompile(compress);
}
length = m_CompiledLength;
return m_CompiledBuffer;
}
}
private void InternalCompile(bool compress)
{
if (m_Length == 0)
{
long streamLen = m_Stream.Length;
m_Stream.Seek(1, SeekOrigin.Begin);
m_Stream.Write((ushort)streamLen);
}
else if (m_Stream.Length != m_Length)
{
int diff = (int)m_Stream.Length - m_Length;
Console.WriteLine("Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)", PacketID, diff >= 0 ? "+" : "",
diff);
}
MemoryStream ms = m_Stream.UnderlyingStream;
m_CompiledBuffer = ms.GetBuffer();
int length = (int)ms.Length;
if (compress)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(CompressorBufferSize);
Compression.Compress(m_CompiledBuffer, 0, length, buffer, out length);
if (length <= 0)
{
Console.WriteLine("Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})",
PacketID, GetType().Name, length);
using (StreamWriter op = new StreamWriter("compression_overflow.log", true))
{
op.WriteLine("{0} Warning: Compression buffer overflowed on packet 0x{1:X2} ('{2}') (length={3})",
DateTime.UtcNow, PacketID, GetType().Name, length);
op.WriteLine(new StackTrace());
}
}
else
{
m_CompiledLength = length;
if ((m_State & State.Static) != 0)
{
m_CompiledBuffer = new byte[length];
Buffer.BlockCopy(buffer, 0, m_CompiledBuffer, 0, length);
ArrayPool<byte>.Shared.Return(buffer);
}
else
{
m_CompiledBuffer = buffer;
m_State |= State.Buffered;
}
}
}
else if (length > 0)
{
byte[] old = m_CompiledBuffer;
m_CompiledLength = length;
if ((m_State & State.Static) != 0)
m_CompiledBuffer = new byte[length];
else
{
m_CompiledBuffer = ArrayPool<byte>.Shared.Rent(length);
m_State |= State.Buffered;
}
Buffer.BlockCopy(old, 0, m_CompiledBuffer, 0, length);
}
PacketWriter.ReleaseInstance(m_Stream);
m_Stream = null;
}
[Flags]
private enum State
{
Inactive = 0x00,
Static = 0x01,
Acquired = 0x02,
Accessed = 0x04,
Buffered = 0x08,
Warned = 0x10
}
}
}

View file

@ -3781,65 +3781,6 @@ namespace Server.Network
}
}
public sealed class CityInfo
{
private Point3D m_Location;
public CityInfo(string city, string building, int description, int x, int y, int z, Map m)
{
City = city;
Building = building;
Description = description;
m_Location = new Point3D(x, y, z);
Map = m;
}
public CityInfo(string city, string building, int x, int y, int z, Map m) : this(city, building, 0, x, y, z, m)
{
}
public CityInfo(string city, string building, int description, int x, int y, int z) : this(city, building,
description, x, y, z, Map.Trammel)
{
}
public CityInfo(string city, string building, int x, int y, int z) : this(city, building, 0, x, y, z, Map.Trammel)
{
}
public string City{ get; set; }
public string Building{ get; set; }
public int Description{ get; set; }
public int X
{
get => m_Location.X;
set => m_Location.X = value;
}
public int Y
{
get => m_Location.Y;
set => m_Location.Y = value;
}
public int Z
{
get => m_Location.Z;
set => m_Location.Z = value;
}
public Point3D Location
{
get => m_Location;
set => m_Location = value;
}
public Map Map{ get; set; }
}
public sealed class CharacterListUpdate : Packet
{
public CharacterListUpdate(IAccount a) : base(0x86)