diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/NetworkManager.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/NetworkManager.cs index d0962bbadb..7368e1c009 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/NetworkManager.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/NetworkManager.cs @@ -305,10 +305,15 @@ namespace CSNetwork _receiveOctets.Capacity - currentBufferLength, token ); - - if (currentBufferLength < _receiveOctets.Length) - _logger.Log(LogType.Info, $"ProcessReceivedData:: Buffer remaining data size from {_previousLength} to {currentBufferLength} --- Last byte: {_receiveOctets.RawBuffer[currentBufferLength - 1]}"); - _previousLength = currentBufferLength; // cache to check if the buffer is growing + + // if (bytesRead > 0) + // { + // _logger.Log(LogType.Info, $"ProcessReceivedData:: Last Byte: {_receiveOctets.RawBuffer[currentBufferLength + bytesRead - 1]}"); + // if (_previousLength > 0) + // _logger.Log(LogType.Info, $"ProcessReceivedData:: Buffer remaining data size from {_previousLength} to {currentBufferLength + bytesRead} --- Last byte: {_receiveOctets.RawBuffer[_previousLength - 1]}"); + // } + // + // _previousLength = currentBufferLength + bytesRead; // cache to check if the buffer is growing } catch (IOException ex) when (ex.InnerException is SocketException se @@ -399,7 +404,7 @@ namespace CSNetwork catch (Exception ex) { _logger.Log(LogType.Info, - $"Input security update error: {ex.Message} - Clearing receive buffer." + $"Input security update error: {ex.Message} - {ex.StackTrace} - Clearing receive buffer." ); OnErrorOccurred($"Input security error: {ex.Message}"); _receiveOctets.SetSize(0); diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs index b2b7f20450..4aceb693d2 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs @@ -10,43 +10,43 @@ namespace CSNetwork.Security private const int MPPC_HIST_LEN = 8192; private byte[] history = new byte[MPPC_HIST_LEN]; - private int historyPos; - private uint bitPos; - private uint adjust_bitPos; - private uint bitsProcessed; - private uint totalBits; + private int histptr; + private uint l; + private uint adjust_l; + private uint blen; + private uint blen_total; private List legacyInput = new List(); - private int readPos; - private int adjust_readPos; + private int rptr; + private int adjust_rptr; public Decompress() { - historyPos = 0; - bitPos = 0; + histptr = 0; + l = 0; } public Decompress(Decompress source) { Array.Copy(source.history, history, MPPC_HIST_LEN); - historyPos = source.historyPos; - bitPos = source.bitPos; - adjust_bitPos = source.adjust_bitPos; - bitsProcessed = source.bitsProcessed; - totalBits = source.totalBits; + histptr = source.histptr; + l = source.l; + adjust_l = source.adjust_l; + blen = source.blen; + blen_total = source.blen_total; legacyInput = new List(source.legacyInput); - readPos = source.readPos; - adjust_readPos = source.adjust_readPos; + rptr = source.rptr; + adjust_rptr = source.adjust_rptr; } - private bool PassBits(uint n) + private bool passbits(uint n) { - bitPos += n; - bitsProcessed += n; - if (bitsProcessed < totalBits) + l += n; + blen += n; + if (blen < blen_total) return true; - bitPos = adjust_bitPos; - readPos = adjust_readPos; + l = adjust_l; + rptr = adjust_rptr; return false; } @@ -58,19 +58,19 @@ namespace CSNetwork.Security | ((value & 0xFF000000) >> 24); } - private uint Fetch() + private uint fetch() { - readPos += (int)(bitPos >> 3); - bitPos &= 7; + rptr += (int)(l >> 3); + l &= 7; byte[] fourBytes = new byte[4]; - for (int i = 0; i < 4 && readPos + i < legacyInput.Count; i++) + for (int i = 0; i < 4; i++) { - fourBytes[i] = legacyInput[readPos + i]; + fourBytes[i] = legacyInput[rptr + i]; } uint value = BitConverter.ToUInt32(fourBytes, 0); - return ByteOrder32(value) << (int)bitPos; + return ByteOrder32(value) << (int)l; } private void LameCopy(int dstPos, int srcPos, int len) @@ -93,34 +93,6 @@ namespace CSNetwork.Security } } - // Copy bytes from history using MPPC's 8 KB circular window semantics. - // Source starts at (historyPos - offset) modulo window size and may overlap - // destination; freshly written bytes must be visible to subsequent reads. - private void CopyFromHistoryCircular(int offset, int length) - { - int srcPos = historyPos - offset; - if (srcPos < 0) - srcPos += MPPC_HIST_LEN; // wrap source into window - - int dstPos = historyPos; - - while (length-- > 0) - { - history[dstPos] = history[srcPos]; - - dstPos++; - if (dstPos == MPPC_HIST_LEN) - dstPos = 0; // wrap destination - - srcPos++; - if (srcPos == MPPC_HIST_LEN) - srcPos = 0; // wrap source - } - - // Advance history head to the end of the copied sequence - historyPos = dstPos; - } - public Octets Update(Octets input) { // Add input to legacy buffer @@ -129,253 +101,163 @@ namespace CSNetwork.Security legacyInput.Add(b); } - totalBits = (uint)(legacyInput.Count * 8 - bitPos); - readPos = 0; - bitsProcessed = 7; + blen_total = (uint)(legacyInput.Count * 8 - l); + rptr = 0; + blen = 7; Octets output = new Octets(); - int histHead = historyPos; + int histhead = histptr; - while (totalBits > bitsProcessed) + while (blen_total > blen) { - adjust_bitPos = bitPos; - adjust_readPos = readPos; - uint val = Fetch(); - + adjust_l = l; + adjust_rptr = rptr; + + uint val = fetch(); if (val < 0x80000000) { - if (!PassBits(8)) + if (!passbits(8)) break; - // Defer if writing this literal would cross the end of the linear window. - // We only wrap at EOB to match the original C++ semantics. - if (historyPos + 1 > MPPC_HIST_LEN) - { - bitPos = adjust_bitPos; - readPos = adjust_readPos; - break; - } - history[historyPos++] = (byte)(val >> 24); - // Do not wrap here; wrapping is handled only at EOB. + + history[histptr++] = (byte)(val >> 24); continue; } - if (val < 0xC0000000) { - if (!PassBits(9)) + if (!passbits(9)) break; - // Defer if writing this literal would cross the end of the linear window. - if (historyPos + 1 > MPPC_HIST_LEN) - { - bitPos = adjust_bitPos; - readPos = adjust_readPos; - break; - } - history[historyPos++] = (byte)(((val >> 23) | 0x80) & 0xFF); - // Do not wrap here; wrapping is handled only at EOB. + history[histptr++] = (byte)(((val >> 23) | 0x80) & 0xFF); continue; } - uint offset = 0, - length = 0; + uint off = 0, len = 0; if (val >= 0xF0000000) { - if (!PassBits(10)) + if (!passbits(10)) break; - offset = (val >> 22) & 0x3F; - if (offset == CTRL_OFF_EOB) + off = (val >> 22) & 0x3F; + if (off == CTRL_OFF_EOB) { - uint advance = 8 - (bitPos & 7); + uint advance = (uint)(8 - (l & 7)); if (advance < 8) - if (!PassBits(advance)) + if (!passbits(advance)) break; // Copy current history segment to output - if (historyPos >= histHead) - { - byte[] segment = new byte[historyPos - histHead]; - Array.Copy(history, histHead, segment, 0, segment.Length); + byte[] segment = new byte[histptr - histhead]; + Array.Copy(history, histhead, segment, 0, segment.Length); + output.Insert(output.Size, segment); - // If output is empty, replace it, otherwise insert at the end - if (output.Size == 0) - output.Replace(segment); - else - output.Insert(output.Size, segment); - } - else - { - // Wrap around case - two segments - byte[] segment1 = new byte[MPPC_HIST_LEN - histHead]; - Array.Copy(history, histHead, segment1, 0, segment1.Length); + if (histptr - histhead == MPPC_HIST_LEN) + histptr = 0; - // Add first segment (from histHead to end of buffer) - if (output.Size == 0) - output.Replace(segment1); - else - output.Insert(output.Size, segment1); - - // Add second segment (from beginning to historyPos) - if (historyPos > 0) - { - byte[] segment2 = new byte[historyPos]; - Array.Copy(history, 0, segment2, 0, historyPos); - output.Insert(output.Size, segment2); - } - } - - if (historyPos == MPPC_HIST_LEN) - historyPos = 0; - - histHead = historyPos; + histhead = histptr; continue; } } else if (val >= 0xE0000000) { - if (!PassBits(12)) + if (!passbits(12)) break; - offset = ((val >> 20) & 0xFF) + 64; + off = ((val >> 20) & 0xFF) + 64; } else if (val >= 0xC0000000) { - if (!PassBits(16)) + if (!passbits(16)) break; - offset = ((val >> 16) & 0x1FFF) + 320; + off = ((val >> 16) & 0x1FFF) + 320; + } + + val = fetch(); + if ( val < 0x80000000 ) + { + if ( !passbits(1) ) + break; + len = 3; + } + else if ( val < 0xc0000000 ) + { + if ( !passbits(4) ) + break; + len = 4|((val>>28)&3); + } + else if ( val < 0xe0000000 ) + { + if ( !passbits(6) ) + break; + len = 8|((val>>26)&7); + } + else if ( val < 0xf0000000 ) + { + if ( !passbits(8) ) + break; + len = 16|((val>>24)&15); + } + else if ( val < 0xf8000000 ) + { + if ( !passbits(10) ) + break; + len = 32|((val>>22)&0x1f); + } + else if ( val < 0xfc000000 ) + { + if ( !passbits(12) ) + break; + len = 64|((val>>20)&0x3f); + } + else if ( val < 0xfe000000 ) + { + if ( !passbits(14) ) + break; + len = 128|((val>>18)&0x7f); + } + else if ( val < 0xff000000 ) + { + if ( !passbits(16) ) + break; + len = 256|((val>>16)&0xff); + } + else if ( val < 0xff800000 ) + { + if ( !passbits(18) ) + break; + len = 0x200|((val>>14)&0x1ff); + } + else if ( val < 0xffc00000 ) + { + if ( !passbits(20) ) + break; + len = 0x400|((val>>12)&0x3ff); + } + else if ( val < 0xffe00000 ) + { + if ( !passbits(22) ) + break; + len = 0x800|((val>>10)&0x7ff); + } + else if ( val < 0xfff00000 ) + { + if ( !passbits(24) ) + break; + len = 0x1000|((val>>8)&0xfff); } else { - // Invalid data - bitPos = adjust_bitPos; - readPos = adjust_readPos; + l = adjust_l; + rptr = adjust_rptr; break; } - - val = Fetch(); - if (val < 0x80000000) - { - if (!PassBits(1)) - break; - length = 3; - } - else if (val < 0xC0000000) - { - if (!PassBits(4)) - break; - length = 4 | ((val >> 28) & 3); - } - else if (val < 0xE0000000) - { - if (!PassBits(6)) - break; - length = 8 | ((val >> 26) & 7); - } - else if (val < 0xF0000000) - { - if (!PassBits(8)) - break; - length = 16 | ((val >> 24) & 15); - } - else if (val < 0xF8000000) - { - if (!PassBits(10)) - break; - length = 32 | ((val >> 22) & 0x1F); - } - else if (val < 0xFC000000) - { - if (!PassBits(12)) - break; - length = 64 | ((val >> 20) & 0x3F); - } - else if (val < 0xFE000000) - { - if (!PassBits(14)) - break; - length = 128 | ((val >> 18) & 0x7F); - } - else if (val < 0xFF000000) - { - if (!PassBits(16)) - break; - length = 256 | ((val >> 16) & 0xFF); - } - else if (val < 0xFF800000) - { - if (!PassBits(18)) - break; - length = 0x200 | ((val >> 14) & 0x1FF); - } - else if (val < 0xFFC00000) - { - if (!PassBits(20)) - break; - length = 0x400 | ((val >> 12) & 0x3FF); - } - else if (val < 0xFFE00000) - { - if (!PassBits(22)) - break; - length = 0x800 | ((val >> 10) & 0x7FF); - } - else if (val < 0xFFF00000) - { - if (!PassBits(24)) - break; - length = 0x1000 | ((val >> 8) & 0xFFF); - } - else - { - bitPos = adjust_bitPos; - readPos = adjust_readPos; + if (histptr < off || histptr + len > MPPC_HIST_LEN) break; - } - - // Validate match boundaries against the current linear window. Defer if it would cross. - // This mirrors the C++ check: if (histptr - off < history || histptr + len > history + MPPC_HIST_LEN) break; - if (offset == 0 || offset > MPPC_HIST_LEN || historyPos - (int)offset < 0 || historyPos + (int)length > MPPC_HIST_LEN) - { - // Not enough room in the current linear window; rollback and wait for more data. - bitPos = adjust_bitPos; - readPos = adjust_readPos; - break; - } - - // Linear, overlap-safe copy within current window. No mid-block wrap. - LameCopy(historyPos, historyPos - (int)offset, (int)length); - historyPos += (int)length; - } - - // Copy remaining history segment to output - if (historyPos >= histHead) - { - byte[] result = new byte[historyPos - histHead]; - Array.Copy(history, histHead, result, 0, result.Length); - if (output.Size == 0) - output.Replace(result); - else - output.Insert(output.Size, result); - } - else - { - if (histHead < MPPC_HIST_LEN) - { - byte[] segment1 = new byte[MPPC_HIST_LEN - histHead]; - Array.Copy(history, histHead, segment1, 0, segment1.Length); - if (output.Size == 0) - output.Replace(segment1); - else - output.Insert(output.Size, segment1); - } - - if (historyPos > 0) - { - byte[] segment2 = new byte[historyPos]; - Array.Copy(history, 0, segment2, 0, historyPos); - output.Insert(output.Size, segment2); - } + LameCopy(histptr, histptr - (int)off, (int)len); + histptr += (int)len; } + byte[] result = new byte[histptr - histhead]; + Array.Copy(history, histhead, result, 0, result.Length); + output.Insert(output.Size, result); // Remove processed bytes from legacy input - legacyInput.RemoveRange(0, readPos); + legacyInput.RemoveRange(0, rptr); return output; }