Skip to content

feat:支持解压Gzip Content-Encoding格式的数据包 - #142

Open
zhicheng233 wants to merge 1 commit into
MuNET-OSS:mainfrom
zhicheng233:Gzip-content-encoding-support
Open

feat:支持解压Gzip Content-Encoding格式的数据包#142
zhicheng233 wants to merge 1 commit into
MuNET-OSS:mainfrom
zhicheng233:Gzip-content-encoding-support

Conversation

@zhicheng233

@zhicheng233 zhicheng233 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

开启后游戏将支持解压非deflate格式的数据包,比如Gzip;
用于服务器使用Cloudflare等不支持deflate格式的CDN;

Review in cubic

Summary by Sourcery

添加一个可选的游戏系统设置,在解压网络响应时支持额外的 HTTP content-encoding 格式。

新功能:

  • 引入 MoreContentEncoding 游戏系统模块,将解压支持从仅 deflate 扩展到包括 gzipzlib 编码的负载,并在必要时回退到纯文本。

增强:

  • 在排序后的配置列表中注册 MoreContentEncoding 配置选项,以便可以在设置中启用或禁用扩展的 content-encoding 支持。
Original summary in English

Summary by Sourcery

Add an optional game system setting to support additional HTTP content-encoding formats when decompressing network responses.

New Features:

  • Introduce the MoreContentEncoding game system module that extends decompression support beyond deflate to include gzip and zlib-encoded payloads, falling back to plaintext when necessary.

Enhancements:

  • Register the MoreContentEncoding configuration option in the sorted config list to allow enabling or disabling extended content-encoding support from settings.

Copilot AI lite review requested due to automatic review settings August 15, 2026 01:09
@sourcery-ai

sourcery-ai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Reviewer's Guide

添加一个可选的模组配置,通过挂钩 NetHttpClient.Decompress 来支持 gzip 和更健壮的 zlib/deflate 处理,在无法解压时回退为纯文本。

针对 gzip/zlib/纯文本处理的 NetHttpClient.Decompress 补丁序列图

sequenceDiagram
    participant NetHttpClient
    participant MoreContentEncoding
    participant GZipStream
    participant DeflateStream

    NetHttpClient->>MoreContentEncoding: PreDecompress(__instance)
    MoreContentEncoding->>MoreContentEncoding: Traverse.Field _temporaryStream/_memoryStream/_buffer
    MoreContentEncoding->>MoreContentEncoding: memoryStream.SetLength(0)
    alt [temporaryStream.Length == 0]
        MoreContentEncoding-->>NetHttpClient: return false
    else [raw starts with gzip header]
        MoreContentEncoding->>GZipStream: new GZipStream(MemoryStream(raw), Decompress)
        MoreContentEncoding->>MoreContentEncoding: CopyTo(gz, memoryStream, buffer)
    else [raw starts with zlib header and TryInflateZlib succeeds]
        MoreContentEncoding->>DeflateStream: new DeflateStream(MemoryStream(raw,2,...), Decompress)
        MoreContentEncoding->>MoreContentEncoding: CopyTo(deflate, memoryStream, buffer)
    else [no compression detected]
        MoreContentEncoding->>MoreContentEncoding: memoryStream.Write(raw)
    end
    MoreContentEncoding->>MoreContentEncoding: memoryStream.Seek(0)
    MoreContentEncoding->>MoreContentEncoding: temporaryStream.SetLength(0)
    MoreContentEncoding-->>NetHttpClient: return false
Loading

File-Level Changes

Change Details Files
引入一个 GameSystem 模组,扩展 HTTP 响应解压逻辑以处理 gzip 和 zlib 编码的负载,同时保留现有的 deflate/纯文本行为。
  • 在全局 configSort.yaml 中注册新的 MoreContentEncoding 配置节,使其显示在 GameSystem 设置中。
  • 在 NetHttpClient.Decompress 上创建 MoreContentEncoding 的 Harmony 前缀补丁,以检查临时缓冲区,并根据 Content-Encoding 标记选择解压策略。
  • 通过魔数头字节实现 gzip 检测,并使用 GZipStream 将数据解压到现有的内存流缓冲区中。
  • 实现 zlib 检测,并通过跳过 zlib 头和尾、对 deflate 载荷使用 DeflateStream 膨胀来进行尽力解压,在失败时回滚。
  • 确保未压缩或不支持的负载被视为纯文本,直接复制字节,并在处理后重置内部流和缓冲区。
AquaMai/configSort.yaml
AquaMai.Mods/GameSystem/MoreContentEncoding.cs

Tips and commands

Interacting with Sourcery

  • 触发新评审: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub issue: 通过回复评审评论来让 Sourcery 从该评论创建一个 issue。也可以在评审评论下回复 @sourcery-ai issue 来创建对应的 issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。也可以在 Pull Request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 Pull Request 摘要: 在 Pull Request 正文任意位置写上 @sourcery-ai summary,即可在该位置生成 PR 摘要。也可以在 Pull Request 中评论 @sourcery-ai summary 来随时(重新)生成摘要。
  • 生成评审者指南: 在 Pull Request 中评论 @sourcery-ai guide,即可随时(重新)生成评审者指南。
  • 解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 关闭所有 Sourcery 评审: 在 Pull Request 中评论 @sourcery-ai dismiss,即可关闭所有现有的 Sourcery 评审。特别适用于你希望从头开始新的评审——别忘了再评论 @sourcery-ai review 来触发新评审!

Customizing Your Experience

访问你的 dashboard 来:

  • 启用或禁用评审功能,例如 Sourcery 生成的 Pull Request 摘要、评审者指南等。
  • 修改评审语言。
  • 添加、删除或编辑自定义评审说明。
  • 调整其他评审设置。

Getting Help

Original review guide in English

Reviewer's Guide

Adds an optional mod configuration that hooks NetHttpClient.Decompress to support gzip and robust zlib/deflate handling, falling back to plaintext when decompression is not possible.

Sequence diagram for patched NetHttpClient.Decompress with gzip/zlib/plaintext handling

sequenceDiagram
    participant NetHttpClient
    participant MoreContentEncoding
    participant GZipStream
    participant DeflateStream

    NetHttpClient->>MoreContentEncoding: PreDecompress(__instance)
    MoreContentEncoding->>MoreContentEncoding: Traverse.Field _temporaryStream/_memoryStream/_buffer
    MoreContentEncoding->>MoreContentEncoding: memoryStream.SetLength(0)
    alt [temporaryStream.Length == 0]
        MoreContentEncoding-->>NetHttpClient: return false
    else [raw starts with gzip header]
        MoreContentEncoding->>GZipStream: new GZipStream(MemoryStream(raw), Decompress)
        MoreContentEncoding->>MoreContentEncoding: CopyTo(gz, memoryStream, buffer)
    else [raw starts with zlib header and TryInflateZlib succeeds]
        MoreContentEncoding->>DeflateStream: new DeflateStream(MemoryStream(raw,2,...), Decompress)
        MoreContentEncoding->>MoreContentEncoding: CopyTo(deflate, memoryStream, buffer)
    else [no compression detected]
        MoreContentEncoding->>MoreContentEncoding: memoryStream.Write(raw)
    end
    MoreContentEncoding->>MoreContentEncoding: memoryStream.Seek(0)
    MoreContentEncoding->>MoreContentEncoding: temporaryStream.SetLength(0)
    MoreContentEncoding-->>NetHttpClient: return false
Loading

File-Level Changes

Change Details Files
Introduce a GameSystem mod that extends HTTP response decompression logic to handle gzip and zlib-encoded payloads while preserving existing deflate/plaintext behavior.
  • Register the new MoreContentEncoding config section in the global configSort.yaml so it appears in the GameSystem settings.
  • Create the MoreContentEncoding Harmony prefix patch on NetHttpClient.Decompress to inspect the temporary buffer and choose decompression strategy based on Content-Encoding signature.
  • Implement gzip detection via magic header bytes and decompression using GZipStream into the existing memory stream buffer.
  • Implement zlib detection and best-effort decompression by skipping the zlib header and trailer and inflating the deflate payload with DeflateStream, rolling back on failure.
  • Ensure that non-compressed or unsupported payloads are treated as plaintext by copying bytes directly, and that internal streams and buffers are reset after handling.
AquaMai/configSort.yaml
AquaMai.Mods/GameSystem/MoreContentEncoding.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new GameSystem mod to extend the game client’s HTTP payload decompression beyond the stock zlib/deflate path, enabling compatibility with servers/CDNs that deliver gzip-encoded responses (e.g., Cloudflare setups that don’t support deflate).

Changes:

  • Introduces GameSystem.MoreContentEncoding, a Harmony prefix patch over NetHttpClient.Decompress that detects gzip vs zlib vs plaintext.
  • Registers the new config section key in configSort.yaml so it appears in the intended ordering.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
AquaMai/configSort.yaml Adds GameSystem.MoreContentEncoding to config key ordering.
AquaMai.Mods/GameSystem/MoreContentEncoding.cs New decompression patch supporting gzip + zlib + plaintext fallback.
Suppressed comments (2)

AquaMai.Mods/GameSystem/MoreContentEncoding.cs:53

  • The comment looks unfinished and contains an unmatched "(" which reads like a typo and may confuse future readers.
        else if (raw.Length >= 6 && raw[0] == 0x78 && TryInflateZlib(raw, memoryStream, buffer))  
        {  
            // zlib 成功解压(
        }  

AquaMai.Mods/GameSystem/MoreContentEncoding.cs:89

  • CopyTo reads with a hard-coded BufferSize (1024) but uses the instance-provided buffer. If _buffer is ever smaller than 1024, Stream.Read will throw because count exceeds buffer.Length. It’s safer to cap the read size by buffer.Length.
        {  
            var count = from.Read(buffer, 0, BufferSize);  
            if (count <= 0) break;  
            to.Write(buffer, 0, count);  

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +45 to +49
if (raw.Length >= 2 && raw[0] == 0x1F && raw[1] == 0x8B)
{
using var gz = new GZipStream(new MemoryStream(raw, writable: false), CompressionMode.Decompress);
CopyTo(gz, memoryStream, buffer);
}

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了一个问题,并给出了一些总体反馈:

  • CopyTo 中,你在 Read 调用里使用了 BufferSize 常量,但传入的缓冲区长度可能不同;建议要么移除 BufferSize 并始终使用 buffer.Length,要么验证 buffer.Length == BufferSize,以避免越界或低效的读取。
  • Harmony 的前缀假设私有字段 _temporaryStream_memoryStream_buffer 总是非空;添加空值检查或回退逻辑会让这个补丁在面对 NetHttpClient 内部实现的未来变更时更加健壮。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
-`CopyTo` 中,你在 `Read` 调用里使用了 `BufferSize` 常量,但传入的缓冲区长度可能不同;建议要么移除 `BufferSize` 并始终使用 `buffer.Length`,要么验证 `buffer.Length == BufferSize`,以避免越界或低效的读取。
- Harmony 的前缀假设私有字段 `_temporaryStream``_memoryStream``_buffer` 总是非空;添加空值检查或回退逻辑会让这个补丁在面对 NetHttpClient 内部实现的未来变更时更加健壮。

## Individual Comments

### Comment 1
<location path="AquaMai.Mods/GameSystem/MoreContentEncoding.cs" line_range="23-32" />
<code_context>
+    private const int BufferSize = 1024;  
</code_context>
<issue_to_address>
**issue (bug_risk):** CopyTo 使用固定的 BufferSize 而不是实际的缓冲区长度,如果底层缓冲区大小发生变化,就可能产生不匹配。

`CopyTo` 接受一个 `buffer` 参数,但在读取时总是使用 `BufferSize` 常量。如果 NetHttpClient 中的 `_buffer` 不是恰好 1024 字节,或者将来发生变化,就可能导致过度读取和运行时错误。考虑改为使用 `buffer.Length`,或者移除缓冲区参数并明确强制使用固定大小缓冲区的约定。
</issue_to_address>

Sourcery 对开源项目是免费的——如果你喜欢我们的代码审查,请考虑分享它 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的审查。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • In CopyTo you use the BufferSize constant for the Read call but pass in a buffer whose length may differ; consider either removing BufferSize and always using buffer.Length or validating that buffer.Length == BufferSize to avoid overruns or inefficient reads.
  • The Harmony prefix assumes the private fields _temporaryStream, _memoryStream, and _buffer are always non-null; adding null checks or fallback behavior would make the patch more robust against future changes in NetHttpClient’s internals.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In CopyTo you use the BufferSize constant for the Read call but pass in a buffer whose length may differ; consider either removing BufferSize and always using buffer.Length or validating that buffer.Length == BufferSize to avoid overruns or inefficient reads.
- The Harmony prefix assumes the private fields _temporaryStream, _memoryStream, and _buffer are always non-null; adding null checks or fallback behavior would make the patch more robust against future changes in NetHttpClient’s internals.

## Individual Comments

### Comment 1
<location path="AquaMai.Mods/GameSystem/MoreContentEncoding.cs" line_range="23-32" />
<code_context>
+    private const int BufferSize = 1024;  
</code_context>
<issue_to_address>
**issue (bug_risk):** CopyTo uses a fixed BufferSize instead of the actual buffer length, which can cause mismatches if the underlying buffer size changes.

`CopyTo` takes a `buffer` argument but always uses the `BufferSize` constant when reading. If `_buffer` in `NetHttpClient` is not exactly 1024 bytes or changes in the future, this can lead to over-reads and runtime errors. Consider using `buffer.Length` instead, or remove the buffer parameter and enforce a fixed-size buffer contract explicitly.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +23 to +32
private const int BufferSize = 1024;

[HarmonyPrefix]
[HarmonyPatch(typeof(NetHttpClient), "Decompress")]
public static bool PreDecompress(NetHttpClient __instance)
{
var traverse = Traverse.Create(__instance);
var temporaryStream = traverse.Field<MemoryStream>("_temporaryStream").Value;
var memoryStream = traverse.Field<MemoryStream>("_memoryStream").Value;
var buffer = traverse.Field<byte[]>("_buffer").Value;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): CopyTo 使用固定的 BufferSize 而不是实际的缓冲区长度,如果底层缓冲区大小发生变化,就可能产生不匹配。

CopyTo 接受一个 buffer 参数,但在读取时总是使用 BufferSize 常量。如果 NetHttpClient 中的 _buffer 不是恰好 1024 字节,或者将来发生变化,就可能导致过度读取和运行时错误。考虑改为使用 buffer.Length,或者移除缓冲区参数并明确强制使用固定大小缓冲区的约定。

Original comment in English

issue (bug_risk): CopyTo uses a fixed BufferSize instead of the actual buffer length, which can cause mismatches if the underlying buffer size changes.

CopyTo takes a buffer argument but always uses the BufferSize constant when reading. If _buffer in NetHttpClient is not exactly 1024 bytes or changes in the future, this can lead to over-reads and runtime errors. Consider using buffer.Length instead, or remove the buffer parameter and enforce a fixed-size buffer contract explicitly.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="AquaMai.Mods/GameSystem/MoreContentEncoding.cs">

<violation number="1" location="AquaMai.Mods/GameSystem/MoreContentEncoding.cs:23">
P2: `BufferSize` 固定为 1024,但读取目标 `_buffer` 是游戏内部字段,其长度未知。若 `_buffer.Length < 1024`,`CopyTo` 中的 `Read(buffer, 0, 1024)` 会抛 `ArgumentOutOfRangeException`。建议按 `_buffer.Length` 读取(如 `Math.Min(BufferSize, buffer.Length)`),或直接使用 `Math.Min` 保证不超过缓冲区长度。</violation>

<violation number="2" location="AquaMai.Mods/GameSystem/MoreContentEncoding.cs:45">
P2: gzip 解压分支没有 try/catch,而 zlib 分支有。由于该 prefix 完全替换了 `Decompress`,损坏/被截断的 gzip 或碰巧以 0x1F 0x8B 开头的明文都会让 `GZipStream` 抛出未捕获的 `InvalidDataException`,传播出 prefix 后可能中断网络包处理。为 gzip 分支加上与 `TryInflateZlib` 一致的 try/catch,失败时回退到明文写入。</violation>

<violation number="3" location="AquaMai.Mods/GameSystem/MoreContentEncoding.cs:50">
P2: 使用非默认窗口大小的合法 zlib 响应不会被解压。不要只匹配 `raw[0] == 0x78`,应校验完整 zlib 头部(CM、CINFO 和 FCHECK)后再调用 `TryInflateZlib`。</violation>

<violation number="4" location="AquaMai.Mods/GameSystem/MoreContentEncoding.cs:71">
P2: 该分支会接受 `Adler32` 校验失败的 zlib 响应,可能把损坏数据当成正常网络数据。解压后校验 zlib 尾部的 `Adler32`,校验失败时应返回失败并清理输出。</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

try
{
// 跳过 2 字节的 zlib 头部,忽略末尾的 4 字节 Adler32 校验和。
using var input = new MemoryStream(raw, 2, raw.Length - 6, writable: false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: 该分支会接受 Adler32 校验失败的 zlib 响应,可能把损坏数据当成正常网络数据。解压后校验 zlib 尾部的 Adler32,校验失败时应返回失败并清理输出。

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At AquaMai.Mods/GameSystem/MoreContentEncoding.cs, line 71:

<comment>该分支会接受 `Adler32` 校验失败的 zlib 响应,可能把损坏数据当成正常网络数据。解压后校验 zlib 尾部的 `Adler32`,校验失败时应返回失败并清理输出。</comment>

<file context>
@@ -0,0 +1,92 @@
+        try  
+        {  
+            // 跳过 2 字节的 zlib 头部,忽略末尾的 4 字节 Adler32 校验和。
+            using var input = new MemoryStream(raw, 2, raw.Length - 6, writable: false);  
+            using var deflate = new DeflateStream(input, CompressionMode.Decompress);  
+            CopyTo(deflate, output, buffer);  
</file context>

using var gz = new GZipStream(new MemoryStream(raw, writable: false), CompressionMode.Decompress);
CopyTo(gz, memoryStream, buffer);
}
else if (raw.Length >= 6 && raw[0] == 0x78 && TryInflateZlib(raw, memoryStream, buffer))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: 使用非默认窗口大小的合法 zlib 响应不会被解压。不要只匹配 raw[0] == 0x78,应校验完整 zlib 头部(CM、CINFO 和 FCHECK)后再调用 TryInflateZlib

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At AquaMai.Mods/GameSystem/MoreContentEncoding.cs, line 50:

<comment>使用非默认窗口大小的合法 zlib 响应不会被解压。不要只匹配 `raw[0] == 0x78`,应校验完整 zlib 头部(CM、CINFO 和 FCHECK)后再调用 `TryInflateZlib`。</comment>

<file context>
@@ -0,0 +1,92 @@
+            using var gz = new GZipStream(new MemoryStream(raw, writable: false), CompressionMode.Decompress);  
+            CopyTo(gz, memoryStream, buffer);  
+        }  
+        else if (raw.Length >= 6 && raw[0] == 0x78 && TryInflateZlib(raw, memoryStream, buffer))  
+        {  
+            // zlib 成功解压(
</file context>


public class MoreContentEncoding
{
private const int BufferSize = 1024;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: BufferSize 固定为 1024,但读取目标 _buffer 是游戏内部字段,其长度未知。若 _buffer.Length < 1024CopyTo 中的 Read(buffer, 0, 1024) 会抛 ArgumentOutOfRangeException。建议按 _buffer.Length 读取(如 Math.Min(BufferSize, buffer.Length)),或直接使用 Math.Min 保证不超过缓冲区长度。

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At AquaMai.Mods/GameSystem/MoreContentEncoding.cs, line 23:

<comment>`BufferSize` 固定为 1024,但读取目标 `_buffer` 是游戏内部字段,其长度未知。若 `_buffer.Length < 1024`,`CopyTo` 中的 `Read(buffer, 0, 1024)` 会抛 `ArgumentOutOfRangeException`。建议按 `_buffer.Length` 读取(如 `Math.Min(BufferSize, buffer.Length)`),或直接使用 `Math.Min` 保证不超过缓冲区长度。</comment>

<file context>
@@ -0,0 +1,92 @@
+
+public class MoreContentEncoding
+{
+    private const int BufferSize = 1024;  
+  
+    [HarmonyPrefix]  
</file context>

// - 0x1F 0x8B -> gzip
// - 0x78 ?? + valid zlib -> zlib (the stock format: zlib header + raw deflate + adler32)
// - otherwise -> treat as plaintext
if (raw.Length >= 2 && raw[0] == 0x1F && raw[1] == 0x8B)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: gzip 解压分支没有 try/catch,而 zlib 分支有。由于该 prefix 完全替换了 Decompress,损坏/被截断的 gzip 或碰巧以 0x1F 0x8B 开头的明文都会让 GZipStream 抛出未捕获的 InvalidDataException,传播出 prefix 后可能中断网络包处理。为 gzip 分支加上与 TryInflateZlib 一致的 try/catch,失败时回退到明文写入。

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At AquaMai.Mods/GameSystem/MoreContentEncoding.cs, line 45:

<comment>gzip 解压分支没有 try/catch,而 zlib 分支有。由于该 prefix 完全替换了 `Decompress`,损坏/被截断的 gzip 或碰巧以 0x1F 0x8B 开头的明文都会让 `GZipStream` 抛出未捕获的 `InvalidDataException`,传播出 prefix 后可能中断网络包处理。为 gzip 分支加上与 `TryInflateZlib` 一致的 try/catch,失败时回退到明文写入。</comment>

<file context>
@@ -0,0 +1,92 @@
+        //  - 0x1F 0x8B            -> gzip
+        //  - 0x78 ?? + valid zlib -> zlib (the stock format: zlib header + raw deflate + adler32)
+        //  - otherwise            -> treat as plaintext
+        if (raw.Length >= 2 && raw[0] == 0x1F && raw[1] == 0x8B)  
+        {  
+            using var gz = new GZipStream(new MemoryStream(raw, writable: false), CompressionMode.Decompress);  
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants