Merge pull request #1 from czp3009/master

p
This commit is contained in:
sunyymq 2018-05-02 15:15:20 +08:00 committed by GitHub
commit 1d91763f96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
156 changed files with 11202 additions and 806 deletions

206
README.md
View File

@ -3,7 +3,7 @@
由于B站即使更新客户端, 也会继续兼容以前的旧版本客户端, 所以短期内不用担心 API 失效的问题.
注意, 该项目使用 Bilibili Android 客户端协议, 与 Web 端的协议有差异, 不要提交 Web 端有关的 API.
对于一些 Bilibili Android APP 上没有的功能, 可以先[将 token 转换为 cookie](#sso), 然后再去调用 Bilibili Web API.
# API 不完全
由于本项目还在开发初期, 大量 API 没有完成, 所以很可能没有你想要的 API.
@ -13,7 +13,7 @@
# 添加依赖
## Gradle
compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.4'
compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.10'
# 名词解释
B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一些常见参数对应的含义
@ -35,9 +35,11 @@ B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一
### 登录
使用账户名和密码作为登录参数
BilibiliAPI bilibiliAPI = new BilibiliAPI()
.login(String username, String password) throws IOException, LoginException
String username = "yourUsername";
String password = "yourPassword";
BilibiliAPI bilibiliAPI = new BilibiliAPI();
LoginResponseEntity loginResponseEntity = bilibiliAPI.login(String username, String password);
IOException 在网络故障时抛出
LoginException 在用户名密码不匹配时抛出
@ -46,28 +48,32 @@ CaptchaMismatchException 在验证码不正确时抛出, 见下文 [验证码问
login 方法的返回值为 LoginResponseEntity 类型, 使用
.login(...).toBilibiliAccount()
BilibiliAccount bilibiliAccount = loginResponseEntity.toBilibiliAccount();
来获得一个 BilibiliAccount 实例, 其中包含了 OAuth2 的用户凭证, 如果有需要, 可以将其持久化保存.
将一个登陆状态恢复出来(从之前保存的 BilibiliAccount 实例)使用如下代码
BilibiliAPI bilibiliAPI = new BilibiliAPI(BilibiliAccount bilibiliAccount)
BilibiliAPI bilibiliAPI = new BilibiliAPI(BilibiliAccount bilibiliAccount);
注意, 如果这个 BilibiliAccount 实例含有的 accessToken 是错误的或者过期的, 需要鉴权的 API 将全部 401.
### 刷新 Token
OAuth2 的重要凭证有两个, token 与 refreshToken, token 到期之后, 并不需要再次用用户名密码登录一次, 仅需要用 refreshToken 刷新一次 token 即可(会得到新的 token 和 refreshToken, refreshToken 的有效期不是无限的. B站的 refreshToken 有效期不明确).
bilibiliAPI.refreshToken() throws IOException, LoginException
bilibiliAPI.refreshToken();
IOException 在网络故障时抛出
LoginException 在 token 错误,或者 refreshToken 错误或过期时抛出.
refreshToken 操作在正常情况下将在服务器返回 401(实际上 B站 不用 401 来表示未登录)时自动进行, 因此 BilibiliAPI 内部持有的 BilibiliAccount 的实例的内容可能会发生改变, 如果需要在应用关闭时持久化用户 token, 需要这样来取得最后的 BilibiliAccount 状态
BilibiliAccount bilibiliAccount = bilibiliAPI.getBilibiliAccount();
### 登出
BilibiliRESTAPI.logout() throws IOException, LoginException
bilibiliAPI.logout();
IOException 在网络故障时抛出
@ -93,8 +99,8 @@ LoginException 在 accessToken 错误或过期时抛出
try {
bilibiliAPI.login(username, password);
} catch (CaptchaMismatchException e) { //如果该账号现在需要验证码来进行登录, 就会抛出异常
final cookie = "sid=123456"; //自己造一个 cookie 或者从服务器取得
Response response = bilibiliAPI.getPassportService()
cookie = "sid=123456"; //自己造一个 cookie 或者从服务器取得
Response response = bilibiliAPI.getCaptchaService()
.getCaptcha(cookie)
.execute();
InputStream inputStream = response.body().byteStream();
@ -133,10 +139,72 @@ LoginException 在 accessToken 错误或过期时抛出
这个带验证码的登录接口也会继续抛出 CaptchaMismatchException, 如果验证码输入错误的话.
### SSO
通过 SSO API 可以将 accessToken 转为 cookie, 用 cookie 就可以访问 B站 的 Web API.
B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访问页面时, 处于登录状态).
首先, 我们需要登录
String username = "yourUsername";
String password = "yourPassword";
BilibiliAPI bilibiliAPI = new BilibiliAPI();
bilibiliAPI.login(String username, String password);
通过
bilibiliAPI.toCookies();
来得到对应的 cookies, 类型为 Map<String, List\<Cookie>>, key 为 domain(可能是通配类型的, 例如 ".bilibili.com"), value 为此 domain 对应的 cookies.
如果只想得到用于进行 SSO 操作的那条 URL, 可以这么做
String goUrl = "https://account.bilibili.com/account/home";
bilibiliAPI.getSsoUrl(goUrl);
返回值是一个 HttpUrl, 里面 url 的值差不多是这样的
https://passport.bilibili.com/api/login/sso?access_key=c3bf6002bd2e539f5bfce56308f14789&appkey=1d8b6e7d45233436&build=515000&gourl=https%3A%2F%2Faccount.bilibili.com%2Faccount%2Fhome&mobi_app=android&platform=android&ts=1520079995&sign=654e2d00aa827aa1d7acef6fbeb9ee70
如果 access_key 是正确的话, 这个 url 访问一下就登录 B站 了.
如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址, 如果 goUrl 不存在或为空则将跳转到B站首页).
### Web API
上文讲到, 通过 SSO API, 可以将 token 转为 cookie, 在本项目中, Web API 封装在 BilibiliWebAPI 中, 可以通过如下方式得到一个已经登录了的 BilibiliWebAPI 实例
String username = "yourUsername";
String password = "yourPassword";
BilibiliAPI bilibiliAPI = new BilibiliAPI();
bilibiliAPI.login(String username, String password);
BilibiliWebAPI bilibiliWebAPI = bilibiliAPI.getBilibiliWebAPI();
IOException 在网络错误时抛出(获取 cookie 时需要进行网络请求)
如果将之前的 bilibiliAPI.toCookies() 的返回值(cookiesMap)持久化了下来的话, 下次可以通过以下方式直接获得一个已经登录了的 BilibiliWebAPI 实例(注意, cookie 没有 refreshToken 机制, 过期不会自动刷新, 因此不推荐持久化 cookie)
Map<String, List<Cookie>> cookiesMap = bilibiliAPI.toCookies();
//序列化后存储
//...
//反序列化后得到上次存储的 cookiesMap
BilibiliWebAPI bilibiliWebAPI = new BilibiliWebAPI(cookiesMap);
有了 BilibiliWebAPI 实例之后, 通过类似以下代码的形式来获取对应的 Service, API 调用方法和基于 Token 方式的 API 一致
LiveService liveService = bilibiliWebAPI.getLiveService();
(这个 LiveService 是 Web API 里的 LiveService)
由于 Web API 是有状态的, 每个 BilibiliWebAPI 内部维护的 CookieJar 是同一个, 一些验证有关的 API 可能会改变 cookie.
通过以下代码来获得一个 BilibiliWebAPI 中目前持有的 CookieJar 的引用
bilibiliWebAPI.getCookieJar();
### API 调用示例
打印一个直播间的历史弹幕
int roomId = 3;
long roomId = 3;
new BilibiliAPI()
.getLiveService()
.getHistoryBulletScreens(roomId)
@ -151,14 +219,23 @@ LoginException 在 accessToken 错误或过期时抛出
liveHistoryBulletScreenEntity.getText())
);
发送一条弹幕到指定直播间
签到
String username = "yourUsername";
String password = "yourPassword";
int roomId = 3;
BilibiliAPI bilibiliAPI = new BilibiliAPI()
.login(username, password);
BilibiliAPI bilibiliAPI = new BilibiliAPI();
bilibiliAPI.login(username, password);
bilibiliAPI.getLiveService()
.getSignInfo()
.execute();
发送一条弹幕到指定直播间
long roomId = 3;
String username = "yourUsername";
String password = "yourPassword";
BilibiliAPI bilibiliAPI = new BilibiliAPI();
bilibiliAPI.login(username, password);
bilibiliAPI.getLiveService()
.sendBulletScreen(
@ -167,7 +244,8 @@ LoginException 在 accessToken 错误或过期时抛出
bilibiliAPI.getBilibiliAccount().getUserId(), //实际上并不需要包含 mid 就可以正常发送弹幕, 但是真实的 Android 客户端确实发送了 mid
"这是自动发送的弹幕"
)
).execute();
)
.execute();
(如果要调用需要鉴权的 API, 需要先登录)
@ -178,18 +256,21 @@ API 文档
## Socket
### 获取直播间实时弹幕
int roomId = 3;
long roomId = 3;
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
LiveClient liveClient = new BilibiliAPI()
.getLiveClient(roomId)
.getLiveClient(eventLoopGroup, roomId)
.registerListener(new MyListener())
.connect();
.connect() 会抛出 IOException 当网络故障时.
(connect 以及 close 方法都是阻塞的)
(connect 是阻塞的)
使用 .getLiveClient() 前可以先登录也可以不登陆直接用, 如果 API 已经登录, 那么进房数据包中会带有用户ID, 尚不明确有什么作用, 可能与一些统计有关.
多个 LiveClient 可以复用同一个 EventLoopGroup.
(connect 方法运行结束只代表 socket 确实是连上了, 但是服务器还没有响应进房请求数据包)
(当服务器响应进房请求数据包时才代表真的连上了, 此时会有一个连接成功的事件, 见下文)
@ -216,29 +297,57 @@ API 文档
如果持续 40 秒(心跳包为 30 秒)没有收到任何消息, 将视为掉线, 会跟服务器主动断开连接一样(这通常是发送了服务器无法读取的数据包)触发一次 ConnectionCloseEvent.
liveClient.close();
liveClient.closeChannel();
即可关闭连接.
即可阻塞关闭连接.
liveClient.closeChannelAsync();
即可异步关闭连接.
eventLoopGroup.shutdownGracefully();
即可关闭事件循环, 结束 Nio 工作线程(所有使用这个 EventLoopGroup 的 LiveClient 也将在此时被关闭).
如果需要在直播间发送弹幕可以直接使用如下代码(需要先登录)
String message = "这是一条弹幕";
liveClient.sendBulletScreen(message);
所有的事件(有些数据包我也不知道它里面的一些值是什么含义, /record 目录下面有抓取到的 Json, 可以用来查看):
| 事件 | 抛出条件 |
| :--- | :--- |
| ActivityEventPackageEvent | 收到 ACTIVITY_EVENT 数据包 |
| ChangeRoomInfoPackageEvent | 收到 CHANGE_ROOM_INFO 数据包 |
| ConnectionCloseEvent | 连接断开(主动或被动) |
| ConnectSucceedEvent | 进房成功 |
| CutOffPackageEvent | 收到 CUT_OFF 数据包 |
| DanMuMsgPackageEvent | 收到 DANMU_MSG 数据包 |
| EventCmdPackageEvent | 收到 EVENT_CMD 数据包 |
| GuardBuyPackageEvent | 收到 GUARD_BUY 数据包 |
| GuardMsgPackageEvent | 收到 GUARD_MSG 数据包 |
| LivePackageEvent | 收到 LIVE 数据包 |
| PreparingPackageEvent | 收到 PREPARING 数据包 |
| RaffleEndPackageEvent | 收到 RAFFLE_END 数据包 |
| RaffleStartPackageEvent | 收到 RAFFLE_START 数据包 |
| ReceiveDataPackageDebugEvent | 该事件用于调试, 收到任何 Data 数据包时都会触发 |
| RoomAdminsPackageEvent | 收到 ROOM_ADMINS 数据包 |
| RoomBlockMsgPackageEvent | 收到 ROOM_BLOCK_MSG 数据包 |
| RoomLockPackageEvent | 收到 ROOM_LOCK 数据包 |
| RoomShieldPackageEvent | 收到 ROOM_SHIELD 数据包 |
| RoomSilentOffPackageEvent | 收到 ROOM_SILENT_OFF 数据包 |
| RoomSilentOnPackageEvent | 收到 ROOM_SILENT_ON 数据包 |
| SendGiftPackageEvent | 收到 SEND_GIFT 数据包 |
| SendHeartBeatPackageEvent | 每次发送心跳包后触发一次 |
| SpecialGiftPackageEvent | 收到 SPECIAL_GIFT 数据包 |
| SysGiftPackageEvent | 收到 SYS_GIFT 数据包 |
| SysMsgPackageEvent | 收到 SYS_MSG 数据包 |
| TVEndPackageEvent | 收到 TV_END 数据包 |
| TVStartPackageEvent | 收到 TV_START 数据包 |
| UnknownPackageEvent | B站新增了新种类的数据包, 出现此情况请提交 issue |
| ViewerCountPackageEvent | 收到 房间人数 数据包(不是 Json) |
| WelcomeActivityPackageEvent | 收到 WELCOME_ACTIVITY 数据包 |
| WelcomeGuardPackageEvent | 收到 WELCOME_GUARD 数据包 |
| WelcomePackageEvent | 收到 WELCOME 数据包 |
| WishBottlePackageEvent | 收到 WISH_BOTTLE 数据包 |
@ -280,8 +389,8 @@ room_id 的获取要通过
在代码中我们这样做
int showRoomId = 3;
int roomId = bilibiliAPI.getLiveService()
long showRoomId = 3;
long roomId = bilibiliAPI.getLiveService()
.getRoomInfo(showRoomId)
.execute()
.body()
@ -299,5 +408,52 @@ room_id 的获取要通过
(B站所有 API 无论是否执行成功, HttpStatus 都是 200, 判断 HTTP 状态码是无用的, 必须通过 JSON 中的 code 字段来知道 API 是否执行成功).
# 测试
测试前需要先设置用户名和密码, 在 src/test/resources 目录下, 找到 config-template.json, 将其复制一份到同目录下并命名为 config.json 然后填写其中的字段即可.
本项目使用 JUnit 作为单元测试框架. 命令行只需要执行
gradle test
如果要在 IDEA 上进行测试, 需要运行 test 目录中的 RuleSuite 类(在 IDEA 中打开这个类, 点击行号上的重叠的两个向右箭头图标).
# 继续开发
如果您想加入到开发中, 欢迎提交 Merge Request.
本项目的 Http 请求全部使用 Retrofit 完成, 因此请求的地址和参数需要放在接口中统一管理, 如果您对 Retrofit 不是很熟悉, 可以看[这篇文章](http://square.github.io/retrofit/).
服务器返回值将被 Gson 转换为 Java POJO(Entity), 通过[这篇文章](https://github.com/google/gson/blob/master/UserGuide.md)来了解 Gson.
POJO 使用 IDEA 插件 [GsonFormat](https://plugins.jetbrains.com/plugin/7654-gsonformat) 自动化生成, 而非手动编写, 并且尽可能避免对自动生成的结果进行修改以免导致可能出现混淆或含义不明确的情况.
(插件必须开启 "use SerializedName" 选项从而保证字段名符合小驼峰命名法)
由于 B站 一些 JSON 是瞎鸡巴来的, 比如可能出现以下这种情况
"list": [
{
"name": "value",
},
...
]
此时自动生成的类型将是
List<List> lists
因此必须要为内层元素指定一个具有语义的名称, 例如 Name, 此时类型变为
List<Name> names
API 尽可能按照 UI 位置来排序, 例如
侧拉抽屉 -> 直播中心 -> 我的关注
这是 "直播中心" 页面的第一个可点击控件, 那么下一个 API 或 API 组就应该是第二个可点击组件 "观看历史".
和 UI 不对应的 API, 按照执行顺序排序, 例如进入直播间会按顺序访问一系列 API, 这些 API 就按照时间顺序排序.
对于不知道怎么排的 API, 瞎鸡巴排就好了.
# License
GPL V3

View File

@ -1,5 +1,5 @@
group = 'com.hiczp'
version = '0.0.5'
version = '0.0.10'
description = 'Bilibili android client API library written in Java'
apply plugin: 'idea'
@ -10,7 +10,6 @@ apply plugin: 'signing'
sourceCompatibility = 1.8
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral()
}
@ -22,11 +21,11 @@ dependencies {
// https://mvnrepository.com/artifact/com.google.code.gson/gson
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.2'
// https://mvnrepository.com/artifact/com.squareup.okhttp3/logging-interceptor
compile group: 'com.squareup.okhttp3', name: 'logging-interceptor', version: '3.9.1'
compile group: 'com.squareup.okhttp3', name: 'logging-interceptor', version: '3.10.0'
// https://mvnrepository.com/artifact/org.slf4j/slf4j-api
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
// https://mvnrepository.com/artifact/io.netty/netty-all
compile group: 'io.netty', name: 'netty-all', version: '4.1.20.Final'
compile group: 'io.netty', name: 'netty-all', version: '4.1.22.Final'
// https://mvnrepository.com/artifact/com.google.guava/guava
compile group: 'com.google.guava', name: 'guava', version: '24.0-jre'
}

View File

@ -0,0 +1,4 @@
{
"cmd": "CHANGE_ROOM_INFO",
"background": "http://static.hdslb.com/live-static/images/bg/4.jpg"
}

View File

@ -0,0 +1,5 @@
{
"cmd": "CUT_OFF",
"msg": "禁播游戏",
"roomid": 8446134
}

View File

@ -32,7 +32,8 @@
0,
// svip
10000,
1
1,
""
],
//(, JsonArray )
[
@ -41,9 +42,9 @@
"夏沫",
//
"乄夏沫丶",
//
//
"1547306",
//
//
16746162,
""
],
@ -62,7 +63,10 @@
"title-131-1"
],
0,
0
0,
{
"uname_color": ""
}
],
"cmd": "DANMU_MSG"
}

View File

@ -19,7 +19,8 @@
1,
0,
10000,
1
1,
""
],
[
13,
@ -37,7 +38,10 @@
],
[],
0,
0
0,
{
"uname_color": ""
}
],
"cmd": "DANMU_MSG"
}

View File

@ -0,0 +1,8 @@
{
"roomid": 234024,
"cmd": "EVENT_CMD",
"data": {
"event_type": "flower_rain-16915",
"event_img": "http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/activity/lover_2018/raffle.png"
}
}

View File

@ -0,0 +1,10 @@
{
"cmd": "GUARD_BUY",
"data": {
"uid": 4561799,
"username": "微笑The迪妮莎",
"guard_level": 1,
"num": 1
},
"roomid": "5279"
}

View File

@ -0,0 +1,17 @@
{
"cmd": "RAFFLE_END",
"roomid": 521429,
"data": {
"raffleId": 16897,
"type": "flower_rain",
"from": "鷺沢怜人",
"fromFace": "http://i1.hdslb.com/bfs/face/09eafe44f913012512014e91f25001edf6e072d0.jpg",
"win": {
"uname": "nbqgd",
"face": "http://i1.hdslb.com/bfs/face/09eafe44f913012512014e91f25001edf6e072d0.jpg",
"giftId": 115,
"giftName": "桃花",
"giftNum": 66
}
}
}

View File

@ -0,0 +1,10 @@
{
"cmd": "RAFFLE_START",
"roomid": 234024,
"data": {
"raffleId": 16915,
"type": "flower_rain",
"from": "爱吃喵姐的鱼",
"time": 60
}
}

View File

@ -0,0 +1,14 @@
{
"cmd": "ROOM_ADMINS",
"uids": [
4561799,
432672,
2179804,
7928207,
94380,
1626161,
3168349,
13182672
],
"roomid": 5279
}

View File

@ -0,0 +1,5 @@
{
"cmd": "ROOM_LOCK",
"expire": "2018-03-15 10:24:18",
"roomid": 6477301
}

View File

@ -0,0 +1,11 @@
{
"cmd": "ROOM_SHIELD",
"type": 1,
"user": [],
"keyword": [
"暗号",
"摄像头",
"色相头"
],
"roomid": 505447
}

View File

@ -0,0 +1,9 @@
{
"cmd": "ROOM_SILENT_ON",
"data": {
"type": "level",
"level": 1,
"second": 1520424615
},
"roomid": 5279
}

View File

@ -1,73 +1,85 @@
{
"cmd": "SEND_GIFT",
"data": {
"giftName": "\u4ebf\u5706",
"giftName": "节奏风暴",
"num": 1,
"uname": "\u30c5\u4ee3\u6211\u56de\u5bb6",
"rcost": 106855699,
"uid": 14146398,
"uname": "爱上熹",
"rcost": 569788,
"uid": 230845505,
"top_list": [
{
"uid": 10952886,
"uname": "\u5b89\u4e36\u664b",
"coin": 498900,
"face": "http://static.hdslb.com/images/member/noface.gif",
"guard_level": 0,
"uid": 288348879,
"uname": "我爱我家一生",
"face": "http://i1.hdslb.com/bfs/face/dd52e4f2dfe881751816e45522f504f10458b514.jpg",
"rank": 1,
"score": 498900
},
{
"uid": 13174983,
"uname": "-\u56db\u5b63\u8c46-",
"coin": 384300,
"face": "http://i0.hdslb.com/bfs/face/23f9f57a69378736f68b50fc4cac4f6b01683e97.jpg",
"guard_level": "3",
"rank": 2,
"score": 384300
},
{
"uid": 87444977,
"uname": "\u964c\u964c\u821e\u98ce",
"coin": 377700,
"face": "http://i2.hdslb.com/bfs/face/c06c835bf8ed6401535847bf21e78d4d3b89d402.jpg",
"score": 1852300,
"guard_level": 0,
"isSelf": 0
},
{
"uid": 287551243,
"uname": "熹上城的专属天使菲",
"face": "http://i1.hdslb.com/bfs/face/c3ef04ba6c267c41067cd7708b7abd60c0c5c49f.jpg",
"rank": 2,
"score": 1245200,
"guard_level": 3,
"isSelf": 0
},
{
"uid": 32416351,
"uname": "镜子。。",
"face": "http://i1.hdslb.com/bfs/face/08c54c2c97434811a99e9d070d621ccbb5d3f2c4.jpg",
"rank": 3,
"score": 377700
"score": 332862,
"guard_level": 3,
"isSelf": 0
}
],
"timestamp": 1510565032,
"giftId": 6,
"timestamp": 1520992553,
"giftId": 39,
"giftType": 0,
"action": "\u8d60\u9001",
"super": 0,
"price": 1000,
"rnd": "541907145",
"action": "赠送",
"super": 1,
"price": 100000,
"rnd": "1980508331",
"newMedal": 0,
"newTitle": 0,
"medal": [],
"medal": {
"medalId": "95723",
"medalName": "布丁诶",
"level": 1
},
"title": "",
"beatId": "",
"beatId": "4",
"biz_source": "live",
"metadata": "",
"remain": 0,
"gold": 0,
"silver": 0,
"gold": 88570,
"silver": 127492,
"eventScore": 0,
"eventNum": 0,
"smalltv_msg": [],
"specialGift": null,
"specialGift": {
"id": 207945,
"time": 90,
"hadJoin": 0,
"num": 1,
"content": "你们城里人真会玩",
"action": "start",
"storm_gif": "http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901"
},
"notice_msg": [],
"capsule": {
"normal": {
"coin": 6,
"change": 0,
"coin": 166,
"change": 10,
"progress": {
"now": 4800,
"now": 3630,
"max": 10000
}
},
"colorful": {
"coin": 0,
"coin": 2,
"change": 0,
"progress": {
"now": 0,
@ -75,6 +87,9 @@
}
}
},
"addFollow": 0
"addFollow": 0,
"effect_block": 0,
"coin_type": "gold",
"total_coin": 100000
}
}

View File

@ -0,0 +1,14 @@
{
"cmd": "SPECIAL_GIFT",
"data": {
"39": {
"id": 202090,
"time": 90,
"hadJoin": 0,
"num": 1,
"content": "月轮来袭",
"action": "start",
"storm_gif": "http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901"
}
}
}

View File

@ -0,0 +1,9 @@
{
"cmd": "SYS_GIFT",
"msg": "jjhghhfgh:? 在蜜桃姐姐w的:?直播间7813816:?内赠送:?6:?共450个",
"msg_text": "jjhghhfgh在蜜桃姐姐w的直播间7813816内赠送亿圆共450个",
"roomid": 0,
"real_roomid": 0,
"giftId": 0,
"msgTips": 0
}

View File

@ -0,0 +1,11 @@
{
"cmd": "SYS_GIFT",
"msg": "【情怀家的尹蓝ovo】在直播间【147191】洒下漫天花雨快来拾撷桃花邂逅你的缘分",
"msg_text": "【情怀家的尹蓝ovo】在直播间【147191】洒下漫天花雨快来拾撷桃花邂逅你的缘分",
"tips": "【情怀家的尹蓝ovo】在直播间【147191】洒下漫天花雨快来拾撷桃花邂逅你的缘分",
"url": "http://live.bilibili.com/147191",
"roomid": 147191,
"real_roomid": 147191,
"giftId": 116,
"msgTips": 0
}

View File

@ -0,0 +1,10 @@
{
"cmd": "SYS_GIFT",
"msg": "十四不落:? 在直播间 :?590:? 使用了 20 倍节奏风暴,大家快去跟风领取奖励吧!",
"tips": "【十四不落】在直播间【590】使用了 20 倍节奏风暴,大家快去跟风领取奖励吧!",
"url": "http://live.bilibili.com/590",
"roomid": 847617,
"real_roomid": 0,
"giftId": 39,
"msgTips": 1
}

View File

@ -1,11 +0,0 @@
{
"cmd": "SYS_GIFT",
"msg": "sakamakiryoryo\u5728\u76f4\u64ad\u95f471084\u5f00\u542f\u4e86\u4e30\u6536\u796d\u5178\uff0c\u4e00\u8d77\u6765\u5206\u4eab\u6536\u83b7\u7684\u798f\u5229\u5427\uff01",
"msg_text": "sakamakiryoryo\u5728\u76f4\u64ad\u95f471084\u5f00\u542f\u4e86\u4e30\u6536\u796d\u5178\uff0c\u4e00\u8d77\u6765\u5206\u4eab\u6536\u83b7\u7684\u798f\u5229\u5427\uff01",
"tips": "sakamakiryoryo\u5728\u76f4\u64ad\u95f471084\u5f00\u542f\u4e86\u4e30\u6536\u796d\u5178\uff0c\u4e00\u8d77\u6765\u5206\u4eab\u6536\u83b7\u7684\u798f\u5229\u5427\uff01",
"url": "http:\/\/live.bilibili.com\/71084",
"roomid": 71084,
"real_roomid": 71084,
"giftId": 102,
"msgTips": 0
}

View File

@ -1,12 +1,12 @@
{
"cmd": "SYS_MSG",
"msg": "\u3010\u5e7d\u5c0f\u591c\u5929\u5c0f\u52ab\u3011:?\u5728\u76f4\u64ad\u95f4:?\u3010392\u3011:?\u8d60\u9001 \u5c0f\u7535\u89c6\u4e00\u4e2a\uff0c\u8bf7\u524d\u5f80\u62bd\u5956",
"msg_text": "\u3010\u5e7d\u5c0f\u591c\u5929\u5c0f\u52ab\u3011:?\u5728\u76f4\u64ad\u95f4:?\u3010392\u3011:?\u8d60\u9001 \u5c0f\u7535\u89c6\u4e00\u4e2a\uff0c\u8bf7\u524d\u5f80\u62bd\u5956",
"msg": "【天南地狗-】:?在直播间:?【531】:?赠送 小电视一个,请前往抽奖",
"msg_text": "【天南地狗-】:?在直播间:?【531】:?赠送 小电视一个,请前往抽奖",
"rep": 1,
"styleType": 2,
"url": "http:\/\/live.bilibili.com\/392",
"roomid": 392,
"real_roomid": 71084,
"rnd": 44332151,
"tv_id": "29349"
"url": "http://live.bilibili.com/531",
"roomid": 531,
"real_roomid": 22237,
"rnd": 1520992662,
"tv_id": "40478"
}

View File

@ -0,0 +1,21 @@
{
"cmd": "TV_END",
"data": {
"id": "39077",
"uname": "かこゆきこvew",
"sname": "是你的苏苏吖",
"giftName": "10W银瓜子",
"mobileTips": "恭喜 かこゆきこvew 获得10W银瓜子",
"raffleId": "39077",
"type": "small_tv",
"from": "是你的苏苏吖",
"fromFace": "http://i0.hdslb.com/bfs/face/147f137d24138d1cfec5443d98ac8b03c4332398.jpg",
"win": {
"uname": "かこゆきこvew",
"face": "http://i0.hdslb.com/bfs/face/4d63bd62322e7f3ef38723a91440bc6930626d9f.jpg",
"giftName": "银瓜子",
"giftId": "silver",
"giftNum": 100000
}
}
}

View File

@ -0,0 +1,23 @@
{
"cmd": "TV_START",
"data": {
"id": "40072",
"dtime": 180,
"msg": {
"cmd": "SYS_MSG",
"msg": "【杰宝Yvan生命倒计时】:?在直播间:?【102】:?赠送 小电视一个,请前往抽奖",
"msg_text": "【杰宝Yvan生命倒计时】:?在直播间:?【102】:?赠送 小电视一个,请前往抽奖",
"rep": 1,
"styleType": 2,
"url": "http://live.bilibili.com/102",
"roomid": 102,
"real_roomid": 5279,
"rnd": 12987955,
"tv_id": "40072"
},
"raffleId": 40072,
"type": "small_tv",
"from": "杰宝Yvan生命倒计时",
"time": 180
}
}

View File

@ -0,0 +1,9 @@
{
"cmd": "WELCOME_ACTIVITY",
"data": {
"uid": 49427998,
"uname": "起个名真tm费事",
"type": "forever_love",
"display_mode": 1
}
}

View File

@ -3,14 +3,20 @@ package com.hiczp.bilibili.api;
import com.hiczp.bilibili.api.interceptor.*;
import com.hiczp.bilibili.api.live.LiveService;
import com.hiczp.bilibili.api.live.socket.LiveClient;
import com.hiczp.bilibili.api.passport.CaptchaService;
import com.hiczp.bilibili.api.passport.PassportService;
import com.hiczp.bilibili.api.passport.SsoService;
import com.hiczp.bilibili.api.passport.entity.InfoEntity;
import com.hiczp.bilibili.api.passport.entity.LoginResponseEntity;
import com.hiczp.bilibili.api.passport.entity.LogoutResponseEntity;
import com.hiczp.bilibili.api.passport.entity.RefreshTokenResponseEntity;
import com.hiczp.bilibili.api.passport.exception.CaptchaMismatchException;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import com.hiczp.bilibili.api.provider.*;
import com.hiczp.bilibili.api.web.BilibiliWebAPI;
import com.hiczp.bilibili.api.web.BrowserProperties;
import com.hiczp.bilibili.api.web.cookie.SimpleCookieJar;
import io.netty.channel.EventLoopGroup;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -18,6 +24,7 @@ import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.security.auth.login.LoginException;
import java.io.IOException;
import java.text.SimpleDateFormat;
@ -25,21 +32,27 @@ import java.time.Instant;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider {
public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProvider, BilibiliSsoProvider, BilibiliWebAPIProvider, LiveClientProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(BilibiliAPI.class);
private final Long apiInitTime = Instant.now().getEpochSecond(); //记录当前类被实例化的时间
private final BilibiliClientProperties bilibiliClientProperties;
private final BilibiliAccount bilibiliAccount;
private Boolean autoRefreshToken = true;
//用于阻止进行多次错误的 refreshToken 操作
private String invalidToken;
private String invalidRefreshToken;
private PassportService passportService;
private CaptchaService captchaService;
private LiveService liveService;
private BilibiliWebAPI bilibiliWebAPI;
public BilibiliAPI() {
this.bilibiliClientProperties = BilibiliClientProperties.defaultSetting();
this.bilibiliAccount = BilibiliAccount.emptyInstance();
@ -50,17 +63,16 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
this.bilibiliAccount = BilibiliAccount.emptyInstance();
}
public BilibiliAPI(BilibiliAccount bilibiliAccount) {
public BilibiliAPI(BilibiliSecurityContext bilibiliSecurityContext) {
this.bilibiliClientProperties = BilibiliClientProperties.defaultSetting();
this.bilibiliAccount = new BilibiliAccount(bilibiliAccount);
this.bilibiliAccount = new BilibiliAccount(bilibiliSecurityContext);
}
public BilibiliAPI(BilibiliClientProperties bilibiliClientProperties, BilibiliAccount bilibiliAccount) {
public BilibiliAPI(BilibiliClientProperties bilibiliClientProperties, BilibiliSecurityContext bilibiliSecurityContext) {
this.bilibiliClientProperties = bilibiliClientProperties;
this.bilibiliAccount = new BilibiliAccount(bilibiliAccount);
this.bilibiliAccount = new BilibiliAccount(bilibiliSecurityContext);
}
//TODO 不明确客户端访问 passport.bilibili.com 时使用的 UA
@Override
public PassportService getPassportService() {
if (passportService == null) {
@ -72,9 +84,15 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
public PassportService getPassportService(@Nonnull List<Interceptor> interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
interceptors.forEach(okHttpClientBuilder::addInterceptor);
//TODO 不明确客户端访问 passport.bilibili.com 时使用的 UA
okHttpClientBuilder
.addInterceptor(new AddFixedHeadersInterceptor(
"Buvid", bilibiliClientProperties.getBuvId(),
"User-Agent", "bili-universal/6560 CFNetwork/894 Darwin/17.4.0" //这是 IOS UA
))
.addInterceptor(new AddDynamicHeadersInterceptor(
() -> "Display-ID", () -> String.format("%s-%d", bilibiliAccount.getUserId() == null ? bilibiliClientProperties.getBuvId() : bilibiliAccount.getUserId(), apiInitTime)
))
.addInterceptor(new AddFixedParamsInterceptor(
"build", bilibiliClientProperties.getBuild(),
"mobi_app", "android",
@ -85,7 +103,11 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
))
.addInterceptor(new AddAppKeyInterceptor(bilibiliClientProperties))
.addInterceptor(new SortParamsAndSignInterceptor(bilibiliClientProperties))
.addInterceptor(new ErrorResponseConverterInterceptor())
.addInterceptor(new ErrorResponseConverterInterceptor());
interceptors.forEach(okHttpClientBuilder::addInterceptor);
okHttpClientBuilder
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(logLevel));
return new Retrofit.Builder()
@ -107,12 +129,10 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
public LiveService getLiveService(@Nonnull List<Interceptor> interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
interceptors.forEach(okHttpClientBuilder::addInterceptor);
okHttpClientBuilder
.addInterceptor(new AddFixedHeadersInterceptor(
"Buvid", bilibiliClientProperties.getBuvId(),
"User-Agent", "Mozilla/5.0 BiliDroid/5.15.0 (bbcallen@gmail.com)",
"User-Agent", String.format("Mozilla/5.0 BiliDroid/%s (bbcallen@gmail.com)", bilibiliClientProperties.getSimpleVersion()),
"Device-ID", bilibiliClientProperties.getHardwareId()
))
.addInterceptor(new AddDynamicHeadersInterceptor(
@ -122,6 +142,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
.addInterceptor(new AddFixedParamsInterceptor(
"_device", "android",
"_hwid", bilibiliClientProperties.getHardwareId(),
"actionKey", "appkey",
"build", bilibiliClientProperties.getBuild(),
"mobi_app", "android",
"platform", "android",
@ -134,7 +155,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
() -> "trace_id", () -> new SimpleDateFormat("yyyyMMddHHmm000ss").format(new Date())
))
.addInterceptor(new AddAppKeyInterceptor(bilibiliClientProperties))
.addInterceptor(new RefreshTokenInterceptor(
.addInterceptor(new AutoRefreshTokenInterceptor(
this,
ServerErrorCode.Common.UNAUTHORIZED,
ServerErrorCode.Live.USER_NO_LOGIN,
@ -144,7 +165,11 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
))
.addInterceptor(new AddAccessKeyInterceptor(bilibiliAccount))
.addInterceptor(new SortParamsAndSignInterceptor(bilibiliClientProperties))
.addInterceptor(new ErrorResponseConverterInterceptor())
.addInterceptor(new ErrorResponseConverterInterceptor());
interceptors.forEach(okHttpClientBuilder::addInterceptor);
okHttpClientBuilder
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(logLevel));
return new Retrofit.Builder()
@ -155,6 +180,102 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
.create(LiveService.class);
}
@Override
public CaptchaService getCaptchaService() {
if (captchaService == null) {
captchaService = getCaptchaService(Collections.emptyList(), HttpLoggingInterceptor.Level.BASIC);
}
return captchaService;
}
public CaptchaService getCaptchaService(@Nonnull List<Interceptor> interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
interceptors.forEach(okHttpClientBuilder::addInterceptor);
okHttpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(logLevel));
return new Retrofit.Builder()
.baseUrl(BaseUrlDefinition.PASSPORT)
.client(okHttpClientBuilder.build())
.build()
.create(CaptchaService.class);
}
public SsoService getSsoService() {
return getSsoService(new SimpleCookieJar());
}
//sso 需要保存 cookie, 不对 SsoService 进行缓存
@Override
public SsoService getSsoService(CookieJar cookieJar) {
return getSsoService(cookieJar, Collections.emptyList(), HttpLoggingInterceptor.Level.BASIC);
}
public SsoService getSsoService(@Nonnull CookieJar cookieJar, @Nonnull List<Interceptor> interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder
.cookieJar(cookieJar)
.addInterceptor(new AddFixedParamsInterceptor(
"build", bilibiliClientProperties.getBuild(),
"mobi_app", "android",
"platform", "android"
))
.addInterceptor(new AddDynamicParamsInterceptor(
() -> "ts", () -> Long.toString(Instant.now().getEpochSecond())
))
.addInterceptor(new AddAccessKeyInterceptor(bilibiliAccount))
.addInterceptor(new AddAppKeyInterceptor(bilibiliClientProperties))
.addInterceptor(new SortParamsAndSignInterceptor(bilibiliClientProperties));
interceptors.forEach(okHttpClientBuilder::addInterceptor);
okHttpClientBuilder
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(logLevel));
return new Retrofit.Builder()
.baseUrl(BaseUrlDefinition.PASSPORT)
.client(okHttpClientBuilder.build())
.build()
.create(SsoService.class);
}
@Override
public HttpUrl getSsoUrl(@Nullable String goUrl) {
CancelRequestInterceptor cancelRequestInterceptor = new CancelRequestInterceptor();
try {
getSsoService(new SimpleCookieJar(), Collections.singletonList(cancelRequestInterceptor), HttpLoggingInterceptor.Level.BASIC)
.sso(goUrl)
.execute();
} catch (IOException ignored) {
}
return cancelRequestInterceptor.getRequest().url();
}
@Override
public Map<String, List<Cookie>> toCookies() throws IOException {
//用这个地址是因为这个地址一定不会改变( B站 未来的更新中)并且很省流量
return toCookies(BaseUrlDefinition.PASSPORT + "api/oauth2/getKey");
}
public Map<String, List<Cookie>> toCookies(@Nullable String goUrl) throws IOException {
SimpleCookieJar simpleCookieJar = new SimpleCookieJar();
getSsoService(simpleCookieJar).sso(goUrl).execute();
return simpleCookieJar.getCookiesMap();
}
@Override
public BilibiliWebAPI getBilibiliWebAPI() throws IOException {
return getBilibiliWebAPI(BrowserProperties.defaultSetting());
}
public BilibiliWebAPI getBilibiliWebAPI(BrowserProperties browserProperties) throws IOException {
if (bilibiliWebAPI == null) {
bilibiliWebAPI = new BilibiliWebAPI(browserProperties, toCookies());
}
return bilibiliWebAPI;
}
public LoginResponseEntity login(@Nonnull String username, @Nonnull String password) throws IOException, LoginException, CaptchaMismatchException {
return login(username, password, null, null);
}
@ -191,6 +312,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
}
}
bilibiliAccount.copyFrom(loginResponseEntity.toBilibiliAccount());
bilibiliWebAPI = null;
LOGGER.info("Login succeed with username: {}", username);
return loginResponseEntity;
}
@ -224,6 +346,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
}
}
bilibiliAccount.copyFrom(refreshTokenResponseEntity.toBilibiliAccount());
bilibiliWebAPI = null;
LOGGER.info("RefreshToken succeed with userId: {}", bilibiliAccount.getUserId());
return refreshTokenResponseEntity;
}
@ -271,10 +394,10 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
}
@Override
public LiveClient getLiveClient(long showRoomId) {
public LiveClient getLiveClient(EventLoopGroup eventLoopGroup, long showRoomId) {
return bilibiliAccount.getUserId() == null ?
new LiveClient(this, showRoomId) :
new LiveClient(this, showRoomId, bilibiliAccount.getUserId());
new LiveClient(this, eventLoopGroup, showRoomId) :
new LiveClient(this, eventLoopGroup, showRoomId, bilibiliAccount.getUserId());
}
private void markCurrentTokenAndRefreshTokenInvalid() {
@ -296,4 +419,13 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider
public BilibiliAccount getBilibiliAccount() {
return bilibiliAccount;
}
public boolean isAutoRefreshToken() {
return autoRefreshToken;
}
public BilibiliAPI setAutoRefreshToken(boolean autoRefreshToken) {
this.autoRefreshToken = autoRefreshToken;
return this;
}
}

View File

@ -8,19 +8,22 @@ public class BilibiliClientProperties {
private String hardwareId = "JxdyESFAJkcjEicQbBBsCTlbal5uX2Y";
private String scale = "xxhdpi";
private String version = "5.15.0.515000";
private String simpleVersion;
private String build;
private String buvId = "JxdyESFAJkcjEicQbBBsCTlbal5uX2Yinfoc";
private BilibiliClientProperties() {
generateBuildProperty();
onVersionChange();
}
public static BilibiliClientProperties defaultSetting() {
return new BilibiliClientProperties();
}
private void generateBuildProperty() {
this.build = version.substring(version.lastIndexOf(".") + 1);
private void onVersionChange() {
int lastIndexOfDot = version.lastIndexOf(".");
this.simpleVersion = version.substring(0, lastIndexOfDot);
this.build = version.substring(lastIndexOfDot + 1);
}
public String getAppKey() {
@ -65,10 +68,14 @@ public class BilibiliClientProperties {
public BilibiliClientProperties setVersion(@Nonnull String version) {
this.version = version;
generateBuildProperty();
onVersionChange();
return this;
}
public String getSimpleVersion() {
return simpleVersion;
}
public String getBuild() {
return build;
}

View File

@ -4,6 +4,7 @@ import com.hiczp.bilibili.api.passport.entity.KeyEntity;
import com.hiczp.bilibili.api.passport.entity.LoginResponseEntity;
import com.hiczp.bilibili.api.passport.entity.LogoutResponseEntity;
import com.hiczp.bilibili.api.passport.entity.RefreshTokenResponseEntity;
import com.hiczp.bilibili.api.provider.BilibiliServiceProvider;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -22,6 +23,14 @@ import java.util.List;
import java.util.stream.Collectors;
public class BilibiliSecurityHelper {
/**
* 加密一个明文密码
*
* @param bilibiliServiceProvider BilibiliServiceProvider 实例
* @param password 明文密码
* @return 密文密码
* @throws IOException 网络错误
*/
private static String cipherPassword(@Nonnull BilibiliServiceProvider bilibiliServiceProvider,
@Nonnull String password) throws IOException {
KeyEntity keyEntity = bilibiliServiceProvider.getPassportService().getKey().execute().body();
@ -46,7 +55,7 @@ public class BilibiliSecurityHelper {
//加密密码
String cipheredPassword;
try {
Cipher cipher = Cipher.getInstance("RSA");
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipheredPassword = new String(
Base64.getEncoder().encode(
@ -61,14 +70,24 @@ public class BilibiliSecurityHelper {
return cipheredPassword;
}
//计算 sign
//传入值为 name1=value1 形式
//传入值必须已经排序
//value 必须已经 URLEncode
/**
* 计算 sign
*
* @param nameAndValues 传入值为 name1=value1 形式, 传入值必须已经排序. value 必须已经经过 URLEncode
* @param appSecret APP 密钥
* @return sign
*/
public static String calculateSign(@Nonnull List<String> nameAndValues, @Nonnull String appSecret) {
return calculateSign(nameAndValues.stream().collect(Collectors.joining("&")), appSecret);
}
/**
* 计算 sign
*
* @param encodedQuery 已经经过 URLEncode 处理的 Query 参数字符串
* @param appSecret APP 密钥
* @return sign
*/
public static String calculateSign(@Nonnull String encodedQuery, @Nonnull String appSecret) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
@ -81,24 +100,56 @@ public class BilibiliSecurityHelper {
}
}
//直接生成添加了 sign query
//传入值为 name1=value1 形式
//传入值必须已经排序
//value 必须已经 URLEncode
/**
* 向一个 Query 参数字符串中添加 sign
*
* @param nameAndValues 传入值为 name1=value1 形式, 传入值必须已经排序. value 必须已经经过 URLEncode
* @param appSecret APP 密钥
* @return 添加了 sign Query 参数字符串
*/
public static String addSignToQuery(@Nonnull List<String> nameAndValues, @Nonnull String appSecret) {
return addSignToQuery(nameAndValues.stream().collect(Collectors.joining("&")), appSecret);
}
/**
* 向一个 Query 参数字符串中添加 sign
*
* @param encodedQuery 已经经过 URLEncode 处理的 Query 参数字符串
* @param appSecret APP 密钥
* @return 添加了 sign Query 参数字符串
*/
public static String addSignToQuery(@Nonnull String encodedQuery, @Nonnull String appSecret) {
return encodedQuery + String.format("&%s=%s", "sign", calculateSign(encodedQuery, appSecret));
}
/**
* 登录
*
* @param bilibiliServiceProvider BilibiliServiceProvider 实例
* @param username 用户名
* @param password 明文密码
* @return 返回值包含有 token refreshToken
* @throws IOException 网络错误
*/
public static LoginResponseEntity login(@Nonnull BilibiliServiceProvider bilibiliServiceProvider,
@Nonnull String username,
@Nonnull String password) throws IOException {
return login(bilibiliServiceProvider, username, password, null, null);
}
/**
* 带验证码的登录
* 在一段时间内使用错误的密码尝试登录多次, 再次使用这个 IP 地址登录这个账号会被要求验证码
*
* @param bilibiliServiceProvider BilibiliServiceProvider 实例
* @param username 用户名
* @param password 明文密码
* @param captcha 验证码
* @param cookie 与验证码对应的 cookies
* @return 返回值包含有 token refreshToken
* @throws IOException 网络错误
* @see com.hiczp.bilibili.api.passport.CaptchaService
*/
public static LoginResponseEntity login(@Nonnull BilibiliServiceProvider bilibiliServiceProvider,
@Nonnull String username,
@Nonnull String password,
@ -114,6 +165,15 @@ public class BilibiliSecurityHelper {
.body();
}
/**
* 刷新 Token
*
* @param bilibiliServiceProvider BilibiliServiceProvider 实例
* @param accessToken token
* @param refreshToken refreshToken
* @return 返回值包含一个新的 token refreshToken
* @throws IOException 网络错误
*/
public static RefreshTokenResponseEntity refreshToken(@Nonnull BilibiliServiceProvider bilibiliServiceProvider,
@Nonnull String accessToken,
@Nonnull String refreshToken) throws IOException {
@ -122,6 +182,14 @@ public class BilibiliSecurityHelper {
.body();
}
/**
* 注销
*
* @param bilibiliServiceProvider BilibiliServiceProvider 实例
* @param accessToken token
* @return 返回 0 表示成功
* @throws IOException 网络错误
*/
public static LogoutResponseEntity logout(@Nonnull BilibiliServiceProvider bilibiliServiceProvider,
@Nonnull String accessToken) throws IOException {
return bilibiliServiceProvider.getPassportService().logout(accessToken)

View File

@ -1,7 +0,0 @@
package com.hiczp.bilibili.api;
import com.hiczp.bilibili.api.live.socket.LiveClient;
public interface LiveClientProvider {
LiveClient getLiveClient(long showRoomId);
}

View File

@ -1,49 +1,116 @@
package com.hiczp.bilibili.api;
//不知道为什么错误码都要加负号
/**
* 不知道为什么错误码都要加负号
* 根据推断, 负数错误码表示是 APP 专用的 API, 正数错误码表示是 Web API 或者共用的 API
*/
public class ServerErrorCode {
//服务网关上鉴权失败的话, 会返回这些标准错误码
//B站后台设计很混乱, 不是所有鉴权都在服务网关上完成
/**
* 服务网关上鉴权失败的话, 会返回这些标准错误码
* B站 后台设计很混乱, 不是所有鉴权都在服务网关上完成
*/
public static class Common {
public static final int API_SIGN_INVALID = -3;
public static final int OK = 0;
/**
* 参数错误或已达 API 每日访问限制(比如银瓜子换硬币每日只能访问一次)
*/
public static final int BAD_REQUEST = -400;
public static final int UNAUTHORIZED = -401;
public static final int FORBIDDEN = -403;
public static final int NOT_FOUND = -404;
/**
* 一些 API 在参数错误的情况下也会引起 -500
*/
public static final int INTERNAL_SERVER_ERROR = -500;
}
//现在 access token 错误统一返回 -101
/**
* 现在 access token 错误统一返回 -101
*/
public static class Passport {
//"access_key not found"
/**
* "access_key not found"
*/
public static final int NO_LOGIN = -101;
//短时间内进行多次错误的登录将被要求输入验证码
/**
* 短时间内进行多次错误的登录将被要求输入验证码
*/
public static final int CAPTCHA_NOT_MATCH = -105;
//用户名不存在
/**
* 用户名不存在
*/
public static final int USERNAME_OR_PASSWORD_INVALID = -629;
//密码不可解密或者密码错误
/**
* 密码不可解密或者密码错误
*/
public static final int CANT_DECRYPT_RSA_PASSWORD = -662;
/**
* B站换了错误码, 现在 "access_key not found." 对应 -101
*/
@Deprecated
public static final int ACCESS_TOKEN_NOT_FOUND = -901; //B站换了错误码, 现在 "access_key not found." 对应 -101
public static final int ACCESS_TOKEN_NOT_FOUND = -901;
/**
* refreshToken token 不匹配
*/
public static final int REFRESH_TOKEN_NOT_MATCH = -903;
}
//一些 API 未登录时返回 3, 一些返回 -101, 还有一些返回 401, 在网关上鉴权的 API 返回 -401
//甚至有一些 API 返回 32205 这种奇怪的错误码
/**
* 一些 API 未登录时返回 3, 一些返回 -101, 还有一些返回 401, 在网关上鉴权的 API 返回 -401, 甚至有一些 API 返回 32205 这种奇怪的错误码
*/
public static class Live {
//"user no login"
/**
* "invalid params"
*/
public static final int INVALID_PARAMS = 1;
/**
* "user no login"
*/
public static final int USER_NO_LOGIN = 3;
//"请登录"
/**
* "请登录"
*/
public static final int PLEASE_LOGIN = 401;
//"请登录"
/**
* "每天最多能兑换 1 个"
*/
public static final int FORBIDDEN = 403;
/**
* 送礼物时房间号与用户号不匹配
* "只能送给主播(591)"
*/
public static final int ONLY_CAN_SEND_TO_HOST = 200012;
/**
* 赠送一个不存在的礼物
* "获取包裹数据失败"
*/
public static final int GET_BAG_DATA_FAIL = 200019;
/**
* "请登录"
*/
public static final int PLEASE_LOGIN0 = 32205;
//"请先登录"
/**
* "message": "invalid request"
* "data": "bad token"
*/
public static final int INVALID_REQUEST = 65530;
/**
* "请先登录"
*/
public static final int NO_LOGIN = -101;
//"关键字不能小于2个字节或大于50字节"
/**
* 搜索时, 关键字字数过少或过多
* "关键字不能小于2个字节或大于50字节"
*/
public static final int KEYWORD_CAN_NOT_LESS_THAN_2_BYTES_OR_GREATER_THAN_50_BYTES = -609;
//已经领取过这个宝箱
/**
* 已经领取过这个宝箱
*/
public static final int THIS_SILVER_TASK_ALREADY_TOOK = -903;
//今天所有的宝箱已经领完
/**
* 今天所有的宝箱已经领完
*/
public static final int NO_MORE_SILVER_TASK = -10017;
}
}

View File

@ -0,0 +1,21 @@
package com.hiczp.bilibili.api.exception;
import java.io.IOException;
public class UserCancelRequestException extends IOException {
public UserCancelRequestException() {
}
public UserCancelRequestException(String message) {
super(message);
}
public UserCancelRequestException(String message, Throwable cause) {
super(message, cause);
}
public UserCancelRequestException(Throwable cause) {
super(cause);
}
}

View File

@ -12,14 +12,18 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.stream.IntStream;
//自动刷新 token
public class RefreshTokenInterceptor implements Interceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(RefreshTokenInterceptor.class);
/**
* 自动刷新 token
* 如果一次请求的返回值表示鉴权失败, 会尝试刷新一次 token 然后自动重放请求
* 刷新 token 的行为将只发生一次, 如果刷新 token 失败, 下次请求的时候不会再次执行刷新 token 操作而会直接返回原本的返回内容
*/
public class AutoRefreshTokenInterceptor implements Interceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(AutoRefreshTokenInterceptor.class);
private BilibiliAPI bilibiliAPI;
private int[] codes;
public RefreshTokenInterceptor(BilibiliAPI bilibiliAPI, int... codes) {
public AutoRefreshTokenInterceptor(BilibiliAPI bilibiliAPI, int... codes) {
this.bilibiliAPI = bilibiliAPI;
this.codes = codes;
}
@ -28,6 +32,10 @@ public class RefreshTokenInterceptor implements Interceptor {
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if (!bilibiliAPI.isAutoRefreshToken()) {
return response;
}
JsonObject jsonObject = InterceptorHelper.getJsonInBody(response);
JsonElement codeElement = jsonObject.get("code");
if (codeElement == null) {

View File

@ -0,0 +1,28 @@
package com.hiczp.bilibili.api.interceptor;
import com.hiczp.bilibili.api.exception.UserCancelRequestException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
/**
* 这个拦截器用于取消请求
* 如果需要让数据经过其他拦截器处理, 但是不想发生真实的网络请求, 就可以使用这个
*
* @see UserCancelRequestException
*/
public class CancelRequestInterceptor implements Interceptor {
private Request request;
@Override
public Response intercept(Chain chain) throws IOException {
request = chain.request();
throw new UserCancelRequestException();
}
public Request getRequest() {
return request;
}
}

View File

@ -10,8 +10,11 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
//由于服务器返回错误时的 data 字段类型不固定, 会导致 json 反序列化出错.
//该拦截器将在返回的 code 不为 0 , response 转换为包含一个空 data json 字符串.
/**
* 错误返回码内容转换拦截器
* 由于服务器返回错误时的 data 字段类型不固定, 会导致 json 反序列化出错.
* 该拦截器将在返回的 code 不为 0 , response 转换为包含一个空 data json 字符串.
*/
public class ErrorResponseConverterInterceptor implements Interceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(ErrorResponseConverterInterceptor.class);
private static final Gson GSON = new Gson();
@ -24,13 +27,18 @@ public class ErrorResponseConverterInterceptor implements Interceptor {
JsonObject jsonObject = InterceptorHelper.getJsonInBody(response);
JsonElement code = jsonObject.get("code");
//code 字段不存在
if (code == null) {
if (code == null || code.isJsonNull()) {
return response;
}
//code 0
if (code.getAsInt() == ServerErrorCode.Common.OK) {
try {
if (code.getAsInt() == ServerErrorCode.Common.OK) {
return response;
}
} catch (NumberFormatException e) { //如果 code 不是数字的话直接返回
return response;
}
//打印 body
LOGGER.error("Get error response below: \n{}",
new GsonBuilder()

View File

@ -5,80 +5,215 @@ import com.hiczp.bilibili.api.live.entity.*;
import retrofit2.Call;
import retrofit2.http.*;
/* 常见参数含义
mid: 用户 id, 也可能是指主播的用户 id
cid: 房间 id, 可以指 room_id 也可以指 show_room_id, 推荐所有 API 都使用 room_id 进行访问
*/
/**
* 常见参数含义
* mid: 用户 id, 也可能是指主播的用户 id
* cid: 房间 id, 可以指 room_id 也可以指 show_room_id, 推荐所有 API 都使用 room_id 进行访问
*/
public interface LiveService {
//type 必须是 "all", 否则返回的所有字段的值都是 0
/**
* 获取弹幕设置
*
* @param type 必须是 "all", 否则返回的所有字段的值都是 0
*/
@GET("AppRoom/danmuConfig")
Call<BulletScreenConfigEntity> getBulletScreenConfig(@Query("type") String type);
/**
* 获取弹幕设置的快捷调用
*/
default Call<BulletScreenConfigEntity> getBulletScreenConfig() {
return getBulletScreenConfig("all");
}
//获得房间的历史弹幕(十条)
/**
* 获得房间的历史弹幕(十条)
*
* @param roomId 房间号
*/
@GET("AppRoom/msg")
Call<LiveHistoryBulletScreensEntity> getHistoryBulletScreens(@Query("room_id") long roomId);
//获取房间信息
//登录后访问该 API 将在服务器新增一条直播间观看历史
/**
* 获取直播间信息
* 登录后访问该 API 将在服务器新增一条直播间观看历史
*
* @param roomId 房间号
*/
@GET("AppRoom/index")
Call<LiveRoomInfoEntity> getRoomInfo(@Query("room_id") long roomId);
//获得是否关注了一个主播
//未登录时返回 401
/**
* 获得是否关注了一个主播
*
* @param hostUserId 主播的用户 ID
* @return 未登录时返回 401
*/
@POST("feed/v1/feed/isFollowed")
Call<IsFollowedResponseEntity> isFollowed(@Query("follow") long hostUserId);
//TODO sendDaily
// API 意义不明
@GET("AppBag/sendDaily")
Call<SendDailyResponseEntity> sendDaily();
//获得所有礼物的列表
/**
* 获得所有礼物的列表
*/
@GET("AppIndex/getAllItem")
Call<ItemsEntity> getAllItem();
// API 的返回值意义不明确, 所有房间似乎都一样, 且返回的 code -400
/**
* 查看可用的小电视抽奖
*
* @param roomId 房间号
* @return 当目标房间没有可用的小电视抽奖时返回 -400
*/
@GET("AppSmallTV/index")
Call<AppSmallTVEntity> getAppSmallTV();
Call<AppSmallTVEntity> getAppSmallTV(@Query("roomid") long roomId);
//获得所有头衔的列表
//这里的 Title 是头衔的意思
/**
* 参与小电视抽奖
* 房间号必须与小电视号对应
* SYS_MSG 里面取得的小电视编号是一个字符串, 实际上它肯定是一个数字
*
* @param roomId 房间号
* @param tvId 小电视号
* @return 目标小电视不存在时(房间号与小电视号不匹配时也视为不存在)返回 -400 "不存在小电视信息"
*/
@POST("AppSmallTV/join")
Call<JoinAppSmallTVResponseEntity> joinAppSmallTV(@Query("roomid") long roomId, @Query("id") String tvId);
/**
* 通过 getAppSmallTV 取得的小电视编号是一个数字
*
* @param roomId 房间号
* @param tvId 小电视号
*/
default Call<JoinAppSmallTVResponseEntity> joinAppSmallTV(long roomId, long tvId) {
return joinAppSmallTV(roomId, String.valueOf(tvId));
}
/**
* 获得小电视抽奖结果(不访问这个 API, 奖励也会自动进入背包)
*
* @param tvId 小电视号
* @return 返回内容中的 status 0 , 表示返回正常开奖结果, 1 为没有参与抽奖或小电视已过期, 2 为正在开奖过程中
*/
@GET("AppSmallTV/getReward")
Call<GetAppSmallTVRewardResponseEntity> getAppSmallTVReward(@Query("id") long tvId);
/**
* 获得所有头衔的列表
* 这里的 Title 是头衔的意思
*/
@GET("appUser/getTitle")
Call<TitlesEntity> getTitle();
//这个 API 不是很明确, 所有房间都一样, 可能和什么活动有关
//TODO 查看房间里是否有节奏风暴
@GET("SpecialGift/room/{roomId}")
Call<SpecialGiftEntity> getSpecialGift(@Path("roomId") long roomId);
//TODO 参与节奏风暴抽奖
//TODO 查看节奏风暴奖励
//获取自己的用户信息(live 站的个人信息, 非总站)
//未登录时返回 3
/**
* 获取自己的用户信息(live 站的个人信息, 非总站)
*
* @return 未登录时返回 3
*/
@GET("mobile/getUser")
Call<UserInfoEntity> getUserInfo();
//获取一个直播间的流地址(flv)
//这里的 cid 必须用实际的 room_id, 不能使用 show_room_id, 否则得不到 playUrl. 实际 room_id 要首先通过 getRoomInfo() 获取
//outputType 为固定值 "json", 否则返回一个空的 JsonArray (以前是返回一个 XML)
/**
* 获取一个直播间的流地址(flv)
*
* @param cid 必须用实际的 room_id, 不能使用 show_room_id, 否则得不到 playUrl. 实际 room_id 要首先通过 getRoomInfo() 获取
* @param outputType 为固定值 "json", 否则返回一个空的 JsonArray (以前是返回一个 XML)
*/
@GET("api/playurl")
Call<PlayUrlEntity> getPlayUrl(@Query("cid") long cid, @Query("otype") String outputType);
/**
* 获取直播间推流地址的快捷调用
*
* @param cid 房间号
*/
default Call<PlayUrlEntity> getPlayUrl(long cid) {
return getPlayUrl(cid, "json");
}
//发送一个 Restful 的心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级
//未登录时返回 3
/**
* 获取当前这段时间的活动(不定期活动, 每次持续几周)和信仰任务
*
* @param roomId 房间号
*/
@GET("activity/v1/Common/mobileActivity")
Call<MobileActivityEntity> getMobileActivity(@Query("roomid") long roomId);
/**
* 获取用户的信仰任务列表
*
* @return 2018-02 现在只有 double_watch_task 这个任务是有效的
*/
@GET("activity/v1/task/user_tasks")
Call<UserTasksEntity> getUserTasks();
/**
* 领取一个信仰任务
*
* @param taskId 任务名
* @return 任务未完成或者已领取返回 -400
*/
@POST("activity/v1/task/receive_award")
Call<ReceiveUserTaskAward> receiveUserTaskAward(@Query("task_id") String taskId);
/**
* 领取 double_watch_task 任务的奖励
*/
default Call<ReceiveUserTaskAward> receiveDoubleWatchTaskAward() {
return receiveUserTaskAward("double_watch_task");
}
//TODO 查看一个房间是否有活动抽奖
//TODO 参与活动抽奖
//TODO 查看活动抽奖奖励
/**
* 发送一个 Restful 心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级
* 2018-03-06 开始, 只有老爷才能通过观看直播获得经验
*
* @param roomId 房间号
* @param scale 屏幕大小
* @return 未登录时返回 3
*/
@POST("mobile/userOnlineHeart")
@FormUrlEncoded
Call<SendOnlineHeartResponseEntity> sendOnlineHeart(@Field("room_id") long roomId, @Field("scale") String scale);
/**
* 发送心跳包的快捷调用
*
* @param roomId 房间号
*/
default Call<SendOnlineHeartResponseEntity> sendOnlineHeart(long roomId) {
return sendOnlineHeart(roomId, BilibiliClientProperties.defaultSetting().getScale());
}
//发送一条弹幕
/**
* 发送一条弹幕
*
* @param cid 房间号
* @param mid 自己的用户 ID
* @param message 内容
* @param random 随机数
* @param mode 弹幕模式
* @param pool 弹幕池
* @param type 必须为 "json"
* @param color 颜色
* @param fontSize 字体大小
* @param playTime 播放时间
* @see BulletScreenEntity
*/
@POST("api/sendmsg")
@FormUrlEncoded
Call<SendBulletScreenResponseEntity> sendBulletScreen(@Field("cid") long cid,
@ -92,6 +227,11 @@ public interface LiveService {
@Field("fontsize") int fontSize,
@Field("playTime") String playTime);
/**
* 发送弹幕的快捷调用
*
* @param bulletScreenEntity 弹幕实体类
*/
default Call<SendBulletScreenResponseEntity> sendBulletScreen(BulletScreenEntity bulletScreenEntity) {
return sendBulletScreen(
bulletScreenEntity.getCid(),
@ -107,23 +247,45 @@ public interface LiveService {
);
}
//获取下一个宝箱任务的信息
/**
* 获取下一个宝箱任务的信息
*/
@GET("mobile/freeSilverCurrentTask")
Call<FreeSilverCurrentTaskEntity> getFreeSilverCurrentTask();
//领取宝箱
/**
* 领取宝箱
*/
@GET("mobile/freeSilverAward")
Call<FreeSilverAwardEntity> getFreeSilverAward();
//查看自己的背包(礼物)
/**
* 查看自己的背包(礼物)
*/
@GET("AppBag/playerBag")
Call<PlayerBagEntity> getPlayerBag();
//查看哪些礼物是活动礼物, 在客户端上, 活动礼物会有一个右上角标记 "活动"
/**
* 查看哪些礼物是活动礼物, 在客户端上, 活动礼物会有一个右上角标记 "活动"
*
* @param roomId 房间号
*/
@GET("AppRoom/activityGift")
Call<ActivityGiftsEntity> getActivityGifts(@Query("room_id") long roomId);
//送礼物
/**
* 送礼物
*
* @param giftId 礼物 ID
* @param number 数量
* @param roomUserId 主播的用户 ID
* @param roomId 房间号
* @param timeStamp 时间戳
* @param bagId 礼物在自己背包里的 ID
* @param random 随机数
* @return roomUserId roomId 不匹配时返回 200012
* bagId 错误时(背包里没有这个礼物)返回 200019
*/
@POST("AppBag/send")
@FormUrlEncoded
Call<SendGiftResponseEntity> sendGift(@Field("giftId") long giftId,
@ -134,6 +296,11 @@ public interface LiveService {
@Field("bag_id") long bagId,
@Field("rnd") long random);
/**
* 送礼物的快捷调用
*
* @param giftEntity 礼物实体类
*/
default Call<SendGiftResponseEntity> sendGift(GiftEntity giftEntity) {
return sendGift(
giftEntity.getGiftId(),
@ -146,44 +313,321 @@ public interface LiveService {
);
}
//获得礼物榜(七日榜)
/**
* 获得礼物榜(七日榜)
*
* @param roomId 房间号
*/
@GET("AppRoom/getGiftTop")
Call<GiftTopEntity> getGiftTop(@Query("room_id") int roomId);
//签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能))(侧拉抽屉 -> 直播中心 -> 右上角日历图标)
//无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign()
@GET("AppUser/getSignInfo")
Call<SignInfoEntity> getSignInfo();
/**
* "直播" 页面(这个页面对应的后台数据, 包括 banner, 推荐主播, 各种分区的推荐等)
*
* @param device 这个 API 会读取 "_device"(固定参数) 或者 "device" 来判断平台, 只需要有一个就能正常工作, 客户端上是两个都有, 且值都为 "android"
*/
@GET("room/v1/AppIndex/getAllList")
Call<AllListEntity> getAllList(@Query("device") String device);
//获得关注列表(直播 -> 关注)
//未登录时返回 32205
@GET("AppFeed/index")
Call<FollowedHostsEntity> getFollowedHosts(@Query("page") long page, @Query("pagesize") long pageSize);
/**
* 获取 "直播" 页面数据的快捷调用
*/
default Call<AllListEntity> getAllList() {
return getAllList("android");
}
//live 站的搜索
//type room 时只返回 房间 的搜索结果
//type user 时只返回 用户 的搜索结果
//type all 房间 用户 的搜索结果都有
/**
* 刷新 "推荐主播" 区域, 必须有 device, platform, scala
* scala xxhdpi 时返回 12 , 客户端显示六个, 刷新两次后再次访问该 API
* API 返回的内容结构与 getAllList 返回的内容中的 recommend_data 字段是一样的
* API 返回的 banner_data 是在普通分区的推荐的上面的那个 banner, 在新版 APP , 点击这个 banner 会固定的跳转到 bilibili 相簿的 画友 标签页
*
* @param device 设备类型
*/
@GET("room/v1/AppIndex/recRefresh")
Call<RecommendRoomRefreshResponseEntity> recommendRefresh(@Query("device") String device);
/**
* 刷新 "推荐主播" 区域 的快捷调用
*/
default Call<RecommendRoomRefreshResponseEntity> recommendRefresh() {
return recommendRefresh("android");
}
/**
* 获取对应分类和状态的直播间
*
* @param areaId 分区 ID
* @param categoryId 不明确其含义
* @param parentAreaId 父分区 ID
* @param sortType 排序方式
* @param page 页码, 可以为 null(第一页)
*/
@GET("room/v1/Area/getRoomList")
Call<RoomListEntity> getRoomList(
@Query("area_id") int areaId,
@Query("cate_id") int categoryId,
@Query("parent_area_id") int parentAreaId,
@Query("sort_type") String sortType,
@Query("page") Long page
);
/**
* 直播页面 下面的 普通分区(复数) 的刷新, 一次会返回 20 个结果, 客户端显示 6 , 数据用完了之后再次访问该 API
*
* @param parentAreaId 父分区 ID
*/
default Call<RoomListEntity> getRoomList(int parentAreaId) {
return getRoomList(0, 0, parentAreaId, "dynamic", null);
}
/**
* 直播 -> 某个分区 -> 查看更多
* 获取该页面上方的分类标签
*
* @param parentAreaId 父分区 ID
*/
@GET("room/v1/Area/getList")
Call<AreaListEntity> getAreaList(@Query("parent_id") int parentAreaId);
/**
* 获取该页面下的的直播间(areaId 0 表示选择了 "全部"(上方的分类标签), areaId 如果和 parentAreaId 不匹配将返回空的 data 字段)
*
* @param areaId 分区 ID
* @param parentAreaId 父分区 ID
* @param page 页码
*/
default Call<RoomListEntity> getRoomList(int areaId, int parentAreaId, long page) {
return getRoomList(areaId, 0, parentAreaId, "online", page);
}
/**
* 直播 -> 全部直播(直播页面的最下面的一个按钮)
*
* @param areaId 分区 ID
* @param page 页码
* @param sort 分类
*/
@GET("mobile/rooms")
Call<RoomsEntity> getRooms(@Query("area_id") int areaId, @Query("page") int page, @Query("sort") String sort);
/**
* 推荐直播
*
* @param page 页码
*/
default Call<RoomsEntity> getSuggestionRooms(int page) {
return getRooms(0, page, "suggestion");
}
/**
* 最热直播
*
* @param page 页码
*/
default Call<RoomsEntity> getHottestRooms(int page) {
return getRooms(0, page, "hottest");
}
/**
* 最新直播
*
* @param page 页码
*/
default Call<RoomsEntity> getLatestRooms(int page) {
return getRooms(0, page, "latest");
}
/**
* 视频轮播
*
* @param page 页码
*/
default Call<RoomsEntity> getRoundRooms(int page) {
return getRooms(0, page, "roundroom");
}
/**
* live 站的搜索("直播" 页面)
*
* @param keyword 关键字
* @param page 页码
* @param pageSize 页容量
* @param type room 时只返回 房间 的搜索结果, user 时只返回 用户 的搜索结果, all 房间 用户 的搜索结果都有
*/
@GET("AppSearch/index")
Call<SearchResponseEntity> search(@Query("keyword") String keyword, @Query("page") long page, @Query("pagesize") long pageSize, @Query("type") String type);
/**
* 搜索的快捷调用
*
* @param keyword 关键字
* @param page 页码
* @param pageSize 页容量
*/
default Call<SearchResponseEntity> search(String keyword, long page, long pageSize) {
return search(keyword, page, pageSize, "all");
}
//"直播" 页面下面的推荐, 每个分类有六个的那种
@GET("mobile/rooms")
Call<RoomsEntity> getRooms();
/**
* 侧拉抽屉 -> 直播中心 -> 右上角日历图标
* 签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能))
*
* @return 无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign()
*/
@GET("AppUser/getSignInfo")
Call<SignInfoEntity> getSignInfo();
//侧拉抽屉 -> 直播中心 -> 佩戴中心
//获得用户拥有的头衔
/**
* 侧拉抽屉 -> 直播中心 -> 我的关注
* 获得关注列表
* 未登录时返回 32205
*
* @param page 页码
* @param pageSize 页容量
*/
@GET("AppFeed/index")
Call<FollowedHostsEntity> getFollowedHosts(@Query("page") long page, @Query("pagesize") long pageSize);
/**
* 侧拉抽屉 -> 直播中心 -> 观看历史
*
* @param page 页码
* @param pageSize 页容量
*/
@GET("AppUser/history")
Call<HistoryEntity> getHistory(@Query("page") long page, @Query("pagesize") long pageSize);
/**
* 佩戴中心
* 侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 粉丝勋章
* 获得用户拥有的粉丝勋章
*/
@GET("AppUser/medal")
Call<MyMedalListEntity> getMyMedalList();
/**
* 佩戴粉丝勋章
*
* @param medalId 勋章 ID
*/
@POST("AppUser/wearMedal")
Call<WearMedalResponseEntity> wearMedal(@Query("medal_id") int medalId);
/**
* 取消佩戴粉丝勋章(取消佩戴当前佩戴着的粉丝勋章)
* URL 上的 canel 不是拼写错误, 它原本就是这样的
*/
@GET("AppUser/canelMedal")
Call<CancelMedalResponseEntity> cancelMedal();
/**
* 侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 我的头衔
* 获得用户拥有的头衔
*/
@GET("appUser/myTitleList")
Call<MyTitleListEntity> getMyTitleList();
//佩戴头衔
@GET("AppUser/wearTitle")
/**
* 获得当前佩戴着的头衔的详情
*
* @return 当前未佩戴任何东西时, 返回的 code -1, message "nodata"
*/
@GET("appUser/getWearTitle")
Call<WearTitleEntity> getWearTitle();
/**
* 佩戴头衔
*
* @param title 头衔名
*/
@POST("AppUser/wearTitle")
Call<WearTitleResponseEntity> wearTitle(@Query("title") String title);
//侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币
// 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次
/**
* 取消佩戴头衔(取消佩戴当前佩戴着的头衔)
*/
@GET("appUser/cancelTitle")
Call<CancelTitleResponseEntity> cancelTitle();
//TODO 头衔工坊(没有可升级头衔, 暂不明确此 API)
/**
* 侧拉抽屉 -> 直播中心 -> 获奖记录
* 获得用户的获奖记录
*/
@GET("AppUser/awards")
Call<AwardsEntity> getAwardRecords();
/**
* 瓜子商店
* 侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币
* 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次
*
* @return 已经兑换过时返回 403
* 2018-03-15 访问此 API 必须有一个合法的 UA, 否则返回 65530
*/
@POST("AppExchange/silver2coin")
Call<Silver2CoinResponseEntity> silver2Coin();
/**
* 扭蛋机
* 侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋
* 获得 扭蛋机(普通扭蛋) 这个页面对应的后台数据
*/
@GET("AppUser/capsuleInfo")
Call<CapsuleInfoEntity> getCapsuleInfo();
/**
* 抽扭蛋
*
* @param count 数量, 只能为 1, 10, 100
* @param type 扭蛋类型, 只能为 "normal" "colorful"
*/
@POST("AppUser/capsuleInfoOpen")
@FormUrlEncoded
Call<OpenCapsuleResponseEntity> openCapsule(@Field("count") int count, @Field("type") String type);
/**
* 抽普通扭蛋
* 侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 ->
* 普通扭蛋的 type "normal"
*
* @param count 数量, 只能为 1, 10, 100
*/
default Call<OpenCapsuleResponseEntity> openNormalCapsule(int count) {
return openCapsule(count, "normal");
}
/**
* 抽梦幻扭蛋
*
* @param count 数量, 只能为 1, 10, 100
*/
default Call<OpenCapsuleResponseEntity> openColorfulCapsule(int count) {
return openCapsule(count, "colorful");
}
/**
* 房间设置
* 侧拉抽屉 -> 直播中心 -> 房间设置 -> (上面的个人信息, 包括 房间号, 粉丝数, UP 经验)
* 根据用户 ID 来获取房间信息, 通常用于获取自己的直播间信息(可以用来获取他人的房间信息)
* API 不会增加直播间观看历史
*
* @param userId 用户 ID
*/
@GET("assistant/getRoomInfo")
Call<AssistantRoomInfoEntity> getAssistantRoomInfo(@Query("uId") long userId);
/**
* 侧拉抽屉 -> 直播中心 -> 房间设置 -> 我的封面
* 获取自己的直播间的封面
*
* @param roomId 房间号
* @return 获取其他人的封面会 -403
*/
@GET("mhand/assistant/getCover")
Call<CoverEntity> getCover(@Query("roomId") long roomId);
//TODO 粉丝勋章(尚未达到开通粉丝勋章的最低要求, 无法对该 API 截包)
}

View File

@ -1,7 +1,7 @@
package com.hiczp.bilibili.api.live.bulletScreen;
import com.hiczp.bilibili.api.BilibiliServiceProvider;
import com.hiczp.bilibili.api.live.entity.BulletScreenEntity;
import com.hiczp.bilibili.api.provider.BilibiliServiceProvider;
public class BulletScreenSendingTask {
private BilibiliServiceProvider bilibiliServiceProvider;

File diff suppressed because one or more lines are too long

View File

@ -2,19 +2,24 @@ package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class AppSmallTVEntity {
/**
* code : -400
* message : no
* data : {"status":-1}
* code : 0
* msg : OK
* message : OK
* data : {"lastid":0,"join":[{"id":39674,"dtime":32}],"unjoin":[{"id":39674,"dtime":32}]}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private DataEntity data;
private Data data;
public int getCode() {
return code;
@ -24,6 +29,14 @@ public class AppSmallTVEntity {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
@ -32,28 +45,106 @@ public class AppSmallTVEntity {
this.message = message;
}
public DataEntity getData() {
public Data getData() {
return data;
}
public void setData(DataEntity data) {
public void setData(Data data) {
this.data = data;
}
public static class DataEntity {
public static class Data {
/**
* status : -1
* lastid : 0
* join : [{"id":39674,"dtime":32}]
* unjoin : [{"id":39674,"dtime":32}]
*/
@SerializedName("status")
private int status;
@SerializedName("lastid")
private long lastid;
@SerializedName("join")
private List<Join> join;
@SerializedName("unjoin")
private List<Unjoin> unjoin;
public int getStatus() {
return status;
public long getLastid() {
return lastid;
}
public void setStatus(int status) {
this.status = status;
public void setLastid(long lastid) {
this.lastid = lastid;
}
public List<Join> getJoin() {
return join;
}
public void setJoin(List<Join> join) {
this.join = join;
}
public List<Unjoin> getUnjoin() {
return unjoin;
}
public void setUnjoin(List<Unjoin> unjoin) {
this.unjoin = unjoin;
}
public static class Join {
/**
* id : 39674
* dtime : 32
*/
@SerializedName("id")
private long id;
@SerializedName("dtime")
private int dtime;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getDtime() {
return dtime;
}
public void setDtime(int dtime) {
this.dtime = dtime;
}
}
public static class Unjoin {
/**
* id : 39674
* dtime : 32
*/
@SerializedName("id")
private long id;
@SerializedName("dtime")
private int dtime;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getDtime() {
return dtime;
}
public void setDtime(int dtime) {
this.dtime = dtime;
}
}
}
}

View File

@ -0,0 +1,116 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class AreaListEntity {
/**
* code : 0
* msg : success
* message : success
* data : [{"id":"56","parent_id":"2","old_area_id":"1","name":"我的世界","act_id":"0"},{"id":"57","parent_id":"2","old_area_id":"1","name":"以撒","act_id":"0"},{"id":"64","parent_id":"2","old_area_id":"1","name":"饥荒","act_id":"0"},{"id":"65","parent_id":"2","old_area_id":"1","name":"彩虹六号","act_id":"0"},{"id":"78","parent_id":"2","old_area_id":"3","name":"DNF","act_id":"0"},{"id":"80","parent_id":"2","old_area_id":"1","name":"绝地求生:大逃杀","act_id":"0"},{"id":"81","parent_id":"2","old_area_id":"3","name":"三国杀","act_id":"0"},{"id":"82","parent_id":"2","old_area_id":"3","name":"剑网3","act_id":"0"},{"id":"83","parent_id":"2","old_area_id":"3","name":"魔兽世界","act_id":"0"},{"id":"84","parent_id":"2","old_area_id":"3","name":"300英雄","act_id":"0"},{"id":"86","parent_id":"2","old_area_id":"4","name":"英雄联盟","act_id":"0"},{"id":"87","parent_id":"2","old_area_id":"3","name":"守望先锋","act_id":"0"},{"id":"88","parent_id":"2","old_area_id":"4","name":"穿越火线","act_id":"0"},{"id":"89","parent_id":"2","old_area_id":"4","name":"CSGO","act_id":"0"},{"id":"90","parent_id":"2","old_area_id":"4","name":"CS","act_id":"0"},{"id":"91","parent_id":"2","old_area_id":"3","name":"炉石传说","act_id":"0"},{"id":"92","parent_id":"2","old_area_id":"4","name":"DOTA2","act_id":"0"},{"id":"93","parent_id":"2","old_area_id":"4","name":"星际争霸2","act_id":"0"},{"id":"102","parent_id":"2","old_area_id":"3","name":"最终幻想14","act_id":"0"},{"id":"112","parent_id":"2","old_area_id":"3","name":"龙之谷","act_id":"0"},{"id":"114","parent_id":"2","old_area_id":"4","name":"风暴英雄","act_id":"0"},{"id":"115","parent_id":"2","old_area_id":"3","name":"坦克世界","act_id":"0"},{"id":"138","parent_id":"2","old_area_id":"1","name":"超级马里奥奥德赛","act_id":"0"},{"id":"147","parent_id":"2","old_area_id":"1","name":"怪物猎人:世界","act_id":"0"},{"id":"107","parent_id":"2","old_area_id":"1","name":"其他游戏","act_id":"0"}]
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private List<Data> data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
public static class Data {
/**
* id : 56
* parent_id : 2
* old_area_id : 1
* name : 我的世界
* act_id : 0
*/
@SerializedName("id")
private String id;
@SerializedName("parent_id")
private String parentId;
@SerializedName("old_area_id")
private String oldAreaId;
@SerializedName("name")
private String name;
@SerializedName("act_id")
private String actId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getOldAreaId() {
return oldAreaId;
}
public void setOldAreaId(String oldAreaId) {
this.oldAreaId = oldAreaId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getActId() {
return actId;
}
public void setActId(String actId) {
this.actId = actId;
}
}
}

View File

@ -0,0 +1,356 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
public class AssistantRoomInfoEntity {
/**
* code : 0
* message : ok
* msg : ok
* data : {"roomId":29434,"face":"https://i1.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg","uname":"hyx5020","rcost":35946,"online":519,"status":0,"fansNum":548,"title":"SpaceX重型猎鹰FH发射重播","istry":0,"try_time":"0000-00-00 00:00:00","is_medal":1,"medal_name":"502零","medal_status":1,"medal_rename_status":1,"master_score":8786,"master_level":11,"master_level_color":5805790,"master_next_level":12,"master_level_current":12450,"max_level":40,"end_day":-1,"identification":1,"identification_check_status":1,"area":33,"open_medal_level":10,"is_set_medal":1,"fulltext":"LV等级5级或UP等级10级才能开通粉丝勋章哦~加油!"}
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("msg")
private String msg;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* roomId : 29434
* face : https://i1.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg
* uname : hyx5020
* rcost : 35946
* online : 519
* status : 0
* fansNum : 548
* title : SpaceX重型猎鹰FH发射重播
* istry : 0
* try_time : 0000-00-00 00:00:00
* is_medal : 1
* medal_name : 502零
* medal_status : 1
* medal_rename_status : 1
* master_score : 8786
* master_level : 11
* master_level_color : 5805790
* master_next_level : 12
* master_level_current : 12450
* max_level : 40
* end_day : -1
* identification : 1
* identification_check_status : 1
* area : 33
* open_medal_level : 10
* is_set_medal : 1
* fulltext : LV等级5级或UP等级10级才能开通粉丝勋章哦~加油
*/
@SerializedName("roomId")
private int roomId;
@SerializedName("face")
private String face;
@SerializedName("uname")
private String uname;
@SerializedName("rcost")
private int rcost;
@SerializedName("online")
private int online;
@SerializedName("status")
private int status;
@SerializedName("fansNum")
private int fansNum;
@SerializedName("title")
private String title;
@SerializedName("istry")
private int istry;
@SerializedName("try_time")
private String tryTime;
@SerializedName("is_medal")
private int isMedal;
@SerializedName("medal_name")
private String medalName;
@SerializedName("medal_status")
private int medalStatus;
@SerializedName("medal_rename_status")
private int medalRenameStatus;
@SerializedName("master_score")
private int masterScore;
@SerializedName("master_level")
private int masterLevel;
@SerializedName("master_level_color")
private int masterLevelColor;
@SerializedName("master_next_level")
private int masterNextLevel;
@SerializedName("master_level_current")
private int masterLevelCurrent;
@SerializedName("max_level")
private int maxLevel;
@SerializedName("end_day")
private int endDay;
@SerializedName("identification")
private int identification;
@SerializedName("identification_check_status")
private int identificationCheckStatus;
@SerializedName("area")
private int area;
@SerializedName("open_medal_level")
private int openMedalLevel;
@SerializedName("is_set_medal")
private int isSetMedal;
@SerializedName("fulltext")
private String fulltext;
public int getRoomId() {
return roomId;
}
public void setRoomId(int roomId) {
this.roomId = roomId;
}
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getRcost() {
return rcost;
}
public void setRcost(int rcost) {
this.rcost = rcost;
}
public int getOnline() {
return online;
}
public void setOnline(int online) {
this.online = online;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getFansNum() {
return fansNum;
}
public void setFansNum(int fansNum) {
this.fansNum = fansNum;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getIstry() {
return istry;
}
public void setIstry(int istry) {
this.istry = istry;
}
public String getTryTime() {
return tryTime;
}
public void setTryTime(String tryTime) {
this.tryTime = tryTime;
}
public int getIsMedal() {
return isMedal;
}
public void setIsMedal(int isMedal) {
this.isMedal = isMedal;
}
public String getMedalName() {
return medalName;
}
public void setMedalName(String medalName) {
this.medalName = medalName;
}
public int getMedalStatus() {
return medalStatus;
}
public void setMedalStatus(int medalStatus) {
this.medalStatus = medalStatus;
}
public int getMedalRenameStatus() {
return medalRenameStatus;
}
public void setMedalRenameStatus(int medalRenameStatus) {
this.medalRenameStatus = medalRenameStatus;
}
public int getMasterScore() {
return masterScore;
}
public void setMasterScore(int masterScore) {
this.masterScore = masterScore;
}
public int getMasterLevel() {
return masterLevel;
}
public void setMasterLevel(int masterLevel) {
this.masterLevel = masterLevel;
}
public int getMasterLevelColor() {
return masterLevelColor;
}
public void setMasterLevelColor(int masterLevelColor) {
this.masterLevelColor = masterLevelColor;
}
public int getMasterNextLevel() {
return masterNextLevel;
}
public void setMasterNextLevel(int masterNextLevel) {
this.masterNextLevel = masterNextLevel;
}
public int getMasterLevelCurrent() {
return masterLevelCurrent;
}
public void setMasterLevelCurrent(int masterLevelCurrent) {
this.masterLevelCurrent = masterLevelCurrent;
}
public int getMaxLevel() {
return maxLevel;
}
public void setMaxLevel(int maxLevel) {
this.maxLevel = maxLevel;
}
public int getEndDay() {
return endDay;
}
public void setEndDay(int endDay) {
this.endDay = endDay;
}
public int getIdentification() {
return identification;
}
public void setIdentification(int identification) {
this.identification = identification;
}
public int getIdentificationCheckStatus() {
return identificationCheckStatus;
}
public void setIdentificationCheckStatus(int identificationCheckStatus) {
this.identificationCheckStatus = identificationCheckStatus;
}
public int getArea() {
return area;
}
public void setArea(int area) {
this.area = area;
}
public int getOpenMedalLevel() {
return openMedalLevel;
}
public void setOpenMedalLevel(int openMedalLevel) {
this.openMedalLevel = openMedalLevel;
}
public int getIsSetMedal() {
return isSetMedal;
}
public void setIsSetMedal(int isSetMedal) {
this.isSetMedal = isSetMedal;
}
public String getFulltext() {
return fulltext;
}
public void setFulltext(String fulltext) {
this.fulltext = fulltext;
}
}
}

View File

@ -0,0 +1,287 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class AwardsEntity {
/**
* code : 0
* message : OK
* data : {"list":[{"id":100000,"uid":1000000,"gift_name":"小电视","gift_type":"2","gift_num":1,"user_name":"打码","user_phone":"打码","user_address":"打码","user_extra_field":"{\"user_area\":\"打码\",\"user_post_code\":\"打码\",\"user_city\":\"打码\",\"user_province\":\"打码\"}","source":"小电视抽奖","source_id":10000,"create_time":"2018-02-01 00:00:00","update_time":null,"expire_time":"2018-02-16 00:00:00","comment":null,"status":0,"expire":true,"finished":true},{"id":10000,"uid":1000000,"gift_name":"小米Max2手机","gift_type":"2","gift_num":1,"user_name":"打码","user_phone":"打码","user_address":"打码","user_extra_field":"{\"user_province\":\"\\u6253\\u7801\",\"user_city\":\"\\u6253\\u7801\",\"user_area\":\"\\u6253\\u7801\",\"user_post_code\":\"打码\"}","source":"小米Max2超耐久直播第二季","source_id":1,"create_time":"2017-06-01 00:00:00","update_time":"2017-06-01 00:00:00","expire_time":"2017-06-30 00:00:00","comment":null,"status":0,"expire":true,"finished":true}],"use_count":0,"count":2}
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("data")
private DataEntity data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public DataEntity getData() {
return data;
}
public void setData(DataEntity data) {
this.data = data;
}
public static class DataEntity {
/**
* list : [{"id":100000,"uid":1000000,"gift_name":"小电视","gift_type":"2","gift_num":1,"user_name":"打码","user_phone":"打码","user_address":"打码","user_extra_field":"{\"user_area\":\"打码\",\"user_post_code\":\"打码\",\"user_city\":\"打码\",\"user_province\":\"打码\"}","source":"小电视抽奖","source_id":10000,"create_time":"2018-02-01 00:00:00","update_time":null,"expire_time":"2018-02-16 00:00:00","comment":null,"status":0,"expire":true,"finished":true},{"id":10000,"uid":1000000,"gift_name":"小米Max2手机","gift_type":"2","gift_num":1,"user_name":"打码","user_phone":"打码","user_address":"打码","user_extra_field":"{\"user_province\":\"\\u6253\\u7801\",\"user_city\":\"\\u6253\\u7801\",\"user_area\":\"\\u6253\\u7801\",\"user_post_code\":\"打码\"}","source":"小米Max2超耐久直播第二季","source_id":1,"create_time":"2017-06-01 00:00:00","update_time":"2017-06-01 00:00:00","expire_time":"2017-06-30 00:00:00","comment":null,"status":0,"expire":true,"finished":true}]
* use_count : 0
* count : 2
*/
@SerializedName("use_count")
private int useCount;
@SerializedName("count")
private int count;
@SerializedName("list")
private List<AwardEntity> awardList;
public int getUseCount() {
return useCount;
}
public void setUseCount(int useCount) {
this.useCount = useCount;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<AwardEntity> getAwardList() {
return awardList;
}
public void setAwardList(List<AwardEntity> awardList) {
this.awardList = awardList;
}
public static class AwardEntity {
/**
* id : 100000
* uid : 1000000
* gift_name : 小电视
* gift_type : 2
* gift_num : 1
* user_name : 打码
* user_phone : 打码
* user_address : 打码
* user_extra_field : {"user_area":"打码","user_post_code":"打码","user_city":"打码","user_province":"打码"}
* source : 小电视抽奖
* source_id : 10000
* create_time : 2018-02-01 00:00:00
* update_time : null
* expire_time : 2018-02-16 00:00:00
* comment : null
* status : 0
* expire : true
* finished : true
*/
@SerializedName("id")
private int id;
@SerializedName("uid")
private int uid;
@SerializedName("gift_name")
private String giftName;
@SerializedName("gift_type")
private String giftType;
@SerializedName("gift_num")
private int giftNum;
@SerializedName("user_name")
private String userName;
@SerializedName("user_phone")
private String userPhone;
@SerializedName("user_address")
private String userAddress;
@SerializedName("user_extra_field")
private String userExtraField;
@SerializedName("source")
private String source;
@SerializedName("source_id")
private int sourceId;
@SerializedName("create_time")
private String createTime;
@SerializedName("update_time")
private Object updateTime;
@SerializedName("expire_time")
private String expireTime;
@SerializedName("comment")
private Object comment;
@SerializedName("status")
private int status;
@SerializedName("expire")
private boolean expire;
@SerializedName("finished")
private boolean finished;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getGiftName() {
return giftName;
}
public void setGiftName(String giftName) {
this.giftName = giftName;
}
public String getGiftType() {
return giftType;
}
public void setGiftType(String giftType) {
this.giftType = giftType;
}
public int getGiftNum() {
return giftNum;
}
public void setGiftNum(int giftNum) {
this.giftNum = giftNum;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPhone() {
return userPhone;
}
public void setUserPhone(String userPhone) {
this.userPhone = userPhone;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public String getUserExtraField() {
return userExtraField;
}
public void setUserExtraField(String userExtraField) {
this.userExtraField = userExtraField;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public int getSourceId() {
return sourceId;
}
public void setSourceId(int sourceId) {
this.sourceId = sourceId;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public Object getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Object updateTime) {
this.updateTime = updateTime;
}
public String getExpireTime() {
return expireTime;
}
public void setExpireTime(String expireTime) {
this.expireTime = expireTime;
}
public Object getComment() {
return comment;
}
public void setComment(Object comment) {
this.comment = comment;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public boolean isExpire() {
return expire;
}
public void setExpire(boolean expire) {
this.expire = expire;
}
public boolean isFinished() {
return finished;
}
public void setFinished(boolean finished) {
this.finished = finished;
}
}
}
}

View File

@ -7,25 +7,35 @@ public class BulletScreenEntity {
private long mid;
//弹幕长度限制为 LiveRoomInfoEntity.getData().getMsgLength(), 但是实际上所有房间的弹幕长度限制都是 20
/**
* 弹幕长度限制为 LiveRoomInfoEntity.getData().getMsgLength(), 对于每个用户而言, 每个房间都一样
* 通过完成 B站 有关任务, 获得成就, 可以加大这个限制(舰长, 老爷等可以直接加大限制), 最长好像是 40 个字
*/
@SerializedName("msg")
private String message;
// web 端发送弹幕, 该字段是固定的, 为用户进入直播页面的时间的时间戳. 但是在 Android , 这是一个随机数
//该随机数不包括符号位有 9
/**
* web 端发送弹幕, 该字段是固定的, 为用户进入直播页面的时间的时间戳. 但是在 Android , 这是一个随机数
* 该随机数不包括符号位有 9
*/
@SerializedName("rnd")
private long random = (long) (Math.random() * (999999999 - (-999999999)) + (-999999999));
//1 普通
//4 底端
//5 顶端
//6 逆向
//7 特殊
//9 高级
//一些模式需要 VIP
/**
* 1 普通
* 4 底端
* 5 顶端
* 6 逆向
* 7 特殊
* 9 高级
* 一些模式需要 VIP
*/
private int mode = 1;
//尚且只见过为 0 的情况
/**
* 弹幕池
* 尚且只见过为 0 的情况
*/
private int pool = 0;
private String type = "json";
@ -37,7 +47,9 @@ public class BulletScreenEntity {
private String playTime = "0.0";
//实际上并不需要包含 mid 就可以正常发送弹幕, 但是真实的 Android 客户端确实发送了 mid
/**
* 实际上并不需要包含 mid 就可以正常发送弹幕, 但是真实的 Android 客户端确实发送了 mid
*/
public BulletScreenEntity(long cid, long mid, String message) {
this.cid = cid;
this.mid = mid;

View File

@ -0,0 +1,44 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class CancelMedalResponseEntity {
/**
* code : 0
* message : OK
* data : []
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("data")
private List<?> data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<?> getData() {
return data;
}
public void setData(List<?> data) {
this.data = data;
}
}

View File

@ -0,0 +1,55 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class CancelTitleResponseEntity {
/**
* code : 0
* msg : success
* message : success
* data : []
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private List<?> data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<?> getData() {
return data;
}
public void setData(List<?> data) {
this.data = data;
}
}

View File

@ -0,0 +1,289 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class CapsuleInfoEntity {
/**
* code : 0
* message : OK
* data : {"normal":{"status":1,"coin":65,"change":5,"progress":{"now":1800,"max":10000},"rule":"使用价值累计达到10000瓜子的礼物包含直接使用瓜子购买、道具包裹但不包括产生梦幻扭蛋币的活动道具可以获得1枚扭蛋币。使用扭蛋币可以参与抽奖。","gift":[{"id":22,"name":"经验曜石","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/22.png?20171116172700"},{"id":21,"name":"经验原石","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/21.png?20171116172700"},{"id":30,"name":"爱心便当","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/30.png?20171116172700"},{"id":0,"name":"小号小电视","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/b.png?20171116172700"},{"id":4,"name":"蓝白胖次","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/4.png?20171116172700"},{"id":3,"name":"B坷垃","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/3.png?20171116172700"},{"id":2,"name":"亿圆","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/2.png?20171116172700"},{"id":1,"name":"辣条","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/1.png?20171116172700"}],"list":[{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验曜石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"五河墨子"},{"num":"1","gift":"经验曜石","date":"2018-03-02","name":"五河墨子"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"吃包子的560"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"莯兮吖"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"莯兮吖"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"黎梦的莫语小迷妹"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"ltg86692169"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"亦真亦幻似梦似醒"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"ATICN"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"黎离溱洧"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"龘卛逼"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"FENGHETAO"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"殇璃奏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"= -"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"楠瓜精"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"楠瓜精"}]},"colorful":{"status":0}}
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* normal : {"status":1,"coin":65,"change":5,"progress":{"now":1800,"max":10000},"rule":"使用价值累计达到10000瓜子的礼物包含直接使用瓜子购买、道具包裹但不包括产生梦幻扭蛋币的活动道具可以获得1枚扭蛋币。使用扭蛋币可以参与抽奖。","gift":[{"id":22,"name":"经验曜石","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/22.png?20171116172700"},{"id":21,"name":"经验原石","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/21.png?20171116172700"},{"id":30,"name":"爱心便当","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/30.png?20171116172700"},{"id":0,"name":"小号小电视","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/b.png?20171116172700"},{"id":4,"name":"蓝白胖次","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/4.png?20171116172700"},{"id":3,"name":"B坷垃","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/3.png?20171116172700"},{"id":2,"name":"亿圆","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/2.png?20171116172700"},{"id":1,"name":"辣条","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/1.png?20171116172700"}],"list":[{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验曜石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"五河墨子"},{"num":"1","gift":"经验曜石","date":"2018-03-02","name":"五河墨子"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"吃包子的560"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"莯兮吖"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"莯兮吖"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"黎梦的莫语小迷妹"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"ltg86692169"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"亦真亦幻似梦似醒"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"ATICN"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"黎离溱洧"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"龘卛逼"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"FENGHETAO"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"殇璃奏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"= -"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"楠瓜精"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"楠瓜精"}]}
* colorful : {"status":0}
*/
@SerializedName("normal")
private Normal normal;
@SerializedName("colorful")
private Colorful colorful;
public Normal getNormal() {
return normal;
}
public void setNormal(Normal normal) {
this.normal = normal;
}
public Colorful getColorful() {
return colorful;
}
public void setColorful(Colorful colorful) {
this.colorful = colorful;
}
public static class Normal {
/**
* status : 1
* coin : 65
* change : 5
* progress : {"now":1800,"max":10000}
* rule : 使用价值累计达到10000瓜子的礼物包含直接使用瓜子购买道具包裹但不包括产生梦幻扭蛋币的活动道具可以获得1枚扭蛋币使用扭蛋币可以参与抽奖
* gift : [{"id":22,"name":"经验曜石","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/22.png?20171116172700"},{"id":21,"name":"经验原石","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/21.png?20171116172700"},{"id":30,"name":"爱心便当","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/30.png?20171116172700"},{"id":0,"name":"小号小电视","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/b.png?20171116172700"},{"id":4,"name":"蓝白胖次","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/4.png?20171116172700"},{"id":3,"name":"B坷垃","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/3.png?20171116172700"},{"id":2,"name":"亿圆","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/2.png?20171116172700"},{"id":1,"name":"辣条","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/1.png?20171116172700"}]
* list : [{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验曜石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"我去取经"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"五河墨子"},{"num":"1","gift":"经验曜石","date":"2018-03-02","name":"五河墨子"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"吃包子的560"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"莯兮吖"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"莯兮吖"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"NShy小马"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"黎梦的莫语小迷妹"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"薄荷and紫苏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"ltg86692169"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"亦真亦幻似梦似醒"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"ATICN"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"黎离溱洧"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"龘卛逼"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"FENGHETAO"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"殇璃奏"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"= -"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"楠瓜精"},{"num":"1","gift":"经验原石","date":"2018-03-02","name":"楠瓜精"}]
*/
@SerializedName("status")
private int status;
@SerializedName("coin")
private long coin;
@SerializedName("change")
private int change;
@SerializedName("progress")
private Progress progress;
@SerializedName("rule")
private String rule;
@SerializedName("gift")
private List<Gift> gift;
@SerializedName("list")
private List<Winner> winners;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public long getCoin() {
return coin;
}
public void setCoin(long coin) {
this.coin = coin;
}
public int getChange() {
return change;
}
public void setChange(int change) {
this.change = change;
}
public Progress getProgress() {
return progress;
}
public void setProgress(Progress progress) {
this.progress = progress;
}
public String getRule() {
return rule;
}
public void setRule(String rule) {
this.rule = rule;
}
public List<Gift> getGift() {
return gift;
}
public void setGift(List<Gift> gift) {
this.gift = gift;
}
public List<Winner> getWinners() {
return winners;
}
public void setWinners(List<Winner> winners) {
this.winners = winners;
}
public static class Progress {
/**
* now : 1800
* max : 10000
*/
@SerializedName("now")
private int now;
@SerializedName("max")
private int max;
public int getNow() {
return now;
}
public void setNow(int now) {
this.now = now;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
}
public static class Gift {
/**
* id : 22
* name : 经验曜石
* img : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/normal/22.png?20171116172700
*/
@SerializedName("id")
private int id;
@SerializedName("name")
private String name;
@SerializedName("img")
private String img;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
}
public static class Winner {
/**
* num : 1
* gift : 经验原石
* date : 2018-03-02
* name : NShy小马
*/
@SerializedName("num")
private String num;
@SerializedName("gift")
private String gift;
@SerializedName("date")
private String date;
@SerializedName("name")
private String name;
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getGift() {
return gift;
}
public void setGift(String gift) {
this.gift = gift;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
public static class Colorful {
/**
* status : 0
*/
@SerializedName("status")
private int status;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
}
}

View File

@ -0,0 +1,199 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class CoverEntity {
/**
* code : 0
* message : OK
* msg : OK
* data : {"cover":"https://i0.hdslb.com/bfs/live/b4d4dbf35f7a30fb6b0a2ea4077514235262797e.jpg","status":1,"reason":"","isup":0,"cover_list":[{"id":381657,"iscover":1,"cover":"https://i0.hdslb.com/bfs/live/b4d4dbf35f7a30fb6b0a2ea4077514235262797e.jpg","status":1,"reason":"","isup":1,"lock":0},{"id":0,"reason":"","cover":"","isup":0,"lock":1,"status":2,"iscover":0},{"id":0,"reason":"","cover":"","isup":0,"lock":1,"status":2,"iscover":0},{"id":0,"reason":"","cover":"","isup":0,"lock":1,"status":2,"iscover":0}]}
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("msg")
private String msg;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* cover : https://i0.hdslb.com/bfs/live/b4d4dbf35f7a30fb6b0a2ea4077514235262797e.jpg
* status : 1
* reason :
* isup : 0
* cover_list : [{"id":381657,"iscover":1,"cover":"https://i0.hdslb.com/bfs/live/b4d4dbf35f7a30fb6b0a2ea4077514235262797e.jpg","status":1,"reason":"","isup":1,"lock":0},{"id":0,"reason":"","cover":"","isup":0,"lock":1,"status":2,"iscover":0},{"id":0,"reason":"","cover":"","isup":0,"lock":1,"status":2,"iscover":0},{"id":0,"reason":"","cover":"","isup":0,"lock":1,"status":2,"iscover":0}]
*/
@SerializedName("cover")
private String cover;
@SerializedName("status")
private int status;
@SerializedName("reason")
private String reason;
@SerializedName("isup")
private int isup;
@SerializedName("cover_list")
private List<CoverList> coverList;
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public int getIsup() {
return isup;
}
public void setIsup(int isup) {
this.isup = isup;
}
public List<CoverList> getCoverList() {
return coverList;
}
public void setCoverList(List<CoverList> coverList) {
this.coverList = coverList;
}
public static class CoverList {
/**
* id : 381657
* iscover : 1
* cover : https://i0.hdslb.com/bfs/live/b4d4dbf35f7a30fb6b0a2ea4077514235262797e.jpg
* status : 1
* reason :
* isup : 1
* lock : 0
*/
@SerializedName("id")
private int id;
@SerializedName("iscover")
private int iscover;
@SerializedName("cover")
private String cover;
@SerializedName("status")
private int status;
@SerializedName("reason")
private String reason;
@SerializedName("isup")
private int isup;
@SerializedName("lock")
private int lock;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getIscover() {
return iscover;
}
public void setIscover(int iscover) {
this.iscover = iscover;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public int getIsup() {
return isup;
}
public void setIsup(int isup) {
this.isup = isup;
}
public int getLock() {
return lock;
}
public void setLock(int lock) {
this.lock = lock;
}
}
}
}

View File

@ -0,0 +1,164 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
public class GetAppSmallTVRewardResponseEntity {
/**
* code : 0
* msg : ok
* message : ok
* data : {"fname":"","sname":"麦麦0w0","win":0,"reward":{"id":7,"num":2,"name":"辣条","url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-1.png?20171118161652"},"status":0}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* fname :
* sname : 麦麦0w0
* win : 0
* reward : {"id":7,"num":2,"name":"辣条","url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-1.png?20171118161652"}
* status : 0
*/
@SerializedName("fname")
private String fname;
@SerializedName("sname")
private String sname;
@SerializedName("win")
private int win;
@SerializedName("reward")
private Reward reward;
@SerializedName("status")
private int status;
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getWin() {
return win;
}
public void setWin(int win) {
this.win = win;
}
public Reward getReward() {
return reward;
}
public void setReward(Reward reward) {
this.reward = reward;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public static class Reward {
/**
* id : 7
* num : 2
* name : 辣条
* url : http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-1.png?20171118161652
*/
@SerializedName("id")
private int id;
@SerializedName("num")
private int num;
@SerializedName("name")
private String name;
@SerializedName("url")
private String url;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,92 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
public class JoinAppSmallTVResponseEntity {
/**
* code : 0
* msg : OK
* message : OK
* data : {"id":40147,"dtime":179,"status":1}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* id : 40147
* dtime : 179
* status : 1
*/
@SerializedName("id")
private long id;
@SerializedName("dtime")
private int dtime;
@SerializedName("status")
private int status;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getDtime() {
return dtime;
}
public void setDtime(int dtime) {
this.dtime = dtime;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,225 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
public class MobileActivityEntity {
/**
* code : 0
* msg :
* message :
* data : {"activity":{"keyword":"lover_2018","icon_web":"","jump_web":"","icon_mobile":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/activity/lover_2018/mobile.png","jump_mobile":"https://live.bilibili.com/blackboard/hour-rank.html#/?1110317","status":1},"task":{"keyword":"task_2017","icon_web":"//i0.hdslb.com/bfs/live/b86792f129a641d8fd4f1ee4a337fcb9d4eac25c.png","jump_web":"//link.bilibili.com/p/center/index#/user-center/achievement/task","jump_mobile":"https://live.bilibili.com/p/eden/task-h5#/","icon_mobile":"https://i0.hdslb.com/bfs/live/61f1b388c1f4ed2838800a4d928dae5ab03d7c44.png","status":0}}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* activity : {"keyword":"lover_2018","icon_web":"","jump_web":"","icon_mobile":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/activity/lover_2018/mobile.png","jump_mobile":"https://live.bilibili.com/blackboard/hour-rank.html#/?1110317","status":1}
* task : {"keyword":"task_2017","icon_web":"//i0.hdslb.com/bfs/live/b86792f129a641d8fd4f1ee4a337fcb9d4eac25c.png","jump_web":"//link.bilibili.com/p/center/index#/user-center/achievement/task","jump_mobile":"https://live.bilibili.com/p/eden/task-h5#/","icon_mobile":"https://i0.hdslb.com/bfs/live/61f1b388c1f4ed2838800a4d928dae5ab03d7c44.png","status":0}
*/
@SerializedName("activity")
private Activity activity;
@SerializedName("task")
private Task task;
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
}
public Task getTask() {
return task;
}
public void setTask(Task task) {
this.task = task;
}
public static class Activity {
/**
* keyword : lover_2018
* icon_web :
* jump_web :
* icon_mobile : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/activity/lover_2018/mobile.png
* jump_mobile : https://live.bilibili.com/blackboard/hour-rank.html#/?1110317
* status : 1
*/
@SerializedName("keyword")
private String keyword;
@SerializedName("icon_web")
private String iconWeb;
@SerializedName("jump_web")
private String jumpWeb;
@SerializedName("icon_mobile")
private String iconMobile;
@SerializedName("jump_mobile")
private String jumpMobile;
@SerializedName("status")
private int status;
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public String getIconWeb() {
return iconWeb;
}
public void setIconWeb(String iconWeb) {
this.iconWeb = iconWeb;
}
public String getJumpWeb() {
return jumpWeb;
}
public void setJumpWeb(String jumpWeb) {
this.jumpWeb = jumpWeb;
}
public String getIconMobile() {
return iconMobile;
}
public void setIconMobile(String iconMobile) {
this.iconMobile = iconMobile;
}
public String getJumpMobile() {
return jumpMobile;
}
public void setJumpMobile(String jumpMobile) {
this.jumpMobile = jumpMobile;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
public static class Task {
/**
* keyword : task_2017
* icon_web : //i0.hdslb.com/bfs/live/b86792f129a641d8fd4f1ee4a337fcb9d4eac25c.png
* jump_web : //link.bilibili.com/p/center/index#/user-center/achievement/task
* jump_mobile : https://live.bilibili.com/p/eden/task-h5#/
* icon_mobile : https://i0.hdslb.com/bfs/live/61f1b388c1f4ed2838800a4d928dae5ab03d7c44.png
* status : 0
*/
@SerializedName("keyword")
private String keyword;
@SerializedName("icon_web")
private String iconWeb;
@SerializedName("jump_web")
private String jumpWeb;
@SerializedName("jump_mobile")
private String jumpMobile;
@SerializedName("icon_mobile")
private String iconMobile;
@SerializedName("status")
private int status;
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public String getIconWeb() {
return iconWeb;
}
public void setIconWeb(String iconWeb) {
this.iconWeb = iconWeb;
}
public String getJumpWeb() {
return jumpWeb;
}
public void setJumpWeb(String jumpWeb) {
this.jumpWeb = jumpWeb;
}
public String getJumpMobile() {
return jumpMobile;
}
public void setJumpMobile(String jumpMobile) {
this.jumpMobile = jumpMobile;
}
public String getIconMobile() {
return iconMobile;
}
public void setIconMobile(String iconMobile) {
this.iconMobile = iconMobile;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
}
}

View File

@ -0,0 +1,160 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class MyMedalListEntity {
/**
* code : 0
* message : OK
* data : [{"medal_id":7,"medal_name":"欧皇","level":3,"uname":"哔哩哔哩直播","intimacy":218,"next_intimacy":500,"status":1,"color":6406234,"guard_type":0,"buff_msg":""},{"medal_id":296,"medal_name":"滚滚","level":2,"uname":"iPanda熊猫频道","intimacy":200,"next_intimacy":300,"status":0,"color":6406234,"guard_type":0,"buff_msg":""},{"medal_id":1411,"medal_name":"工程师","level":1,"uname":"ici2cc","intimacy":0,"next_intimacy":201,"status":0,"color":6406234,"guard_type":0,"buff_msg":""},{"medal_id":13197,"medal_name":"QPC","level":2,"uname":"QPCKerman","intimacy":299,"next_intimacy":300,"status":0,"color":6406234,"guard_type":0,"buff_msg":""}]
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("data")
private List<Medal> data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<Medal> getData() {
return data;
}
public void setData(List<Medal> data) {
this.data = data;
}
public static class Medal {
/**
* medal_id : 7
* medal_name : 欧皇
* level : 3
* uname : 哔哩哔哩直播
* intimacy : 218
* next_intimacy : 500
* status : 1
* color : 6406234
* guard_type : 0
* buff_msg :
*/
@SerializedName("medal_id")
private int medalId;
@SerializedName("medal_name")
private String medalName;
@SerializedName("level")
private int level;
@SerializedName("uname")
private String uname;
@SerializedName("intimacy")
private int intimacy;
@SerializedName("next_intimacy")
private int nextIntimacy;
@SerializedName("status")
private int status;
@SerializedName("color")
private int color;
@SerializedName("guard_type")
private int guardType;
@SerializedName("buff_msg")
private String buffMsg;
public int getMedalId() {
return medalId;
}
public void setMedalId(int medalId) {
this.medalId = medalId;
}
public String getMedalName() {
return medalName;
}
public void setMedalName(String medalName) {
this.medalName = medalName;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public int getIntimacy() {
return intimacy;
}
public void setIntimacy(int intimacy) {
this.intimacy = intimacy;
}
public int getNextIntimacy() {
return nextIntimacy;
}
public void setNextIntimacy(int nextIntimacy) {
this.nextIntimacy = nextIntimacy;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getGuardType() {
return guardType;
}
public void setGuardType(int guardType) {
this.guardType = guardType;
}
public String getBuffMsg() {
return buffMsg;
}
public void setBuffMsg(String buffMsg) {
this.buffMsg = buffMsg;
}
}
}

View File

@ -0,0 +1,172 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class OpenCapsuleResponseEntity {
/**
* code : 0
* message : OK
* data : {"status":1,"text":[{"name":"辣条","num":"1","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/open/normal/1.png?20171116172700"}],"isEntity":0,"coin":43,"progress":{"now":7000,"max":10000}}
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* status : 1
* text : [{"name":"辣条","num":"1","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/open/normal/1.png?20171116172700"}]
* isEntity : 0
* coin : 43
* progress : {"now":7000,"max":10000}
*/
@SerializedName("status")
private int status;
@SerializedName("isEntity")
private int isEntity;
@SerializedName("coin")
private int coin;
@SerializedName("progress")
private Progress progress;
@SerializedName("text")
private List<Gift> gifts;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getIsEntity() {
return isEntity;
}
public void setIsEntity(int isEntity) {
this.isEntity = isEntity;
}
public int getCoin() {
return coin;
}
public void setCoin(int coin) {
this.coin = coin;
}
public Progress getProgress() {
return progress;
}
public void setProgress(Progress progress) {
this.progress = progress;
}
public List<Gift> getGifts() {
return gifts;
}
public void setGifts(List<Gift> gifts) {
this.gifts = gifts;
}
public static class Progress {
/**
* now : 7000
* max : 10000
*/
@SerializedName("now")
private int now;
@SerializedName("max")
private int max;
public int getNow() {
return now;
}
public void setNow(int now) {
this.now = now;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
}
public static class Gift {
/**
* name : 辣条
* num : 1
* img : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/capsule-toy/open/normal/1.png?20171116172700
*/
@SerializedName("name")
private String name;
@SerializedName("num")
private String num;
@SerializedName("img")
private String img;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
}
}
}

View File

@ -0,0 +1,55 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class ReceiveUserTaskAward {
/**
* code : 0
* msg :
* message :
* data : []
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private List<?> data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<?> getData() {
return data;
}
public void setData(List<?> data) {
this.data = data;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,12 +9,15 @@ import java.util.List;
public class SendGiftResponseEntity {
/**
* code : 0
* message : ok
* msg : success
* message : success
* data : {"silver":"2696","gold":"0","data":{"giftName":"辣条","num":1,"uname":"czp3009","rcost":31134,"uid":20293030,"top_list":[{"uid":20293030,"uname":"czp3009","coin":25100,"face":"http://i0.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg","guard_level":0,"rank":1,"score":25100},{"uid":19946822,"uname":"罗非鱼追上来了","coin":8000,"face":"http://i2.hdslb.com/bfs/face/e71031a931125617fad2c148213381bb6e0e9f26.jpg","guard_level":0,"rank":2,"score":8000},{"uid":8353249,"uname":"TcCoke","coin":3500,"face":"http://i2.hdslb.com/bfs/face/7c3c131f89380db0046024d1a903d3a6e4dc6128.jpg","guard_level":0,"rank":3,"score":3500}],"timestamp":1509972225,"giftId":1,"giftType":0,"action":"喂食","super":0,"price":100,"rnd":"1430788195","newMedal":0,"newTitle":0,"medal":[],"title":"","beatId":0,"biz_source":"live","metadata":"","remain":1,"gold":0,"silver":0,"eventScore":0,"eventNum":0,"smalltv_msg":[],"specialGift":null,"notice_msg":[],"capsule":{"normal":{"coin":10,"change":0,"progress":{"now":2900,"max":10000}},"colorful":{"coin":0,"change":0,"progress":{"now":0,"max":5000}}},"addFollow":0},"remain":1}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
@ -28,6 +31,14 @@ public class SendGiftResponseEntity {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
@ -138,7 +149,7 @@ public class SendGiftResponseEntity {
@SerializedName("uid")
private int uid;
@SerializedName("timestamp")
private int timestamp;
private long timestamp;
@SerializedName("giftId")
private int giftId;
@SerializedName("giftType")
@ -181,12 +192,15 @@ public class SendGiftResponseEntity {
private int addFollow;
@SerializedName("top_list")
private List<TopListEntity> topList;
/**
* medal 可能是空的 JsonArray, 也可能是一个 JsonObject
*/
@SerializedName("medal")
private List<?> medal;
private JsonElement medal;
@SerializedName("smalltv_msg")
private List<?> smalltvMsg;
private JsonElement smalltvMsg;
@SerializedName("notice_msg")
private List<?> noticeMsg;
private JsonElement noticeMsg;
public String getGiftName() {
return giftName;
@ -228,11 +242,11 @@ public class SendGiftResponseEntity {
this.uid = uid;
}
public int getTimestamp() {
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(int timestamp) {
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
@ -404,27 +418,27 @@ public class SendGiftResponseEntity {
this.topList = topList;
}
public List<?> getMedal() {
public JsonElement getMedal() {
return medal;
}
public void setMedal(List<?> medal) {
public void setMedal(JsonElement medal) {
this.medal = medal;
}
public List<?> getSmalltvMsg() {
public JsonElement getSmalltvMsg() {
return smalltvMsg;
}
public void setSmalltvMsg(List<?> smalltvMsg) {
public void setSmalltvMsg(JsonElement smalltvMsg) {
this.smalltvMsg = smalltvMsg;
}
public List<?> getNoticeMsg() {
public JsonElement getNoticeMsg() {
return noticeMsg;
}
public void setNoticeMsg(List<?> noticeMsg) {
public void setNoticeMsg(JsonElement noticeMsg) {
this.noticeMsg = noticeMsg;
}

View File

@ -0,0 +1,103 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
public class Silver2CoinResponseEntity {
/**
* code : 0
* msg : 兑换成功
* message : 兑换成功
* data : {"silver":"22494","gold":"0","tid":"e32cb3fc6bca9a7dff343469b1ff981f2123","coin":1}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* silver : 22494
* gold : 0
* tid : e32cb3fc6bca9a7dff343469b1ff981f2123
* coin : 1
*/
@SerializedName("silver")
private String silver;
@SerializedName("gold")
private String gold;
@SerializedName("tid")
private String tid;
@SerializedName("coin")
private int coin;
public String getSilver() {
return silver;
}
public void setSilver(String silver) {
this.silver = silver;
}
public String getGold() {
return gold;
}
public void setGold(String gold) {
this.gold = gold;
}
public String getTid() {
return tid;
}
public void setTid(String tid) {
this.tid = tid;
}
public int getCoin() {
return coin;
}
public void setCoin(int coin) {
this.coin = coin;
}
}
}

View File

@ -5,16 +5,19 @@ import com.google.gson.annotations.SerializedName;
public class UserInfoEntity {
/**
* code : 0
* message : ok
* data : {"silver":1896,"gold":0,"vip":0,"svip":0,"svip_time":"0000-00-00 00:00:00","vip_time":"0000-00-00 00:00:00","room_id":1110317,"user_level":20,"user_level_color":6406234,"vip_view_status":1,"isSign":1,"use_count":0,"wearTitle":{"title":"0","activity":"0"}}
* msg : OK
* message : OK
* data : {"silver":129890,"gold":16102,"medal":{"medal_name":"欧皇","level":3,"color":6406234,"medal_color":6406234},"vip":1,"svip":1,"svip_time":"2019-02-09 11:03:54","vip_time":"2019-02-09 11:03:54","wearTitle":{"title":"title-111-1","activity":"bilibili Link"},"isSign":0,"user_level":22,"user_level_color":5805790,"room_id":29434,"use_count":0,"vip_view_status":1}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private UserEntity data;
private Data data;
public int getCode() {
return code;
@ -24,6 +27,14 @@ public class UserInfoEntity {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
@ -32,35 +43,38 @@ public class UserInfoEntity {
this.message = message;
}
public UserEntity getData() {
public Data getData() {
return data;
}
public void setData(UserEntity data) {
public void setData(Data data) {
this.data = data;
}
public static class UserEntity {
public static class Data {
/**
* silver : 1896
* gold : 0
* vip : 0
* svip : 0
* svip_time : 0000-00-00 00:00:00
* vip_time : 0000-00-00 00:00:00
* room_id : 1110317
* user_level : 20
* user_level_color : 6406234
* vip_view_status : 1
* isSign : 1
* silver : 129890
* gold : 16102
* medal : {"medal_name":"欧皇","level":3,"color":6406234,"medal_color":6406234}
* vip : 1
* svip : 1
* svip_time : 2019-02-09 11:03:54
* vip_time : 2019-02-09 11:03:54
* wearTitle : {"title":"title-111-1","activity":"bilibili Link"}
* isSign : 0
* user_level : 22
* user_level_color : 5805790
* room_id : 29434
* use_count : 0
* wearTitle : {"title":"0","activity":"0"}
* vip_view_status : 1
*/
@SerializedName("silver")
private int silver;
@SerializedName("gold")
private int gold;
@SerializedName("medal")
private Medal medal;
@SerializedName("vip")
private int vip;
@SerializedName("svip")
@ -69,20 +83,20 @@ public class UserInfoEntity {
private String svipTime;
@SerializedName("vip_time")
private String vipTime;
@SerializedName("room_id")
private int roomId;
@SerializedName("wearTitle")
private WearTitle wearTitle;
@SerializedName("isSign")
private boolean isSign;
@SerializedName("user_level")
private int userLevel;
@SerializedName("user_level_color")
private int userLevelColor;
@SerializedName("vip_view_status")
private int vipViewStatus;
@SerializedName("isSign")
private int isSign;
@SerializedName("room_id")
private int roomId;
@SerializedName("use_count")
private int useCount;
@SerializedName("wearTitle")
private WearTitleEntity wearTitle;
@SerializedName("vip_view_status")
private int vipViewStatus;
public int getSilver() {
return silver;
@ -100,6 +114,14 @@ public class UserInfoEntity {
this.gold = gold;
}
public Medal getMedal() {
return medal;
}
public void setMedal(Medal medal) {
this.medal = medal;
}
public int getVip() {
return vip;
}
@ -132,12 +154,20 @@ public class UserInfoEntity {
this.vipTime = vipTime;
}
public int getRoomId() {
return roomId;
public WearTitle getWearTitle() {
return wearTitle;
}
public void setRoomId(int roomId) {
this.roomId = roomId;
public void setWearTitle(WearTitle wearTitle) {
this.wearTitle = wearTitle;
}
public boolean isIsSign() {
return isSign;
}
public void setIsSign(boolean isSign) {
this.isSign = isSign;
}
public int getUserLevel() {
@ -156,20 +186,12 @@ public class UserInfoEntity {
this.userLevelColor = userLevelColor;
}
public int getVipViewStatus() {
return vipViewStatus;
public int getRoomId() {
return roomId;
}
public void setVipViewStatus(int vipViewStatus) {
this.vipViewStatus = vipViewStatus;
}
public int getIsSign() {
return isSign;
}
public void setIsSign(int isSign) {
this.isSign = isSign;
public void setRoomId(int roomId) {
this.roomId = roomId;
}
public int getUseCount() {
@ -180,18 +202,68 @@ public class UserInfoEntity {
this.useCount = useCount;
}
public WearTitleEntity getWearTitle() {
return wearTitle;
public int getVipViewStatus() {
return vipViewStatus;
}
public void setWearTitle(WearTitleEntity wearTitle) {
this.wearTitle = wearTitle;
public void setVipViewStatus(int vipViewStatus) {
this.vipViewStatus = vipViewStatus;
}
public static class WearTitleEntity {
public static class Medal {
/**
* title : 0
* activity : 0
* medal_name : 欧皇
* level : 3
* color : 6406234
* medal_color : 6406234
*/
@SerializedName("medal_name")
private String medalName;
@SerializedName("level")
private int level;
@SerializedName("color")
private int color;
@SerializedName("medal_color")
private int medalColor;
public String getMedalName() {
return medalName;
}
public void setMedalName(String medalName) {
this.medalName = medalName;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getMedalColor() {
return medalColor;
}
public void setMedalColor(int medalColor) {
this.medalColor = medalColor;
}
}
public static class WearTitle {
/**
* title : title-111-1
* activity : bilibili Link
*/
@SerializedName("title")

View File

@ -0,0 +1,478 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class UserTasksEntity {
/**
* code : 0
* msg : success
* message : success
* data : {"share_info":{"task_id":"share_task","share_count":0,"progress":{"now":0,"max":1},"status":0,"awards":[{"name":"扭蛋币","type":"toycoin","num":5},{"name":"亲密度","type":"intimacy","num":10}]},"watch_info":{"task_id":"single_watch_task","status":0,"progress":{"now":0,"max":1},"awards":[{"name":"银瓜子","type":"silver","num":500}]},"double_watch_info":{"task_id":"double_watch_task","status":2,"web_watch":1,"mobile_watch":1,"progress":{"now":2,"max":2},"awards":[{"name":"银瓜子","type":"silver","num":700},{"name":"友爱金","type":"union_money","num":1000},{"name":"亲密度","type":"intimacy","num":20}]}}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* share_info : {"task_id":"share_task","share_count":0,"progress":{"now":0,"max":1},"status":0,"awards":[{"name":"扭蛋币","type":"toycoin","num":5},{"name":"亲密度","type":"intimacy","num":10}]}
* watch_info : {"task_id":"single_watch_task","status":0,"progress":{"now":0,"max":1},"awards":[{"name":"银瓜子","type":"silver","num":500}]}
* double_watch_info : {"task_id":"double_watch_task","status":2,"web_watch":1,"mobile_watch":1,"progress":{"now":2,"max":2},"awards":[{"name":"银瓜子","type":"silver","num":700},{"name":"友爱金","type":"union_money","num":1000},{"name":"亲密度","type":"intimacy","num":20}]}
*/
@SerializedName("share_info")
private ShareInfo shareInfo;
@SerializedName("watch_info")
private WatchInfo watchInfo;
@SerializedName("double_watch_info")
private DoubleWatchInfo doubleWatchInfo;
public ShareInfo getShareInfo() {
return shareInfo;
}
public void setShareInfo(ShareInfo shareInfo) {
this.shareInfo = shareInfo;
}
public WatchInfo getWatchInfo() {
return watchInfo;
}
public void setWatchInfo(WatchInfo watchInfo) {
this.watchInfo = watchInfo;
}
public DoubleWatchInfo getDoubleWatchInfo() {
return doubleWatchInfo;
}
public void setDoubleWatchInfo(DoubleWatchInfo doubleWatchInfo) {
this.doubleWatchInfo = doubleWatchInfo;
}
public static class ShareInfo {
/**
* task_id : share_task
* share_count : 0
* progress : {"now":0,"max":1}
* status : 0
* awards : [{"name":"扭蛋币","type":"toycoin","num":5},{"name":"亲密度","type":"intimacy","num":10}]
*/
@SerializedName("task_id")
private String taskId;
@SerializedName("share_count")
private int shareCount;
@SerializedName("progress")
private Progress progress;
@SerializedName("status")
private int status;
@SerializedName("awards")
private List<Awards> awards;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public int getShareCount() {
return shareCount;
}
public void setShareCount(int shareCount) {
this.shareCount = shareCount;
}
public Progress getProgress() {
return progress;
}
public void setProgress(Progress progress) {
this.progress = progress;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public List<Awards> getAwards() {
return awards;
}
public void setAwards(List<Awards> awards) {
this.awards = awards;
}
public static class Progress {
/**
* now : 0
* max : 1
*/
@SerializedName("now")
private int now;
@SerializedName("max")
private int max;
public int getNow() {
return now;
}
public void setNow(int now) {
this.now = now;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
}
public static class Awards {
/**
* name : 扭蛋币
* type : toycoin
* num : 5
*/
@SerializedName("name")
private String name;
@SerializedName("type")
private String type;
@SerializedName("num")
private int num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
}
public static class WatchInfo {
/**
* task_id : single_watch_task
* status : 0
* progress : {"now":0,"max":1}
* awards : [{"name":"银瓜子","type":"silver","num":500}]
*/
@SerializedName("task_id")
private String taskId;
@SerializedName("status")
private int status;
@SerializedName("progress")
private ProgressX progress;
@SerializedName("awards")
private List<AwardsX> awards;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public ProgressX getProgress() {
return progress;
}
public void setProgress(ProgressX progress) {
this.progress = progress;
}
public List<AwardsX> getAwards() {
return awards;
}
public void setAwards(List<AwardsX> awards) {
this.awards = awards;
}
public static class ProgressX {
/**
* now : 0
* max : 1
*/
@SerializedName("now")
private int now;
@SerializedName("max")
private int max;
public int getNow() {
return now;
}
public void setNow(int now) {
this.now = now;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
}
public static class AwardsX {
/**
* name : 银瓜子
* type : silver
* num : 500
*/
@SerializedName("name")
private String name;
@SerializedName("type")
private String type;
@SerializedName("num")
private int num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
}
public static class DoubleWatchInfo {
/**
* task_id : double_watch_task
* status : 2
* web_watch : 1
* mobile_watch : 1
* progress : {"now":2,"max":2}
* awards : [{"name":"银瓜子","type":"silver","num":700},{"name":"友爱金","type":"union_money","num":1000},{"name":"亲密度","type":"intimacy","num":20}]
*/
@SerializedName("task_id")
private String taskId;
@SerializedName("status")
private int status;
@SerializedName("web_watch")
private int webWatch;
@SerializedName("mobile_watch")
private int mobileWatch;
@SerializedName("progress")
private ProgressXX progress;
@SerializedName("awards")
private List<AwardsXX> awards;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getWebWatch() {
return webWatch;
}
public void setWebWatch(int webWatch) {
this.webWatch = webWatch;
}
public int getMobileWatch() {
return mobileWatch;
}
public void setMobileWatch(int mobileWatch) {
this.mobileWatch = mobileWatch;
}
public ProgressXX getProgress() {
return progress;
}
public void setProgress(ProgressXX progress) {
this.progress = progress;
}
public List<AwardsXX> getAwards() {
return awards;
}
public void setAwards(List<AwardsXX> awards) {
this.awards = awards;
}
public static class ProgressXX {
/**
* now : 2
* max : 2
*/
@SerializedName("now")
private int now;
@SerializedName("max")
private int max;
public int getNow() {
return now;
}
public void setNow(int now) {
this.now = now;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
}
public static class AwardsXX {
/**
* name : 银瓜子
* type : silver
* num : 700
*/
@SerializedName("name")
private String name;
@SerializedName("type")
private String type;
@SerializedName("num")
private int num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
}
}
}

View File

@ -0,0 +1,44 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class WearMedalResponseEntity {
/**
* code : 0
* message : OK
* data : []
*/
@SerializedName("code")
private int code;
@SerializedName("message")
private String message;
@SerializedName("data")
private List<?> data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<?> getData() {
return data;
}
public void setData(List<?> data) {
this.data = data;
}
}

View File

@ -0,0 +1,453 @@
package com.hiczp.bilibili.api.live.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class WearTitleEntity {
/**
* code : 0
* msg : success
* message : success
* data : {"id":"5940800","uid":"2866663","tid":"111","num":"1","score":"0","create_time":"2017-08-03 21:53:22","expire_time":"0000-00-00 00:00:00","status":"1","level":[0],"category":[{"name":"热门","class":"red"}],"pic":[{"id":"title-111-1","title":"2017Blink","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/titles/title/3/title-111-1.png?20180302110600","width":0,"height":0,"is_lihui":0,"lihui_img":"","lihui_width":0,"lihui_height":0}],"title_pic":{"id":"title-111-1","title":"2017Blink","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/titles/title/3/title-111-1.png?20180302110600","width":0,"height":0,"is_lihui":0,"lihui_img":"","lihui_width":0,"lihui_height":0},"name":"bilibili Link","upgrade_score":1000000}
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
private Data data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* id : 5940800
* uid : 2866663
* tid : 111
* num : 1
* score : 0
* create_time : 2017-08-03 21:53:22
* expire_time : 0000-00-00 00:00:00
* status : 1
* level : [0]
* category : [{"name":"热门","class":"red"}]
* pic : [{"id":"title-111-1","title":"2017Blink","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/titles/title/3/title-111-1.png?20180302110600","width":0,"height":0,"is_lihui":0,"lihui_img":"","lihui_width":0,"lihui_height":0}]
* title_pic : {"id":"title-111-1","title":"2017Blink","img":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/titles/title/3/title-111-1.png?20180302110600","width":0,"height":0,"is_lihui":0,"lihui_img":"","lihui_width":0,"lihui_height":0}
* name : bilibili Link
* upgrade_score : 1000000
*/
@SerializedName("id")
private String id;
@SerializedName("uid")
private String uid;
@SerializedName("tid")
private String tid;
@SerializedName("num")
private String num;
@SerializedName("score")
private String score;
@SerializedName("create_time")
private String createTime;
@SerializedName("expire_time")
private String expireTime;
@SerializedName("status")
private String status;
@SerializedName("title_pic")
private TitlePic titlePic;
@SerializedName("name")
private String name;
@SerializedName("upgrade_score")
private int upgradeScore;
@SerializedName("level")
private List<Integer> level;
@SerializedName("category")
private List<Category> category;
@SerializedName("pic")
private List<Pic> pic;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getTid() {
return tid;
}
public void setTid(String tid) {
this.tid = tid;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getScore() {
return score;
}
public void setScore(String score) {
this.score = score;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getExpireTime() {
return expireTime;
}
public void setExpireTime(String expireTime) {
this.expireTime = expireTime;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public TitlePic getTitlePic() {
return titlePic;
}
public void setTitlePic(TitlePic titlePic) {
this.titlePic = titlePic;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getUpgradeScore() {
return upgradeScore;
}
public void setUpgradeScore(int upgradeScore) {
this.upgradeScore = upgradeScore;
}
public List<Integer> getLevel() {
return level;
}
public void setLevel(List<Integer> level) {
this.level = level;
}
public List<Category> getCategory() {
return category;
}
public void setCategory(List<Category> category) {
this.category = category;
}
public List<Pic> getPic() {
return pic;
}
public void setPic(List<Pic> pic) {
this.pic = pic;
}
public static class TitlePic {
/**
* id : title-111-1
* title : 2017Blink
* img : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/titles/title/3/title-111-1.png?20180302110600
* width : 0
* height : 0
* is_lihui : 0
* lihui_img :
* lihui_width : 0
* lihui_height : 0
*/
@SerializedName("id")
private String id;
@SerializedName("title")
private String title;
@SerializedName("img")
private String img;
@SerializedName("width")
private int width;
@SerializedName("height")
private int height;
@SerializedName("is_lihui")
private int isLihui;
@SerializedName("lihui_img")
private String lihuiImg;
@SerializedName("lihui_width")
private int lihuiWidth;
@SerializedName("lihui_height")
private int lihuiHeight;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getIsLihui() {
return isLihui;
}
public void setIsLihui(int isLihui) {
this.isLihui = isLihui;
}
public String getLihuiImg() {
return lihuiImg;
}
public void setLihuiImg(String lihuiImg) {
this.lihuiImg = lihuiImg;
}
public int getLihuiWidth() {
return lihuiWidth;
}
public void setLihuiWidth(int lihuiWidth) {
this.lihuiWidth = lihuiWidth;
}
public int getLihuiHeight() {
return lihuiHeight;
}
public void setLihuiHeight(int lihuiHeight) {
this.lihuiHeight = lihuiHeight;
}
}
public static class Category {
/**
* name : 热门
* class : red
*/
@SerializedName("name")
private String name;
@SerializedName("class")
private String classX;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassX() {
return classX;
}
public void setClassX(String classX) {
this.classX = classX;
}
}
public static class Pic {
/**
* id : title-111-1
* title : 2017Blink
* img : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/titles/title/3/title-111-1.png?20180302110600
* width : 0
* height : 0
* is_lihui : 0
* lihui_img :
* lihui_width : 0
* lihui_height : 0
*/
@SerializedName("id")
private String id;
@SerializedName("title")
private String title;
@SerializedName("img")
private String img;
@SerializedName("width")
private int width;
@SerializedName("height")
private int height;
@SerializedName("is_lihui")
private int isLihui;
@SerializedName("lihui_img")
private String lihuiImg;
@SerializedName("lihui_width")
private int lihuiWidth;
@SerializedName("lihui_height")
private int lihuiHeight;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getIsLihui() {
return isLihui;
}
public void setIsLihui(int isLihui) {
this.isLihui = isLihui;
}
public String getLihuiImg() {
return lihuiImg;
}
public void setLihuiImg(String lihuiImg) {
this.lihuiImg = lihuiImg;
}
public int getLihuiWidth() {
return lihuiWidth;
}
public void setLihuiWidth(int lihuiWidth) {
this.lihuiWidth = lihuiWidth;
}
public int getLihuiHeight() {
return lihuiHeight;
}
public void setLihuiHeight(int lihuiHeight) {
this.lihuiHeight = lihuiHeight;
}
}
}
}

View File

@ -7,12 +7,15 @@ import java.util.List;
public class WearTitleResponseEntity {
/**
* code : 0
* message : 佩戴成功
* msg : success
* message : success
* data : []
*/
@SerializedName("code")
private int code;
@SerializedName("msg")
private String msg;
@SerializedName("message")
private String message;
@SerializedName("data")
@ -26,6 +29,14 @@ public class WearTitleResponseEntity {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMessage() {
return message;
}

View File

@ -1,71 +1,66 @@
package com.hiczp.bilibili.api.live.socket;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.hiczp.bilibili.api.BilibiliServiceProvider;
import com.hiczp.bilibili.api.live.bulletScreen.BulletScreenConstDefinition;
import com.hiczp.bilibili.api.live.entity.BulletScreenEntity;
import com.hiczp.bilibili.api.live.entity.LiveRoomInfoEntity;
import com.hiczp.bilibili.api.live.entity.SendBulletScreenResponseEntity;
import com.hiczp.bilibili.api.live.socket.codec.PackageDecoder;
import com.hiczp.bilibili.api.live.socket.codec.PackageEncoder;
import com.hiczp.bilibili.api.live.socket.event.ConnectionCloseEvent;
import com.hiczp.bilibili.api.live.socket.handler.LiveClientHandler;
import com.hiczp.bilibili.api.provider.BilibiliServiceProvider;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Call;
import javax.annotation.Nonnull;
import java.io.Closeable;
import java.io.IOException;
import java.util.Optional;
public class LiveClient implements Closeable {
public class LiveClient {
private static final Logger LOGGER = LoggerFactory.getLogger(LiveClient.class);
private final EventBus eventBus = new EventBus("BilibiliLiveClientEventBus");
private final BilibiliServiceProvider bilibiliServiceProvider;
private final EventLoopGroup eventLoopGroup;
private final long showRoomId;
private final long userId;
private final EventBus eventBus = new EventBus("BilibiliLiveClientEventBus");
private LiveRoomInfoEntity.LiveRoomEntity liveRoomEntity;
private EventLoopGroup eventLoopGroup;
private Channel channel;
private void initEventBus() {
eventBus.register(new ConnectionCloseListener());
}
public LiveClient(@Nonnull BilibiliServiceProvider bilibiliServiceProvider, long showRoomId) {
this.bilibiliServiceProvider = bilibiliServiceProvider;
this.showRoomId = showRoomId;
this.userId = 0;
initEventBus();
}
public LiveClient(@Nonnull BilibiliServiceProvider bilibiliServiceProvider, long showRoomId, long userId) {
public LiveClient(@Nonnull BilibiliServiceProvider bilibiliServiceProvider, EventLoopGroup eventLoopGroup, long showRoomId, long userId) {
this.bilibiliServiceProvider = bilibiliServiceProvider;
this.eventLoopGroup = eventLoopGroup;
this.showRoomId = showRoomId;
this.userId = userId;
initEventBus();
}
@Nonnull
public LiveClient(@Nonnull BilibiliServiceProvider bilibiliServiceProvider, EventLoopGroup eventLoopGroup, long showRoomId) {
this(bilibiliServiceProvider, eventLoopGroup, showRoomId, 0);
}
public Call<LiveRoomInfoEntity> fetchRoomInfoAsync() {
return bilibiliServiceProvider.getLiveService()
.getRoomInfo(showRoomId);
}
public LiveRoomInfoEntity.LiveRoomEntity fetchRoomInfo() throws IOException {
LiveRoomInfoEntity.LiveRoomEntity liveRoomEntity = bilibiliServiceProvider.getLiveService()
.getRoomInfo(showRoomId)
.execute()
.body()
.getData();
LiveRoomInfoEntity.LiveRoomEntity liveRoomEntity =
fetchRoomInfoAsync()
.execute()
.body()
.getData();
if (liveRoomEntity != null) {
return liveRoomEntity;
} else {
@ -79,16 +74,11 @@ public class LiveClient implements Closeable {
return this;
}
if (eventLoopGroup != null) {
eventLoopGroup.shutdownGracefully();
}
LOGGER.info("Fetching info of live room {}", showRoomId);
liveRoomEntity = fetchRoomInfo();
long roomId = liveRoomEntity.getRoomId();
LOGGER.info("Get actual room id {}", roomId);
eventLoopGroup = new NioEventLoopGroup(1);
LOGGER.debug("Init SocketChannel Bootstrap");
Bootstrap bootstrap = new Bootstrap()
.group(eventLoopGroup)
@ -107,7 +97,7 @@ public class LiveClient implements Closeable {
.addLast(new IdleStateHandler(40, 0, 0))
.addLast(new PackageEncoder())
.addLast(new PackageDecoder())
.addLast(new LiveClientHandler(roomId, userId, eventBus));
.addLast(new LiveClientHandler(self(), roomId, userId));
}
});
@ -120,32 +110,28 @@ public class LiveClient implements Closeable {
.channel();
} catch (InterruptedException e) {
e.printStackTrace();
close();
} catch (Exception e) { //有可能在此时出现网络错误
close();
throw new IOException(e);
}
return this;
}
@Override
public synchronized void close() {
if (eventLoopGroup != null) {
public synchronized ChannelFuture closeChannelAsync() {
if (channel != null) {
LOGGER.info("Closing connection");
try {
eventLoopGroup.shutdownGracefully().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
eventLoopGroup = null;
ChannelFuture channelFuture = channel.close();
channel = null;
return channelFuture;
} else {
return null;
}
}
private class ConnectionCloseListener {
@Subscribe
public void onConnectionClose(ConnectionCloseEvent connectionCloseEvent) {
eventLoopGroup.shutdownGracefully();
public void closeChannel() {
ChannelFuture channelFuture = closeChannelAsync();
if (channelFuture != null) {
channelFuture.awaitUninterruptibly();
}
}
@ -163,33 +149,22 @@ public class LiveClient implements Closeable {
return this;
}
public SendBulletScreenResponseEntity sendBulletScreen(@Nonnull String message) throws IOException {
public Call<SendBulletScreenResponseEntity> sendBulletScreenAsync(@Nonnull String message) {
return bilibiliServiceProvider.getLiveService()
.sendBulletScreen(createBulletScreenEntity(message))
.sendBulletScreen(createBulletScreenEntity(message));
}
public SendBulletScreenResponseEntity sendBulletScreen(@Nonnull String message) throws IOException {
return sendBulletScreenAsync(message)
.execute()
.body();
}
private LiveClient self() {
return this;
}
//TODO 弹幕发送队列
// public void sendBulletScreenAsync(@Nonnull String message, @Nonnull BulletScreenSendingCallback bulletScreenSendingCallback, boolean autoSplit) {
// if (!autoSplit) {
// sendBulletScreenAsync(message, bulletScreenSendingCallback);
// } else {
// for (String s : BulletScreenHelper.splitMessageByFixedLength(message, getBulletScreenLengthLimitOrDefaultLengthLimit())) {
// sendBulletScreenAsync(s, bulletScreenSendingCallback);
// }
// }
// }
//
// public void sendBulletScreenAsync(@Nonnull String message, @Nonnull BulletScreenSendingCallback bulletScreenSendingCallback) {
// BulletScreenSendingDequeHolder.addTask(
// new BulletScreenSendingTask(
// bilibiliServiceProvider,
// createBulletScreenEntity(message),
// bulletScreenSendingCallback
// )
// );
// }
private BulletScreenEntity createBulletScreenEntity(String message) {
return new BulletScreenEntity(
@ -225,4 +200,8 @@ public class LiveClient implements Closeable {
public int getBulletScreenLengthLimitOrDefaultLengthLimit() {
return getRoomInfo().map(LiveRoomInfoEntity.LiveRoomEntity::getMsgLength).orElse(BulletScreenConstDefinition.DEFAULT_MESSAGE_LENGTH_LIMIT);
}
public Channel getChannel() {
return channel;
}
}

View File

@ -1,13 +1,15 @@
package com.hiczp.bilibili.api.live.socket;
//数据包结构说明
//00 00 00 28 00 10 00 00 00 00 00 07 00 00 00 00
//00 00 00 28/00 10/00 00 00 00 00 07/00 00 00 00
//1-4 字节: 数据包长度
//5-6 字节: 协议头长度, 固定值 0x10
//7-8 字节: 设备类型, Android 固定为 0
//9-12 字节: 数据包类型
//13-16 字节: 设备类型, 7-8 字节
/**
* 数据包结构说明
* 00 00 00 28 00 10 00 00 00 00 00 07 00 00 00 00
* 00 00 00 28/00 10/00 00 00 00 00 07/00 00 00 00
* 1-4 字节: 数据包长度
* 5-6 字节: 协议头长度, 固定值 0x10
* 7-8 字节: 设备类型, Android 固定为 0
* 9-12 字节: 数据包类型
* 13-16 字节: 设备类型, 7-8 字节
*/
public class Package {
public static final short LENGTH_FIELD_LENGTH = 4;

View File

@ -6,6 +6,13 @@ import com.hiczp.bilibili.api.live.socket.entity.EnterRoomEntity;
public class PackageHelper {
private static final Gson GSON = new Gson();
/**
* 创建一个进房数据包
*
* @param roomId 房间号
* @param userId 用户号
* @return 进房数据包
*/
public static Package createEnterRoomPackage(long roomId, long userId) {
return new Package(
Package.PackageType.ENTER_ROOM,
@ -13,6 +20,10 @@ public class PackageHelper {
);
}
/**
* 创建一个心跳包
* @return 心跳包
*/
public static Package createHeartBeatPackage() {
return new Package(
Package.PackageType.HEART_BEAT,

View File

@ -7,6 +7,9 @@ import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
/**
* 数据包解码器
*/
public class PackageDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

View File

@ -5,6 +5,9 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
/**
* 数据包编码器
*/
public class PackageEncoder extends MessageToByteEncoder<Package> {
@Override
protected void encode(ChannelHandlerContext ctx, Package msg, ByteBuf out) throws Exception {

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class ActivityEventEntity {
public class ActivityEventEntity implements DataEntity {
/**
* cmd : ACTIVITY_EVENT
* data : {"keyword":"newspring_2018","type":"cracker","limit":300000,"progress":158912}
@ -13,6 +13,7 @@ public class ActivityEventEntity {
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}

View File

@ -0,0 +1,32 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class ChangeRoomInfoEntity implements DataEntity {
/**
* cmd : CHANGE_ROOM_INFO
* background : http://static.hdslb.com/live-static/images/bg/4.jpg
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("background")
private String background;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getBackground() {
return background;
}
public void setBackground(String background) {
this.background = background;
}
}

View File

@ -0,0 +1,43 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class CutOffEntity implements DataEntity {
/**
* cmd : CUT_OFF
* msg : 禁播游戏
* roomid : 8446134
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("msg")
private String msg;
@SerializedName("roomid")
private int roomid;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getRoomid() {
return roomid;
}
public void setRoomid(int roomid) {
this.roomid = roomid;
}
}

View File

@ -9,13 +9,13 @@ import java.lang.reflect.Type;
import java.util.List;
import java.util.Optional;
public class DanMuMsgEntity {
public class DanMuMsgEntity implements DataEntity {
private static final Gson GSON = new Gson();
private static final Type STRING_LIST_TYPE = new TypeToken<List<String>>() {
}.getType();
/**
* info : [[0,1,25,16777215,1510498713,"1510498712",0,"8a0f75dc",0],"网易云音乐库在当前直播间已停留0天0时39分41秒",[39042255,"夏沫丶琉璃浅梦",0,1,0,10000,1],[13,"夏沫","乄夏沫丶","1547306",16746162,""],[41,0,16746162,6603],[],0,0]
* info : [[0,1,25,16777215,1520664535,1662637384,0,"88874b7b",0],"czpnb",[15723776,"Dough君",0,0,0,"10000",1,""],[],[10,0,9868950,">50000"],[],0,0,{"uname_color":""}]
* cmd : DANMU_MSG
*/
@ -24,6 +24,7 @@ public class DanMuMsgEntity {
@SerializedName("info")
private JsonArray info;
@Override
public String getCmd() {
return cmd;
}
@ -40,68 +41,94 @@ public class DanMuMsgEntity {
this.info = info;
}
//pool 发布的弹幕池 (0 普通 1 字幕 2 特殊)
/**
* 弹幕池 (0 普通 1 字幕 2 特殊)
*/
public int getPool() {
return info.get(0).getAsJsonArray().get(0).getAsInt();
}
//mode 弹幕的模式 (1 普通 4 底端 5 顶端 6 逆向 7 特殊 9 高级)
/**
* 弹幕的模式 (1 普通 4 底端 5 顶端 6 逆向 7 特殊 9 高级)
*/
public int getMode() {
return info.get(0).getAsJsonArray().get(1).getAsInt();
}
//fontSize 字体大小
/**
* 字体大小
*/
public int getFontSize() {
return info.get(0).getAsJsonArray().get(2).getAsInt();
}
//color 字体颜色
/**
* 字体颜色
*/
public int getColor() {
return info.get(0).getAsJsonArray().get(3).getAsInt();
}
//弹幕发送时间(Unix 时间戳)(其实是服务器接收到弹幕的时间)
/**
* 弹幕发送时间(Unix 时间戳)(其实是服务器接收到弹幕的时间)
*/
public long getSendTime() {
return info.get(0).getAsJsonArray().get(4).getAsInt();
}
//用户进入房间的时间(Unix 时间戳)(但是 Android 发送的弹幕, 这个值会是随机数)
/**
* 用户进入房间的时间(Unix 时间戳)(但是 Android 发送的弹幕, 这个值会是随机数)
*/
public String getUserEnterTime() {
return info.get(0).getAsJsonArray().get(5).getAsString();
}
//得到弹幕内容
/**
* 弹幕内容
*/
public String getMessage() {
return info.get(1).getAsString();
}
//得到发送者的用户 ID
/**
* 发送者的用户 ID
*/
public long getUserId() {
return info.get(2).getAsJsonArray().get(0).getAsLong();
}
//得到发送者的用户名
/**
* 发送者的用户名
*/
public String getUsername() {
return info.get(2).getAsJsonArray().get(1).getAsString();
}
//发送者是否是管理员
/**
* 发送者是否是管理员
*/
public boolean isAdmin() {
return info.get(2).getAsJsonArray().get(2).getAsBoolean();
}
//发送者是否是 VIP
/**
* 发送者是否是 VIP
*/
public boolean isVip() {
return info.get(2).getAsJsonArray().get(3).getAsBoolean();
}
//发送者是否是 SVip
/**
* 发送者是否是 SVip
*/
public boolean isSVip() {
return info.get(2).getAsJsonArray().get(4).getAsBoolean();
}
//表示粉丝勋章有关信息的 JsonArray 可能是空的
//获取粉丝勋章等级
/**
* 表示粉丝勋章有关信息的 JsonArray 可能是空的
* 获取粉丝勋章等级
*/
public Optional<Integer> getFansMedalLevel() {
if (info.get(3).getAsJsonArray().size() > 0) {
return Optional.of(info.get(3).getAsJsonArray().get(0).getAsInt());
@ -110,7 +137,9 @@ public class DanMuMsgEntity {
}
}
//获取粉丝勋章名称
/**
* 获取粉丝勋章名称
*/
public Optional<String> getFansMedalName() {
if (info.get(3).getAsJsonArray().size() > 0) {
return Optional.of(info.get(3).getAsJsonArray().get(1).getAsString());
@ -119,7 +148,9 @@ public class DanMuMsgEntity {
}
}
//获取粉丝勋章对应的主播的名字
/**
* 粉丝勋章对应的主播的名字
*/
public Optional<String> getFansMedalOwnerName() {
if (info.get(3).getAsJsonArray().size() > 0) {
return Optional.of(info.get(3).getAsJsonArray().get(2).getAsString());
@ -128,7 +159,9 @@ public class DanMuMsgEntity {
}
}
//获取粉丝勋章对应的主播的直播间 ID
/**
* 粉丝勋章对应的主播的直播间 ID
*/
public Optional<String> getFansMedalOwnerRoomId() {
if (info.get(3).getAsJsonArray().size() > 0) {
return Optional.of(info.get(3).getAsJsonArray().get(3).getAsString());
@ -137,18 +170,31 @@ public class DanMuMsgEntity {
}
}
//获得用户的观众等级
/**
* 用户的观众等级
*/
public int getUserLevel() {
return info.get(4).getAsJsonArray().get(0).getAsInt();
}
//获得用户的观众等级排名
/**
* 用户的观众等级排名
*/
public String getUserRank() {
return info.get(4).getAsJsonArray().get(3).getAsString();
}
//获得用户头衔
/**
* 用户头衔
*/
public List<String> getUserTitles() {
return GSON.fromJson(info.get(5), STRING_LIST_TYPE);
}
/**
* 用户名颜色
*/
public String getUsernameColor() {
return info.get(8).getAsJsonObject().get("uname_color").getAsString();
}
}

View File

@ -0,0 +1,5 @@
package com.hiczp.bilibili.api.live.socket.entity;
public interface DataEntity {
String getCmd();
}

View File

@ -0,0 +1,71 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class EventCmdEntity implements DataEntity {
/**
* roomid : 234024
* cmd : EVENT_CMD
* data : {"event_type":"flower_rain-16915","event_img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/activity/lover_2018/raffle.png"}
*/
@SerializedName("roomid")
private long roomid;
@SerializedName("cmd")
private String cmd;
@SerializedName("data")
private Data data;
public long getRoomid() {
return roomid;
}
public void setRoomid(long roomid) {
this.roomid = roomid;
}
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* event_type : flower_rain-16915
* event_img : http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/activity/lover_2018/raffle.png
*/
@SerializedName("event_type")
private String eventType;
@SerializedName("event_img")
private String eventImg;
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public String getEventImg() {
return eventImg;
}
public void setEventImg(String eventImg) {
this.eventImg = eventImg;
}
}
}

View File

@ -0,0 +1,93 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class GuardBuyEntity implements DataEntity {
/**
* cmd : GUARD_BUY
* data : {"uid":4561799,"username":"微笑The迪妮莎","guard_level":1,"num":1}
* roomid : 5279
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("data")
private Data data;
@SerializedName("roomid")
private String roomid;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public String getRoomid() {
return roomid;
}
public void setRoomid(String roomid) {
this.roomid = roomid;
}
public static class Data {
/**
* uid : 4561799
* username : 微笑The迪妮莎
* guard_level : 1
* num : 1
*/
@SerializedName("uid")
private int uid;
@SerializedName("username")
private String username;
@SerializedName("guard_level")
private int guardLevel;
@SerializedName("num")
private int num;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getGuardLevel() {
return guardLevel;
}
public void setGuardLevel(int guardLevel) {
this.guardLevel = guardLevel;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class GuardMsgEntity {
public class GuardMsgEntity implements DataEntity {
/**
* cmd : GUARD_MSG
* msg : 乘客 :?想不想joice:? 成功购买1313366房间总督船票1张欢迎登船
@ -13,6 +13,7 @@ public class GuardMsgEntity {
@SerializedName("msg")
private String msg;
@Override
public String getCmd() {
return cmd;
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class LiveEntity {
public class LiveEntity implements RoomStatusEntity {
/**
* cmd : LIVE
* roomid : 1110317
@ -13,6 +13,7 @@ public class LiveEntity {
@SerializedName("roomid")
private String roomId;
@Override
public String getCmd() {
return cmd;
}
@ -21,6 +22,7 @@ public class LiveEntity {
this.cmd = cmd;
}
@Override
public String getRoomId() {
return roomId;
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class PreparingEntity {
public class PreparingEntity implements RoomStatusEntity {
/**
* cmd : PREPARING
* roomid : 1110317
@ -13,6 +13,7 @@ public class PreparingEntity {
@SerializedName("roomid")
private String roomId;
@Override
public String getCmd() {
return cmd;
}
@ -21,6 +22,7 @@ public class PreparingEntity {
this.cmd = cmd;
}
@Override
public String getRoomId() {
return roomId;
}

View File

@ -0,0 +1,165 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class RaffleEndEntity implements DataEntity {
/**
* cmd : RAFFLE_END
* roomid : 521429
* data : {"raffleId":16897,"type":"flower_rain","from":"鷺沢怜人","fromFace":"http://i1.hdslb.com/bfs/face/09eafe44f913012512014e91f25001edf6e072d0.jpg","win":{"uname":"nbqgd","face":"http://i1.hdslb.com/bfs/face/09eafe44f913012512014e91f25001edf6e072d0.jpg","giftId":115,"giftName":"桃花","giftNum":66}}
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("roomid")
private long roomid;
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public long getRoomid() {
return roomid;
}
public void setRoomid(long roomid) {
this.roomid = roomid;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* raffleId : 16897
* type : flower_rain
* from : 鷺沢怜人
* fromFace : http://i1.hdslb.com/bfs/face/09eafe44f913012512014e91f25001edf6e072d0.jpg
* win : {"uname":"nbqgd","face":"http://i1.hdslb.com/bfs/face/09eafe44f913012512014e91f25001edf6e072d0.jpg","giftId":115,"giftName":"桃花","giftNum":66}
*/
@SerializedName("raffleId")
private int raffleId;
@SerializedName("type")
private String type;
@SerializedName("from")
private String from;
@SerializedName("fromFace")
private String fromFace;
@SerializedName("win")
private Win win;
public int getRaffleId() {
return raffleId;
}
public void setRaffleId(int raffleId) {
this.raffleId = raffleId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getFromFace() {
return fromFace;
}
public void setFromFace(String fromFace) {
this.fromFace = fromFace;
}
public Win getWin() {
return win;
}
public void setWin(Win win) {
this.win = win;
}
public static class Win {
/**
* uname : nbqgd
* face : http://i1.hdslb.com/bfs/face/09eafe44f913012512014e91f25001edf6e072d0.jpg
* giftId : 115
* giftName : 桃花
* giftNum : 66
*/
@SerializedName("uname")
private String uname;
@SerializedName("face")
private String face;
@SerializedName("giftId")
private String giftId; //礼物如果是 经验原石 一类的东西, 它的 id 是个字符串, 例如 "stuff-1"
@SerializedName("giftName")
private String giftName;
@SerializedName("giftNum")
private int giftNum;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getGiftId() {
return giftId;
}
public void setGiftId(String giftId) {
this.giftId = giftId;
}
public String getGiftName() {
return giftName;
}
public void setGiftName(String giftName) {
this.giftName = giftName;
}
public int getGiftNum() {
return giftNum;
}
public void setGiftNum(int giftNum) {
this.giftNum = giftNum;
}
}
}
}

View File

@ -0,0 +1,93 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class RaffleStartEntity implements DataEntity {
/**
* cmd : RAFFLE_START
* roomid : 234024
* data : {"raffleId":16915,"type":"flower_rain","from":"爱吃喵姐的鱼","time":60}
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("roomid")
private int roomid;
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public int getRoomid() {
return roomid;
}
public void setRoomid(int roomid) {
this.roomid = roomid;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* raffleId : 16915
* type : flower_rain
* from : 爱吃喵姐的鱼
* time : 60
*/
@SerializedName("raffleId")
private int raffleId;
@SerializedName("type")
private String type;
@SerializedName("from")
private String from;
@SerializedName("time")
private int time;
public int getRaffleId() {
return raffleId;
}
public void setRaffleId(int raffleId) {
this.raffleId = raffleId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
}
}

View File

@ -0,0 +1,45 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class RoomAdminsEntity implements DataEntity {
/**
* cmd : ROOM_ADMINS
* uids : [4561799,432672,2179804,7928207,94380,1626161,3168349,13182672]
* roomid : 5279
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("roomid")
private long roomId;
@SerializedName("uids")
private List<Long> uids;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public long getRoomId() {
return roomId;
}
public void setRoomId(long roomId) {
this.roomId = roomId;
}
public List<Long> getUids() {
return uids;
}
public void setUids(List<Long> uids) {
this.uids = uids;
}
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class RoomBlockMsgEntity {
public class RoomBlockMsgEntity implements DataEntity {
/**
* cmd : ROOM_BLOCK_MSG
* uid : 60244207
@ -19,6 +19,7 @@ public class RoomBlockMsgEntity {
@SerializedName("roomid")
private long roomid;
@Override
public String getCmd() {
return cmd;
}

View File

@ -0,0 +1,43 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class RoomLockEntity implements DataEntity {
/**
* cmd : ROOM_LOCK
* expire : 2018-03-15 10:24:18
* roomid : 6477301
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("expire")
private String expire;
@SerializedName("roomid")
private int roomid;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getExpire() {
return expire;
}
public void setExpire(String expire) {
this.expire = expire;
}
public int getRoomid() {
return roomid;
}
public void setRoomid(int roomid) {
this.roomid = roomid;
}
}

View File

@ -0,0 +1,67 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class RoomShieldEntity implements DataEntity {
/**
* cmd : ROOM_SHIELD
* type : 1
* user : []
* keyword : ["暗号","摄像头","色相头"]
* roomid : 505447
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("type")
private int type;
@SerializedName("roomid")
private long roomid;
@SerializedName("user")
private List<String> user;
@SerializedName("keyword")
private List<String> keyword;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public long getRoomid() {
return roomid;
}
public void setRoomid(long roomid) {
this.roomid = roomid;
}
public List<String> getUser() {
return user;
}
public void setUser(List<String> user) {
this.user = user;
}
public List<String> getKeyword() {
return keyword;
}
public void setKeyword(List<String> keyword) {
this.keyword = keyword;
}
}

View File

@ -4,7 +4,7 @@ import com.google.gson.annotations.SerializedName;
import java.util.List;
public class RoomSilentOffEntity {
public class RoomSilentOffEntity implements DataEntity {
/**
* cmd : ROOM_SILENT_OFF
* data : []
@ -18,6 +18,7 @@ public class RoomSilentOffEntity {
@SerializedName("data")
private List<?> data;
@Override
public String getCmd() {
return cmd;
}

View File

@ -0,0 +1,82 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class RoomSilentOnEntity implements DataEntity {
/**
* cmd : ROOM_SILENT_ON
* data : {"type":"level","level":1,"second":1520424615}
* roomid : 5279
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("data")
private Data data;
@SerializedName("roomid")
private long roomId;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public long getRoomId() {
return roomId;
}
public void setRoomId(long roomId) {
this.roomId = roomId;
}
public static class Data {
/**
* type : level
* level : 1
* second : 1520424615
*/
@SerializedName("type")
private String type;
@SerializedName("level")
private int level;
@SerializedName("second")
private long second;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public long getSecond() {
return second;
}
public void setSecond(long second) {
this.second = second;
}
}
}

View File

@ -0,0 +1,5 @@
package com.hiczp.bilibili.api.live.socket.entity;
public interface RoomStatusEntity extends DataEntity {
String getRoomId();
}

View File

@ -1,15 +1,14 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class SendGiftEntity {
public class SendGiftEntity implements DataEntity {
/**
* cmd : SEND_GIFT
* data : {"giftName":"辣条","num":64,"uname":"明暗纠结星","rcost":66347035,"uid":12768615,"top_list":[{"uid":9256,"userName":"SSR","coin":2905900,"face":"http://i0.hdslb.com/bfs/face/eba52abb1daaf3aecd7b986b9731451872d66613.jpg","guard_level":"3","rank":1,"score":2905900},{"uid":4986301,"userName":"乄夏沫丶","coin":1386000,"face":"http://i2.hdslb.com/bfs/face/b3969027a263d2610711317addf437fe59a9b97e.jpg","guard_level":0,"rank":2,"score":1386000},{"uid":5211302,"userName":"朝雾怜","coin":805700,"face":"http://i1.hdslb.com/bfs/face/d366be69d716469514d355642aa324ceba3fa122.jpg","guard_level":0,"rank":3,"score":805700}],"timestamp":1510498496,"giftId":1,"giftType":0,"action":"喂食","super":0,"price":100,"rnd":"1510498460","newMedal":0,"newTitle":0,"medal":[],"title":"","beatId":"0","biz_source":"live","metadata":"","remain":0,"gold":0,"silver":0,"eventScore":0,"eventNum":0,"smalltv_msg":[],"notice_msg":[],"capsule":{"normal":{"coin":13,"change":1,"progress":{"now":4000,"max":10000}},"colorful":{"coin":0,"change":0,"progress":{"now":0,"max":5000}}},"addFollow":0}
* data : {"giftName":"节奏风暴","num":1,"uname":"爱上熹","rcost":569788,"uid":230845505,"top_list":[{"uid":288348879,"uname":"我爱我家一生","face":"http://i1.hdslb.com/bfs/face/dd52e4f2dfe881751816e45522f504f10458b514.jpg","rank":1,"score":1852300,"guard_level":0,"isSelf":0},{"uid":287551243,"uname":"熹上城的专属天使菲","face":"http://i1.hdslb.com/bfs/face/c3ef04ba6c267c41067cd7708b7abd60c0c5c49f.jpg","rank":2,"score":1245200,"guard_level":3,"isSelf":0},{"uid":32416351,"uname":"镜子。。","face":"http://i1.hdslb.com/bfs/face/08c54c2c97434811a99e9d070d621ccbb5d3f2c4.jpg","rank":3,"score":332862,"guard_level":3,"isSelf":0}],"timestamp":1520992553,"giftId":39,"giftType":0,"action":"赠送","super":1,"price":100000,"rnd":"1980508331","newMedal":0,"newTitle":0,"medal":{"medalId":"95723","medalName":"布丁诶","level":1},"title":"","beatId":"4","biz_source":"live","metadata":"","remain":0,"gold":88570,"silver":127492,"eventScore":0,"eventNum":0,"smalltv_msg":[],"specialGift":{"id":207945,"time":90,"hadJoin":0,"num":1,"content":"你们城里人真会玩","action":"start","storm_gif":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901"},"notice_msg":[],"capsule":{"normal":{"coin":166,"change":10,"progress":{"now":3630,"max":10000}},"colorful":{"coin":2,"change":0,"progress":{"now":0,"max":5000}}},"addFollow":0,"effect_block":0,"coin_type":"gold","total_coin":100000}
*/
@SerializedName("cmd")
@ -35,35 +34,39 @@ public class SendGiftEntity {
public static class DataEntity {
/**
* giftName : 辣条
* num : 64
* uname : 明暗纠结星
* rcost : 66347035
* uid : 12768615
* top_list : [{"uid":9256,"uname":"SSR","coin":2905900,"face":"http://i0.hdslb.com/bfs/face/eba52abb1daaf3aecd7b986b9731451872d66613.jpg","guard_level":"3","rank":1,"score":2905900},{"uid":4986301,"userName":"乄夏沫丶","coin":1386000,"face":"http://i2.hdslb.com/bfs/face/b3969027a263d2610711317addf437fe59a9b97e.jpg","guard_level":0,"rank":2,"score":1386000},{"uid":5211302,"userName":"朝雾怜","coin":805700,"face":"http://i1.hdslb.com/bfs/face/d366be69d716469514d355642aa324ceba3fa122.jpg","guard_level":0,"rank":3,"score":805700}]
* timestamp : 1510498496
* giftId : 1
* giftName : 节奏风暴
* num : 1
* uname : 爱上熹
* rcost : 569788
* uid : 230845505
* top_list : [{"uid":288348879,"uname":"我爱我家一生","face":"http://i1.hdslb.com/bfs/face/dd52e4f2dfe881751816e45522f504f10458b514.jpg","rank":1,"score":1852300,"guard_level":0,"isSelf":0},{"uid":287551243,"uname":"熹上城的专属天使菲","face":"http://i1.hdslb.com/bfs/face/c3ef04ba6c267c41067cd7708b7abd60c0c5c49f.jpg","rank":2,"score":1245200,"guard_level":3,"isSelf":0},{"uid":32416351,"uname":"镜子。。","face":"http://i1.hdslb.com/bfs/face/08c54c2c97434811a99e9d070d621ccbb5d3f2c4.jpg","rank":3,"score":332862,"guard_level":3,"isSelf":0}]
* timestamp : 1520992553
* giftId : 39
* giftType : 0
* action : 喂食
* super : 0
* price : 100
* rnd : 1510498460
* action : 赠送
* super : 1
* price : 100000
* rnd : 1980508331
* newMedal : 0
* newTitle : 0
* medal : []
* medal : {"medalId":"95723","medalName":"布丁诶","level":1}
* title :
* beatId : 0
* beatId : 4
* biz_source : live
* metadata :
* remain : 0
* gold : 0
* silver : 0
* gold : 88570
* silver : 127492
* eventScore : 0
* eventNum : 0
* smalltv_msg : []
* specialGift : {"id":207945,"time":90,"hadJoin":0,"num":1,"content":"你们城里人真会玩","action":"start","storm_gif":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901"}
* notice_msg : []
* capsule : {"normal":{"coin":13,"change":1,"progress":{"now":4000,"max":10000}},"colorful":{"coin":0,"change":0,"progress":{"now":0,"max":5000}}}
* capsule : {"normal":{"coin":166,"change":10,"progress":{"now":3630,"max":10000}},"colorful":{"coin":2,"change":0,"progress":{"now":0,"max":5000}}}
* addFollow : 0
* effect_block : 0
* coin_type : gold
* total_coin : 100000
*/
@SerializedName("giftName")
@ -71,9 +74,9 @@ public class SendGiftEntity {
@SerializedName("num")
private int num;
@SerializedName("uname")
private String userName;
private String username;
@SerializedName("rcost")
private int rCost;
private int rcost;
@SerializedName("uid")
private long uid;
@SerializedName("timestamp")
@ -94,6 +97,17 @@ public class SendGiftEntity {
private int newMedal;
@SerializedName("newTitle")
private int newTitle;
/**
* medal 字段可能是一个空的 JsonArray, 也可能是 JsonObject
* JsonObject , 内部字段如下
* {
* "medalId": "95723",
* "medalName": "布丁诶",
* "level": 1
* }
*/
@SerializedName("medal")
private JsonElement medal;
@SerializedName("title")
private String title;
@SerializedName("beatId")
@ -112,18 +126,24 @@ public class SendGiftEntity {
private int eventScore;
@SerializedName("eventNum")
private int eventNum;
@SerializedName("specialGift")
private SpecialGift specialGift;
@SerializedName("capsule")
private CapsuleEntity capsule;
private Capsule capsule;
@SerializedName("addFollow")
private int addFollow;
@SerializedName("effect_block")
private int effectBlock;
@SerializedName("coin_type")
private String coinType;
@SerializedName("total_coin")
private int totalCoin;
@SerializedName("top_list")
private List<TopListEntity> topList;
@SerializedName("medal")
private JsonElement medal;
private List<TopList> topList;
@SerializedName("smalltv_msg")
private JsonElement smallTVMsg;
private JsonElement smalltvMsg;
@SerializedName("notice_msg")
private List<?> noticeMsg;
private JsonElement noticeMsg;
public String getGiftName() {
return giftName;
@ -141,20 +161,20 @@ public class SendGiftEntity {
this.num = num;
}
public String getUserName() {
return userName;
public String getUsername() {
return username;
}
public void setUserName(String userName) {
this.userName = userName;
public void setUsername(String username) {
this.username = username;
}
public int getrCost() {
return rCost;
public int getRcost() {
return rcost;
}
public void setrCost(int rCost) {
this.rCost = rCost;
public void setRcost(int rcost) {
this.rcost = rcost;
}
public long getUid() {
@ -237,6 +257,14 @@ public class SendGiftEntity {
this.newTitle = newTitle;
}
public JsonElement getMedal() {
return medal;
}
public void setMedal(JsonElement medal) {
this.medal = medal;
}
public String getTitle() {
return title;
}
@ -309,11 +337,19 @@ public class SendGiftEntity {
this.eventNum = eventNum;
}
public CapsuleEntity getCapsule() {
public SpecialGift getSpecialGift() {
return specialGift;
}
public void setSpecialGift(SpecialGift specialGift) {
this.specialGift = specialGift;
}
public Capsule getCapsule() {
return capsule;
}
public void setCapsule(CapsuleEntity capsule) {
public void setCapsule(Capsule capsule) {
this.capsule = capsule;
}
@ -325,70 +361,208 @@ public class SendGiftEntity {
this.addFollow = addFollow;
}
public List<TopListEntity> getTopList() {
public int getEffectBlock() {
return effectBlock;
}
public void setEffectBlock(int effectBlock) {
this.effectBlock = effectBlock;
}
public String getCoinType() {
return coinType;
}
public void setCoinType(String coinType) {
this.coinType = coinType;
}
public int getTotalCoin() {
return totalCoin;
}
public void setTotalCoin(int totalCoin) {
this.totalCoin = totalCoin;
}
public List<TopList> getTopList() {
return topList;
}
public void setTopList(List<TopListEntity> topList) {
public void setTopList(List<TopList> topList) {
this.topList = topList;
}
public JsonElement getMedal() {
return medal;
public JsonElement getSmalltvMsg() {
return smalltvMsg;
}
public void setMedal(JsonElement medal) {
this.medal = medal;
public void setSmalltvMsg(JsonElement smalltvMsg) {
this.smalltvMsg = smalltvMsg;
}
public JsonElement getSmallTVMsg() {
return smallTVMsg;
}
public void setSmallTVMsg(JsonObject smallTVMsg) {
this.smallTVMsg = smallTVMsg;
}
public List<?> getNoticeMsg() {
public JsonElement getNoticeMsg() {
return noticeMsg;
}
public void setNoticeMsg(List<?> noticeMsg) {
public void setNoticeMsg(JsonElement noticeMsg) {
this.noticeMsg = noticeMsg;
}
public static class CapsuleEntity {
public static class Medal {
/**
* normal : {"coin":13,"change":1,"progress":{"now":4000,"max":10000}}
* colorful : {"coin":0,"change":0,"progress":{"now":0,"max":5000}}
* medalId : 95723
* medalName : 布丁诶
* level : 1
*/
@SerializedName("medalId")
private String medalId;
@SerializedName("medalName")
private String medalName;
@SerializedName("level")
private int level;
public String getMedalId() {
return medalId;
}
public void setMedalId(String medalId) {
this.medalId = medalId;
}
public String getMedalName() {
return medalName;
}
public void setMedalName(String medalName) {
this.medalName = medalName;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
public static class SpecialGift {
/**
* id : 207945
* time : 90
* hadJoin : 0
* num : 1
* content : 你们城里人真会玩
* action : start
* storm_gif : http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901
*/
@SerializedName("id")
private int id;
@SerializedName("time")
private int time;
@SerializedName("hadJoin")
private int hadJoin;
@SerializedName("num")
private int num;
@SerializedName("content")
private String content;
@SerializedName("action")
private String action;
@SerializedName("storm_gif")
private String stormGif;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int getHadJoin() {
return hadJoin;
}
public void setHadJoin(int hadJoin) {
this.hadJoin = hadJoin;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getStormGif() {
return stormGif;
}
public void setStormGif(String stormGif) {
this.stormGif = stormGif;
}
}
public static class Capsule {
/**
* normal : {"coin":166,"change":10,"progress":{"now":3630,"max":10000}}
* colorful : {"coin":2,"change":0,"progress":{"now":0,"max":5000}}
*/
@SerializedName("normal")
private NormalEntity normal;
private Normal normal;
@SerializedName("colorful")
private ColorfulEntity colorful;
private Colorful colorful;
public NormalEntity getNormal() {
public Normal getNormal() {
return normal;
}
public void setNormal(NormalEntity normal) {
public void setNormal(Normal normal) {
this.normal = normal;
}
public ColorfulEntity getColorful() {
public Colorful getColorful() {
return colorful;
}
public void setColorful(ColorfulEntity colorful) {
public void setColorful(Colorful colorful) {
this.colorful = colorful;
}
public static class NormalEntity {
public static class Normal {
/**
* coin : 13
* change : 1
* progress : {"now":4000,"max":10000}
* coin : 166
* change : 10
* progress : {"now":3630,"max":10000}
*/
@SerializedName("coin")
@ -396,7 +570,7 @@ public class SendGiftEntity {
@SerializedName("change")
private int change;
@SerializedName("progress")
private ProgressEntity progress;
private Progress progress;
public int getCoin() {
return coin;
@ -414,17 +588,17 @@ public class SendGiftEntity {
this.change = change;
}
public ProgressEntity getProgress() {
public Progress getProgress() {
return progress;
}
public void setProgress(ProgressEntity progress) {
public void setProgress(Progress progress) {
this.progress = progress;
}
public static class ProgressEntity {
public static class Progress {
/**
* now : 4000
* now : 3630
* max : 10000
*/
@ -451,9 +625,9 @@ public class SendGiftEntity {
}
}
public static class ColorfulEntity {
public static class Colorful {
/**
* coin : 0
* coin : 2
* change : 0
* progress : {"now":0,"max":5000}
*/
@ -463,7 +637,7 @@ public class SendGiftEntity {
@SerializedName("change")
private int change;
@SerializedName("progress")
private ProgressEntityX progress;
private ProgressX progress;
public int getCoin() {
return coin;
@ -481,15 +655,15 @@ public class SendGiftEntity {
this.change = change;
}
public ProgressEntityX getProgress() {
public ProgressX getProgress() {
return progress;
}
public void setProgress(ProgressEntityX progress) {
public void setProgress(ProgressX progress) {
this.progress = progress;
}
public static class ProgressEntityX {
public static class ProgressX {
/**
* now : 0
* max : 5000
@ -519,31 +693,31 @@ public class SendGiftEntity {
}
}
public static class TopListEntity {
public static class TopList {
/**
* uid : 9256
* uname : SSR
* coin : 2905900
* face : http://i0.hdslb.com/bfs/face/eba52abb1daaf3aecd7b986b9731451872d66613.jpg
* guard_level : 3
* uid : 288348879
* uname : 我爱我家一生
* face : http://i1.hdslb.com/bfs/face/dd52e4f2dfe881751816e45522f504f10458b514.jpg
* rank : 1
* score : 2905900
* score : 1852300
* guard_level : 0
* isSelf : 0
*/
@SerializedName("uid")
private int uid;
@SerializedName("uname")
private String userName;
@SerializedName("coin")
private int coin;
private String uname;
@SerializedName("face")
private String face;
@SerializedName("guard_level")
private String guardLevel;
@SerializedName("rank")
private int rank;
@SerializedName("score")
private int score;
@SerializedName("guard_level")
private int guardLevel;
@SerializedName("isSelf")
private int isSelf;
public int getUid() {
return uid;
@ -553,20 +727,12 @@ public class SendGiftEntity {
this.uid = uid;
}
public String getUserName() {
return userName;
public String getUname() {
return uname;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getCoin() {
return coin;
}
public void setCoin(int coin) {
this.coin = coin;
public void setUname(String uname) {
this.uname = uname;
}
public String getFace() {
@ -577,14 +743,6 @@ public class SendGiftEntity {
this.face = face;
}
public String getGuardLevel() {
return guardLevel;
}
public void setGuardLevel(String guardLevel) {
this.guardLevel = guardLevel;
}
public int getRank() {
return rank;
}
@ -600,6 +758,22 @@ public class SendGiftEntity {
public void setScore(int score) {
this.score = score;
}
public int getGuardLevel() {
return guardLevel;
}
public void setGuardLevel(int guardLevel) {
this.guardLevel = guardLevel;
}
public int getIsSelf() {
return isSelf;
}
public void setIsSelf(int isSelf) {
this.isSelf = isSelf;
}
}
}
}

View File

@ -0,0 +1,132 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class SpecialGiftEntity implements DataEntity {
/**
* cmd : SPECIAL_GIFT
* data : {"39":{"id":202090,"time":90,"hadJoin":0,"num":1,"content":"月轮来袭","action":"start","storm_gif":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901"}}
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* 39 : {"id":202090,"time":90,"hadJoin":0,"num":1,"content":"月轮来袭","action":"start","storm_gif":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901"}
*/
@SerializedName("39")
private _$39 $39;
public _$39 get$39() {
return $39;
}
public void set$39(_$39 $39) {
this.$39 = $39;
}
public static class _$39 {
/**
* id : 202090
* time : 90
* hadJoin : 0
* num : 1
* content : 月轮来袭
* action : start
* storm_gif : http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901
*/
@SerializedName("id")
private long id;
@SerializedName("time")
private int time;
@SerializedName("hadJoin")
private int hadJoin;
@SerializedName("num")
private int num;
@SerializedName("content")
private String content;
@SerializedName("action")
private String action;
@SerializedName("storm_gif")
private String stormGif;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int getHadJoin() {
return hadJoin;
}
public void setHadJoin(int hadJoin) {
this.hadJoin = hadJoin;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getStormGif() {
return stormGif;
}
public void setStormGif(String stormGif) {
this.stormGif = stormGif;
}
}
}
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class SysGiftEntity {
public class SysGiftEntity implements DataEntity {
/**
* cmd : SYS_GIFT
* msg : あさひなみよう在直播间5135178开启了丰收祭典一起来分享收获的福利吧
@ -34,6 +34,7 @@ public class SysGiftEntity {
@SerializedName("msgTips")
private int msgTips;
@Override
public String getCmd() {
return cmd;
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class SysMsgEntity {
public class SysMsgEntity implements DataEntity {
/**
* cmd : SYS_MSG
* msg : 瑾然-:?在直播间:?3939852:?赠送 小电视一个请前往抽奖
@ -38,6 +38,7 @@ public class SysMsgEntity {
@SerializedName("tv_id")
private String tvId;
@Override
public String getCmd() {
return cmd;
}

View File

@ -0,0 +1,209 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class TVEndEntity implements DataEntity {
/**
* cmd : TV_END
* data : {"id":"39077","uname":"かこゆきこvew","sname":"是你的苏苏吖","giftName":"10W银瓜子","mobileTips":"恭喜 かこゆきこvew 获得10W银瓜子","raffleId":"39077","type":"small_tv","from":"是你的苏苏吖","fromFace":"http://i0.hdslb.com/bfs/face/147f137d24138d1cfec5443d98ac8b03c4332398.jpg","win":{"uname":"かこゆきこvew","face":"http://i0.hdslb.com/bfs/face/4d63bd62322e7f3ef38723a91440bc6930626d9f.jpg","giftName":"银瓜子","giftId":"silver","giftNum":100000}}
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* id : 39077
* uname : かこゆきこvew
* sname : 是你的苏苏吖
* giftName : 10W银瓜子
* mobileTips : 恭喜 かこゆきこvew 获得10W银瓜子
* raffleId : 39077
* type : small_tv
* from : 是你的苏苏吖
* fromFace : http://i0.hdslb.com/bfs/face/147f137d24138d1cfec5443d98ac8b03c4332398.jpg
* win : {"uname":"かこゆきこvew","face":"http://i0.hdslb.com/bfs/face/4d63bd62322e7f3ef38723a91440bc6930626d9f.jpg","giftName":"银瓜子","giftId":"silver","giftNum":100000}
*/
@SerializedName("id")
private String id;
@SerializedName("uname")
private String uname;
@SerializedName("sname")
private String sname;
@SerializedName("giftName")
private String giftName;
@SerializedName("mobileTips")
private String mobileTips;
@SerializedName("raffleId")
private String raffleId;
@SerializedName("type")
private String type;
@SerializedName("from")
private String from;
@SerializedName("fromFace")
private String fromFace;
@SerializedName("win")
private Win win;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGiftName() {
return giftName;
}
public void setGiftName(String giftName) {
this.giftName = giftName;
}
public String getMobileTips() {
return mobileTips;
}
public void setMobileTips(String mobileTips) {
this.mobileTips = mobileTips;
}
public String getRaffleId() {
return raffleId;
}
public void setRaffleId(String raffleId) {
this.raffleId = raffleId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getFromFace() {
return fromFace;
}
public void setFromFace(String fromFace) {
this.fromFace = fromFace;
}
public Win getWin() {
return win;
}
public void setWin(Win win) {
this.win = win;
}
public static class Win {
/**
* uname : かこゆきこvew
* face : http://i0.hdslb.com/bfs/face/4d63bd62322e7f3ef38723a91440bc6930626d9f.jpg
* giftName : 银瓜子
* giftId : silver
* giftNum : 100000
*/
@SerializedName("uname")
private String uname;
@SerializedName("face")
private String face;
@SerializedName("giftName")
private String giftName;
@SerializedName("giftId")
private String giftId;
@SerializedName("giftNum")
private int giftNum;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getGiftName() {
return giftName;
}
public void setGiftName(String giftName) {
this.giftName = giftName;
}
public String getGiftId() {
return giftId;
}
public void setGiftId(String giftId) {
this.giftId = giftId;
}
public int getGiftNum() {
return giftNum;
}
public void setGiftNum(int giftNum) {
this.giftNum = giftNum;
}
}
}
}

View File

@ -0,0 +1,231 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class TVStartEntity implements DataEntity {
/**
* cmd : TV_START
* data : {"id":"40072","dtime":180,"msg":{"cmd":"SYS_MSG","msg":"【杰宝Yvan生命倒计时】:?在直播间:?【102】:?赠送 小电视一个,请前往抽奖","msg_text":"【杰宝Yvan生命倒计时】:?在直播间:?【102】:?赠送 小电视一个,请前往抽奖","rep":1,"styleType":2,"url":"http://live.bilibili.com/102","roomid":102,"real_roomid":5279,"rnd":12987955,"tv_id":"40072"},"raffleId":40072,"type":"small_tv","from":"杰宝Yvan生命倒计时","time":180}
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* id : 40072
* dtime : 180
* msg : {"cmd":"SYS_MSG","msg":"【杰宝Yvan生命倒计时】:?在直播间:?【102】:?赠送 小电视一个,请前往抽奖","msg_text":"【杰宝Yvan生命倒计时】:?在直播间:?【102】:?赠送 小电视一个,请前往抽奖","rep":1,"styleType":2,"url":"http://live.bilibili.com/102","roomid":102,"real_roomid":5279,"rnd":12987955,"tv_id":"40072"}
* raffleId : 40072
* type : small_tv
* from : 杰宝Yvan生命倒计时
* time : 180
*/
@SerializedName("id")
private String id;
@SerializedName("dtime")
private int dtime;
@SerializedName("msg")
private Msg msg;
@SerializedName("raffleId")
private int raffleId;
@SerializedName("type")
private String type;
@SerializedName("from")
private String from;
@SerializedName("time")
private int time;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getDtime() {
return dtime;
}
public void setDtime(int dtime) {
this.dtime = dtime;
}
public Msg getMsg() {
return msg;
}
public void setMsg(Msg msg) {
this.msg = msg;
}
public int getRaffleId() {
return raffleId;
}
public void setRaffleId(int raffleId) {
this.raffleId = raffleId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public static class Msg {
/**
* cmd : SYS_MSG
* msg : 杰宝Yvan生命倒计时:?在直播间:?102:?赠送 小电视一个请前往抽奖
* msg_text : 杰宝Yvan生命倒计时:?在直播间:?102:?赠送 小电视一个请前往抽奖
* rep : 1
* styleType : 2
* url : http://live.bilibili.com/102
* roomid : 102
* real_roomid : 5279
* rnd : 12987955
* tv_id : 40072
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("msg")
private String msg;
@SerializedName("msg_text")
private String msgText;
@SerializedName("rep")
private int rep;
@SerializedName("styleType")
private int styleType;
@SerializedName("url")
private String url;
@SerializedName("roomid")
private int roomid;
@SerializedName("real_roomid")
private int realRoomid;
@SerializedName("rnd")
private int rnd;
@SerializedName("tv_id")
private String tvId;
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsgText() {
return msgText;
}
public void setMsgText(String msgText) {
this.msgText = msgText;
}
public int getRep() {
return rep;
}
public void setRep(int rep) {
this.rep = rep;
}
public int getStyleType() {
return styleType;
}
public void setStyleType(int styleType) {
this.styleType = styleType;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getRoomid() {
return roomid;
}
public void setRoomid(int roomid) {
this.roomid = roomid;
}
public int getRealRoomid() {
return realRoomid;
}
public void setRealRoomid(int realRoomid) {
this.realRoomid = realRoomid;
}
public int getRnd() {
return rnd;
}
public void setRnd(int rnd) {
this.rnd = rnd;
}
public String getTvId() {
return tvId;
}
public void setTvId(String tvId) {
this.tvId = tvId;
}
}
}
}

View File

@ -0,0 +1,82 @@
package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class WelcomeActivityEntity implements DataEntity {
/**
* cmd : WELCOME_ACTIVITY
* data : {"uid":49427998,"uname":"起个名真tm费事","type":"forever_love","display_mode":1}
*/
@SerializedName("cmd")
private String cmd;
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public static class Data {
/**
* uid : 49427998
* uname : 起个名真tm费事
* type : forever_love
* display_mode : 1
*/
@SerializedName("uid")
private long uid;
@SerializedName("uname")
private String uname;
@SerializedName("type")
private String type;
@SerializedName("display_mode")
private int displayMode;
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getDisplayMode() {
return displayMode;
}
public void setDisplayMode(int displayMode) {
this.displayMode = displayMode;
}
}
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class WelcomeEntity {
public class WelcomeEntity implements DataEntity {
/**
* cmd : WELCOME
* data : {"uid":516505,"uname":"圣蝎","is_admin":false,"vip":1}
@ -13,6 +13,7 @@ public class WelcomeEntity {
@SerializedName("data")
private DataEntity data;
@Override
public String getCmd() {
return cmd;
}

View File

@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.entity;
import com.google.gson.annotations.SerializedName;
public class WelcomeGuardEntity {
public class WelcomeGuardEntity implements DataEntity {
/**
* cmd : WELCOME_GUARD
* data : {"uid":23598108,"username":"lovevael","guard_level":3,"water_god":0}
@ -16,6 +16,7 @@ public class WelcomeGuardEntity {
@SerializedName("roomid")
private long roomId;
@Override
public String getCmd() {
return cmd;
}

View File

@ -4,7 +4,7 @@ import com.google.gson.annotations.SerializedName;
import java.util.List;
public class WishBottleEntity {
public class WishBottleEntity implements DataEntity {
/**
* cmd : WISH_BOTTLE
* data : {"action":"update","id":1832,"wish":{"id":1832,"uid":110631,"type":1,"type_id":7,"wish_limit":99999,"wish_progress":14381,"status":1,"content":"女装直播","ctime":"2018-01-12 17:25:58","count_map":[1,3,5]}}
@ -15,6 +15,7 @@ public class WishBottleEntity {
@SerializedName("data")
private Data data;
@Override
public String getCmd() {
return cmd;
}

View File

@ -1,9 +1,10 @@
package com.hiczp.bilibili.api.live.socket.event;
import com.hiczp.bilibili.api.live.socket.LiveClient;
import com.hiczp.bilibili.api.live.socket.entity.ActivityEventEntity;
public class ActivityEventPackageEvent extends ReceivePackageEvent<ActivityEventEntity> {
public ActivityEventPackageEvent(Object source, ActivityEventEntity entity) {
public class ActivityEventPackageEvent extends ReceiveDataPackageEvent<ActivityEventEntity> {
public ActivityEventPackageEvent(LiveClient source, ActivityEventEntity entity) {
super(source, entity);
}
}

View File

@ -0,0 +1,10 @@
package com.hiczp.bilibili.api.live.socket.event;
import com.hiczp.bilibili.api.live.socket.LiveClient;
import com.hiczp.bilibili.api.live.socket.entity.ChangeRoomInfoEntity;
public class ChangeRoomInfoPackageEvent extends ReceiveDataPackageEvent<ChangeRoomInfoEntity> {
public ChangeRoomInfoPackageEvent(LiveClient source, ChangeRoomInfoEntity entity) {
super(source, entity);
}
}

View File

@ -1,9 +1,9 @@
package com.hiczp.bilibili.api.live.socket.event;
import java.util.EventObject;
import com.hiczp.bilibili.api.live.socket.LiveClient;
public class ConnectSucceedEvent extends EventObject {
public ConnectSucceedEvent(Object source) {
public class ConnectSucceedEvent extends Event {
public ConnectSucceedEvent(LiveClient source) {
super(source);
}
}

View File

@ -1,9 +1,9 @@
package com.hiczp.bilibili.api.live.socket.event;
import java.util.EventObject;
import com.hiczp.bilibili.api.live.socket.LiveClient;
public class ConnectionCloseEvent extends EventObject {
public ConnectionCloseEvent(Object source) {
public class ConnectionCloseEvent extends Event {
public ConnectionCloseEvent(LiveClient source) {
super(source);
}
}

Some files were not shown because too many files have changed in this diff Show More