本帖最后由 berry64 于 2018-8-26 00:34 编辑




Chapter 2
CustomPayload, PluginMessage, 以及BC&服务端插件之间的通讯 Part I


一些BC插件的常规操作
嘛,虽然我本人是希望把这个联动通讯放到晚一点再编写的,不过思考了半天讲道理BC插件不与bukkit联动能达到的功能好像都已经有人写了...
不过作为一些基本常规操作还是希望介绍一下


首先是ServerInfoServer这两个类,ServerInfo可以理解成在BungeeCord的config.yml (如果不知道这个是什么建议你去自己开个BC然后看看配置文件) 里面设置的server。

比如这里我拿我自己配置的一个server信息来
  1. lobby:
  2.   motd: '&1Just another BungeeCord - Forced Host'
  3.   address: localhost:25565
  4.   restricted: false
复制代码

可以看到这里有几个信息:
  • 服务器名字 (lobby)
  • 服务器的MOTD (这里是默认)
  • 服务器的ip(localhost)
  • 服务器的端口25565

有了这些信息之后我们就可以做出一些高端操作,比如 获取服务器名字 ServerInfo.getName()  高端你个蛇皮鬼
甚至可以做到获取服务器的玩家 (ServerInfo.getPlayers())
关于这个是怎么做到的:


而在BungeeCord插件编写里要获得这样的数据很简单,比如如果是个ProxiedPlayer玩家就是酱紫玩:
  1. ProxiedPlayer.getServer().getInfo();
复制代码
,如果你有一串String作为服务器名称的话可以利用bungeecord自带的api获取:
  1. BungeeCord.getInstance().getServerInfo(servername);
复制代码
不过使用第二种方法要注意,如果BC没有注册这个名字的服务器,那么会返回null


然后一个基本操作了解一下就可以了:
  1. ProxyPlayer.connect(ServerInfo);
复制代码
这个就是把指定玩家强行转接到另一个服务器, 没有什么高端操作


CustomPayload的起源, PluginMessage以及BC服务端联动的基本概念
Once upon a time ,所有mc客户端与服务端的数据通讯都是在同一串数据里的,作为原版MC这本来并没有什么非常严重的问题,但随着MCP和mod的兴起,客户端与服务端之间的通讯越来越复杂,而如此复杂的信息难免会有错误存在。如果是以前所有数据都在同一串数据里,那么这些错误会导致整串数据无法被读取或者读取错误,这时候为了保证游戏体验,MC会自动帮你断开连接。

然而虽然官方能保证原生mc数据的低错误率,但却不能保证各mod (也就是第三方开发的) 完全不会出现这些问题,可是 (大概是notch/jeb玩mod的时候莫名其妙被断开链接了) 很多时候这些错误并不会怎么影响游戏体验,只是单纯的发错了包而已,而在这种情况下又断开连接才是最难受的,所以mojang就把自定义数据包给分流发送了,这样即使自定义数据有错误也不会导致整个游戏崩溃。


官方支持的自定义数据包允许了很多意想♂不到的可能性,而从此衍伸出了很多奇♂特的东西, PluginMessage就是其中之一, pluginmessage通过fml和bukkit的支持允许了开发者以更简易的方式达到mod(客户端)与插件(服务端)的通讯, 详细介绍可以看这里


上面的页面翻到最底下可以看到BungeeCord频道, BC基于这个pluginmessage开发了自己的一套支持从各服务器发送给BC本体各式各样的信息的渠道,嘛,大概就是酱紫了,各式各样的信息


那么问题来了,要怎么发送这些数据呢
因为是网络通讯,所以这里所有信息都是以一串字节发送的 (byte[])  
当然,这个字节码有一万种 很多个方法可以读取,不过为了简化我们的操作,在本教程里我们将使用Google GuavaByteArrayDataOutputByteArrayDataInput来:
在BungeeCord使用的话我们要先注册自己的频道,本教程将在onEnable里注册:
  1. getProxy().registerChannel("MyChannel");
复制代码
感谢BC的支持,我们很轻松就注册了一个频道。
频道是注册好了,可是怎么监听呢?
代码                                                                - □ ╳
//就像监听一个事件一样, 主类里注册监听器
BungeeCord.getInstance().getPluginManager().registerListener(this, new MyChannelListener());

//然后我们用新的类来写
public class MyChannelListener implements Listener{
        @EventHandler
        public void onPluginMessageRecieve(PluginMessageEvent evt) {
                //到这里就非常好理解了
                String channel = evt.getTag();                      //频道id
                ByteArrayDataInput data =ByteStreams.newDataInput(evt.getData);               //方便处理的消息
                ProxiedPlayer recipient = BungeeCord.getInstance().getPlayer(evt.getReciever().toString());          //目标玩家
        }
}
> _

其他核心(bukkit/sponge)的监听方法

BukkitSponge


至此,本篇完结,关于发送和自定义将会在下一篇继续讲


如果本教程有帮到你请考虑给个好评评价/回复一下本帖,P.S. 给人气不会损失金币的哦