125 Star 1.7K Fork 288

nico / ratel

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
PROTOCO_CN.md 5.65 KB
一键复制 编辑 原始数据 按行查看 历史
nico 提交于 2018-11-19 11:45 . Squashed commit of the following:

[toc]

Ratel-Client开发文档

介绍

什么是Ratel

Ratel 是一个可以在命令行中玩斗地主的项目,可以使用小巧的jar包在拥有JVM环境的终端中进行游戏,同时支持人人对战和人机对战两种模式,丰富你的空闲时间!

Ratel使用Java语言开发,Netty 4.x网络框架搭配protobuf数据协议,可以支持多客户端同时游戏。

Ratel-Client扩展

Ratel面向响应式架构,通过事件码进行通讯,对于Ratel-Client,支持跨平台扩展,换一种说法,任何后端语言都可以开发Ratel-Client!

在开发Ratel-Client前应该知道:

  • Ratel Server-Client交互网络协议为TCP/IP
  • Ratel Server-Client交互数据协议为protobuf
  • Ratel以事件为驱动,在Client将各个环节串联起来。
  • Ratel所有的文案都由Client显示。

对接

架构你的客户端

我们可以使用任何后端语言就重写Ratel客户端,Ratel默认的客户端的由Java语言编写,如果你想使用其他语言重写,以下是我们推荐的一种架构:

这种架构对于事件的处理非常友好,你可以设计一个抽象的Event-Listener接口,然后开发不同的实现去处理不同CODE对应的响应数据,例如一个而简单的例子——Poker的显示,以下是我们的处理流程的伪代码:

1、对服务端响应数据解码 -> 

decode(msg)

2、解码后的数据 ->

ClientData{
    String code;
    String data;
}

3、通过code寻找对应的EventListener ->

showPokersEventListener = Map<code, EventListener>.get(code)

4、处理响应数据 ->

showPokersEventListener.call(server, data){
    show(data);
    server.write(msg);
}

以上只是简单的Server-Client的交互流程,有时候可能会出现Client-Client的场景,例如客户端的选项面板的显示,在我们从A层切换到B层,再从B层返回到A层,这时就需要做Client-Client的交互。

当然,大多数的交互重点集中在Server-Client,而另一方面,客户端大多都是在处理并显示服务端响应的数据,对于真正的业务交互很少,这对于客户端来说,只要将事件绝对的丰富,那么客户端的流程就会绝对的灵活。因此,Ratel的客户端响应事件相比于服务端的响应事件数量多了几倍有余,所以这对于客户端的架构要求就是要有足够的灵活性,能够支持以下两个业务流:

  • Server-Client-Server
  • Server-Client-Client-Server

之后,我们进入下一步!

定义数据实体

对于客户端和服务端交互的数据,为了承载,我们需要设计两个类去存放编解码后的数据,值得一提的是,客户端和服务端的数据结构一样,都由CODEDATAINFO三个字段组成:

  • CODE - 对应的事件
  • DATA - 传递的数据
  • INFO - 信息(暂时用不到)

我们的编解码方式为Protobuf序列化,参考文件请看这里

对接协议

在我们做好对接的准备工作之后,可以通过以下协议文档开始实现客户端的业务!

客户端事件

连接成功事件
  • CODE - CODE_CLIENT_CONNECT
  • TYPE - TEXT
  • DATA - 客户端被分配的ID
退出房间事件
  • CODE - CODE_CLIENT_EXIT
  • TYPE - JSON
  • DATA - 如下
字段名 含义
roomId 房间ID
exitClientId 退出者ID
exitClientNickname 退出者昵称

参考数据

{"roomId":14,"exitClientId":64330,"exitClientNickname":"nico"}
客户端踢出事件
  • CODE - CODE_CLIENT_KICK
  • TYPE - Text
  • DATA - NULL
设置昵称事件
  • CODE - CODE_CLIENT_NICKNAME_SET
  • TYPE - JSON
  • DATA - 如下
字段名 含义
invalidLength 有效长度,当设置昵称超过10个字节会返回此字段

参考数据:

{"invalidLength":10}
抢地主-地主诞生事件
  • CODE - CODE_GAME_LANDLORD_CONFIRM
  • TYPE - JSON
  • DATA - 如下
字段名 含义
roomId 房间ID
roomOwner 房间所有者昵称
roomClientCount 房间人数
landlordNickname 地主昵称
landlordId 地主ID
additionalPokers 额外的三张牌

参考数据:

{"roomId":14,"roomOwner":"nico","roomClientCount":3,"landlordNickname":"robot_2","landlordId":-8,"additionalPokers":[{"level":"LEVEL_5","type":"DIAMOND"},{"level":"LEVEL_6","type":"CLUB"},{"level":"LEVEL_A","type":"DIAMOND"}]}
抢地主-大家都没抢事件
  • CODE - CODE_GAME_LANDLORD_CYCLE
  • TYPE - TEXT
  • DATA - NULL

TIP:该事件触发后会连续触发重新游戏事件

抢地主-抢地主决策事件
  • CODE - CODE_GAME_LANDLORD_ELECT
  • TYPE - JSON
  • DATA - 如下
字段名 含义
roomId 房间ID
roomOwner 房间所有者昵称
roomClientCount 房间人数
preClientNickname 上一个客户端的昵称
nextClientNickname 下一个客户端的昵称
nextClientId 下一个客户端的ID

参考数据:

{"roomId":14,"roomOwner":"nico","roomClientCount":3,"preClientNickname":"nico1","nextClientNickname":"nico2","nextClientId":2}
游戏结束事件
  • CODE - CODE_GAME_OVER
  • TYPE - JSON
  • DATA - 如下
字段名 含义
winnerNickname 获胜者昵称
winnerType 获胜者类型(地主?农民)

参考数据:

{"winnerNickname":"nico","winnerType":"LANDLORD?PEASANT"}
Java
1
https://gitee.com/ainilili/ratel.git
git@gitee.com:ainilili/ratel.git
ainilili
ratel
ratel
master

搜索帮助