mirror of
https://github.com/layue13/MoonBridge.git
synced 2026-10-26 19:03:49 +00:00
refactor: 并掉 proxy-core 中只有一个类的包
- core.relay.RawRelay → core.session.play(PLAY 数据通路) - core.net.NetworkTransport → core.session.channel(与后端拨号同处) - core.forwarding.BungeeLegacyForwarding → core.auth - core.permission.PermissionService → core.event(会话调用插件运行时的端口) 纯内部移动,不影响插件 API;测试随类移动,文档与 CLAUDE.md 同步。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GGL9BudzWm4dUQgBsQw4Qr
This commit is contained in:
32 files changed
+36
-43
No files matched your search
@@ -32,7 +32,7 @@ The slow tests are the session integration tests (`ProxySessionListenerTest`, `S
|
||||
|
||||
**Session threading.** `ProxySessionListener` owns the listener, event loops and the UUID→session index. Each `Session` (one per player connection) confines its mutable state to the frontend event loop, and its backend channels are created on that same loop (`SessionChannels.backendBootstrap` enforces it). Login verification, backend DNS and plugin callbacks run off that loop and re-enter it by posting a task; results are checked against the current connection identity so a stale async result cannot act on a reconnected player. Plugin work goes through bounded pools that reject when full.
|
||||
|
||||
**Session layout.** `core.session` holds `Session` (the Netty handler and lifecycle owner) plus the pieces it delegates to: `FrontendLogin` (handshake, status, encryption, Mojang verification), `InitialRouter` (placement decision and first backend dial), `BackendHandshakes`. `core.session.transfer` is `TransferCoordinator`, which reaches the session only through the `TransferHost` port (Session supplies it as an adapter) and owns all transfer state. `core.session.play` has the per-frame PLAY handlers and relay start-up buffering; `core.session.channel` has backend dialing, pipeline lookups and `clientAddress` (the player IP: a trusted forwarded address or the socket peer; use it instead of `remoteAddress()`). `core.websocket` is the optional WebSocket frontend; after the upgrade the pipeline behind `WebSocketFrameAdapter` is the same as for TCP. Dependencies point one way: `session` -> `transfer` -> `play`/`channel`.
|
||||
**Session layout.** `core.session` holds `Session` (the Netty handler and lifecycle owner) plus the pieces it delegates to: `FrontendLogin` (handshake, status, encryption, Mojang verification), `InitialRouter` (placement decision and first backend dial), `BackendHandshakes`. `core.session.transfer` is `TransferCoordinator`, which reaches the session only through the `TransferHost` port (Session supplies it as an adapter) and owns all transfer state. `core.session.play` has the PLAY data path (`RawRelay`, the per-frame handlers, relay start-up buffering); `core.session.channel` has `NetworkTransport`, backend dialing, pipeline lookups and `clientAddress` (the player IP: a trusted forwarded address or the socket peer; use it instead of `remoteAddress()`). `core.websocket` is the optional WebSocket frontend; after the upgrade the pipeline behind `WebSocketFrameAdapter` is the same as for TCP. Dependencies point one way: `session` -> `transfer` -> `play`/`channel`.
|
||||
|
||||
**Data path.** After login, `RawRelay` forwards already-framed PLAY frames between the two channels without copying. Per-frame concerns are separate inbound handlers (`KeepAliveBridge`, `PlayerCommandInterceptor`, `TabCompletionBridge`, `TransferFrameHandler`) in front of the relay. Backpressure works by pausing reads on the source when the peer is not writable; the relay flushes once per read batch (`channelReadComplete`).
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ public final class ProxySessionBenchmark {
|
||||
int commandInterceptor = intArg(args, "command-interceptor", 1);
|
||||
int burst = intArg(args, "burst", 1);
|
||||
String mode = modeArg(args);
|
||||
var transport = dev.moonbridge.core.net.NetworkTransport.select(
|
||||
dev.moonbridge.core.net.NetworkTransport.Preference.valueOf(
|
||||
var transport = dev.moonbridge.core.session.channel.NetworkTransport.select(
|
||||
dev.moonbridge.core.session.channel.NetworkTransport.Preference.valueOf(
|
||||
stringArg(args, "transport", "auto").toUpperCase(java.util.Locale.ROOT)));
|
||||
boolean afterTransfer = mode.equals("post-transfer");
|
||||
if (connections < 1 || connections > 32 || messages < 1 || messages > 100_000
|
||||
|
||||
@@ -5,7 +5,7 @@ import dev.moonbridge.core.session.play.KeepAliveBridge;
|
||||
import dev.moonbridge.core.protocol.MinecraftFrameDecoder;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import dev.moonbridge.core.protocol.ProtocolVarInt;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
@@ -30,7 +30,7 @@ flowchart LR
|
||||
F --> G[PLAY / Forge 握手与转发]
|
||||
```
|
||||
|
||||
普通转发沿用协议 5 帧边界,不重新编码普通帧;同一次 socket 读取解码出的帧逐个写入对端,在读取完成时合并为一次 flush,读取之外转发的帧由每批一次的事件循环任务补发 flush。前后端通道绑定同一 Netty EventLoop,会话控制状态在该循环串行变更。Keep Alive ID 由代理转换并跟踪未完成请求;必要的玩家实体 ID 数据包在转服后改写。通道不可写时通过暂停对端读取施加背压。实现见 [`Session`](../proxy-core/src/main/java/dev/moonbridge/core/session/Session.java)、[`RawRelay`](../proxy-core/src/main/java/dev/moonbridge/core/relay/RawRelay.java) 与 [`KeepAliveBridge`](../proxy-core/src/main/java/dev/moonbridge/core/session/play/KeepAliveBridge.java)。
|
||||
普通转发沿用协议 5 帧边界,不重新编码普通帧;同一次 socket 读取解码出的帧逐个写入对端,在读取完成时合并为一次 flush,读取之外转发的帧由每批一次的事件循环任务补发 flush。前后端通道绑定同一 Netty EventLoop,会话控制状态在该循环串行变更。Keep Alive ID 由代理转换并跟踪未完成请求;必要的玩家实体 ID 数据包在转服后改写。通道不可写时通过暂停对端读取施加背压。实现见 [`Session`](../proxy-core/src/main/java/dev/moonbridge/core/session/Session.java)、[`RawRelay`](../proxy-core/src/main/java/dev/moonbridge/core/session/play/RawRelay.java) 与 [`KeepAliveBridge`](../proxy-core/src/main/java/dev/moonbridge/core/session/play/KeepAliveBridge.java)。
|
||||
|
||||
## 后端目录与发现所有权
|
||||
|
||||
@@ -69,10 +69,11 @@ flowchart LR
|
||||
|---|---|
|
||||
| `core.session` | `ProxySessionListener`(监听与会话索引);`Session`(每个玩家连接一个,Netty handler 与生命周期)及其委托:`FrontendLogin`(握手、状态、加密、Mojang 验证)、`InitialRouter`(放置决策与首个后端拨号)、`ClientControl`(代发聊天与有序断开)、`BackendHandshakes` |
|
||||
| `core.session.transfer` | `TransferCoordinator` 转服状态机,经 `TransferHost` 接口读取会话状态,自己持有全部转服状态 |
|
||||
| `core.session.play` | PLAY 阶段逐帧 handler(Keep Alive、命令拦截、Tab 补全)与中继启动缓冲 |
|
||||
| `core.session.channel` | 后端拨号、pipeline 查找辅助与玩家地址(`clientAddress`) |
|
||||
| `core.session.play` | PLAY 阶段数据通路:`RawRelay` 帧转发热路径、逐帧 handler(Keep Alive、命令拦截、Tab 补全)与中继启动缓冲 |
|
||||
| `core.session.channel` | `NetworkTransport`(epoll/kqueue/NIO 选择)、后端拨号、pipeline 查找辅助与玩家地址(`clientAddress`) |
|
||||
| `core.websocket` | WebSocket 前端:升级、可信代理真实 IP(`ClientAddressPolicy`)、二进制消息与字节流互转;不依赖 `session` |
|
||||
| `core.relay` | `RawRelay` 帧转发热路径 |
|
||||
| `core.auth` | 在线认证与加密、Mojang 会话验证、Bungee 旧版身份转发(`BungeeLegacyForwarding`) |
|
||||
| `core.event` | 会话调用插件运行时的端口:`EventDispatcher`、转服准备、`PermissionService` |
|
||||
| `core.plugin` | `PluginHost` 生命周期,分出 `EventRouter`、`CommandService`、`PlacementService`、`PluginContextImpl` |
|
||||
| `core.control` | 后端控制通道:`BackendControlService` 接入,`LeaseRegistry`、`InboundRouter`、`BackendExchange`、`OutboundWriter` |
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.moonbridge.app;
|
||||
|
||||
import dev.moonbridge.core.net.NetworkTransport;
|
||||
import dev.moonbridge.core.session.channel.NetworkTransport;
|
||||
import dev.moonbridge.core.backend.InMemoryBackendCatalog;
|
||||
import dev.moonbridge.core.control.BackendControlService;
|
||||
import dev.moonbridge.core.auth.MojangSessionVerifier;
|
||||
|
||||
+1
-3
@@ -1,11 +1,9 @@
|
||||
package dev.moonbridge.core.forwarding;
|
||||
package dev.moonbridge.core.auth;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import dev.moonbridge.core.auth.ProfileProperty;
|
||||
import dev.moonbridge.core.auth.VerifiedProfile;
|
||||
import dev.moonbridge.core.protocol.MinecraftHandshake;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.moonbridge.core.permission;
|
||||
package dev.moonbridge.core.event;
|
||||
|
||||
import dev.moonbridge.api.PlayerIdentity;
|
||||
import dev.moonbridge.api.PlayerView;
|
||||
@@ -13,7 +13,7 @@ import dev.moonbridge.api.Players;
|
||||
import dev.moonbridge.api.Plugin;
|
||||
import dev.moonbridge.api.permission.PermissionResult;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import dev.moonbridge.core.permission.PermissionService;
|
||||
import dev.moonbridge.core.event.PermissionService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package dev.moonbridge.core.plugin;
|
||||
import dev.moonbridge.messaging.internal.LocalMessaging;
|
||||
import dev.moonbridge.api.Players;
|
||||
import dev.moonbridge.core.backend.BackendCatalog;
|
||||
import dev.moonbridge.core.permission.PermissionService;
|
||||
import dev.moonbridge.core.event.PermissionService;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import dev.moonbridge.core.backend.BackendCatalog;
|
||||
import dev.moonbridge.core.backend.BackendOwner;
|
||||
import dev.moonbridge.core.control.BackendChannelTransport;
|
||||
import dev.moonbridge.core.event.EventDispatcher;
|
||||
import dev.moonbridge.core.permission.PermissionService;
|
||||
import dev.moonbridge.core.event.PermissionService;
|
||||
import dev.moonbridge.core.event.TransferPreparation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -3,7 +3,7 @@ package dev.moonbridge.core.session;
|
||||
import dev.moonbridge.core.session.channel.SessionChannels;
|
||||
import dev.moonbridge.api.PlayerIdentity;
|
||||
import dev.moonbridge.core.auth.VerifiedProfile;
|
||||
import dev.moonbridge.core.forwarding.BungeeLegacyForwarding;
|
||||
import dev.moonbridge.core.auth.BungeeLegacyForwarding;
|
||||
import dev.moonbridge.core.protocol.MinecraftHandshake;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import dev.moonbridge.messaging.session.ForwardedSessionProof;
|
||||
|
||||
@@ -5,7 +5,7 @@ import dev.moonbridge.api.MessageResult;
|
||||
import dev.moonbridge.core.protocol.Minecraft1710PlayPackets;
|
||||
import dev.moonbridge.core.protocol.MinecraftLoginDisconnect;
|
||||
import dev.moonbridge.core.protocol.MinecraftText;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
@@ -10,7 +10,7 @@ import dev.moonbridge.api.event.ConnectionAdmissionEvent;
|
||||
import dev.moonbridge.api.event.PlayerDisconnectedEvent;
|
||||
import dev.moonbridge.api.event.ServerConnectedEvent;
|
||||
import dev.moonbridge.core.event.EventDispatcher;
|
||||
import dev.moonbridge.core.permission.PermissionService;
|
||||
import dev.moonbridge.core.event.PermissionService;
|
||||
import dev.moonbridge.api.PlayerIdentity;
|
||||
import dev.moonbridge.api.PlayerView;
|
||||
import dev.moonbridge.api.MessageResult;
|
||||
@@ -21,7 +21,7 @@ import dev.moonbridge.api.TransferStatus;
|
||||
import dev.moonbridge.core.auth.MinecraftEncryptionRequest;
|
||||
import dev.moonbridge.core.auth.SessionVerifier;
|
||||
import dev.moonbridge.core.backend.BackendCatalog;
|
||||
import dev.moonbridge.core.net.NetworkTransport;
|
||||
import dev.moonbridge.core.session.channel.NetworkTransport;
|
||||
import dev.moonbridge.core.protocol.ServerListStatus;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
@@ -25,10 +25,10 @@ import dev.moonbridge.core.protocol.LoginStart;
|
||||
import dev.moonbridge.core.protocol.MinecraftLoginSuccess;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import dev.moonbridge.core.protocol.ProtocolVarInt;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import dev.moonbridge.core.backend.BackendCatalog;
|
||||
import dev.moonbridge.core.event.TransferPreparation;
|
||||
import dev.moonbridge.core.net.NetworkTransport;
|
||||
import dev.moonbridge.core.session.channel.NetworkTransport;
|
||||
import io.netty.resolver.AddressResolverGroup;
|
||||
import java.util.function.BiConsumer;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.moonbridge.core.net;
|
||||
package dev.moonbridge.core.session.channel;
|
||||
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.IoEventLoop;
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.moonbridge.core.session.channel;
|
||||
|
||||
import dev.moonbridge.core.net.NetworkTransport;
|
||||
import dev.moonbridge.core.protocol.MinecraftFrameDecoder;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.moonbridge.core.session.play;
|
||||
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.moonbridge.core.relay;
|
||||
package dev.moonbridge.core.session.play;
|
||||
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.moonbridge.core.session.play;
|
||||
|
||||
import dev.moonbridge.core.protocol.MinecraftTabCompletion;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
@@ -4,7 +4,7 @@ import dev.moonbridge.api.TransferResult;
|
||||
import dev.moonbridge.api.event.TransferContext;
|
||||
import dev.moonbridge.core.backend.BackendView;
|
||||
import dev.moonbridge.core.event.TransferPreparation;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import dev.moonbridge.core.protocol.ByteBufs;
|
||||
import dev.moonbridge.core.protocol.LoginStart;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import dev.moonbridge.core.protocol.Minecraft1710PlayPackets;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import dev.moonbridge.core.session.channel.SessionChannels;
|
||||
import dev.moonbridge.core.session.play.KeepAliveBridge;
|
||||
import dev.moonbridge.core.session.play.PlayObservation;
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import dev.moonbridge.core.protocol.Minecraft1710EntityIds;
|
||||
import dev.moonbridge.core.protocol.Minecraft1710PlayPackets;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import dev.moonbridge.core.protocol.ProtocolVarInt;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
@@ -5,8 +5,8 @@ import dev.moonbridge.api.PlayerView;
|
||||
import dev.moonbridge.core.backend.BackendCatalog;
|
||||
import dev.moonbridge.core.backend.BackendView;
|
||||
import dev.moonbridge.core.event.TransferPreparation;
|
||||
import dev.moonbridge.core.net.NetworkTransport;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.channel.NetworkTransport;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import dev.moonbridge.core.session.play.KeepAliveBridge;
|
||||
import dev.moonbridge.core.session.play.PlayObservation;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
package dev.moonbridge.core.forwarding;
|
||||
package dev.moonbridge.core.auth;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import dev.moonbridge.core.auth.ProfileProperty;
|
||||
import dev.moonbridge.core.auth.VerifiedProfile;
|
||||
import dev.moonbridge.core.protocol.MinecraftHandshake;
|
||||
import dev.moonbridge.core.protocol.ProtocolProfile;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.moonbridge.core.permission;
|
||||
package dev.moonbridge.core.event;
|
||||
|
||||
import dev.moonbridge.api.PlayerIdentity;
|
||||
import dev.moonbridge.api.PlayerView;
|
||||
@@ -14,7 +14,7 @@ import dev.moonbridge.core.backend.BackendOwner;
|
||||
import dev.moonbridge.core.backend.BackendRegistration;
|
||||
import dev.moonbridge.core.backend.InMemoryBackendCatalog;
|
||||
import dev.moonbridge.core.event.EventDispatcher;
|
||||
import dev.moonbridge.core.permission.PermissionService;
|
||||
import dev.moonbridge.core.event.PermissionService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
@@ -2384,7 +2384,7 @@ final class ProxySessionListenerTest {
|
||||
backendDone.get(5, TimeUnit.SECONDS);
|
||||
var relayField = Session.class.getDeclaredField("relay");
|
||||
relayField.setAccessible(true);
|
||||
var relay = (dev.moonbridge.core.relay.RawRelay.Link) relayField.get(session);
|
||||
var relay = (dev.moonbridge.core.session.play.RawRelay.Link) relayField.get(session);
|
||||
assertTrue(relay.hasPendingClientboundWrites());
|
||||
backendChannel.eventLoop().submit(() -> backendChannel.pipeline()
|
||||
.fireExceptionCaught(new IOException("backend read failed"))).get(5, TimeUnit.SECONDS);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.moonbridge.core.net;
|
||||
package dev.moonbridge.core.session.channel;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.moonbridge.core.session.play;
|
||||
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.moonbridge.core.relay;
|
||||
package dev.moonbridge.core.session.play;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.moonbridge.core.relay;
|
||||
package dev.moonbridge.core.session.play;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
+1
-1
@@ -4,7 +4,7 @@ import dev.moonbridge.core.session.play.PlayObservation;
|
||||
|
||||
import dev.moonbridge.core.protocol.Minecraft1710PlayPackets;
|
||||
import dev.moonbridge.core.protocol.ProtocolVarInt;
|
||||
import dev.moonbridge.core.relay.RawRelay;
|
||||
import dev.moonbridge.core.session.play.RawRelay;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
Reference in new issue
Block a user