diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs index 12fb2deb35..7b327c9974 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/Security/StreamCompress.cs @@ -93,6 +93,34 @@ 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 @@ -288,13 +316,19 @@ namespace CSNetwork.Security break; } - if (historyPos - (int)offset < 0 || historyPos + (int)length > MPPC_HIST_LEN) + // Perform match copy in the 8 KB circular history buffer. + // Valid offsets are in 1..MPPC_HIST_LEN; offset==0 would be EOB (handled above). + if (offset == 0 || offset > MPPC_HIST_LEN) + { + // Invalid backreference relative to the sliding window; defer until more data + // by restoring bit/read positions to the last safe checkpoint. + bitPos = adjust_bitPos; + readPos = adjust_readPos; break; + } - LameCopy(historyPos, historyPos - (int)offset, (int)length); - historyPos += (int)length; - if (historyPos >= MPPC_HIST_LEN) - historyPos = 0; + // Circular, overlap-safe copy as required by MPPC (LZ77-style) semantics. + CopyFromHistoryCircular((int)offset, (int)length); } // Copy remaining history segment to output