共计 14609 个字符,预计需要花费 37 分钟才能阅读完成。
TODO: 这篇文章是我分析 B 站直播的数据包的过程,可能会有一些待补充的内容,如果有什么建议可以私信我或者跟评。感谢一下下面的各位做出的卓越贡献~CREDITS: 冰块 TiO2 – 提供样本数据(十个辣条呢~!)炒鸡嗨客协管徐 – 参考文章:获取 bilibili 直播弹幕的 WebSocket 协议(这篇文章写的很全了 www)
我这次分析是通过移动端的 h5 网页进行的,比如我的直播间是 4568796,然后打开的网页是 http://live.bilibili.com/h5/4568796,如果被跳转到了一般网页,可以试一下改成 iPhone 的 UA。
主流程(点击前往)
1. 获取房间 ID / 2. 封包结构 / 3. 初始化连接 / 4. 心跳包 / 5. 数据包
获取房间 ID
大部分跟直播间 ID 是一样的,也就是 URL 路由后面跟着的那一串数字,比如我的就是 4568796,通过 API 请求房间 ID 是一样的。
{
“code”: 0,
“msg”: “ok”,
“message”: “ok”,
“data”: {
“uid”: 8759339,
“room_id”: 4568796,
“short_id”: 0,
“attention”: 65,
“online”: 15,
“is_portrait”: false,
“description”: “<p> 主要直播 FFXIV,渣渣水平,不要吐槽啊~</p>\n<p> 欢迎大家一起来讨论 一起来玩 FF 呀 ~</p>\n<p> 偶尔也会直播一些 PS4 游玩过程~</p>”,
“live_status”: 0,
“area_id”: 102,
“parent_area_id”: 2,
“parent_area_name”: “ 游戏 ”,
“old_area_id”: 3,
“background”: “https://static.hdslb.com/live-static/images/bg/6.jpg”,
“title”: “ 光之赤石 国际服咸鱼 + 日常 ”,
“user_cover”: “https://i0.hdslb.com/bfs/live/ddc99aeab675f33b0f84afcd41ced570bd9c2d9c.jpg”,
“keyframe”: “https://i0.hdslb.com/bfs/live/4568796.jpg?12050340”,
“is_strict_room”: false,
“live_time”: “0000-00-00 00:00:00”,
“tags”: “stormblood,ff14, 最终幻想, 最终幻想 14”,
“is_anchor”: 1,
“room_silent_type”: “”,
“room_silent_level”: 0,
“room_silent_second”: 0,
“area_name”: “ 最终幻想 14”,
“pendants”: “”,
“area_pendants”: “”,
“hot_words”: [“2333333”, “ 喂,妖妖零吗 ”, “ 红红火火恍恍惚惚 ”, “FFFFFFFFFF”, “Yooooooo”, “ 啪啪啪啪啪 ”, “666666666”, “ 老司机带带我 ”, “ 你为什么这么熟练啊 ”, “gg”, “prprpr”, “ 向大佬低头 ”, “ 请大家注意弹幕礼仪哦!”, “ 还有这种操作!”, “ 囍 ”, “ 打 call”, “ 你气不气?”, “ 队友呢?”],
“hot_words_status”: 0,
“verify”: “”,
“new_pendants”: {
“frame”: null,
“badge”: null,
“mobile_frame”: null,
“mobile_badge”: null
},
“up_session”: “”,
“pk_status”: 0,
“pk_id”: 0,
“allow_change_area_time”: 0,
“allow_upload_cover_time”: 0
}
}
当然也会有不一样的,比如 URL 后面的数字是 419, 但是通过 API 访问拿到的房间 ID 是 3151254。貌似前者在 B 站的定义是 short_id,后者是真实的房间 ID,我们请求数据要用的是后面的那个 ID。
{
“code”: 0,
“msg”: “ok”,
“message”: “ok”,
“data”: {
“uid”: 37164813,
“room_id”: 3151254,
“short_id”: 419
/*…*/
}
}
JSON 部分感觉有用的字段
FIELD
EXAMPLE
DESCRIPTION
code
0
应该是正常返回代码 0,如果出现错误,可能不是这个数值。
data.uid
8759339
UP 主用户 ID,可以通过 https://space.bilibili.com/8759339 访问 B 站空间。
data.room_id
4568796
这是我们要用来连接 websocket 的 ID。
data.short_id
0
如果不是 0 的话,可以拼接为进入直播间的 URL。类似于靓号的存在么?
data.attention
65
粉丝数
data.online
15
旧版的在线人数,现在的人气值。
data.description
HTML
直播间下方的描述,是一段 HTML。
data.live_status
0
1 表示正在直播,0 表示不在直播。
data.description
HTML
直播间下方的描述,是一段 HTML。
data.parent_area_namedata.area_name
游戏最终幻想 14
直播的一级分类跟二级分类。
data.live_time
0000-00-00 00:00:00
直播开始的时间,如果全零就是表示不在直播。
data.background
URL
一个 URL 指向直播间(桌面版)的背景。
data.user_cover
URL
一个 URL 指向直播间的封面。
data.keyframe
URL
一个 URL 指向直播间的直播截图。
data.title
光之赤石 国际服咸鱼 + 日常
直播的标题。
data.tags
stormblood,ff14, 最终幻想, 最终幻想 14
用半角空格分隔的标签列表。
data.verify
UP 主认证类型,如果是签约的会有 bilibili 直播签约主播。
封包结构
引用自:获取 bilibili 直播弹幕的 WebSocket 协议
封包由头部和数据组成,字节序均为大端模式头部格式:
偏移量
长度
含义
0
4
封包总大小
4
2
头部长度
6
2
协议版本,目前是 1
8
4
操作码(封包类型)
12
4
sequence,可以取常数 1
已知的操作码:
操作码
含义
2
客户端发送的心跳包
3
人气值,数据不是 JSON,是 4 字节整数
5
命令,数据中 [‘cmd’] 表示具体命令
7
认证并加入房间
8
服务器发送的心跳包
示意图:
初始化连接
H5 播放器使用的弹幕连接是 wss://broadcastlv.chat.bilibili.com/sub,桌面版的会使用 CDN 的连接,每次都不一样,没有测试过是否每次连接都可用。我使用桌面版的时候就出现过:wss://tx-live-dmcmt-sel-01.chat.bilibili.com/subwss://tx-tokyo-live-comet-01.chat.bilibili.com/subplayer.js 中定义的默认服务器则是 ws://broadcastlv.chat.bilibili.com:2244/sub
连接上 ws 以后,第一件事情就是发认证包,截获的数据大致如下:
# Client.1 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 65 00 10 00 01 00 00 00 07 00 00 00 01
0000001x |7B 22 75 69 64 22 3A 38 37 35 39 33 33 39 2C 22
0000002x |72 6F 6F 6D 69 64 22 3A 34 35 36 38 37 39 36 2C
0000003x |22 70 72 6F 74 6F 76 65 72 22 3A 31 2C 22 70 6C
0000004x |61 74 66 6F 72 6D 22 3A 22 77 65 62 22 2C 22 63
0000005x |6C 69 65 6E 74 76 65 72 22 3A 22 31 2E 35 2E 31
0000006x |30 2E 31 22 7D
———————————————————–
{“uid”:8759339,”roomid”:4568796,”protover”:1,”platform”:”web”,”clientver”:”1.5.10.1″}
===========================================================
MASK: D6-CD-12-0E
这里的 uid 为登录用户的 id,roomid 就是上一步中我们得到的真实房间 ID。服务器会返回一个数据包,如下:
# Server.2 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 10 00 10 00 01 00 00 00 08 00 00 00 01
———————————————————–
操作码为 08,服务器发来的心跳包,表示服务器在线。
心跳包
每隔 30s 需要向服务器发送心跳包保持在线状态。从浏览器中截获的心跳包如下:
# Client.3 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 1F 00 10 00 01 00 00 00 02 00 00 00 01
0000001x |5B 6F 62 6A 65 63 74 20 4F 62 6A 65 63 74 5D
———————————————————–
[object Object]
===========================================================
MASK: 26-E1-EC-F2
NOTES: 很奇怪为什么心跳包的主体是 [object Object] 文本,感觉似乎是调用了什么的 toString,准备尝试一下使用无主体的心跳包试试,日后更新这个部分。UPDATE1: player.js 中有一行 var t = this.convertToArrayBuffer({}, r.a.WS_OP_HEARTBEAT); 用于生成心跳包,貌似传入的是一个空的对象。
服务器通常会返回一个带有人气值的数据包
# Server.4 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 14 00 10 00 01 00 00 00 03 00 00 00 01
0000001x |00 00 00 01
———————————————————
操作码为 3,人气值数据,主体部分是一个四字节的整数。
数据包
这个部分可能涉及到的内容比较多,也是比较核心的部分。大概包括以下部分:
开始直播 / 结束直播 / 收到弹幕 / 收到礼物 / 欢迎进入 / 广播消息
这些数据包的操作码都是恒定为 5。很奇怪的是,这些数据包的版本位定义是 0,sequence 常数也是 0。
开始直播
# Server.7 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 2F 00 10 00 00 00 00 00 05 00 00 00 00
0000001x |7B 22 63 6D 64 22 3A 22 4C 49 56 45 22 2C 22 72
0000002x |6F 6F 6D 69 64 22 3A 34 35 36 38 37 39 36 7D
———————————————————
{“cmd”:”LIVE”,”roomid”:4568796}
=========================================================
操作码为 5,主体的 cmd 定义为 LIVE,roomid 表示对应直播间的 id。
结束直播
# Server.23 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 36 00 10 00 00 00 00 00 05 00 00 00 00
0000001x |7B 22 63 6D 64 22 3A 22 50 52 45 50 41 52 49 4E
0000002x |47 22 2C 22 72 6F 6F 6D 69 64 22 3A 22 34 35 36
0000003x |38 37 39 36 22 7D
———————————————————
{“cmd”:”PREPARING”,”roomid”:”4568796″}
=========================================================
操作码为 5,主体的 cmd 定义为 PREPARING,roomid 表示对应直播间的 id。
收到弹幕
# Server.19 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 C7 00 10 00 00 00 00 00 05 00 00 00 00
0000001x |7B 22 69 6E 66 6F 22 3A 5B 5B 30 2C 31 2C 32 35
0000002x |2C 31 36 37 37 37 32 31 35 2C 31 35 34 34 30 38
0000003x |31 37 37 31 2C 39 33 36 35 37 35 39 32 39 2C 30
0000004x |2C 22 38 32 63 61 61 34 31 39 22 2C 30 2C 30 5D
0000005x |2C 22 E5 96 B5 22 2C 5B 32 37 33 32 32 34 35 36
0000006x |2C 22 E5 86 B0 E5 9D 97 54 69 4F 32 22 2C 30 2C
0000007x |30 2C 30 2C 31 30 30 30 30 2C 31 2C 22 22 5D 2C
0000008x |5B 5D 2C 5B 31 2C 30 2C 39 38 36 38 39 35 30 2C
0000009x |22 3E 35 30 30 30 30 22 5D 2C 5B 5D 2C 30 2C 30
000000Ax |2C 7B 22 75 6E 61 6D 65 5F 63 6F 6C 6F 72 22 3A
000000Bx |22 22 7D 5D 2C 22 63 6D 64 22 3A 22 44 41 4E 4D
000000Cx |55 5F 4D 53 47 22 7D
———————————————————
{“info”:[[0,1,25,16777215,1544081771,936575929,0,”82caa419″,0,0],” 喵 ”,[27322456,” 冰块 TiO2″,0,0,0,10000,1,””],[],[1,0,9868950,”>50000″],[],0,0,{“uname_color”:””}],”cmd”:”DANMU_MSG”}
=========================================================
cmd 定义为 DANMU_MSG,另一个字段为 info,是一个很杂的数组,我们来分析一下他:
info:
[0]: [0,1,25,16777215,1544081771,936575929,0,”82caa419″,0,0]
[14]: “ 喵 ”
[2]: [27322456,” 冰块 TiO2″,0,0,0,10000,1,””]
[15]: []
[16]: [1,0,9868950,”>50000″]
[17]: []
[18]: 0
[7]: 0
[8]: {“uname_color”:””}
不难看出 [1] 是弹幕文本内容,[2]定义了一些用户基本信息。仔细观察可以看出 [0] 中的 1544081771 是一个 Linux 时间戳,转换成北京时间是 December 6, 2018 3:36:11 PM GMT+08:00,这与弹幕送出来的时间是吻合的,所以 [0] 应该是一些弹幕元信息。
UPDATE1: [0][19]应该是一个代表颜色的数值,[0][20]为 rnd,似乎是播放器用于校验使用的数值??。
再看看另两个数据包
[0]: [0, 1, 25, 16772431, 1544172160, 950512928, 0, “4b1a8da4”, 0, 0],
[1]: “ 这头猪这辈子值了 ”,
[2]: [1*7, “ 永 * 幡 ”, 0, 1, 0, 10000, 1, “”],
[3]: [12, “ 杆菌 ”, “ 杆菌无敌 ”, 246, 10512625, “”],
[4]: [49, 0, 16746162, 3071],
[5]: [“title-174-1”, “title-174-1”],
[6]: 0,
[7]: 0,
[8]: {“uname_color”: “”}
[0]: [0, 1, 25, 16777215, 1544172161, 522412774, 0, “b8415757”, 0, 0],
[1]: “ 送猪肉的猪肉工 ”,
[2]: [1*9, “ 七 * 公 ”, 0, 0, 0, 10000, 1, “”],
[3]: [12, “ 杆菌 ”, “ 杆菌无敌 ”, 246, 10512625, “”],
[4]: [23, 0, 5805790, “>50000”],
[5]: [“ice-dust”, “title-48-1”],
[6]: 0,
[7]: 0,
[8]: {“uname_color”: “”}
[3]的数值是粉丝勋章相关的讯息,[3][0]是粉丝勋章等级,[3][21]是粉丝勋章名称。[4]是用户等级相关讯息,[4][0]是用户等级,[4][22]是排名。[5]是活动头衔相关。[2]中 [2][23],[2][24],[2][25] 之中,三个标志位,应该分别是舰长、老爷、房管的标志吧?(猜测)
Index
Description
0
Array 弹幕元信息。[3]为颜色,[4]为弹幕发送时间(Unix 时间戳)
1
String 弹幕内容
2
Array 发言人信息。[0]为用户 ID,[1]为用户名称,[2]是舰长标志位,[3]是老爷标志位,[4]是房管标志位。(这三个标志位是猜测)
3
Array 粉丝勋章相关的讯息。[0]是粉丝勋章等级,[1]是粉丝勋章名称。
4
Array 用户等级相关讯息。[0]是用户等级,[3]是排名。
5
Array 活动头衔相关。
6
Number 未知。
7
Number 未知。
8
Object 未知。
收到礼物
# Server.5 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 02 DE 00 10 00 00 00 00 00 05 00 00 00 00
0000001x |7B 22 63 6D 64 22 3A 22 53 45 4E 44 5F 47 49 46
0000002x |54 22 2C 22 64 61 74 61 22 3A 7B 22 67 69 66 74
0000003x |4E 61 6D 65 22 3A 22 5C 75 38 66 61 33 5C 75 36
0000004x |37 36 31 22 2C 22 6E 75 6D 22 3A 31 2C 22 75 6E
0000005x |61 6D 65 22 3A 22 5C 75 35 36 64 62 5C 75 37 63
0000006x |66 38 5C 75 34 65 34 33 5C 75 37 30 36 63 5C 75
0000007x |35 33 36 31 5C 75 35 34 63 37 5C 75 34 66 30 61
0000008x |22 2C 22 66 61 63 65 22 3A 22 68 74 74 70 3A 5C
0000009x |2F 5C 2F 69 30 2E 68 64 73 6C 62 2E 63 6F 6D 5C
000000Ax |2F 62 66 73 5C 2F 66 61 63 65 5C 2F 62 30 36 39
000000Bx |34 31 34 63 34 34 33 38 65 32 66 61 36 66 64 34
000000Cx |34 30 36 66 65 35 33 61 30 30 32 32 62 37 65 30
000000Dx |63 38 61 62 2E 6A 70 67 22 2C 22 67 75 61 72 64
000000Ex |5F 6C 65 76 65 6C 22 3A 30 2C 22 72 63 6F 73 74
000000Fx |22 3A 31 36 39 30 32 33 34 32 36 2C 22 75 69 64
0000010x |22 3A 31 39 32 32 30 33 36 31 34 2C 22 74 6F 70
0000011x |5F 6C 69 73 74 22 3A 5B 5D 2C 22 74 69 6D 65 73
0000012x |74 61 6D 70 22 3A 31 35 34 34 31 37 32 31 34 33
0000013x |2C 22 67 69 66 74 49 64 22 3A 31 2C 22 67 69 66
0000014x |74 54 79 70 65 22 3A 30 2C 22 61 63 74 69 6F 6E
0000015x |22 3A 22 5C 75 35 35 38 32 5C 75 39 38 64 66 22
0000016x |2C 22 73 75 70 65 72 22 3A 30 2C 22 73 75 70 65
0000017x |72 5F 67 69 66 74 5F 6E 75 6D 22 3A 30 2C 22 70
0000018x |72 69 63 65 22 3A 31 30 30 2C 22 72 6E 64 22 3A
0000019x |22 31 35 34 34 31 37 32 31 32 36 22 2C 22 6E 65
000001Ax |77 4D 65 64 61 6C 22 3A 30 2C 22 6E 65 77 54 69
000001Bx |74 6C 65 22 3A 30 2C 22 6D 65 64 61 6C 22 3A 5B
000001Cx |5D 2C 22 74 69 74 6C 65 22 3A 22 22 2C 22 62 65
000001Dx |61 74 49 64 22 3A 22 30 22 2C 22 62 69 7A 5F 73
000001Ex |6F 75 72 63 65 22 3A 22 6C 69 76 65 22 2C 22 6D
000001Fx |65 74 61 64 61 74 61 22 3A 22 22 2C 22 72 65 6D
0000020x |61 69 6E 22 3A 30 2C 22 67 6F 6C 64 22 3A 30 2C
0000021x |22 73 69 6C 76 65 72 22 3A 30 2C 22 65 76 65 6E
0000022x |74 53 63 6F 72 65 22 3A 30 2C 22 65 76 65 6E 74
0000023x |4E 75 6D 22 3A 30 2C 22 73 6D 61 6C 6C 74 76 5F
0000024x |6D 73 67 22 3A 5B 5D 2C 22 73 70 65 63 69 61 6C
0000025x |47 69 66 74 22 3A 6E 75 6C 6C 2C 22 6E 6F 74 69
0000026x |63 65 5F 6D 73 67 22 3A 5B 5D 2C 22 63 61 70 73
0000027x |75 6C 65 22 3A 6E 75 6C 6C 2C 22 61 64 64 46 6F
0000028x |6C 6C 6F 77 22 3A 30 2C 22 65 66 66 65 63 74 5F
0000029x |62 6C 6F 63 6B 22 3A 31 2C 22 63 6F 69 6E 5F 74
000002Ax |79 70 65 22 3A 22 73 69 6C 76 65 72 22 2C 22 74
000002Bx |6F 74 61 6C 5F 63 6F 69 6E 22 3A 31 30 30 2C 22
000002Cx |74 61 67 5F 69 6D 61 67 65 22 3A 22 22 2C 22 75
000002Dx |73 65 72 5F 63 6F 75 6E 74 22 3A 30 7D 7D
———————————————————
{“cmd”:”SEND_GIFT”,”data”:{“giftName”:”\u8fa3\u6761″,”num”:1,”uname”:”\u56db\u7cf8\u4e43\u706c\u5361\u54c7\u4f0a”,”face”:”http:\/\/i0.hdslb.com\/bfs\/face\/b069414c4438e2fa6fd4406fe53a0022b7e0c8ab.jpg”,”guard_level”:0,”rcost”:169023426,”uid”:192203614,”top_list”:[],”timestamp”:1544172143,”giftId”:1,”giftType”:0,”action”:”\u5582\u98df”,”super”:0,”super_gift_num”:0,”price”:100,”rnd”:”1544172126″,”newMedal”:0,”newTitle”:0,”medal”:[],”title”:””,”beatId”:”0″,”biz_source”:”live”,”metadata”:””,”remain”:0,”gold”:0,”silver”:0,”eventScore”:0,”eventNum”:0,”smalltv_msg”:[],”specialGift”:null,”notice_msg”:[],”capsule”:null,”addFollow”:0,”effect_block”:1,”coin_type”:”silver”,”total_coin”:100,”tag_image”:””,”user_count”:0}}
=========================================================
这次的 json 格式要清晰很多了,我们格式化一下来看。
{
“cmd”: “SEND_GIFT”,
“data”: {
“giftName”: “\u8fa3\u6761”,
“num”: 10,
“uname”: “\u51b0\u5757TiO2”,
“face”: “http:\/\/i0.hdslb.com\/bfs\/face\/880b7078006c262009674a77e3ca9a23c10cfd21.jpg”,
“guard_level”: 0,
“rcost”: 29423,
“uid”: 27322456,
“top_list”: [],
“timestamp”: 1544081779,
“giftId”: 1,
“giftType”: 0,
“action”: “\u5582\u98df”,
“super”: 0,
“super_gift_num”: 0,
“price”: 100,
“rnd”: “1799741030”,
“newMedal”: 0,
“newTitle”: 0,
“medal”: [],
“title”: “”,
“beatId”: “”,
“biz_source”: “live”,
“metadata”: “”,
“remain”: 0,
“gold”: 0,
“silver”: 10910,
“eventScore”: 0,
“eventNum”: 0,
“smalltv_msg”: [],
“specialGift”: null,
“notice_msg”: [],
“capsule”: null,
“addFollow”: 0,
“effect_block”: 1,
“coin_type”: “silver”,
“total_coin”: 1000,
“tag_image”: “”,
“user_count”: 0
}
}
JSON 部分感觉有用的字段
FIELD
EXAMPLE
DESCRIPTION
data.giftName
\u8fa3\u6761
将数据 unescape 一下,就是汉字辣条,明显是礼物名称。
data.num
10
数量。
data.face
URL
用户的头像。
data.timestampe
1544081779
送礼时间,Unix 时间戳。
data.price
100
价值,好像是单价。
data.golddata.silver
010910
好像是用户持有的金瓜子和银瓜子数量,不像是礼物价值。
data.coin_typedata.total_coin
silver1000
礼物总价值。
欢迎进入
# Server.19 | Binary
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
===========================================================
0000000x |00 00 00 65 00 10 00 00 00 00 00 05 00 00 00 00
0000001x |7B 22 63 6D 64 22 3A 22 57 45 4C 43 4F 4D 45 5F
0000002x |47 55 41 52 44 22 2C 22 64 61 74 61 22 3A 7B 22
0000003x |75 69 64 22 3A 32 30 35 39 38 32 33 38 2C 22 75
0000004x |73 65 72 6E 61 6D 65 22 3A 22 E9 99 8C 2D 2D E8
0000005x |90 BD 22 2C 22 67 75 61 72 64 5F 6C 65 76 65 6C
0000006x |22 3A 33 7D 7D 00 00 01 AA 00 10 00 00 00 00 00
0000007x |05 00 00 00 00 7B 22 63 6D 64 22 3A 22 45 4E 54
0000008x |52 59 5F 45 46 46 45 43 54 22 2C 22 64 61 74 61
0000009x |22 3A 7B 22 69 64 22 3A 34 2C 22 75 69 64 22 3A
000000Ax |32 30 35 39 38 32 33 38 2C 22 74 61 72 67 65 74
000000Bx |5F 69 64 22 3A 31 38 33 34 33 30 2C 22 73 68 6F
000000Cx |77 5F 61 76 61 74 61 72 22 3A 31 2C 22 63 6F 70
000000Dx |79 5F 77 72 69 74 69 6E 67 22 3A 22 E6 AC A2 E8
000000Ex |BF 8E E8 88 B0 E9 95 BF 20 3C 25 E9 99 8C 2D 2D
000000Fx |E8 90 BD 25 3E 20 E8 BF 9B E5 85 A5 E7 9B B4 E6
0000010x |92 AD E9 97 B4 22 2C 22 68 69 67 68 6C 69 67 68
0000011x |74 5F 63 6F 6C 6F 72 22 3A 22 23 45 36 46 46 30
0000012x |30 22 2C 22 62 61 73 65 6D 61 70 5F 75 72 6C 22
0000013x |3A 22 68 74 74 70 3A 5C 2F 5C 2F 69 30 2E 68 64
0000014x |73 6C 62 2E 63 6F 6D 5C 2F 62 66 73 5C 2F 6C 69
0000015x |76 65 5C 2F 31 66 61 33 63 63 30 36 32 35 38 65
0000016x |31 36 63 30 61 63 34 63 32 30 39 65 32 36 34 35
0000017x |66 64 61 33 63 32 37 39 31 38 39 34 2E 70 6E 67
0000018x |22 2C 22 65 66 66 65 63 74 69 76 65 5F 74 69 6D
0000019x |65 22 3A 32 2C 22 70 72 69 6F 72 69 74 79 22 3A
000001Ax |37 30 2C 22 70 72 69 76 69 6C 65 67 65 5F 74 79
000001Bx |70 65 22 3A 33 2C 22 66 61 63 65 22 3A 22 68 74
000001Cx |74 70 3A 5C 2F 5C 2F 69 31 2E 68 64 73 6C 62 2E
000001Dx |63 6F 6D 5C 2F 62 66 73 5C 2F 66 61 63 65 5C 2F
000001Ex |37 38 39 36 32 32 38 64 31 31 65 35 63 31 37 36
000001Fx |34 63 61 36 37 34 62 66 64 39 36 33 30 61 37 63
0000020x |30 31 35 62 37 66 66 39 2E 6A 70 67 22 7D 7D 00
0000021x |00 00 66 00 10 00 00 00 00 00 05 00 00 00 00 7B
0000022x |22 63 6D 64 22 3A 22 57 45 4C 43 4F 4D 45 22 2C
0000023x |22 64 61 74 61 22 3A 7B 22 75 69 64 22 3A 33 39
0000024x |32 31 36 32 34 35 2C 22 75 6E 61 6D 65 22 3A 22
0000025x |E6 BA 90 E7 A8 9A E7 82 8E 22 2C 22 69 73 5F 61
0000026x |64 6D 69 6E 22 3A 66 61 6C 73 65 2C 22 76 69 70
0000027x |22 3A 31 7D 7D 00 00 00 66 00 10 00 00 00 00 00
0000028x |05 00 00 00 00 7B 22 63 6D 64 22 3A 22 57 45 4C
0000029x |43 4F 4D 45 22 2C 22 64 61 74 61 22 3A 7B 22 75
000002Ax |69 64 22 3A 32 30 35 39 38 32 33 38 2C 22 75 6E
000002Bx |61 6D 65 22 3A 22 E9 99 8C 2D 2D E8 90 BD 22 2C
000002Cx |22 69 73 5F 61 64 6D 69 6E 22 3A 66 61 6C 73 65
000002Dx |2C 22 73 76 69 70 22 3A 31 7D 7D
———————————————————
{“cmd”:”WELCOME_GUARD”,”data”:{“uid”:2*8,”username”:” 陌 * 落 ”,”guard_level”:3}}
{“cmd”:”ENTRY_EFFECT”,”data”:{“id”:4,”uid”:2*8,”target_id”:183430,”show_avatar”:1,”copy_writing”:” 欢迎舰长 <% 陌 * 落 %> 进入直播间 ”,”highlight_color”:”#E6FF00″,”basemap_url”:”http:\/\/i0.hdslb.com\/bfs\/live\/1fa3cc06258e16c0ac4c209e2645fda3c2791894.png”,”effective_time”:2,”priority”:70,”privilege_type”:3,”face”:”http:\/\/i1.hdslb.com\/bfs\/face\/7896228d11e5c1764ca674bfd9630a7c015b7ff9.jpg”}}
{“cmd”:”WELCOME”,”data”:{“uid”:3*5,”uname”:” 源 * 炎 ”,”is_admin”:false,”vip”:1}}
{“cmd”:”WELCOME”,”data”:{“uid”:2*8,”uname”:” 陌 * 落 ”,”is_admin”:false,”svip”:1}}
四个包黏在一起 (—_— |||。可以看到,舰长的消息是 WELCOME_GUARD 而且会有一个 ENTRY_EFFECT 消息,老爷进入只有 WELCOME 消息。WELCOME_GUARD 消息中,data.uid 为用户 ID,data.username 为用户名称,data.guard_level 表示舰长等级。welcome 消息中,data.uid 为用户 ID,data.uname 为用户名称,(乃们命名不能统一一点吗……)is_admin 表示是否是房管,vip 为 1 的时候表示是老爷,svip 为 1 的时候表示是年费老爷。
(待续。。。