diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 43f3bdeab..635303985 100644 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -32,8 +32,8 @@ namespace Server.Network { public delegate void NetStateCreatedCallback(NetState ns); - public delegate void DecodePacket(ref CircularBuffer buffer, ref int length); - public delegate void EncodePacket(ReadOnlySpan inputBuffer, ref CircularBuffer outputBuffer, out int length); + public delegate void DecodePacket(CircularBuffer buffer, ref int length); + public delegate void EncodePacket(ReadOnlySpan inputBuffer, CircularBuffer outputBuffer, out int length); public partial class NetState : IComparable, IDisposable { @@ -392,7 +392,7 @@ namespace Server.Network { if (_packetEncoder != null) { - _packetEncoder(span, ref buffer, out length); + _packetEncoder(span, buffer, out length); } else { @@ -533,7 +533,7 @@ namespace Server.Network private void DecodePacket(ArraySegment[] buffer, ref int length) { CircularBuffer cBuffer = new CircularBuffer(buffer); - _packetDecoder?.Invoke(ref cBuffer, ref length); + _packetDecoder?.Invoke(cBuffer, ref length); } private async void RecvTask(object state) diff --git a/Projects/Server/Network/NetworkCompression.cs b/Projects/Server/Network/NetworkCompression.cs index 550556157..908d51339 100644 --- a/Projects/Server/Network/NetworkCompression.cs +++ b/Projects/Server/Network/NetworkCompression.cs @@ -61,12 +61,72 @@ namespace Server.Network 0x4, 0x00D }; - public static void Compress(ReadOnlySpan input, ref CircularBuffer output, out int length) + public static void Compress(ReadOnlySpan input, CircularBuffer output, out int length) { - length = Compress(input, ref output); + length = Compress(input, output); } - public static int Compress(ReadOnlySpan input, ref CircularBuffer output) + public static int Compress(ReadOnlySpan input, CircularBuffer output) + { + if (input.Length > DefiniteOverflow) + { + return 0; + } + + int bitCount = 0; + int bitValue = 0; + + int inputIdx = 0; + int outputIdx = 0; + + while (inputIdx < input.Length) + { + int i = input[inputIdx++] << 1; + + bitCount += _huffmanTable[i]; + bitValue = (bitValue << _huffmanTable[i]) | _huffmanTable[i + 1]; + + while (bitCount >= 8) + { + bitCount -= 8; + + if (output.Length < outputIdx + 1) + { + return 0; + } + + output[outputIdx++] = (byte)(bitValue >> bitCount); + } + } + + // terminal code + bitCount += _huffmanTable[0x200]; + bitValue = (bitValue << _huffmanTable[0x200]) | _huffmanTable[0x201]; + + // align on byte boundary + if ((bitCount & 7) != 0) + { + bitValue <<= 8 - (bitCount & 7); + bitCount += 8 - (bitCount & 7); + } + + while (bitCount >= 8) + { + bitCount -= 8; + + if (output.Length < outputIdx + 1) + { + return 0; + } + + output[outputIdx++] = (byte)(bitValue >> bitCount); + } + + return outputIdx; + } + + + public static int Compress(CircularBuffer input, CircularBuffer output) { if (input.Length > DefiniteOverflow) {