Skip to content

Add network module with data packet compression features#80

Closed
Gu-ZT wants to merge 4 commits into
Anvil-Dev:dev/26.1from
Gu-ZT:comp/26.1
Closed

Add network module with data packet compression features#80
Gu-ZT wants to merge 4 commits into
Anvil-Dev:dev/26.1from
Gu-ZT:comp/26.1

Conversation

@Gu-ZT

@Gu-ZT Gu-ZT commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Gu-ZT added 2 commits July 12, 2026 22:26
- 新增 anvillib-network 模块,提供网络API支持
- 实现多种压缩算法(ZSTD、LZ4、GZIP)用于网络数据包
- 添加网络数据包压缩和解压缩功能
- 配置默认压缩算法、压缩阈值和最大解压大小设置
- 更新RPC和同步模块以使用新的压缩流编解码器
- 修改网络版本号从1升级到2
- 添加多语言支持(中文和英文)
- 更新模块依赖关系配置
- 在 AnvilLibNetworkServerConfig 中添加 BoundedDiscrete 注解限制阈值范围
- 修复 AnvilLibWheel 中的命名空间标识符使用问题
- 将配置相关的语言文件从其他模块迁移到 recipe 模块
- 更新各模块的 gradle.properties 文件中的配置标志
- 修正多个模块中 "Anvillib" 的命名显示为 "AnvilLib"
@Gugle2308

Copy link
Copy Markdown

好的,我已获取了完整的 diff。下面是我的审查报告。


代码审查摘要

PR #80 — 新增网络模块及数据包压缩特性

统计 数据
文件总数 35
Java 源文件 17
新增文件 13
删除文件 2
重命名 3
净增行数 ~351

结论:需要修改(1 个警告,数条建议)


⚠️ 警告

1. 生成的 en_us.json 文件缺少末尾换行符(POSIX 兼容性)

两个新生成的 en_us.json 文件末尾均缺少换行符:

  • module.network/src/generated/resources/assets/anvillib_network/lang/en_us.json
  • module.recipe/src/generated/resources/assets/anvillib_recipe/lang/en_us.json

两者末尾都有 \ No newline at end of file 标记。这提示数据生成器可能未正确处理 EOF 换行符。虽然不影响运行时,但影响 diff 整洁度和 POSIX 兼容性。建议在数据生成器中增加换行符保证,或提交前 echo "" >> 修复。


💡 建议

2. PayloadCompression.encode() 每次调用均从 volatile config 读取

algorithm()threshold()maxDecompressedSize() 三个静态方法每次编码/解码时都直接读 AnvilLibNetwork.CONFIGvolatile 字段)。虽然线程安全,但 config 支持运行时热重载——若压缩过程中阈值或算法被重载,同一包的不同分片可能使用不同参数。更重要的是,服务端和客户端可能在编码时读取到不同版本的阈值(若服务端热重载后先于客户端发包)。

建议在 encode()decode() 入口处快照当前 config 值到局部变量,确保一个包在编码/解码过程中使用一致的配置快照:

public static byte[] encode(byte[] data) {
    int threshold = threshold();       // 快照
    int maxSize = maxDecompressedSize();
    CompressionAlgorithm algo = algorithm();
    // ... 使用快照而非重复读 CONFIG
}

3. LZ4 压缩器线程安全无明确文档保证

LZ4Factory.fastestInstance()safeDecompressor() 是线程安全的,但 fastCompressor() 在 LZ4-java 的不同实现版本中保证不同。虽然在当前版本(1.10.1)中实测线程安全,但建议在类 Javadoc 中显式注明 PayloadCompression 是线程安全的,或考虑使用 LZ4Factory.safeInstance().fastCompressor()(始终线程安全),以消除对实现细节的依赖。

4. 配置 move: registrum → network/recipe — 确认 anvillib.needRunConfig 迁移完整性

registrum/gradle.propertieswheel/gradle.propertiesanvillib.needRunConfig=true 行被移除,networkrecipe 新增了这些行。这看起来是将数据生成职责从 registrum(旧的"容器"模块)迁移至各独立模块:

  • module.network — 新增 ✅
  • module.recipe — 新增 ✅
  • ⚠️ module.registrum — 移除 ✅(不再拥有其他模块的 lang)
  • ⚠️ module.wheel — 移除 ← 需确认 wheel needRunConfig 移除后,其 assets/anvillib_wheel/lang/ 是否还需要数据生成?

wheel 的生成 en_us.json(旧路径 assets/anvillib/lang/en_us.json)已被删除,但未在 assets/anvillib_wheel/lang/ 下见过新的生成文件。若 wheel 无 config/lang,移除是合理的——但建议在此 PR 中确认。

5. 旧 assets/anvillib/ 命名空间清理完整性

Wheel 模块将 3 个 shader 文件从 assets/anvillib/shaders/core/ 重命名至 assets/anvillib_wheel/shaders/core/(similarity index 100%),并且 AnvilLibWheel.of() 方法改为使用 MOD_IDanvillib_wheel)替代 MAIN_IDanvillib):

  • annular_sector.fsh → 已迁移
  • ring.fsh → 已迁移
  • selection.fsh → 已迁移
  • AnvilLibWheel.java 引用路径已更新
  • assets/anvillib/ 目录下是否还有其他残留资源未被迁移?建议 grep 确认无 assets/anvillib/ 路径的其他引用未被删除。

6. modules.json 依赖图调整 — 确认 network 已有的依赖声明

network"needs": [] 变为 "needs": ["config"]——正确,因为 AnvilLibNetwork 引用了 ConfigManager.register(),依赖 config 模块。

7. CompressionAlgorithm.byId() — 线性搜索 vs switch

当前使用 for 循环遍历所有值来查找 ID。对于 4 个条目这不是问题,但建议在 byId() 中使用 switch 表达式或预构建 Map<Integer, CompressionAlgorithm>,既更快又为未来添加更多算法做准备。


✅ 看起来不错

  • 模块结构清晰module.network 自包含,有自己的 @Mod、config、数据生成器、压缩逻辑。
  • 压缩封装设计良好PayloadCompression.STREAM_CODEC 作为 StreamCodec<ByteBuf, byte[]> 暴露,可无缝替换 ByteBufCodecs.BYTE_ARRAY——所有调用点(RPC ×3 + Sync ×2)的替换干净统一,无侵入性。
  • 网络版本号递增正确:RPC 从 "1""2",Sync 从 "1""2"——兼容性破坏变更合理使用版本号标识。
  • Config 设计合理:三个配置项(算法、阈值、最大解压尺寸)均有 @BoundedDiscrete 边界约束、@Comment 文档和合理的默认值(ZSTD/128B/16MB)。
  • 边角情况处理encode() 在压缩后尺寸 ≥ 原尺寸 + 1 时自动回退到 NONE(无压缩);decode() 校验解压缩后尺寸与 VarInt 声明一致;GZIP 流式读取时监控 total 不超过 originalLength
  • VarInt 实现:手动实现而非依赖 Netty,减少了依赖;VarInt 内部 record 封装清晰。
  • @NullMarked 所有新 package 均正确使用 org.jspecify.annotations.NullMarked,符合 26.1 迁移规范。
  • CI 配置一致modules.json 中 recipe 新增 en_us.json 与其数据生成器对应。
  • build.gradle 依赖声明正确zstd-jnilz4-java 使用 jarJar(implementation(...)) 嵌入,config 模块使用 jarJar(api(...)) 并区分 dev/prod 模式。

由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown

🌿 Roseau API Breaking Change Report

Module Status Breaking Changes
codec ✅ Compatible 0
collision ✅ Compatible 0
config ✅ Compatible 0
integration ✅ Compatible 0
moveable-entity-block ✅ Compatible 0
network ✅ Compatible 0
rendering ✅ Compatible 0
space-select ✅ Compatible 0
font ✅ Compatible 0
util ✅ Compatible 0
explosion ✅ Compatible 0
rpc ✅ Compatible 0
multiblock ✅ Compatible 0
recipe ✅ Compatible 0
registrum ✅ Compatible 0
sync ✅ Compatible 0
wheel ✅ Compatible 0
main ✅ Compatible 0

Full CSVs: see the Artifacts section of this workflow run.

- 从CompressionAlgorithm枚举中移除ZSTD算法选项
- 将默认压缩算法从ZSTD更改为LZ4
- 从build.gradle中移除zstd-jni依赖
- 更新配置文件注释以反映新的默认算法
- 修改PayloadCompression类中的压缩/解压方法以移除ZSTD相关代码
- 重构编码和解码逻辑以使用配置获取参数
- 更新中英文语言文件以同步压缩算法选项变化
@Gugle2308

Copy link
Copy Markdown

以下是对 PR #80(Anvil-Dev/AnvilLib)的完整代码审查。


代码审查摘要

PR 名称:Add network module with data packet compression features
范围:35 个文件(+421 / -77),其中 13 个新增,2 个删除
分支comp/26.1dev/26.1


🔴 关键

1. zh_cn.json 默认压缩算法翻译错误

// module.network/.../zh_cn.json (新增)
"default_compression_algorithm.tooltip": "默认值:ZSTD"

CompressionAlgorithm 枚举只定义了 NONE, LZ4, GZIP——不存在 ZSTD。且代码中默认值明确为 CompressionAlgorithm.LZ4en_us.json 的对应行正确写着 Default: LZ4。需要将 zh_cn.json 中的 ZSTD 改为 LZ4


⚠️ 警告

2. 8 个文件缺失末尾换行符(No newline at end of file)

  • module.explosion/.../zh_cn.json
  • module.multiblock/.../zh_cn.json
  • module.network/.../en_us.json
  • module.recipe/.../en_us.json
  • module.recipe/.../zh_cn.json
  • module.registrum/gradle.properties
  • module.registrum/.../en_us.json(此文件已删除,但原文件已缺失)
  • module.wheel/.../en_us.json(已删除,同上)

生成的 JSON 缺失 EOF 换行符通常是数据生成器的问题。建议检查 ModLanguageProvider 输出或数据生成器是否需要在末尾追加换行符。gradle.properties 缺失换行符属于手动编写的疏忽,一并修复。


💡 建议

3. Registrum 旧 en_us.json 删除后缺少模块级替代

module.registrum/src/generated/resources/assets/anvillib/lang/en_us.json 被删除(包含旧全局配置键 anvillib.configuration.*)。但 Registrum 模块似乎没有创建新的模块级 en_us 文件(例如 assets/anvillib_registrum/lang/en_us.json)。确认此删除是否意图明确(Registrum 的运行配置已迁移到 recipe/network,不再需要自己的语言文件),如果是则无问题,否则应补充。

4. Wheel shader 路径变更的代码引用交叉验证

三个 .fsh 文件从 assets/anvillib/shaders/core/ 纯重命名(similarity 100%)到 assets/anvillib_wheel/shaders/core/。同时 AnvilLibWheel.of() 的 namespace 从 MAIN_ID("anvillib") 改为 MOD_ID("anvillib_wheel")。需要确认 shader 在代码中的引用路径也同步更新到 anvillib_wheel: namespace,而非硬编码 anvillib:shaders/core/xxx.fsh。建议 grep 整个 repo 中对该三个 shader 的引用,确认路径一致性。

5. PayloadCompression.STREAM_CODEC 配置热重载风险

threshold()maxDecompressedSize()algorithm() 方法在每次编解码时直接从 AnvilLibNetwork.CONFIG 读取。注意配置热重载后,正在进行的解码可能使用新配置导致解压检查不匹配(尤其是 maxDecompressedSize 被缩小后已压缩数据的解压被拒绝)。如果在生产环境中使用,建议在编码时缓存配置快照,解码时使用缓存值。


✅ 看起来不错

  • 模块架构清晰module.networkcompression/data/ 包职责分离明确
  • 压缩信封设计优秀:字节前缀(algorithm ID)+ VarInt 解压前长度 + 数据体;自动回退(压缩后反而不省空间时以无压缩传输)
  • 阈值和最大尺寸双限threshold 避免小包不必要的压缩开销,maxDecompressedSize 防止内存爆炸攻击
  • 编解码一致性高PayloadCompression.STREAM_CODEC 统一替换了 5 个 payload 类的 ByteBufCodecs.BYTE_ARRAY(RpcPayload、RpcRequestPayload、RpcResponsePayload、SyncPayload、LazySyncPayload)
  • 网络版本正确升级:RPC v1→v2、Sync v1→v2——压缩信封改变了 wire format,版本升级防止旧客户端误解析
  • modules.json 依赖整理:network 模块从无依赖改为依赖 configAnvilLibNetworkServerConfig 使用 ConfigManager),module 顺序重新排版更清晰
  • anvillib.needRunConfig 迁移完整:从 registrum/wheel 正确转移到 network/recipe
  • 接口重命名完整性:无 IFluidHandler / 旧 ResourceLocation / builtInRegistryHolder 等旧 API 残留
  • LZ4 依赖管理正确at.yawk.lz4:lz4-java:1.10.1 通过 jarJar(implementation(...)) 打入发布包
  • Config 依赖分发正确build.gradle 中开发时用 project 引用,CI 时用 latest.release

由 Hermes Agent 审查

- 修复了默认压缩算法的提示文本,将默认值从 ZSTD 更正为 LZ4
@Gugle2308

Copy link
Copy Markdown

🌿 Roseau API Breaking Change Report

Module Status Breaking Changes
codec ✅ Compatible 0
collision ✅ Compatible 0
config ✅ Compatible 0
integration ✅ Compatible 0
moveable-entity-block ✅ Compatible 0
network ✅ Compatible 0
rendering ✅ Compatible 0
space-select ✅ Compatible 0
font ✅ Compatible 0
util ✅ Compatible 0
explosion ✅ Compatible 0
rpc ✅ Compatible 0
multiblock ✅ Compatible 0
recipe ✅ Compatible 0
registrum ✅ Compatible 0
sync ✅ Compatible 0
wheel ✅ Compatible 0
main ✅ Compatible 0

Full CSVs: see the Artifacts section of this workflow run.

@Gugle2308

Copy link
Copy Markdown

8 个 No newline at end of file 标记:其中 4 个来自已删除的旧文件(registrum 和 wheel 的旧 anvillib 命名空间 en_us.json),这些可忽略。剩余 4 个来自新增文件:module.network/en_us.json(生成)、module.recipe/en_us.json(生成)、module.recipe/zh_cn.json(手动)、module.multiblock/zh_cn.json(修改)。建议数据生成器侧修复 EOF newline。

TODO/FIXME/HACK — 代码干净 ✅


总结:本 PR 功能完备、架构清晰。PayloadCompression 的编解码逻辑严谨,安全边界考虑充分,各模块的 StreamCodec 替换一致性良好。无阻塞性问题,发布为 评论 级别。

❤️ 好的,已自动输出到 PR 评论区。

@Gu-ZT Gu-ZT closed this Jul 12, 2026
@Gugle2308

Copy link
Copy Markdown

PR #80 的操作是 closed,根据审查流程步骤 0:

"closed" / "labeled"停止,不发评论

因此跳过审查,不发布任何评论。

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