Protocal for socket and backend - NULL-HDU/Barrage_Frontend GitHub Wiki
message introduce
message描述的是socket与backend进行交互时的数据格式。
数据结构看最下方
endian
协议的所有二进制数据用 big endian 编码,如果你已了解 big endian,可以跳过该小节:
When you save binary data you need to decide on something called endianness. The word sounds complicated but all it means is, “the order in which you write your bytes”.
This sounds odd since we, as humans, always write our numbers the same way. When we write the number 5,273, the 5 comes first, the 2 second, 7 is next, and finally the 3. In this example, the “5” is called the most significant digit and the 3 is the least significant digit. You’d never think to write that number in reverse as 3,725. That would be ridiculous.
However, in binary encoding, you do have to make this choice with the order you write bytes. There are two kinds of endianness — big endian and little endian. Big endian is when you write your most significant byte first and little endian is when you write your least significant byte first.
For example, let’s take the decimal number 287,454,020 which is 0x11223344in hexidecimal.The most significant byte is 0x11 and the least significant byte is 0x44.
Encoding this in big endian looks like: 11 22 33 44
and encoding in little endian looks like: 44 33 22 11
base form of message
message的组成如下图所示:
`message length(Uint32) + timestamp(float64) + message type(Uint8) + message body(this is different struct from different message types)`
* message length: Uint32, the length of message, including 'length', 'type' and 'body', the unit of length is 'byte'.
* timestamp: a Unix time, the number of seconds elapsed since January 1, 1970 UTC.
* message type: Uint8, the type of message, type defines the way to decoding the message and what should ends do.
* message body: this is a struct different from message which has different type.
* message length: Uint32, 整个message的长度,包括'length', 'type' 和 'body', 长度单位为 'byte'.
* timestamp: float64, 自1970年1月1日UTC时间的秒数(unix time).
* message type: Uint8, 消息类型,type 定义了解析消息的方法,以及终端需要做的事。
* message body: 根据type不同,这个的数据结构也不一样。
Message Body
标记 '<f>' 意味着 该消息在未来可能会用到或则不会用到
以下为服务器与客户端交互时的body的数据结构
Client send to Server
### <f>1. enter room(进入房间)
type value: 1 (0x01)
message body: `userId(Uint32) + nickname(nickname) + roomNumber(Uint32) + troop(Uint8)`
* userId: Uint32, the id of uint32.
* nickname: nickname, the name of user
* roomNumber: Uint32, the room of game.
* troop: Uint8, the troop number ofbool user.
* userId: Uint32, 用户id.
* nickname: nickname, 用户昵称
* roomNumber: Uint32, 游戏房间.
* troop: Uint8, 用户队伍号
### <f>2. ready game(游戏准备)
type value: 2 (0x02)
message body: `userId(Uint32) + roomNumber(Uint32) + readyValue(Uint8)`
* userId: Uint32, the id of user.
* roomNumber: Uint32, the room of game.
* readyValue: Uint8, 0 (0x00): cancel, 1 (0x01): ready.
* userId: Uint32, 用户id.
* roomNumber: Uint32, 用户房间.
* readyValue: Uint8, 0 (0x00): 取消, 1 (0x01): 准备.
### <f>3. start game(开始游戏)
type value: 3 (0x03)
message body: `userId(Uint32) + roomNumber(Uint32)`
* userId: Uint32, the id of uint64.
* roomNumber: Uint32, the room of game.
* userId: Uint32, 用户id.
* roomNumber: Uint32, 用户房间.
### 8. disconnect(leave early)(断开连接,提前离线)
type value: 8 (0x08)
message body: `userId(Uint32) + roomNumber(Uint32)`
* userId: Uint64, the id of uint64.
* roomNumber: Uint32, the room of game.
* userId: Uint64, 用户id.
* roomNumber: Uint32, 用户房间.
### 9. connect(join game)(加入游戏)
type value: 9 (0x09)
message body: `userId(Uint32) + roomNumber(Uint32) `
* userId: Uint32, the id of uint32.
* roomNumber: Uint32, the room of game.
* userId: Uint32, 用户id.
* roomNumber: Uint32, 用户房间.
### 12. self info
type value: 12 (0x0c)
message body: `newBallsInfos(newBallsInfos) + displacementInfos(displacementInfos) + collisionSocketInfos(collisionSocketInfos) + disappearInfos(disappearInfos)`
* newBallsInfos: newBallsInfos, the information about new balls.
* displacementInfos: displacementInfos, the information about balls(only changed balls) displacement.
* collisionSocketInfos: collisionSocketInfos, the information about ball collision for socket.
* disappearInfos: disappearInfos, the information about balls which is disappeared.
* newBallsInfos: newBallsInfos, 新ball的信息.
* displacementInfos: displacementInfos, 自己的数据变化过的球的信息.
* collisionSocketInfos: collisionSocketInfos, 球的碰撞信息,包括死亡,消失信息.
* disappearInfos: disappearInfos, 消失的球的id
Server send to Client
### <f>4. someone ready(某人准备)
type value: 4 (0x04)
message body: `readyUserId(Uint32) + roomNumber(Uint32) + readyValue(Uint8)`
* readyUserId: Uint64, the id of the ready one.
* roomNumber: Uint32, the room of game.
* readyValue: Uint8, 0 (0x00): cancel, 1 (0x01): ready.
* readyUserId: Uint64, 做准备的用户id.
* roomNumber: Uint32, 用户房间.
* readyValue: Uint8, 0 (0x00): 取消, 1 (0x01): 准备.
### <f>5. game starts(游戏开始)
type value: 5 (0x05)
message body: `roomNumber(Uint32)`
* roomNumber: Uint32, the room of game.
* roomNumber: Uint32, 用户房间.
### 6. connected(joined game)(成功进入游戏)
type value: 6 (0x06)
message body: `userId(Uint32) + roomNumber(Uint32)`
* userId: Uint32, the id of uint32.
* roomNumber: Uint32, the room of game.
* userId: Uint32, 用户id.
* roomNumber: Uint32, 用户房间.
### 7. playground info(虚拟场景信息)
type value: 7 (0x07)
message body: `newBallsInfos(newBallsInfos) + displacementInfos(displacementInfos) + collisionSocketInfos(collisionSocketInfos) + disappearInfos(disappearInfos)`
* newBallsInfos: newBallsInfos, the information about new balls.
* displacementInfos: displacementInfos, the information about balls of other users.
* collisionSocketInfos: collisionSocketInfos, the information about ball collision for socket.
* disappearInfos: disappearInfos, the information about balls which is disappeared.
normally, newBallsInfos and disappearInfos is empty, frontend should let other users data in game mode be same as the displacementInfos.
* newBallsInfos: newBallsInfos, 新ball的信息.
* displacementInfos: displacementInfos, 整个场地中其他玩家的球的信息.
* collisionSocketInfos: collisionSocketInfos, 球的碰撞信息,包括死亡,消失信息.
* disappearInfos: disappearInfos, 消失的球的id
一般来说,在这个message中,newBallsInfos和disappearInfos是空的,前端应该让game mode中的其他人的球的信息与displacementInfos高度同步。
### 10. special message(额外通知)
type value: 10 (0x0a)
message body: `lengthOfSpecialMessage(Uint8) + specialMessage(lengthOfSpecialMessage * Uint8)`
### 11. game over(游戏结束)
type value: 11 (0x0b)
message body: `OverType(Uint8)`
* overType: Uint8, the type of over.
* overType: Uint8, 结束类型。
## 99. test
type value: 99 (0x63)
body 组成为: Uint64 + Uint32 + Uint16 + Uint8 + int64 + bytes
body 的值为: 99 99 99 99 99 success!
### 212. random userId
type value: 212 (0xd4)
message body: `userId(userId)`
footnoot1: struct
*the value in parens is the sturct of this unit*
*某字段旁边括号中的值是该字段的数据类型*
**userId**: `userId(Uint32)`
**ballShortID**: `ballShortID(Uint16)`
**bool**: `bool(Uint8)`
* bool: Uint8, 0 (0x00): false, 1 (0x01): true.
**damage**: `damage(Uint8)`
**location**: `x(Uint16) + y(Uint16)`
* x: Uint16, x axis.
* y: Uint16, y axis.
**ballId**: `userId(userId)+id(ballShortID)`
* userId: Uint32, the id of the creator of this ball
* id: Uint16, it is a value from 1 - 2^16. After user creating a ball, it add to one. 0 is user s airplane
* userId: Uint32, 这个球的创建者的id
* id:Uint16, 这是一个在1到2^32的值。每当用户创建一个球,这个值会加1。0 作为用户飞机的飞机。
**ball**: `camp(userId) + ballId(ballId) + nickname(nickname)+ ballType(Uint8) + hp(Uint8) + damage(damage) + role(Uint8) + special(Uint16) + radius(uint16) + attackDir(float32) + state(uint8) + locationCurrent(location)`
state: uint8, 状态,详情请看footnote3
**nickname**: `lengthOfName(Uint8) + name(lengthOfNickname * Uint8)`
* lengthOfName: Uint8, the length of nickname
* name: lengthOfNickname * byte, it is a string.
* lengthOfName: Uint8, 昵称的长度(以byte为单位)
* name: lengthOfNickname * Uint8, 这其实是一个字符串。
**background**: `imageId(Uint8)`
**collisionViewInfo**: `ballA(ballId) + ballB(ballId) + damageToA(damage) + damageToB(damage)`
**collisionSocketInfo**: `collisionViewInfo(collisionViewInfo) + AState(uint8) + BState(uint8)`
**collisionSocketInfos**: `lengthOfCollisionSocketInfos(Uint32) + collisionSocketInfoArray(lengthOfCollisionSocketInfos * collisionSocketInfo)`
* lengthOfCollisionSocketInfos: Uint32, the length of collisionSocketInfoArray.
* lengthOfCollisionSocketInfos: Uint32, collisionSocketInfoArray 的长度
**displacementInfo**: `displacementOfBall(ball)`
**displacementInfos**: `lengthOfDisplacementInfos(Uint32) + displacementInfoArray(lengthOfDisplacementInfos * displacementInfo)`
* lengthOfDisplacementInfos: Uint32, the length of displacementInfoArray.
* lengthOfDisplacementInfos: Uint32, displacementInfo 的长度.
**newBallsInfo**: `newBall(ball)`
**newBallsInfos**: `lengthOfNewBallsInfos(Uint32) + newBallsInfoArray(lengthOfNewBallsInfos * newBallsInfo)`
**disappearInfo**: `ballShortId(uint16)`
**disappearInfos**: `lengthOfDisappearInfos(Uint32) + disappearInfoArray(lengthOfDisappearInfos * disappearInfo)`
* ballShortId: uint16, ballID without userID
* lengthOfDisappearInfos: Uint32, the length of disappearInfoArray.
* ballShortId: uint16, 不包含userID的球id
footnote2 ball type
airPlane = 0
block = 1
bullet = 2
food = 3
footnote3 state
Alive = 0
Dead = 1
Disappear = 2