本帖最后由 贺兰星辰 于 2020-3-30 10:31 编辑

2020/3/20 注:有一个新的操作,https://github.com/GeyserMC/Geyser 间歇泉,支持到了最新版的基岩版和java版1.15.2,我试了一下,差不多比DragonProxy稳,但还是有其弊端,如果还有人看这个帖子的话我就更新一下233


前言:
    最近有好多圈子里的人问“怎么让基岩版进Java版服务器”或是“怎么让Java版和基岩版互通”这样的问题,因为鄙人恰巧有一段时间一直在研究这一方面的技术,因此今天拿出来跟大家分享一下,如果你觉得这篇帖子对你有一定帮助的话,欢迎评分+回复


目前已经存在的开源项目:
    听说网易或者其他大服自造轮子实现过这类操作,但是我们也不可能拿到那种东西,所以这篇帖子将只讨论已经存在的开源项目。那么目前已有的互通开源项目有两个,分别是:
0.DragonProxy(Proxy):DragonetMC/DragonProxy branch "rewrite"
1.ProtocolSupport(BukkitPlugin):ProtocolSupport/ProtocolSupport branch "mcpenew"
    先说说这俩玩意有何异同点:首先,架构不同,DragonProxy是一套代理,类似于BungeeCord,他通过代理协议向下游服务器发送数据包实现;而ProtocolSupport则是一个Bukkit插件,他在服务端层面拓展了naknet对外进行UDP广播并接受相应的数据包传入以实现。
其次,连接方式设计不同,DragonProxy更偏向于关联你的基岩版账户和你的Java版账户,使你的基岩版游戏进服时实际上是通过Java版账户连接的;而ProtocolSupport则直接继承了来自基岩版的所有数据,包括你的游戏ID,XUID(即Xbox-UUID)(因此这种设计引发了服务端的一大票兼容性问题,下面将会详细论述)
最后,兼容的版本不同,这个是最浅层的了,兼容什么版本取决于作者的代码功底,于是,DragonProxy(截止至目前的最新构建版本)只支持基岩版1.12.0.X连接到Java版1.14.4服务器,而ProtocolSupport(截止至目前的最新构建版本)则支持基岩版1.8.0.X-1.14.0.X(?)连接到Java版1.14.4服务器

好,讲完了异同点,我们来详细讲讲这两个项目具体怎么操作,都有哪些优劣

DragonProxy
测试环境:
服务器环境:
    CPU:E5-2680V2 @2.80Ghz    操作系统:Windows Server 2016
    代理服务端: HotSpot JVM8 内存未指定
    下游服务端(仅参与测试的):[Waterfall]Adopt OpenJDK8-JVM9 512MB
                                                 [Paper1.14.4]Adopt OpenJDK8-JVM9 10240MB
客户端环境:
    手机型号: MI 8 SE 6+64G
    基岩版版本:1.12.0 已登入Xbox Live
    其实这玩意原作者很早就发到过MCBBS里,但是因为其github长期不发布release总让普通服主感觉这玩意已经不更新了,其实作者一直在更新,现在是支持1.12.0.X连接至1.14.4,因为我手机上的基岩版是1.13.0正式版,所以网上找了个破解版1.12.0装上了来测试

首先先看服务端操作
因为DragonProxy作者使用了CodeMC提供的Jenkins CI自动构建,所以我很容易就下载到了最新版本的DragonProxy

下载完成了以后编写CMD并启动代理服务器,可以看到很快就开好了,基本指令只有一个就是stop关闭

关闭服务器,可以看到生成了很多文件,每个文件的意义不言而喻,所以这里我们光看看config.yml
(懒得在贴内一一解释了,就直接贴配置文件代码吧,仅针对部分重要内容进行了汉化)

  1. # -----------------------------------------------
  2. #   DragonProxy 配置文件 (05/08/19)
  3. #   https://github.com/DragonetMC/DragonProxy
  4. #   汉化:贺兰星辰
  5. # -----------------------------------------------

  6. locale: 'EN'

  7. # 代理服务器所需监听(映射到)的IP地址和端口号
  8. # '0.0.0.0' will bind to all IP addresses available on your device
  9. bind-address: '0.0.0.0'
  10. bind-port: 13118

  11. # 基岩版游戏将会看到的MOTD标语
  12. motd: 'DragonProxy'
  13. motd2: 'https://github.com/DragonetMC/DragonProxy'

  14. # 可以加入该代理服务器的最大玩家数
  15. max-players: 100

  16. # 所需要连接到的下游服务器的IP地址和端口号
  17. # TODO: Add support for multiple servers
  18. remote-address: '127.0.0.1'
  19. remote-port: 13108

  20. # TODO
  21. #remote-servers:
  22. #  local:
  23. #    address: '127.0.0.1'
  24. #    port: 25566
  25. #    default: true

  26. # 连接到下游服务器的验证方法.
  27. # 支持的值:
  28. #   credentials   : 连接到代理服务器后将会弹出一个窗口让你输入你的Java版账户密码,验证通过后使用该账户连接下游服务器
  29. #   offline       :  不进行正版验证,无法连接到正版服务器
  30. remote-auth: credentials

  31. # 基岩版客户端是否要求已经登录Xbox Live(即微软账户)?
  32. xbox-auth: true

  33. # 是否应该绕过代理服务器,直接显示下游服务器的MOTD标语和在线玩家数?(功能同BungeeCord的ping-passthrough)
  34. ping-passthrough: true

  35. # 是否从Mojang服务器获取玩家皮肤
  36. fetch-player-skins: true

  37. # 并发线程数.
  38. # Only change if you know what you are doing
  39. thread-pool-size: 8
复制代码
这里我将下游服务器设置成了一个BC服务器,透过BC代理连接到一个Paper子端这里注意一下,基岩版使用的是UDP协议,所以确保你的防火墙没有拦截UDP协议的访问
实际上我这里刚开始登入到服务器时的正版验证流程还是很流畅的,但是连接到下游服务器以后我就注意到很多问题了
0.首先,自你打开这个代理以后,你的下游服务器就将会持续不断的收到来自代理服务器的不同套接字的连接请求(如图)

1.其次,这个玩意目前不支持任何形式的IP转发,也就是说你的子端收到的IP地址永远是你的本地代理服务器地址
2.奇妙的方块贴图问题:进去服务器以后我的基岩版客户端是这个样子的

首先正版皮肤加载出来了可喜可贺
然后就是BOSS血条映射过来了(截图未体现)
然后就什么都没有了
你会发现:出现了奇怪的氧气条;你根本没法移动;头顶上一堆怪物不知道啥情况;仔细看右边,树叶显示出来是基岩???
到此,对DragonProxy的评测结束
可以说这玩意确实还很原始,作者在Github上列的Todo也说明了这么一点
那么,好处是什么呢?其实这个东西因为是代理服务器,所以不需要下游服务器去兼容他,你甚至可以用这个东西去玩Hypixel什么的

那么接下来

ProtocolSupport(较早前测试)

测试环境:
服务器环境:
    CPU:E5-2680V2 @2.80Ghz    操作系统:Windows Server 2016
    服务端(仅参与测试的):[Waterdog]Hotspot JVM8 512MB
                                           [akarin1.13.2]Hotspot JVM8 2048MB
客户端环境:
    手机型号: MI 8 SE 6+64G
    基岩版版本:1.12.0 已登入Xbox Live

    提前说明一下,这个测试我是在今年上半旬进行的测试,当时这个项目只更新到了1.13.2,最高支持基岩版到1.12.0.X,因此和现在不太一样了,仅具有参考意义
    ProtocolSupport这个玩意大家以前应该就听说过,对就是那个跨版本插件,其实他们一直在研究基岩版互通之类的玩意,位于其仓库的mcpenew分支下(截止至发帖日,这个分支似乎停止维护了,作者表示他们将会在另一个地方重构代码?)
    首先,ProtocolSupport(下称PSPE)没有自动官方构建平台(很多老外自己搭了一个,你或许可以去Discord碰碰运气),所以你得自行编译项目
    这是一个Gradle项目,且编译时需要手动置入一份Vanilla服务端(即minecraft_server服务端)以完成编译,完成以后你将会获得一份足足有近30MB的文件

这是一个Bukkit插件,因此将他放入plugins文件夹开服即可
与DragonProxy不同的是,你不需要单独开一个端口给基岩版玩家,基岩版和Java版玩家都可以通过默认的服务器端口进服,因此就很舒服,进服了以后,所有的地方都非常流畅,感觉就和玩基岩版服务器一样,除了......
    0.没有转发皮肤,因此你看别人(基岩版看Java版)有皮肤,别人看你(Java版看基岩版)是史蒂夫,你自己看你自己也是史蒂夫
    1.没有转发BossBar血条
    2.因为1.13神奇的水下更新,在水下游泳很难上岸(咋跳都跳不上去,一直在游泳姿态)
    3.第一次输入指令会卡(奇怪的问题,客户端会卡很长一阵子)
    4.头颅永远是史蒂夫
    5.UUID和玩家ID引起插件强烈不适
        这个实际上是最恶心的,因为按照PSPE的协议,你的玩家名和你的UUID全部继承基岩版的玩家名和XUID,然而这俩玩意都特别鸡肋
             你会发现基岩版的XUID是这个样子的: (左边是我的Java版游戏ID,右边是基岩版游戏ID,全是0打头)
             你会发现基岩版的玩家名可以是“Hello World”这种样子的(可以带空格)
        如果你的基岩版用户名和Java版用户名恰巧相同而且都进过服务器(比如我),那么你的各种插件就会向你诉苦表示UUID不同步(如Luckperms,CMI等);如果对面基岩版用户名带空格,那么结果就不用我说了吧
    6.大箱子被显示为两个末影箱(ProtocolSupport传统)
基本上我遇到的就是这些,其中很多BUG是可以被修复的,具体下面再说

继续更新
账号互通:
那么很显然,我们不希望沙雕网友们东一个账号西一个账号的胡乱注册,然后基岩版一个账号Java版又一个账号,这样不仅数据不互通,而且还很不方便,因此在这里我们就需要这个玩意:
ProtocolSupportAccountsLinkBungee(看名字你就知道了这玩意仅支持BC)将这玩意下载下来,扔到BC的插件文件夹里,重启BC,boom!
你可以叫你的玩家在主账号(比如Java版账号)下输入/accountslink code,服务器会发给玩家一串代码
然后叫你的玩家在子账号(比如基岩版账号)上线,输入.accountslink link [code],轰的一声,子账号的UUID就会同步到主账号上(子账号UUID消失)
是不是很棒呢


兼容性优化:
前面说了很多原生PSPE的BUG,但其实这些BUG有第三方插件修复,那就是
ProtocolSupportStuff
编译起来有点繁琐,需要把你编译好的PSPE扔进指定文件夹里再运行gradle,编译好以后你可以获得一个插件
将这个插件扔进你的Bukkit服务器内,即可看到在plugins/ProtocolSupportStuff生成了config.yml,里面不仅有很多修复选项,也有像是skin.PC_to_PE这种互通优化的功能,因为我手头没文件了所以就不详细讲了

   令群组服服主流泪的进 阶 讨 论
    搞完这个以后我其实有两个感觉
      对于单端腐竹来说:woc,漂亮
      对于群组腐竹来说:淦!
    原因很简单,这是一个Bukkit插件
    你会发现你的BungeeCord根本映射不出去raknet协议请求
    去Discord问了一大圈以后我得到了两个解决方法:
1.使用Waterdog(https://github.com/yesdog/Waterdog
2.使用ProtocolSupportBungee(https://github.com/ProtocolSupport/ProtocolSupportBungee
前者是一个Proxy,fork自Bungeecord,后者是一个Bungee插件
安装好了以后都可以令基岩版玩家透过BungeeCord代理端连接到子端
个人还是偏向于使用前者,很稳定
于是我们来看看前者具体怎么使用
搭建好Waterdog以后,你应该能找到istener.naknet选项,开启以后便可以接受naket协议连接
但是注意了,开了这个以后你的Java版玩家就没法进了
所以你需要创建两个listener,端口不同,一个打开naknet一个关掉,这样的话所有人就都可以进了wwwwwww

Tips:基岩版协议进服很容易导致反作弊误判,本人的解决方法是使用ProtocolSupportAPI提供的isBedrock()方法判断玩家是否为基岩版,如果是的话那么在进服时就给予aac.bypass(AAC权限,其他插件大同小异)权限,退出的时候再撤销(以免有人用基岩版刷bypass,再用Java版作弊)

那么至此,《浅谈Java版与基岩版服务器互通》的内容就全部结束了,如果本帖对你有什么启发的话,欢迎评分+回复哦
[groupid=1511]Server CT[/groupid]