使用 Fabric Loom 1.16.1 + Mojang 官方映射反编译的 Minecraft 26.2-snapshot-7 源码,共 7058 个 Java 文件。
minecraft-src/
├── com/mojang/blaze3d/ # 渲染引擎 (Blaze3D)
├── com/mojang/math/ # 数学工具
├── com/mojang/realmsclient/ # Realms 客户端
└── net/minecraft/
├── advancements/ # 进度系统
├── client/ # 客户端逻辑 (Minecraft.java 2979行)
├── commands/ # 命令系统
├── core/ # 核心注册/ID系统
├── data/ # 数据生成器
├── gametest/ # 游戏测试框架
├── gizmos/ # 调试工具
├── nbt/ # NBT 数据格式
├── network/ # 网络协议
├── server/ # 服务端逻辑 (MinecraftServer.java 2406行)
├── stats/ # 统计系统
├── tags/ # 标签系统
├── util/ # 工具类
└── world/ # 世界/方块/实体/物品
26.2-snapshot-7 新增的 Friends 联机功能基于 WebRTC P2P 架构,无需端口转发即可让好友直连加入游戏。
| 文件 | 路径 | 职责 |
|---|---|---|
P2PManager | net/minecraft/client/multiplayer/p2p/ | 顶层管理器,协调信令/加入/握手 |
FriendJoinHandler | 同上 | 处理好友加入请求/接受/拒绝 |
RtcHandshakeHandler | 同上 | WebRTC SDP/ICE 握手 |
SignalingServiceClient | p2p/client/ | 信令服务器 WebSocket 客户端 |
JsonRpcClient | 同上 | JSON-RPC over WebSocket 通信层 |
SignalingMessage | p2p/ | 信令消息协议定义 |
RtcHandshake | net/minecraft/client/network/webrtc/ | WebRTC 连接建立 |
RtcChannel | 同上 | WebRTC → Netty Channel 适配层 |
Guest (加入方) Signaling Server Host (开服方)
│ │ │
① joinPlayer() │ │
├──── JOIN_REQUEST ───────────────►│──── 转发 ───────────────────────►│
│ │ ② 弹出好友加入 Toast
│ │ (检查 isFriendsPmid)
│ │ │
│ │◄──── JOIN_ACCEPTED ─────────────┤
◄──── JOIN_ACCEPTED ◄─────────────┤ ③ acceptIncomingJoinRequest
④ startHandshake() │ │
├──── OFFER (SDP) ────────────────►│──── 转发 ───────────────────────►│
│ │ ⑤ acceptOffer → ANSWER
│◄──── ANSWER (SDP) ◄──────────────┤◄──── ANSWER (SDP) ──────────────┤
│ │ │
◄──── ICE_CANDIDATE ──────────────►│◄──── ICE_CANDIDATE ─────────────►│
│ │ ⑥ ICE 连接建立
│ │ │
⑦ joinHost() │ acceptGuest()
(通过 RtcChannel 连入) │ (通过 RtcChannel 接入)
① 加入请求:Guest 调用 P2PManager.joinPlayer(peerPmid),通过信令服务器发送 JOIN_REQUEST(含 sessionId)。
② 好友验证:Host 收到请求后,检查发送者是否为好友(PlayerSocialManager.isFriendsPmid())。若好友已发送邀请则自动接受,否则弹出 FriendToast 请求用户确认。
③ 接受加入:Host 调用 acceptIncomingJoinRequest(),回复 JOIN_ACCEPTED,同时将 sessionId 记入 acceptedAwaitingOffer 防止伪造 Offer。
④⑤ SDP 交换:Guest 收到 Accepted 后发起 WebRTC 握手——创建 Offer SDP 发给 Host,Host 调用 acceptOffer() 生成 Answer SDP 回复。使用 Trickle ICE,SDP 设置本地描述后立即发送,ICE 候选单独递送。
⑥ ICE 连接:双方通过信令交换 ICE Candidate,WebRTC 尝试建立 P2P 直连;若直连失败,则通过 TURN 服务器中继。
⑦ 游戏接入:DataChannel 打开后,RtcHandshake 产生 HandshakeResult:
joinHost() 创建 RtcChannel → 包装为 Netty Connection → 发送 ServerboundHelloPacket → 进入正常 Minecraft 登录协议acceptGuest() 调用 server.getConnection().acceptChannel() → 复用现有登录处理逻辑signaling-afd.franchise.minecraft-services.net(生产环境)x-mojangauth Header 传入 Xbox Access TokenSystem_Ping_v1_0Signaling_SendClientMessage_v1_0 — 发送消息给指定玩家Signaling_ReceiveMessage_v1_0 — 接收消息(服务器主动推送)Signaling_TurnAuth_v1_0 — 获取 TURN 服务器凭据Signaling_TurnAuth_v1_0 下发 TURN 服务器列表(含 username/password/urls)disableTcp=true、enableIpv6=true、enableIpv6OnWifi=trueminecraftordered=truemaxRetransmits=-1(无限重传,类似 TCP)priority=HIGHRtcChannel 继承 Netty AbstractChannel,将 WebRTC DataChannel 适配为标准 Netty Channel,使游戏网络层完全无感:
onMessage → ByteBuf → pipeline.fireChannelRead()doWrite → ByteBuf 分片(最大 256KB)→ dataChannel.send()bufferedAmount ≥ 1MB 暂停写,≤ 256KB 恢复attr(Connection.SECURE_TRANSPORT).set(true)(DTLS 加密)PlayerSocialManager.isFriendsPmid(fromPmid),非好友请求被静默忽略isInvitedPmid)自动接受,无需手动确认teardownHostState())acceptedAwaitingOffer 防止未授权的 Offer 注入CachedSignalingUri)CachedTurn)SignalingMessage
├── Type: JOIN_REQUEST | JOIN_ACCEPTED | JOIN_REJECTED | INVITE_DECLINED
│ | OFFER | ANSWER | ICE_CANDIDATE
├── FriendJoin (应用层)
│ ├── Request(sessionId)
│ ├── Accepted(sessionId)
│ ├── Rejected(sessionId)
│ └── InviteDeclined()
└── WebRtc (WebRTC SDP/ICE)
├── Offer(sessionId, sdp)
├── Answer(sessionId, sdp)
└── IceCandidate(sessionId, candidate)
P2P 连接结果通过 P2PTelemetryEvent 上报:
SIGNALING / TIMEOUT / ICE_CONNECTHOST / SRFLX / RELAY / PRFLXexport JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
./gradlew genSources --no-daemon --init-script /workspace/.gradle/init.gradle