Skip to content

XMC: use packet-framed configuration stream by default#6487

Open
spr334-a wants to merge 5 commits into
XTLS:mainfrom
spr334-a:agent/xmc-packet-stream
Open

XMC: use packet-framed configuration stream by default#6487
spr334-a wants to merge 5 commits into
XTLS:mainfrom
spr334-a:agent/xmc-packet-stream

Conversation

@spr334-a

@spr334-a spr334-a commented Jul 13, 2026

Copy link
Copy Markdown

Summary

Make packet-framed XMC the default transport behavior. XMC now completes Login, remains in Configuration state, carries proxy bytes in xmc:data custom payload packets, and exchanges Minecraft Configuration Keep Alive packets.

The user-facing mode setting and the raw post-encryption path have been removed. This is wire-incompatible with the previous XMC behavior, so both endpoints must be updated together.

This also fixes bounded packet parsing, partial CFB8 writes, n+EOF reads, offline UUIDv3 generation, random-source handling, and shared-secret validation.

This intentionally does not emit version-specific Play or Chunk Data packets.

Validation

  • go test -count=20 ./transport/internet/finalmask/xmc
  • go test ./transport/internet/finalmask/...
  • go test ./infra/conf -run '^$'
  • go vet ./transport/internet/finalmask/xmc ./transport/internet/finalmask
  • go build ./main

@Fangliding

Copy link
Copy Markdown
Member

额 这和之前的模式区别是什么

@spr334-a

Copy link
Copy Markdown
Author

额 这和之前的模式区别是什么

之前的 raw 模式只在前面完成 MC 握手和加密协商,之后就直接传输上层字节流,不再按 MC 数据包格式封装。
新增的 packet 模式会继续完成 Login Success / Login Acknowledged,停留在 Configuration 状态,将数据分片放进合法的 custom_payload 包,并使用 MC Keep Alive

@spr334-a

Copy link
Copy Markdown
Author

后续可以再完整进入 Play 阶段:服务端下行的大流量使用合法的 Chunk Data 承载,客户端上行继续使用 Play custom_payload,心跳切换为 Play Keep Alive。由于 Registry 和 Chunk 格式与 MC 版本强相关,建议拆成后续独立 PR。

@Exclude0122

Copy link
Copy Markdown
Contributor

我觉得没必要,因为开启加密以后 中间人看不出来发的是不是真 mc 包。可能有时序和包大小问题,不过现阶段我觉得不会有专门检测这个的

@spr334-a

Copy link
Copy Markdown
Author

我觉得没必要,因为开启加密以后 中间人看不出来发的是不是真 mc 包。可能有时序和包大小问题,不过现阶段我觉得不会有专门检测这个的

AES/CFB8 开启后确实无法解析 Packet ID 和 Payload,这点认同。但 raw 模式会在 Encryption Response 后立即进入任意字节流,缺少正常 MC 会话中的 Login Success、Configuration、Play 等阶段。虽然状态本身不可见,这些阶段产生的方向、首包大小、间隔和后续流量分布仍然可以统计。
后续补充Play/Chunk 模式的主要价值不是让中间人解析出合法 Chunk ID,而是让加密后的流量形态更接近正常游戏:完成阶段转换,下行以较大的区块数据突发为主,上行保持较小的控制数据。合法包结构更多是为了保证实现一致性;对被动识别真正有意义的是长度和时序整形。

Refactor Varint readFrom and writeTo methods to use constants for segment and continue bits.
@RPRX

RPRX commented Jul 16, 2026

Copy link
Copy Markdown
Member

弄成默认的,别加 mode 参数,Finalmask 的东西随便 break

@spr334-a spr334-a changed the title XMC: add packet-framed configuration stream mode XMC: use packet-framed configuration stream by default Jul 17, 2026
@Exclude0122

Copy link
Copy Markdown
Contributor

我觉得没必要改

这是原版 mc 的登陆流程,只有完整实现了这些包才有意义,不然还是有包大小特征。最好是写一个 mod,用真 mc 客户端连接 mc 真服务器,然后用 Plugin channels 传输流量

@@ -229,7 +274,7 @@ func (c *clientConn) SetWriteDeadline(t time.Time) error {
}

func generateOfflineUUID(uuid *UUID, username string) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

正版玩家的 UUID 必须要调用 mojang API 获取,所以最好把 UUID 放到配置里让用户填

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

正版玩家的UUID必须要调用mojang API获取,所以最好把UUID放到配置里让用户填写

单独配置 UUID 还需要认证结果及用户名,皮肤等数据保持一致,完整的正版登录比离线登录复杂,不如就用离线登录

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

离线登陆不能开启加密 😅

@spr334-a spr334-a Jul 17, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

离线登陆不能开启加密 😅

1.20.5 之后,MC 协议本身支持离线模式加密,只是原版服务端没有提供这个开关(离线加密的话Should Authenticate还要改成false)

@Exclude0122 Exclude0122 Jul 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

原版服务端不支持,但是 xmc 支持,这不就是最大的特征吗

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

那我还是按你说的来改吧🤔

}

propertyCount := Varint(0)
if err = writePacket(c.writer, 0x02, &uuid, &username, &propertyCount); err != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

原版服务器会在这个包里下发玩家皮肤的贴图,所以包长度不一样

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

原版服务器会在这个包里下发玩家皮肤的贴图,所以包长度不一样

properties 为空是合法的,客户端会根据 UUID 使用默认皮肤

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

但是这个包的长度就和原版不一样了,伪装了个寂寞

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

还有原版默认开启压缩,xmc 没有实现压缩,也会导致包长度不一样

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

还有原版默认开启压缩,xmc 没有实现压缩,也会导致包长度不一样

这个应该不用管,本来就可以关掉

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

但是这个包的长度就和原版不一样了,伪装了个寂寞

这个符合离线玩家的资料

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

这个应该不用管,本来就可以关掉

压缩默认开启,绝大部分服务器都开压缩,不开就是特征

这个符合离线玩家的资料

开启加密就意味着是正版模式,哪来的离线玩家

@RPRX

RPRX commented Jul 17, 2026

Copy link
Copy Markdown
Member

你们再讨论一下吧,总之就是要尽量像,代码没什么不能改的

@Exclude0122

Copy link
Copy Markdown
Contributor
image

登录阶段这么多包,不可能实现完的,而且只要有一点偏差就是特征。所以还不如写一个 mod 简单

@RPRX

RPRX commented Jul 17, 2026

Copy link
Copy Markdown
Member

那写个 padding 机制吧,可配置长度范围以及包的方向,两端配置一样,因为要检查对端有没有发完这个包,收完再发自己的

@spr334-a

Copy link
Copy Markdown
Author

那写个 padding 机制吧,可配置长度范围以及包的方向,两端配置一样,因为要检查对端有没有发完这个包,收完再发自己的

可以

@Exclude0122

Copy link
Copy Markdown
Contributor

可以用 vless xtls vision 吗?

@spr334-a

Copy link
Copy Markdown
Author

按上面说的补了 padding 机制,参考原版 26.1.2 登录流程,按长度范围和包的方向收完再发,目前模拟到 player_loaded

@RPRX

RPRX commented Jul 20, 2026

Copy link
Copy Markdown
Member

其实我的意思本来是让配置项加个数组可以自定义这些东西,不过你加了预设模板那也留着吧,此外要开放配置数组自定义

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.

4 participants