Commit Graph
23 Commits
Author SHA1 Message Date
layue13andClaude Opus 5.5 b7d6497ca8 perf: WebSocket 经 CDN:wss 改用 BoringSSL、保活 Ping、整合包形态基准
- ProxySessionBenchmark 新增 --profile modded(仿大型整合包的双向包组与 2 MiB 登录突发,逐字节校验)、
  --websocket-tls 1(keytool 一次性证书的 wss)和 --client-coalesce 1。
- wss 监听改用随包附带的 BoringSSL(netty-tcnative-boringssl-static 2.0.84):TLS 占 wss 代理 I/O CPU 的 55%,
  换用后每帧 CPU 在每一对配对测量中都更低(窗口 1 -22%,窗口 8 -36%),帧率 +31%/+34%;其他平台回落 JDK,
  启动日志标明所用实现。jar 由 10.4 MB 增至 16.5 MB。
- 新增 websocket.pingIntervalSeconds(默认 30,0 关闭):升级后代理静默不超过该时长,期间无写出就发空 Ping,
  避免 CDN/负载均衡在安静的登录、选服阶段按空闲超时断开。IdleStateHandler 版本在窗口 8 多耗 7.6% CPU,
  未达规则;改为写时置位标志、每半个间隔检查的实现,JFR 中几乎不可见。
- 文档:WebSocket 接入新增“经 CDN 部署”,更正消息大小描述;记录见
  testing/benchmarks/results/2026-10-23-websocket-cdn.md。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:40:48 +08:00
layue13andClaude Opus 5.5 21a5adf18d perf: WebSocket 出站每次 flush 合并为一条二进制消息
- WebSocketFrameAdapter:flush 前写入的字节用 CoalescingBufferQueue 合并为一条
  BinaryWebSocketFrame,最大 64 KiB。之前每个 Minecraft 帧一条消息,而 Netty 的编码器对
  小于 1 KiB 的消息每条都分配并复制一次。每次写入的 promise 在承载它的消息写出时完成;
  未 flush 的写入在关闭时失败并释放;排队字节计入通道可写性。入站不变
- ProxySessionBenchmark:新增 --websocket 1,代理阶段客户端走 ws://
- 记录 testing/benchmarks/results/2026-10-22-websocket-coalescing:burst32 每帧 CPU 低 21%
  且范围不重叠、吞吐更高;window 1 无变化;window 16 噪声大,补跑 3 对后合计无回退。
  满足事先规则,采用

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:56:00 +08:00
layue13andClaude Opus 5.5 789648c82f refactor: 仓库根目录按用途分组
- proxy/:core、plugin-api、luckperms 及其上游子模块 vendor/luckperms
- messaging/、backend/ 保持在根目录(messaging 是代理与后端共用的 API)
- build-logic/(原 proxy-build-logic)
- testing/:smoke/ 与 benchmarks/,不进入发行物

Gradle 项目名不变(settings.gradle.kts 映射目录),任务路径与 Maven 坐标照旧。
脚本的仓库根定位、文档与记录中的链接同步更新。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 14:34:01 +08:00
Claude d836f6c3d3 build: 统一 release 入口,CI 覆盖客户端 mod,文档同步新结构
- 根任务 release:build/release/ 下收集服务器包、后端插件 JAR 与客户端 mod
  (经 client-mod 自身 wrapper 构建,-PskipClientMod 可跳过),附安装位置说明
  docs/release-layout.md
- verify.yml:-Pluckperms check,并新增 client-mod 构建测试 job;
  ci.yml:-Pluckperms check release,上传 build/release/,发布带 -Pluckperms
- gradlew 加可执行位
- README、CLAUDE.md、架构/发布/测试/权限/后端接入文档与 smoke 脚本改用新模块、
  新坐标与发行包 backend/ 目录

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGL9BudzWm4dUQgBsQw4Qr
2026-10-21 10:13:06 +00:00
Claude 4def198cc0 docs: 修正 CI 引用、拆出历史验证记录并统一中文文档
- CLAUDE.md、testing.md、publishing.md 的 .gitea 路径改为实际的 .github/workflows;
  说明 verify.yml 在 PR 上运行 check
- testing.md 中带日期的逐轮结果迁到 docs/records/
- README 精简为简介、快速开始和入口;配置与迁移细节只保留在 operations.md
- channel-messaging-v2.md 更名为 channel-messaging-contract.md,与 transfer-coordination.md 一起译为中文
- benchmarks/results 中两个记录改为日期前缀命名
- 新增 compileBenchmarks 并挂到 check,防止 benchmarks/ 静默失效
- .gitignore 删除不存在的 deployment/ 条目

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GGL9BudzWm4dUQgBsQw4Qr
2026-10-20 21:06:01 +00:00
Claude 941a499965 Guard the last two Session buffer branches
Session.channelRead releases messages that are not frames of its own
session: anything arriving on a channel that is neither its frontend nor
its backend, and any non-ByteBuf message from either. Neither branch had a
test. SessionFrameOwnershipTest builds a Session directly and checks both,
including that a stray channel does not close the real session; replacing
either release with a no-op makes it fail.

docs/testing.md and docs/operations.md no longer list these as untested.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KcCN2hYyqmU22X2Xfg1nwe
2026-10-06 00:38:09 +00:00
Claude 298fd3c4fc Cover the remaining Session buffer paths with unit-testable helpers
A parallel mutation pass over Session and ConnectionGate (17 sites, three
workers, failures re-run to rule out load-induced flakiness) left five
sites unguarded. Three of them were buffer handling that only integration
tests reached, so it moves into small classes with direct tests:
TransitionFrames (mapping buffered start-up frames and appending the
rewritten opening packets) and TransitionBuffer (the bounded queue that
releases what it holds). transferOpening now uses ByteBufs.fill. A
mutation run over the two new classes catches all four of their release
sites.

Two defensive branches in Session stay untested and are listed in
docs/testing.md: a non-ByteBuf message (its input always comes from the
frame decoder) and a message from a channel that is neither side of the
session.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KcCN2hYyqmU22X2Xfg1nwe
2026-10-06 00:03:36 +00:00
Claude 7de33e72aa Disable Netty leak detection in the distribution
The start scripts now pass -Dio.netty.leakDetection.level=disabled; it can
be re-enabled per deployment with JAVA_OPTS. In its place every
proxy-core test class runs under PARANOID detection through LeakGate (298
tests, no leaks).

Session also moves off hand-written releases at the sites a mutation pass
found unguarded: the login-wait guard is now a FrameTransformHandler and
buffered transition frames go through one mapTransitionFrame helper that
releases on every failure. ConnectionGate gets unit tests with a
TrackingAllocator covering every exit path.

The second mutation pass over Session was stopped at 11 of 24 sites, so
about ten Session releases (mainly transferOpening and the disconnect
packet) are not verified by mutation; docs/testing.md says so.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KcCN2hYyqmU22X2Xfg1nwe
2026-10-05 23:26:27 +00:00
Claude 0cf4017567 Select a native network transport automatically
NetworkTransport picks epoll on Linux, kqueue on macOS and NIO
elsewhere, or when the native library cannot load. The player listener,
session event loops, backend dials and the DNS resolver all take their
channel types from the selected transport, so backend channels keep
sharing the player's event loop. A new `transport: AUTO|NIO|EPOLL|KQUEUE`
setting forces one choice; an unavailable native transport fails
startup instead of falling back silently. The event loops move from the
deprecated NioEventLoopGroup to MultiThreadIoEventLoopGroup.

The distribution ships the linux-x86_64/aarch_64 epoll and
osx-x86_64/aarch_64 kqueue natives. The start scripts and tests pass
--enable-native-access=ALL-UNNAMED.

On the loopback session benchmark, epoll beat NIO on every median and
regressed nowhere. Only window-1 p50 latency separated cleanly (0.060 vs
0.070 ms); see benchmarks/results/2026-10-05-network-transport.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KcCN2hYyqmU22X2Xfg1nwe
2026-10-05 21:05:32 +00:00
Claude 90b21a5b88 Flush relayed frames once per read batch
The PLAY relay called writeAndFlush for every decoded frame. With
TCP_NODELAY, a socket read holding many small packets (a typical server
tick) cost one flush, write syscall and TCP segment per frame. Write each
frame and flush the peer on channelReadComplete. A per-batch event-loop
task flushes frames forwarded outside a socket read, such as delayed tab
completion. Paused-frame replay keeps writeAndFlush.

ProxySessionBenchmark gains --burst plus proxy I/O CPU and TCP segment
counters. On a 4 vCPU Linux container with 32 x 33-byte frames per write,
TCP segments/frame fell from 1.379 to 0.117 and proxy I/O CPU/frame from
4079 to 1827 ns (medians of six paired phases). The existing 1 KiB window
1 and 16 workloads showed no regression.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KcCN2hYyqmU22X2Xfg1nwe
2026-10-05 20:11:18 +00:00
layue13 7f1980269a Add permissions service and native LuckPerms platform 2026-09-28 01:32:31 +08:00
layue13 8401e34639 Make development publishing traceable and polish operator and plugin docs 2026-09-27 23:43:13 +08:00
layue13 64152878d0 Rename project to MoonBridge and expose standalone Bukkit API 2026-09-27 22:39:16 +08:00
layue13 8c2d35b8be feat: name backend host and verify real Uranium lifecycle 2026-09-27 22:16:21 +08:00
layue13 d0aca24839 Merge main backend channel into messages completion 2026-09-27 17:57:21 +08:00
layue13 230f317d0a feat: replace backend discovery with control channel 2026-09-27 02:52:46 +08:00
layue13 1185ae2b2e feat: add Adventure messages and asynchronous command completion 2026-09-27 00:01:02 +08:00
layue13 7fe2c99d6e docs: record current Forge pack acceptance and paired measurements 2026-09-26 22:39:12 +08:00
layue13 12340e146c Test relay backpressure with real TCP slow readers 2026-09-26 21:58:44 +08:00
layue13 c1399b0ac4 Add player messaging, disconnects, and configurable server status 2026-09-26 10:57:24 +00:00
layue13 ea7852375c Unify event results and clarify player admission 2026-09-26 09:53:31 +00:00
layue13 a74527ca5b Unify plugin access and lifecycle event subscriptions 2026-09-26 09:15:07 +00:00
layue13 3c21a6c2e3 Add asynchronous plugin access checks and architecture docs 2026-09-26 08:39:54 +00:00