From f83edb1a968f5325b3f4d9d7e071612078d8ec78 Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 23 Feb 2018 22:41:53 +0800 Subject: [PATCH 01/73] =?UTF-8?q?=E4=B8=BA=E7=9B=B4=E6=92=AD=E9=97=B4?= =?UTF-8?q?=E5=BC=B9=E5=B9=95=E6=8E=A8=E9=80=81=E6=9C=89=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8C=85=E5=AE=9E=E4=BD=93=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=BB=A5=E6=96=B9=E4=BE=BF=E7=BC=96=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/live/socket/entity/ActivityEventEntity.java | 3 ++- .../bilibili/api/live/socket/entity/DanMuMsgEntity.java | 3 ++- .../hiczp/bilibili/api/live/socket/entity/DataEntity.java | 5 +++++ .../bilibili/api/live/socket/entity/GuardMsgEntity.java | 3 ++- .../hiczp/bilibili/api/live/socket/entity/LiveEntity.java | 4 +++- .../bilibili/api/live/socket/entity/PreparingEntity.java | 4 +++- .../api/live/socket/entity/RoomBlockMsgEntity.java | 3 ++- .../api/live/socket/entity/RoomSilentOffEntity.java | 3 ++- .../bilibili/api/live/socket/entity/RoomStatusEntity.java | 7 +++++++ .../bilibili/api/live/socket/entity/SendGiftEntity.java | 3 ++- .../bilibili/api/live/socket/entity/SysGiftEntity.java | 3 ++- .../bilibili/api/live/socket/entity/SysMsgEntity.java | 3 ++- .../bilibili/api/live/socket/entity/WelcomeEntity.java | 3 ++- .../api/live/socket/entity/WelcomeGuardEntity.java | 3 ++- .../bilibili/api/live/socket/entity/WishBottleEntity.java | 3 ++- 15 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/DataEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/ActivityEventEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/ActivityEventEntity.java index f1e8162..5e14206 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/ActivityEventEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/ActivityEventEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java index 05a5b00..718cd75 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java @@ -9,7 +9,7 @@ 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>() { }.getType(); @@ -24,6 +24,7 @@ public class DanMuMsgEntity { @SerializedName("info") private JsonArray info; + @Override public String getCmd() { return cmd; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DataEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DataEntity.java new file mode 100644 index 0000000..eaaf79a --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DataEntity.java @@ -0,0 +1,5 @@ +package com.hiczp.bilibili.api.live.socket.entity; + +public interface DataEntity { + String getCmd(); +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardMsgEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardMsgEntity.java index 3203607..f283da0 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardMsgEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardMsgEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/LiveEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/LiveEntity.java index 2126475..f8078c2 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/LiveEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/LiveEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/PreparingEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/PreparingEntity.java index 26833f9..c34a98d 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/PreparingEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/PreparingEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomBlockMsgEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomBlockMsgEntity.java index d0580f1..f016702 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomBlockMsgEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomBlockMsgEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOffEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOffEntity.java index b965836..a5eda18 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOffEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOffEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java new file mode 100644 index 0000000..446c602 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java @@ -0,0 +1,7 @@ +package com.hiczp.bilibili.api.live.socket.entity; + +public interface RoomStatusEntity { + String getCmd(); + + String getRoomId(); +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java index c9897e4..cf16259 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java @@ -6,7 +6,7 @@ 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} @@ -17,6 +17,7 @@ public class SendGiftEntity { @SerializedName("data") private DataEntity data; + @Override public String getCmd() { return cmd; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysGiftEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysGiftEntity.java index ded016a..fda4261 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysGiftEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysGiftEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysMsgEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysMsgEntity.java index e5a03cf..e7c0eff 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysMsgEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SysMsgEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeEntity.java index dc98347..4c6f4cf 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeGuardEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeGuardEntity.java index d8be2aa..178c067 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeGuardEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeGuardEntity.java @@ -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; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WishBottleEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WishBottleEntity.java index 2d07bbc..c9ac6e6 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WishBottleEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WishBottleEntity.java @@ -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; } From 166559f2cf73f969e08c6e068023dcb3b67055b7 Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 24 Feb 2018 18:32:46 +0800 Subject: [PATCH 02/73] =?UTF-8?q?=E4=B8=BA=E7=9B=B4=E6=92=AD=E9=97=B4?= =?UTF-8?q?=E5=BC=B9=E5=B9=95=E6=8E=A8=E9=80=81=E6=9C=89=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=8E=A5=E5=8F=A3=E4=BB=A5?= =?UTF-8?q?=E6=96=B9=E4=BE=BF=E7=BC=96=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/live/socket/entity/RoomStatusEntity.java | 4 +--- .../api/live/socket/event/ActivityEventPackageEvent.java | 2 +- .../api/live/socket/event/DanMuMsgPackageEvent.java | 2 +- .../api/live/socket/event/GuardMsgPackageEvent.java | 2 +- .../bilibili/api/live/socket/event/LivePackageEvent.java | 2 +- .../api/live/socket/event/PreparingPackageEvent.java | 2 +- .../api/live/socket/event/ReceiveDataPackageEvent.java | 9 +++++++++ .../live/socket/event/ReceiveRoomStatusPackageEvent.java | 9 +++++++++ .../api/live/socket/event/RoomBlockMsgPackageEvent.java | 2 +- .../api/live/socket/event/RoomSilentOffPackageEvent.java | 2 +- .../api/live/socket/event/SendGiftPackageEvent.java | 2 +- .../api/live/socket/event/SysGiftPackageEvent.java | 2 +- .../api/live/socket/event/SysMsgPackageEvent.java | 2 +- .../api/live/socket/event/WelcomeGuardPackageEvent.java | 2 +- .../api/live/socket/event/WelcomePackageEvent.java | 2 +- .../api/live/socket/event/WishBottlePackageEvent.java | 2 +- 16 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java index 446c602..893af97 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomStatusEntity.java @@ -1,7 +1,5 @@ package com.hiczp.bilibili.api.live.socket.entity; -public interface RoomStatusEntity { - String getCmd(); - +public interface RoomStatusEntity extends DataEntity { String getRoomId(); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java index 2d488cf..759d4ee 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.ActivityEventEntity; -public class ActivityEventPackageEvent extends ReceivePackageEvent { +public class ActivityEventPackageEvent extends ReceiveDataPackageEvent { public ActivityEventPackageEvent(Object source, ActivityEventEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java index 4f9104c..c3672a9 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.DanMuMsgEntity; -public class DanMuMsgPackageEvent extends ReceivePackageEvent { +public class DanMuMsgPackageEvent extends ReceiveDataPackageEvent { public DanMuMsgPackageEvent(Object source, DanMuMsgEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java index 28994b7..7094e9c 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.GuardMsgEntity; -public class GuardMsgPackageEvent extends ReceivePackageEvent { +public class GuardMsgPackageEvent extends ReceiveDataPackageEvent { public GuardMsgPackageEvent(Object source, GuardMsgEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java index 8ef1035..76c1f0b 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.LiveEntity; -public class LivePackageEvent extends ReceivePackageEvent { +public class LivePackageEvent extends ReceiveRoomStatusPackageEvent { public LivePackageEvent(Object source, LiveEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java index a258158..f960ff9 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.PreparingEntity; -public class PreparingPackageEvent extends ReceivePackageEvent { +public class PreparingPackageEvent extends ReceiveRoomStatusPackageEvent { public PreparingPackageEvent(Object source, PreparingEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java new file mode 100644 index 0000000..6f6e123 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.DataEntity; + +public abstract class ReceiveDataPackageEvent extends ReceivePackageEvent { + public ReceiveDataPackageEvent(Object source, T entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java new file mode 100644 index 0000000..f147839 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.RoomStatusEntity; + +public class ReceiveRoomStatusPackageEvent extends ReceiveDataPackageEvent { + public ReceiveRoomStatusPackageEvent(Object source, T entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java index fd2494b..8618f80 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.RoomBlockMsgEntity; -public class RoomBlockMsgPackageEvent extends ReceivePackageEvent { +public class RoomBlockMsgPackageEvent extends ReceiveDataPackageEvent { public RoomBlockMsgPackageEvent(Object source, RoomBlockMsgEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java index 5dd8924..f7e5167 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.RoomSilentOffEntity; -public class RoomSilentOffPackageEvent extends ReceivePackageEvent { +public class RoomSilentOffPackageEvent extends ReceiveDataPackageEvent { public RoomSilentOffPackageEvent(Object source, RoomSilentOffEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java index c9303a9..d5f1950 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.SendGiftEntity; -public class SendGiftPackageEvent extends ReceivePackageEvent { +public class SendGiftPackageEvent extends ReceiveDataPackageEvent { public SendGiftPackageEvent(Object source, SendGiftEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java index 67d661c..e1af383 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.SysGiftEntity; -public class SysGiftPackageEvent extends ReceivePackageEvent { +public class SysGiftPackageEvent extends ReceiveDataPackageEvent { public SysGiftPackageEvent(Object source, SysGiftEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java index 2868cf6..78b80ee 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.SysMsgEntity; -public class SysMsgPackageEvent extends ReceivePackageEvent { +public class SysMsgPackageEvent extends ReceiveDataPackageEvent { public SysMsgPackageEvent(Object source, SysMsgEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java index 8ea3f5e..3415885 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.WelcomeGuardEntity; -public class WelcomeGuardPackageEvent extends ReceivePackageEvent { +public class WelcomeGuardPackageEvent extends ReceiveDataPackageEvent { public WelcomeGuardPackageEvent(Object source, WelcomeGuardEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java index 2ffdb4c..e16c911 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.WelcomeEntity; -public class WelcomePackageEvent extends ReceivePackageEvent { +public class WelcomePackageEvent extends ReceiveDataPackageEvent { public WelcomePackageEvent(Object source, WelcomeEntity entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java index c1fdeb1..25363dd 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java @@ -2,7 +2,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.WishBottleEntity; -public class WishBottlePackageEvent extends ReceivePackageEvent { +public class WishBottlePackageEvent extends ReceiveDataPackageEvent { public WishBottlePackageEvent(Object source, WishBottleEntity entity) { super(source, entity); } From 332069a0d14fb84d41007de26ca878124f14851a Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 24 Feb 2018 18:45:15 +0800 Subject: [PATCH 03/73] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=AE=BF=E9=97=AE=E7=BA=A7=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/live/socket/event/ReceiveDataPackageEvent.java | 2 +- .../bilibili/api/live/socket/event/ReceivePackageEvent.java | 2 +- .../api/live/socket/event/ReceiveRoomStatusPackageEvent.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java index 6f6e123..dc0ea07 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java @@ -3,7 +3,7 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.DataEntity; public abstract class ReceiveDataPackageEvent extends ReceivePackageEvent { - public ReceiveDataPackageEvent(Object source, T entity) { + ReceiveDataPackageEvent(Object source, T entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java index 99cb6a7..25f1285 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java @@ -3,7 +3,7 @@ package com.hiczp.bilibili.api.live.socket.event; import java.util.EventObject; public abstract class ReceivePackageEvent extends EventObject { - private T entity; + protected T entity; ReceivePackageEvent(Object source, T entity) { super(source); diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java index f147839..db5a9af 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java @@ -2,8 +2,8 @@ package com.hiczp.bilibili.api.live.socket.event; import com.hiczp.bilibili.api.live.socket.entity.RoomStatusEntity; -public class ReceiveRoomStatusPackageEvent extends ReceiveDataPackageEvent { - public ReceiveRoomStatusPackageEvent(Object source, T entity) { +public abstract class ReceiveRoomStatusPackageEvent extends ReceiveDataPackageEvent { + ReceiveRoomStatusPackageEvent(Object source, T entity) { super(source, entity); } } From 4e97600b014c2d7142cf25986fb011c82f6a86b3 Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 24 Feb 2018 18:59:48 +0800 Subject: [PATCH 04/73] =?UTF-8?q?=E5=BC=B9=E5=B9=95=E6=8E=A8=E9=80=81=20so?= =?UTF-8?q?cket=20=E6=9C=89=E5=85=B3=E7=9A=84=E4=BA=8B=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E6=96=B9=E6=B3=95=E6=B7=BB=E5=8A=A0=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E6=96=B9=E6=B3=95=E4=BB=A5=E6=96=B9=E4=BE=BF=E7=BC=96?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/live/socket/event/ReceiveDataPackageEvent.java | 4 ++++ .../api/live/socket/event/ReceiveRoomStatusPackageEvent.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java index dc0ea07..757e83a 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java @@ -6,4 +6,8 @@ public abstract class ReceiveDataPackageEvent extends Rece ReceiveDataPackageEvent(Object source, T entity) { super(source, entity); } + + public DataEntity getEntity0() { + return entity; + } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java index db5a9af..b97370a 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java @@ -6,4 +6,8 @@ public abstract class ReceiveRoomStatusPackageEvent ReceiveRoomStatusPackageEvent(Object source, T entity) { super(source, entity); } + + public RoomStatusEntity getEntity0() { + return entity; + } } From 912ce9a19d5739367ba28e0ba9fd2818deef2b35 Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 26 Feb 2018 15:51:36 +0800 Subject: [PATCH 05/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E5=BC=B9=E5=B9=95=E6=95=B0=E6=8D=AE=E5=8C=85?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20TV=5FEND?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 +- record/bullet_screen_stream_json/TV_END.json | 21 ++ .../api/live/socket/entity/TVEndEntity.java | 209 ++++++++++++++++++ .../live/socket/event/TVEndPackageEvent.java | 9 + .../socket/handler/LiveClientHandler.java | 4 + .../bilibili/api/test/LiveClientTest.java | 35 +-- 6 files changed, 268 insertions(+), 16 deletions(-) create mode 100644 record/bullet_screen_stream_json/TV_END.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVEndEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java diff --git a/build.gradle b/build.gradle index 749b92f..01980ba 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group = 'com.hiczp' -version = '0.0.5' +version = '0.0.6' description = 'Bilibili android client API library written in Java' apply plugin: 'idea' @@ -22,11 +22,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' } diff --git a/record/bullet_screen_stream_json/TV_END.json b/record/bullet_screen_stream_json/TV_END.json new file mode 100644 index 0000000..00ce340 --- /dev/null +++ b/record/bullet_screen_stream_json/TV_END.json @@ -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 + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVEndEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVEndEntity.java new file mode 100644 index 0000000..ea2d177 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVEndEntity.java @@ -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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java new file mode 100644 index 0000000..df656f5 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.TVEndEntity; + +public class TVEndPackageEvent extends ReceiveDataPackageEvent { + public TVEndPackageEvent(Object source, TVEndEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index df6b29a..1738c27 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -139,6 +139,10 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(content, GuardMsgEntity.class)); } break; + case "TV_END": { + eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(content, TVEndEntity.class)); + } + break; default: { LOGGER.error("Received unknown json below: \n{}", formatJson(content)); eventCreationExpression = () -> new UnknownPackageEvent(this, content); diff --git a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java index 124cadd..370a285 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java @@ -129,7 +129,7 @@ public class LiveClientTest { } @Subscribe - public void SysGift(SysGiftPackageEvent sysGiftPackageEvent) { + public void sysGift(SysGiftPackageEvent sysGiftPackageEvent) { SysGiftEntity sysGiftEntity = sysGiftPackageEvent.getEntity(); LOGGER.info("[SysGift] {}: {}", sysGiftEntity.getMsg(), @@ -138,7 +138,7 @@ public class LiveClientTest { } @Subscribe - public void SysMsg(SysMsgPackageEvent sysMsgPackageEvent) { + public void sysMsg(SysMsgPackageEvent sysMsgPackageEvent) { SysMsgEntity sysMsgEntity = sysMsgPackageEvent.getEntity(); LOGGER.info("[SysMsg] {}: {}", sysMsgEntity.getMsg(), @@ -147,21 +147,16 @@ public class LiveClientTest { } @Subscribe - public void ViewerCount(ViewerCountPackageEvent viewerCountPackageEvent) { - LOGGER.info("[ViewerCount] {}", viewerCountPackageEvent.getViewerCount()); - } - - @Subscribe - public void WelcomeGuard(WelcomeGuardPackageEvent welcomeGuardPackageEvent) { - WelcomeGuardEntity.DataEntity dataEntity = welcomeGuardPackageEvent.getEntity().getData(); - LOGGER.info("[WelcomeGuard] [GL {}] {}", - dataEntity.getGuardLevel(), - dataEntity.getUsername() + public void tvEnd(TVEndPackageEvent tvEndPackageEvent) { + TVEndEntity tvEndEntity = tvEndPackageEvent.getEntity(); + LOGGER.info("[TVEnd] user {} win the {}", + tvEndEntity.getData().getUname(), + tvEndEntity.getData().getType() ); } @Subscribe - public void Welcome(WelcomePackageEvent welcomePackageEvent) { + public void welcome(WelcomePackageEvent welcomePackageEvent) { WelcomeEntity.DataEntity dataEntity = welcomePackageEvent.getEntity().getData(); StringBuilder stringBuilder = new StringBuilder("[Welcome] "); if (dataEntity.isAdmin()) { @@ -171,5 +166,19 @@ public class LiveClientTest { .append(dataEntity.getUserName()); LOGGER.info(stringBuilder.toString()); } + + @Subscribe + public void welcomeGuard(WelcomeGuardPackageEvent welcomeGuardPackageEvent) { + WelcomeGuardEntity.DataEntity dataEntity = welcomeGuardPackageEvent.getEntity().getData(); + LOGGER.info("[WelcomeGuard] [GL {}] {}", + dataEntity.getGuardLevel(), + dataEntity.getUsername() + ); + } + + @Subscribe + public void viewerCount(ViewerCountPackageEvent viewerCountPackageEvent) { + LOGGER.info("[ViewerCount] {}", viewerCountPackageEvent.getViewerCount()); + } } } From 8b332f9e1c907bf218462397a89321d92019c18f Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 26 Feb 2018 22:23:29 +0800 Subject: [PATCH 06/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20live=20=E6=9C=89?= =?UTF-8?q?=E5=85=B3=20API=20assistant/getRoomInfo=20mhand/assistant/getCo?= =?UTF-8?q?ver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/ServerErrorCode.java | 1 + .../hiczp/bilibili/api/live/LiveService.java | 11 +- .../live/entity/AssistantRoomInfoEntity.java | 356 ++++++++++++++++++ .../bilibili/api/live/entity/CoverEntity.java | 199 ++++++++++ 4 files changed, 566 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/AssistantRoomInfoEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/CoverEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java index b5aee4f..7c35957 100644 --- a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java +++ b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java @@ -5,6 +5,7 @@ public class ServerErrorCode { //服务网关上鉴权失败的话, 会返回这些标准错误码 //B站后台设计很混乱, 不是所有鉴权都在服务网关上完成 public static class Common { + public static final int API_SIGN_INVALID = -3; public static final int OK = 0; public static final int BAD_REQUEST = -400; public static final int UNAUTHORIZED = -401; diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index a01d990..1e99963 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -22,11 +22,16 @@ public interface LiveService { @GET("AppRoom/msg") Call getHistoryBulletScreens(@Query("room_id") long roomId); - //获取房间信息 + //获取直播间信息 //登录后访问该 API 将在服务器新增一条直播间观看历史 @GET("AppRoom/index") Call getRoomInfo(@Query("room_id") long roomId); + //根据用户 ID 来获取房间信息, 通常用于获取自己的直播间信息 + //该 API 不会增加直播间观看历史 + @GET("assistant/getRoomInfo") + Call getAssistantRoomInfo(@Query("uId") long userId); + //获得是否关注了一个主播 //未登录时返回 401 @POST("feed/v1/feed/isFollowed") @@ -171,6 +176,10 @@ public interface LiveService { return search(keyword, page, pageSize, "all"); } + //获取自己的直播间的封面(获取其他人的封面会 -403) + @GET("mhand/assistant/getCover") + Call getCover(@Query("roomId") long roomId); + //"直播" 页面下面的推荐, 每个分类有六个的那种 @GET("mobile/rooms") Call getRooms(); diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/AssistantRoomInfoEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/AssistantRoomInfoEntity.java new file mode 100644 index 0000000..ddac49d --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/AssistantRoomInfoEntity.java @@ -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; + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/CoverEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/CoverEntity.java new file mode 100644 index 0000000..d2d710e --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/CoverEntity.java @@ -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; + + 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 getCoverList() { + return coverList; + } + + public void setCoverList(List 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; + } + } + } +} From 4694899ef93a38f6304d1215f6c2a18091be2dff Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 27 Feb 2018 09:13:29 +0800 Subject: [PATCH 07/73] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 137f3e1..32fe2a7 100644 --- a/README.md +++ b/README.md @@ -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.5' # 名词解释 B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一些常见参数对应的含义 From 45848c5816af877f909f7c62379e942137f1d85d Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 28 Feb 2018 14:00:09 +0800 Subject: [PATCH 08/73] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 32fe2a7..ca0ff2f 100644 --- a/README.md +++ b/README.md @@ -237,6 +237,7 @@ API 文档 | SendHeartBeatPackageEvent | 每次发送心跳包后触发一次 | | SysGiftPackageEvent | 收到 SYS_GIFT 数据包 | | SysMsgPackageEvent | 收到 SYS_MSG 数据包 | +| TVEndPackageEvent | 收到 TV_END 数据包 | | UnknownPackageEvent | B站新增了新种类的数据包, 出现此情况请提交 issue | | ViewerCountPackageEvent | 收到 房间人数 数据包(不是 Json) | | WelcomeGuardPackageEvent | 收到 WELCOME_GUARD 数据包 | From 4e954af9d2903616d8ab98f210c038597646f947 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 1 Mar 2018 15:39:40 +0800 Subject: [PATCH 09/73] =?UTF-8?q?=E5=AE=8C=E6=88=90=20sso=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 - .../com/hiczp/bilibili/api/BilibiliAPI.java | 88 +++++++++++++++++-- .../bilibili/api/BilibiliSsoProvider.java | 20 +++++ .../bilibili/api/cookie/SimpleCookieJar.java | 67 ++++++++++++++ .../exception/UserCancelRequestException.java | 21 +++++ .../interceptor/CancelRequestInterceptor.java | 22 +++++ .../api/passport/PassportService.java | 6 -- .../bilibili/api/passport/SsoService.java | 15 ++++ .../com/hiczp/bilibili/api/test/SsoTest.java | 25 +++--- 9 files changed, 238 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/BilibiliSsoProvider.java create mode 100644 src/main/java/com/hiczp/bilibili/api/cookie/SimpleCookieJar.java create mode 100644 src/main/java/com/hiczp/bilibili/api/exception/UserCancelRequestException.java create mode 100644 src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java create mode 100644 src/main/java/com/hiczp/bilibili/api/passport/SsoService.java diff --git a/build.gradle b/build.gradle index 01980ba..19ab67e 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,6 @@ apply plugin: 'signing' sourceCompatibility = 1.8 repositories { - maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } mavenCentral() } diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index f18a52d..7d1e792 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -1,16 +1,17 @@ package com.hiczp.bilibili.api; +import com.hiczp.bilibili.api.cookie.SimpleCookieJar; 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.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 okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,6 +19,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,8 +27,9 @@ 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, BilibiliSsoProvider, LiveClientProvider { private static final Logger LOGGER = LoggerFactory.getLogger(BilibiliAPI.class); private final Long apiInitTime = Instant.now().getEpochSecond(); //记录当前类被实例化的时间 @@ -72,8 +75,6 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider public PassportService getPassportService(@Nonnull List interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) { OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); - interceptors.forEach(okHttpClientBuilder::addInterceptor); - okHttpClientBuilder .addInterceptor(new AddFixedParamsInterceptor( "build", bilibiliClientProperties.getBuild(), @@ -85,7 +86,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,8 +112,6 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider public LiveService getLiveService(@Nonnull List interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) { OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); - interceptors.forEach(okHttpClientBuilder::addInterceptor); - okHttpClientBuilder .addInterceptor(new AddFixedHeadersInterceptor( "Buvid", bilibiliClientProperties.getBuvId(), @@ -144,7 +147,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 +162,45 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider .create(LiveService.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 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); + } + public LoginResponseEntity login(@Nonnull String username, @Nonnull String password) throws IOException, LoginException, CaptchaMismatchException { return login(username, password, null, null); } @@ -270,6 +316,30 @@ public class BilibiliAPI implements BilibiliServiceProvider, LiveClientProvider return infoEntity; } + @Override + public HttpUrl getSsoUrl(@Nullable String goUrl) { + CancelRequestInterceptor cancelRequestInterceptor = new CancelRequestInterceptor(); + try { + getSsoService(new SimpleCookieJar(), Collections.singletonList(cancelRequestInterceptor), HttpLoggingInterceptor.Level.BASIC) + .sso(null) + .execute(); + } catch (IOException ignored) { + + } + return cancelRequestInterceptor.getRequest().url(); + } + + @Override + public Map> toCookies() throws IOException { + return toCookies(BaseUrlDefinition.PASSPORT + "api/oauth2/getKey"); + } + + public Map> toCookies(@Nullable String goUrl) throws IOException { + SimpleCookieJar simpleCookieJar = new SimpleCookieJar(); + getSsoService(simpleCookieJar).sso(goUrl).execute(); + return simpleCookieJar.getCookiesMap(); + } + @Override public LiveClient getLiveClient(long showRoomId) { return bilibiliAccount.getUserId() == null ? diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliSsoProvider.java b/src/main/java/com/hiczp/bilibili/api/BilibiliSsoProvider.java new file mode 100644 index 0000000..d203492 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliSsoProvider.java @@ -0,0 +1,20 @@ +package com.hiczp.bilibili.api; + +import com.hiczp.bilibili.api.passport.SsoService; +import okhttp3.Cookie; +import okhttp3.CookieJar; +import okhttp3.HttpUrl; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public interface BilibiliSsoProvider { + SsoService getSsoService(CookieJar cookieJar); + + //获取用于进行 sso 登录的初始 URL + HttpUrl getSsoUrl(String goUrl); + + //获取当前 token 对应的 cookies + Map> toCookies() throws IOException; +} diff --git a/src/main/java/com/hiczp/bilibili/api/cookie/SimpleCookieJar.java b/src/main/java/com/hiczp/bilibili/api/cookie/SimpleCookieJar.java new file mode 100644 index 0000000..24998bf --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/cookie/SimpleCookieJar.java @@ -0,0 +1,67 @@ +package com.hiczp.bilibili.api.cookie; + +import okhttp3.Cookie; +import okhttp3.CookieJar; +import okhttp3.HttpUrl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SimpleCookieJar implements CookieJar { + private Map> cookiesMap; + + public SimpleCookieJar() { + cookiesMap = new HashMap<>(); + } + + public SimpleCookieJar(Map> cookiesMap) { + this.cookiesMap = new HashMap<>(cookiesMap); + } + + @Override + public void saveFromResponse(HttpUrl url, List cookies) { + cookies.forEach(cookie -> { + String domain = cookie.domain(); + List savedCookies = cookiesMap.get(domain); + if (savedCookies == null) { + savedCookies = new ArrayList<>(); + savedCookies.add(cookie); + cookiesMap.put(domain, savedCookies); + } else { + for (Cookie savedCookie : savedCookies) { + if (savedCookie.name().equals(cookie.name())) { + savedCookies.remove(savedCookie); + break; + } + } + savedCookies.add(cookie); + } + }); + } + + @Override + public List loadForRequest(HttpUrl url) { + return getCookiesForHost(url.host()); + } + + public List getCookiesForHost(String host) { + List cookieList = new ArrayList<>(); + cookiesMap.forEach((domain, cookies) -> { + if (host.endsWith(domain)) { + for (int i = cookies.size() - 1; i >= 0; i--) { + if (cookies.get(i).expiresAt() < System.currentTimeMillis()) { + cookies.remove(i); + } + } + cookieList.addAll(cookies); + } + }); + return cookieList; + } + + public Map> getCookiesMap() { + return cookiesMap; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/exception/UserCancelRequestException.java b/src/main/java/com/hiczp/bilibili/api/exception/UserCancelRequestException.java new file mode 100644 index 0000000..39cb0f9 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/exception/UserCancelRequestException.java @@ -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); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java new file mode 100644 index 0000000..1ed1bd5 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java @@ -0,0 +1,22 @@ +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; + +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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java index 1a308d8..b688930 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java @@ -12,7 +12,6 @@ import retrofit2.http.POST; import retrofit2.http.Query; import javax.annotation.Nonnull; -import javax.annotation.Nullable; public interface PassportService { //获取验证码 @@ -50,9 +49,4 @@ public interface PassportService { @POST("api/oauth2/revoke") Call logout(@Query("access_token") String accessToken); - - //TODO sso 尚不明确 - @Deprecated - @GET("api/login/sso") - Call sso(@Query("access_token") String accessToken, @Nullable @Query("gourl") String goUrl); } diff --git a/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java new file mode 100644 index 0000000..51990d9 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java @@ -0,0 +1,15 @@ +package com.hiczp.bilibili.api.passport; + +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +import javax.annotation.Nullable; + +//sso 很特别, 它可能返回的是一个 HTML 页面, 所以单独分出来 +//sso 会经过两次 302 跳转, 需要保存其中的 cookie, 然后才能抵达最终页面并且进入 cookie 登录状态 +public interface SsoService { + @GET("api/login/sso") + Call sso(@Nullable @Query("gourl") String goUrl); +} diff --git a/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java b/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java index 2c730d6..f2ce613 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java @@ -1,25 +1,28 @@ package com.hiczp.bilibili.api.test; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.hiczp.bilibili.api.BilibiliAPI; -import org.junit.Ignore; +import okhttp3.Cookie; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; +import java.util.Map; + public class SsoTest { - private static final Logger LOGGER = LoggerFactory.getLogger(UserInfoTest.class); - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + private static final Logger LOGGER = LoggerFactory.getLogger(SsoTest.class); private static final BilibiliAPI BILIBILI_API = Config.getBilibiliAPI(); - @Ignore @Test public void test() throws Exception { -// Object object = BILIBILI_API.getPassportService() -// .sso(BILIBILI_API.getBilibiliAccount().getAccessToken(), null) -// .execute() -// .body(); -// LOGGER.info("{}", object.toString()); + Map> cookiesMap = BILIBILI_API.toCookies(); + StringBuilder stringBuilder = new StringBuilder(); + cookiesMap.forEach((domain, cookies) -> { + stringBuilder.append("domain: ").append(domain).append("\n"); + cookies.forEach(cookie -> + stringBuilder.append("\t").append(cookie.name()).append("=").append(cookie.value()).append("\n") + ); + }); + LOGGER.info("Cookies below: \n{}", stringBuilder.toString()); } } From 919167d273853710703e0ce384e45a521b7a2690 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 1 Mar 2018 16:10:04 +0800 Subject: [PATCH 10/73] =?UTF-8?q?=E5=B0=86=20CaptchaService=20=E4=BB=8E=20?= =?UTF-8?q?PassportService=20=E4=B8=AD=E5=8D=95=E7=8B=AC=E5=88=86=E5=87=BA?= =?UTF-8?q?=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hiczp/bilibili/api/BilibiliAPI.java | 27 ++++++++++++++++++- .../bilibili/api/BilibiliSecurityHelper.java | 1 + .../bulletScreen/BulletScreenSendingTask.java | 2 +- .../bilibili/api/live/socket/LiveClient.java | 2 +- .../bilibili/api/passport/CaptchaService.java | 21 +++++++++++++++ .../api/passport/PassportService.java | 23 ---------------- .../api/provider/BilibiliCaptchaProvider.java | 7 +++++ .../BilibiliServiceProvider.java | 2 +- .../{ => provider}/BilibiliSsoProvider.java | 2 +- .../bilibili/api/test/CaptchaInputDialog.java | 12 +++------ .../hiczp/bilibili/api/test/UserInfoTest.java | 14 ++-------- 11 files changed, 64 insertions(+), 49 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java create mode 100644 src/main/java/com/hiczp/bilibili/api/provider/BilibiliCaptchaProvider.java rename src/main/java/com/hiczp/bilibili/api/{ => provider}/BilibiliServiceProvider.java (84%) rename src/main/java/com/hiczp/bilibili/api/{ => provider}/BilibiliSsoProvider.java (92%) diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 7d1e792..4ff65b0 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -4,6 +4,7 @@ import com.hiczp.bilibili.api.cookie.SimpleCookieJar; 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; @@ -11,6 +12,9 @@ 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 com.hiczp.bilibili.api.provider.BilibiliCaptchaProvider; +import com.hiczp.bilibili.api.provider.BilibiliServiceProvider; +import com.hiczp.bilibili.api.provider.BilibiliSsoProvider; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; import org.slf4j.Logger; @@ -29,7 +33,7 @@ import java.util.Date; import java.util.List; import java.util.Map; -public class BilibiliAPI implements BilibiliServiceProvider, BilibiliSsoProvider, LiveClientProvider { +public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProvider, BilibiliSsoProvider, LiveClientProvider { private static final Logger LOGGER = LoggerFactory.getLogger(BilibiliAPI.class); private final Long apiInitTime = Instant.now().getEpochSecond(); //记录当前类被实例化的时间 @@ -41,6 +45,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliSsoProvider private String invalidRefreshToken; private PassportService passportService; + private CaptchaService captchaService; private LiveService liveService; public BilibiliAPI() { @@ -162,6 +167,26 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliSsoProvider .create(LiveService.class); } + @Override + public CaptchaService getCaptchaService() { + if (captchaService == null) { + captchaService = getCaptchaService(Collections.emptyList(), HttpLoggingInterceptor.Level.BASIC); + } + return captchaService; + } + + public CaptchaService getCaptchaService(@Nonnull List 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()); } diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java b/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java index d5c150c..b8f0cc6 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java @@ -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; diff --git a/src/main/java/com/hiczp/bilibili/api/live/bulletScreen/BulletScreenSendingTask.java b/src/main/java/com/hiczp/bilibili/api/live/bulletScreen/BulletScreenSendingTask.java index 81c4084..1b06865 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/bulletScreen/BulletScreenSendingTask.java +++ b/src/main/java/com/hiczp/bilibili/api/live/bulletScreen/BulletScreenSendingTask.java @@ -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; diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java b/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java index c4e29fc..6a5cbeb 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java @@ -2,7 +2,6 @@ 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; @@ -11,6 +10,7 @@ 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.ChannelInitializer; diff --git a/src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java b/src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java new file mode 100644 index 0000000..e180740 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java @@ -0,0 +1,21 @@ +package com.hiczp.bilibili.api.passport; + +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Header; + +import java.io.IOException; +import java.io.InputStream; + +public interface CaptchaService { + @GET("captcha") + Call getCaptcha(@Header("Cookie") String cookies); + + default InputStream getCaptchaAsStream(String cookies) throws IOException { + return getCaptcha(cookies) + .execute() + .body() + .byteStream(); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java index b688930..98f1549 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java @@ -1,36 +1,13 @@ package com.hiczp.bilibili.api.passport; -import com.hiczp.bilibili.api.BaseUrlDefinition; import com.hiczp.bilibili.api.passport.entity.*; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Header; import retrofit2.http.POST; import retrofit2.http.Query; -import javax.annotation.Nonnull; - public interface PassportService { - //获取验证码 - default okhttp3.Call getCaptcha(@Nonnull String cookies) { - return getCaptcha(cookies, HttpLoggingInterceptor.Level.BASIC); - } - - default okhttp3.Call getCaptcha(@Nonnull String cookies, @Nonnull HttpLoggingInterceptor.Level logLevel) { - return new OkHttpClient.Builder() - .addInterceptor(new HttpLoggingInterceptor().setLevel(logLevel)) - .build() - .newCall( - new Request.Builder() - .url(BaseUrlDefinition.PASSPORT + "captcha") - .header("Cookie", cookies) - .build() - ); - } - @POST("api/oauth2/getKey") Call getKey(); diff --git a/src/main/java/com/hiczp/bilibili/api/provider/BilibiliCaptchaProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliCaptchaProvider.java new file mode 100644 index 0000000..82dbe4d --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliCaptchaProvider.java @@ -0,0 +1,7 @@ +package com.hiczp.bilibili.api.provider; + +import com.hiczp.bilibili.api.passport.CaptchaService; + +public interface BilibiliCaptchaProvider { + CaptchaService getCaptchaService(); +} diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliServiceProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliServiceProvider.java similarity index 84% rename from src/main/java/com/hiczp/bilibili/api/BilibiliServiceProvider.java rename to src/main/java/com/hiczp/bilibili/api/provider/BilibiliServiceProvider.java index 432e79e..07a0112 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliServiceProvider.java +++ b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliServiceProvider.java @@ -1,4 +1,4 @@ -package com.hiczp.bilibili.api; +package com.hiczp.bilibili.api.provider; import com.hiczp.bilibili.api.live.LiveService; import com.hiczp.bilibili.api.passport.PassportService; diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliSsoProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliSsoProvider.java similarity index 92% rename from src/main/java/com/hiczp/bilibili/api/BilibiliSsoProvider.java rename to src/main/java/com/hiczp/bilibili/api/provider/BilibiliSsoProvider.java index d203492..fcaf2e8 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliSsoProvider.java +++ b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliSsoProvider.java @@ -1,4 +1,4 @@ -package com.hiczp.bilibili.api; +package com.hiczp.bilibili.api.provider; import com.hiczp.bilibili.api.passport.SsoService; import okhttp3.Cookie; diff --git a/src/test/java/com/hiczp/bilibili/api/test/CaptchaInputDialog.java b/src/test/java/com/hiczp/bilibili/api/test/CaptchaInputDialog.java index 05b84a4..1903bb7 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/CaptchaInputDialog.java +++ b/src/test/java/com/hiczp/bilibili/api/test/CaptchaInputDialog.java @@ -1,7 +1,6 @@ package com.hiczp.bilibili.api.test; import com.hiczp.bilibili.api.BilibiliAPI; -import okhttp3.Response; import javax.imageio.ImageIO; import javax.swing.*; @@ -47,17 +46,12 @@ public class CaptchaInputDialog extends JDialog { private void createUIComponents() { try { - cookie = new BilibiliAPI().getPassportService().getKey() + BilibiliAPI bilibiliAPI = new BilibiliAPI(); + cookie = bilibiliAPI.getPassportService().getKey() .execute() .headers() .get("Set-cookie"); - Response response = Config.getBilibiliAPI().getPassportService() - .getCaptcha(cookie) - .execute(); - if (response.code() != 200) { - throw new IOException(response.message()); - } - label = new JLabel(new ImageIcon(ImageIO.read(response.body().byteStream()))); + label = new JLabel(new ImageIcon(ImageIO.read(bilibiliAPI.getCaptchaService().getCaptchaAsStream(cookie)))); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/test/java/com/hiczp/bilibili/api/test/UserInfoTest.java b/src/test/java/com/hiczp/bilibili/api/test/UserInfoTest.java index 6872c29..8b7af14 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/UserInfoTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/UserInfoTest.java @@ -3,14 +3,11 @@ package com.hiczp.bilibili.api.test; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.hiczp.bilibili.api.BilibiliAPI; -import com.hiczp.bilibili.api.ServerErrorCode; import com.hiczp.bilibili.api.passport.entity.InfoEntity; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.naming.AuthenticationException; - public class UserInfoTest { private static final Logger LOGGER = LoggerFactory.getLogger(UserInfoTest.class); private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); @@ -18,14 +15,7 @@ public class UserInfoTest { @Test public void getUserInfo() throws Exception { - InfoEntity infoEntity = BILIBILI_API.getPassportService() - .getInfo(BILIBILI_API.getBilibiliAccount().getAccessToken()) - .execute() - .body(); - if (infoEntity.getCode() == ServerErrorCode.Common.OK) { - LOGGER.info("UserInfo below: \n{}", GSON.toJson(infoEntity)); - } else { - throw new AuthenticationException(infoEntity.getMessage()); - } + InfoEntity infoEntity = BILIBILI_API.getAccountInfo(); + LOGGER.info("UserInfo below: \n{}", GSON.toJson(infoEntity)); } } From dae4b57e5916f805cd91dbfea26f8225f079fe88 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 1 Mar 2018 17:16:14 +0800 Subject: [PATCH 11/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 47 +++++++++++++++--- .../com/hiczp/bilibili/api/BilibiliAPI.java | 48 +++++++++---------- 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index ca0ff2f..b284b06 100644 --- a/README.md +++ b/README.md @@ -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,20 +48,20 @@ CaptchaMismatchException 在验证码不正确时抛出, 见下文 [验证码问 login 方法的返回值为 LoginResponseEntity 类型, 使用 - .login(...).toBilibiliAccount() + 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 在网络故障时抛出 @@ -67,7 +69,7 @@ LoginException 在 token 错误,或者 refreshToken 错误或过期时抛出. ### 登出 - BilibiliRESTAPI.logout() throws IOException, LoginException + bilibiliAPI.logout(); IOException 在网络故障时抛出 @@ -133,6 +135,37 @@ 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>, key 为 domain(可能是统配类型的, 例如 ".bilibili.com"), value 为此 domain 对应的 cookies. + +如果只想得到用于进行 SSO 操作的那条 URL, 可以这么做 + + final String goUrl = "https://account.bilibili.com/account/home"; + bilibiliAPI.getSsoUrl(); + +返回值是一个 HttpUrl, 里面 url 的值差不多是这样的 + + https://passport.bilibili.com/api/login/sso?access_key=13c346c203de77dfac8b67b169f3029b&appkey=1d8b6e7d45233436&build=515000&mobi_app=android&platform=android&ts=1519895404&sign=ee05f96c636e7745c38918fe343469ee + +如果 access_key 是正确的话, 这个 url 访问一下就登录 B站 了. + +如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址). + ### API 调用示例 打印一个直播间的历史弹幕 diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 4ff65b0..141c91b 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -226,6 +226,30 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv .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(null) + .execute(); + } catch (IOException ignored) { + + } + return cancelRequestInterceptor.getRequest().url(); + } + + @Override + public Map> toCookies() throws IOException { + return toCookies(BaseUrlDefinition.PASSPORT + "api/oauth2/getKey"); + } + + public Map> toCookies(@Nullable String goUrl) throws IOException { + SimpleCookieJar simpleCookieJar = new SimpleCookieJar(); + getSsoService(simpleCookieJar).sso(goUrl).execute(); + return simpleCookieJar.getCookiesMap(); + } + public LoginResponseEntity login(@Nonnull String username, @Nonnull String password) throws IOException, LoginException, CaptchaMismatchException { return login(username, password, null, null); } @@ -341,30 +365,6 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv return infoEntity; } - @Override - public HttpUrl getSsoUrl(@Nullable String goUrl) { - CancelRequestInterceptor cancelRequestInterceptor = new CancelRequestInterceptor(); - try { - getSsoService(new SimpleCookieJar(), Collections.singletonList(cancelRequestInterceptor), HttpLoggingInterceptor.Level.BASIC) - .sso(null) - .execute(); - } catch (IOException ignored) { - - } - return cancelRequestInterceptor.getRequest().url(); - } - - @Override - public Map> toCookies() throws IOException { - return toCookies(BaseUrlDefinition.PASSPORT + "api/oauth2/getKey"); - } - - public Map> toCookies(@Nullable String goUrl) throws IOException { - SimpleCookieJar simpleCookieJar = new SimpleCookieJar(); - getSsoService(simpleCookieJar).sso(goUrl).execute(); - return simpleCookieJar.getCookiesMap(); - } - @Override public LiveClient getLiveClient(long showRoomId) { return bilibiliAccount.getUserId() == null ? From 0acebe1b7ef1cd307c46f6b2a38104d0523423a0 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 1 Mar 2018 17:17:45 +0800 Subject: [PATCH 12/73] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b284b06..42aa4cc 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访 bilibiliAPI.toCookies(); -来得到对应的 cookies, 类型为 Map>, key 为 domain(可能是统配类型的, 例如 ".bilibili.com"), value 为此 domain 对应的 cookies. +来得到对应的 cookies, 类型为 Map>, key 为 domain(可能是通配类型的, 例如 ".bilibili.com"), value 为此 domain 对应的 cookies. 如果只想得到用于进行 SSO 操作的那条 URL, 可以这么做 From 7b493b73264c85fc3c3de3d9d18ee3b2ee03d2bd Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 2 Mar 2018 14:19:32 +0800 Subject: [PATCH 13/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B=20?= =?UTF-8?q?=E4=BE=A7=E6=8B=89=E6=8A=BD=E5=B1=89=20->=20=E7=9B=B4=E6=92=AD?= =?UTF-8?q?=E4=B8=AD=E5=BF=83=20=E9=87=8C=E9=9D=A2=E7=9A=84=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/ServerErrorCode.java | 2 + .../hiczp/bilibili/api/live/LiveService.java | 102 +- .../api/live/entity/AllListEntity.java | 1722 +++++++++++++++++ .../api/live/entity/CapsuleInfoEntity.java | 289 +++ .../api/live/entity/HistoryEntity.java | 232 +++ .../api/live/entity/MyMedalListEntity.java | 160 ++ .../entity/OpenCapsuleResponseEntity.java | 172 ++ .../api/live/entity/WearTitleEntity.java | 453 +++++ 8 files changed, 3111 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/AllListEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/CapsuleInfoEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/HistoryEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/MyMedalListEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/OpenCapsuleResponseEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java index 7c35957..2445a46 100644 --- a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java +++ b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java @@ -32,6 +32,8 @@ public class ServerErrorCode { //一些 API 未登录时返回 3, 一些返回 -101, 还有一些返回 401, 在网关上鉴权的 API 返回 -401 //甚至有一些 API 返回 32205 这种奇怪的错误码 public static class Live { + //"invalid params" + public static final int INVALID_PARAMS = 1; //"user no login" public static final int USER_NO_LOGIN = 3; //"请登录" diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 1e99963..057ca49 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -27,11 +27,6 @@ public interface LiveService { @GET("AppRoom/index") Call getRoomInfo(@Query("room_id") long roomId); - //根据用户 ID 来获取房间信息, 通常用于获取自己的直播间信息 - //该 API 不会增加直播间观看历史 - @GET("assistant/getRoomInfo") - Call getAssistantRoomInfo(@Query("uId") long userId); - //获得是否关注了一个主播 //未登录时返回 401 @POST("feed/v1/feed/isFollowed") @@ -155,17 +150,7 @@ public interface LiveService { @GET("AppRoom/getGiftTop") Call getGiftTop(@Query("room_id") int roomId); - //签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能))(侧拉抽屉 -> 直播中心 -> 右上角日历图标) - //无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign() - @GET("AppUser/getSignInfo") - Call getSignInfo(); - - //获得关注列表(直播 -> 关注) - //未登录时返回 32205 - @GET("AppFeed/index") - Call getFollowedHosts(@Query("page") long page, @Query("pagesize") long pageSize); - - //live 站的搜索 + //live 站的搜索("直播" 页面) //type 为 room 时只返回 房间 的搜索结果 //type 为 user 时只返回 用户 的搜索结果 //type 为 all 时 房间 与 用户 的搜索结果都有 @@ -176,23 +161,98 @@ public interface LiveService { return search(keyword, page, pageSize, "all"); } - //获取自己的直播间的封面(获取其他人的封面会 -403) - @GET("mhand/assistant/getCover") - Call getCover(@Query("roomId") long roomId); + //"直播" 页面(这个页面对应的后台数据, 包括 banner, 推荐主播, 各种分区的推荐等) + //这个 API 会读取 "_device"(固定参数) 或者 "device" 来判断平台, 只需要有一个就能正常工作, 客户端上是两个都有, 且值都为 "android" + @GET("room/v1/AppIndex/getAllList") + Call getAllList(@Query("device") String device); - //"直播" 页面下面的推荐, 每个分类有六个的那种 + default Call getAllList() { + return getAllList("android"); + } + + //直播 -> 全部直播 -> 推荐直播 + //似乎 推荐直播 与 最热直播 的返回值是一样的 @GET("mobile/rooms") Call getRooms(); - //侧拉抽屉 -> 直播中心 -> 佩戴中心 + //侧拉抽屉 -> 直播中心 -> 右上角日历图标 + //签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能)) + //无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign() + @GET("AppUser/getSignInfo") + Call getSignInfo(); + + //侧拉抽屉 -> 直播中心 -> 我的关注 + //获得关注列表 + //未登录时返回 32205 + @GET("AppFeed/index") + Call getFollowedHosts(@Query("page") long page, @Query("pagesize") long pageSize); + + //侧拉抽屉 -> 直播中心 -> 观看历史 + @GET("AppUser/history") + Call getHistory(@Query("page") long page, @Query("pagesize") long pageSize); + + //TODO 佩戴中心 + //侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 粉丝勋章 + //获得用户拥有的粉丝勋章 + @GET("AppUser/medal") + Call getMyMedalList(); + + //TODO 佩戴粉丝勋章 + //TODO 删除粉丝勋章 + + //侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 我的头衔 -> 佩戴头衔 //获得用户拥有的头衔 @GET("appUser/myTitleList") Call getMyTitleList(); + //获得当前佩戴着的头衔的详情 + //当前未佩戴任何东西时, 返回的 code 为 -1, message 为 "nodata" + @GET("appUser/getWearTitle") + Call getWearTitle(); + //佩戴头衔 + //是的, 你没看错, 是 GET 方式 @GET("AppUser/wearTitle") Call wearTitle(@Query("title") String title); + //TODO 获奖记录 + + //TODO 瓜子商店 //侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币 //将 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次 + + //扭蛋机 + //侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 + //获得 扭蛋机(普通扭蛋) 这个页面对应的后台数据 + @GET("AppUser/capsuleInfo") + Call getCapsuleInfo(); + + //抽扭蛋 + //count 只能为 1, 10, 100 + @POST("AppUser/capsuleInfoOpen") + @FormUrlEncoded + Call openCapsule(@Field("count") long count, @Field("type") String type); + + //抽普通扭蛋 + //侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 -> 扭 + //普通扭蛋的 type 为 "normal" + default Call openNormalCapsule(long count) { + return openCapsule(count, "normal"); + } + + //TODO 梦幻扭蛋(没抽过, 不知道 type 的值) + + //房间设置 + //侧拉抽屉 -> 直播中心 -> 房间设置 -> (上面的个人信息, 包括 房间号, 粉丝数, UP 经验) + //根据用户 ID 来获取房间信息, 通常用于获取自己的直播间信息(可以用来获取他人的房间信息) + //该 API 不会增加直播间观看历史 + @GET("assistant/getRoomInfo") + Call getAssistantRoomInfo(@Query("uId") long userId); + + //侧拉抽屉 -> 直播中心 -> 房间设置 -> 我的封面 + //获取自己的直播间的封面(获取其他人的封面会 -403) + @GET("mhand/assistant/getCover") + Call getCover(@Query("roomId") long roomId); + + //TODO 粉丝勋章(尚未达到开通粉丝勋章的最低要求, 无法对该 API 截包) } diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/AllListEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/AllListEntity.java new file mode 100644 index 0000000..ccc9c33 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/AllListEntity.java @@ -0,0 +1,1722 @@ +package com.hiczp.bilibili.api.live.entity; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class AllListEntity { + /** + * code : 0 + * msg : ok + * message : ok + * data : {"banner":[{"title":"直播周刊","img":"https://i0.hdslb.com/bfs/live/af17c8d882104370075f4fa5418343861ac3e540.png","remark":"直播周刊","link":"https://live.bilibili.com/AppBanner/index?id=746"}],"entranceIcons":[{"id":9,"name":"绘画专区","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/9_big.png?20171116172700","height":"132","width":"132"}},{"id":8,"name":"萌宅推荐","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/8_big.png?20171116172700","height":"132","width":"132"}},{"id":3,"name":"网络游戏","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/3_big.png?20171116172700","height":"132","width":"132"}},{"id":1,"name":"单机联机","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/1_big.png?20171116172700","height":"132","width":"132"}},{"id":4,"name":"电子竞技","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/4_big.png?20171116172700","height":"132","width":"132"}}],"partitions":[{"partition":{"id":1,"name":"娱乐","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/1_3x.png?201709151052","height":"63","width":"63"},"count":1484},"lives":[{"roomid":7399897,"uid":7619276,"title":"包裹有免费B坷垃可送哦(点这看直播单)","uname":"星子弈风","online":145,"user_cover":"https://i0.hdslb.com/bfs/live/7fc54c49ed7db4bc53fe6e5c8888db3eb0c01d7c.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/7399897.jpg?03020945","show_cover":false,"link":"/7399897","face":"https://i2.hdslb.com/bfs/face/41c4b60b54795870ac4d209dc949a51ca7614062.jpg","parent_id":1,"parent_name":"娱乐","area_id":123,"area_name":"户外","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/415156/live_7619276_6963984.flv?wsSecret=26f02e69c2e01fc840da1f452d673f37&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":2802503,"uid":34993653,"title":"做个温柔读书哄睡的小姐姐","uname":"楚小芭","online":958,"user_cover":"https://i0.hdslb.com/bfs/live/33e9537f94545758035b14a59a68fd1b78f8184b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/2802503.jpg?03020945","show_cover":false,"link":"/2802503","face":"https://i0.hdslb.com/bfs/face/41a917cb13f546e62bfea4e06a7781d8118c676e.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/368878/live_34993653_4247645.flv?wsSecret=01587e645b73cfeec12992ac3f3b8288&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":910884,"uid":20165629,"title":"跟我走!","uname":"共青团中央","online":15974,"user_cover":"https://i0.hdslb.com/bfs/live/2591ba98c2db7da32dd40ac100322ab8d9a218c6.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/910884.jpg?03020946","show_cover":false,"link":"/910884","face":"https://i0.hdslb.com/bfs/face/3b4caf3ad325fd962bf98f90e4aac0b4ae4679c8.jpg","parent_id":1,"parent_name":"娱乐","area_id":123,"area_name":"户外","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/377121/live_20165629_5904889.flv?wsSecret=88113f81c6eb29be592c43d4cbaddc0c&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":30040,"uid":5480206,"title":"破产 弹到一半随时卖琴","uname":"桥白白白白","online":955,"user_cover":"https://i0.hdslb.com/bfs/live/f7ac32e981f4cd7b0bf6733ba79e705dd312e8f4.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/30040.jpg?03020946","show_cover":false,"link":"/5454","face":"https://i1.hdslb.com/bfs/face/67ba6957182bb865c8b4b5fd9006778af0cf9f71.jpg","parent_id":1,"parent_name":"娱乐","area_id":143,"area_name":"才艺","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/680310/live_5480206_332_c521e483.flv?wsSecret=0d2d608349a38973aaded375418ceca3&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":1338247,"uid":27894414,"title":"来呀来呀造人呀!造人人人人人人人!","uname":"露琪亚Rukiaルキア","online":78,"user_cover":"https://i0.hdslb.com/bfs/live/b5accf156795b0e24c406bb2debe3448032e13fd.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1338247.jpg?03020946","show_cover":false,"link":"/1338247","face":"https://i0.hdslb.com/bfs/face/b4dda315df2c9ffcc5f378b5871932e42122c567.jpg","parent_id":1,"parent_name":"娱乐","area_id":25,"area_name":"手工","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/558698/live_27894414_1428176.flv?wsSecret=1189d19dfda8cc47ae10d258ae9be26a&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":4346987,"uid":30580510,"title":"你来喵~一声,我也会喵~给你听哟~","uname":"是白米不是黑米","online":368,"user_cover":"https://i0.hdslb.com/bfs/live/4f10d04cfebc28bc48a7d9be2f9fb91d83c7226f.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/4346987.jpg?03020946","show_cover":false,"link":"/4346987","face":"https://i0.hdslb.com/bfs/face/f7e093a0613af8cf95ca684deb0fbfa7b2ab2ba3.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/723153/live_30580510_8427291.flv?wsSecret=cb1dd97e388bde304a3aedeab071ca87&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]},{"partition":{"id":2,"name":"游戏","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/2_3x.png?201709151052","height":"63","width":"63"},"count":1075},"lives":[{"roomid":34180,"uid":10404286,"title":"一枪一个嘤嘤宝","uname":"红发杰克丶","online":8502,"user_cover":"https://i0.hdslb.com/bfs/live/771bd280cc478e2816ff0d4dbd66c3e6709d6cc8.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/34180.jpg?03020946","show_cover":false,"link":"/260","face":"https://i2.hdslb.com/bfs/face/ea5235b1c9d9ce2604c37bcef2c0ef965d3b5589.jpg","parent_id":2,"parent_name":"游戏","area_id":80,"area_name":"绝地求生:大逃杀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/756124/live_10404286_9705271.flv?wsSecret=8dd39659dea6f9d0a0163330f50beda4&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":109950,"uid":28761888,"title":"莽夫の686天下无敌","uname":"女粉巨多的楠叔","online":6494,"user_cover":"https://i0.hdslb.com/bfs/live/017cc1afcb9ce8cfe253a8566070866db64762e7.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/109950.jpg?03020945","show_cover":false,"link":"/109950","face":"https://i1.hdslb.com/bfs/face/87b5dac33b652e9a15d5f4659ca2daf0e14cd29f.jpg","parent_id":2,"parent_name":"游戏","area_id":80,"area_name":"绝地求生:大逃杀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/406802/live_28761888_7951947.flv?wsSecret=2fb2a0316d5c07642a0b202e44a84fe2&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":34085,"uid":13376263,"title":"大家一起怂!!","uname":"国家一级loli饲养员","online":1805,"user_cover":"https://i0.hdslb.com/bfs/live/409d4b33bd89c63729b9a4721b7f7fa5063939ad.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/34085.jpg?03020946","show_cover":false,"link":"/34085","face":"https://i0.hdslb.com/bfs/face/a742e7a99884a070570f21e33854d10abbc3b8bb.jpg","parent_id":2,"parent_name":"游戏","area_id":107,"area_name":"其他游戏","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/331431/live_13376263_5317554.flv?wsSecret=d9337ad7717b7ea474443062759c1147&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":280446,"uid":8192168,"title":"大家元宵节快乐!记得吃汤圆!","uname":"叶落莫言","online":49474,"user_cover":"https://i0.hdslb.com/bfs/live/09356a3593cf0d67dee99aefe766ebac2a1d45f3.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/280446.jpg?03020945","show_cover":false,"link":"/387","face":"https://i1.hdslb.com/bfs/face/37bfd9a9f40eb9ff52b697e204386ab918ccd742.jpg","parent_id":2,"parent_name":"游戏","area_id":80,"area_name":"绝地求生:大逃杀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/563981/live_8192168_5923385.flv?wsSecret=d6f6edd11376d1601d5e14c31ede6f15&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":5600543,"uid":38353550,"title":"我的世界吸血鬼暮色星系生存~~~","uname":"丿灬丶落叶FL","online":994,"user_cover":"https://i0.hdslb.com/bfs/live/d782cb8221026b610d4759f214cc5d15d16251ef.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5600543.jpg?03020946","show_cover":false,"link":"/5600543","face":"https://i1.hdslb.com/bfs/face/cf290155d42fd8ca29818197bbda501b7b8656e0.jpg","parent_id":2,"parent_name":"游戏","area_id":56,"area_name":"我的世界","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/607990/live_38353550_9136170.flv?wsSecret=5f0bc0853e5c0cfcf9d36b6c3ed8fd1d&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":22237,"uid":1772434,"title":"饥荒联机智能敌对地狱模式。作死?嗯!","uname":"暮思橙月","online":19194,"user_cover":"https://i0.hdslb.com/bfs/live/0db51626ac6affae89e8e43345e5b8d6e6b95cfa.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/22237.jpg?03020946","show_cover":false,"link":"/531","face":"https://i1.hdslb.com/bfs/face/9e0333da3070d39de806c01106081098011b894e.jpg","parent_id":2,"parent_name":"游戏","area_id":107,"area_name":"其他游戏","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/672474/live_1772434_332_c521e483.flv?wsSecret=723497319c91e7a79c955de0132b431b&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]},{"partition":{"id":3,"name":"手游","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/3_3x.png?201709151052","height":"63","width":"63"},"count":473},"lives":[{"roomid":1218338,"uid":28046227,"title":"(乖巧)颜值主播不谈技术0-0","uname":"惆怅玉米头","online":1034,"user_cover":"https://i0.hdslb.com/bfs/live/41139d3b1a5e5e89aead6fb8d8b0e685633eb2c9.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1218338.jpg?03020945","show_cover":false,"link":"/1218338","face":"https://i2.hdslb.com/bfs/face/3da294e650d153612421142cf351266b3a0688c4.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://xl.live-play.acgvideo.com/live-xl/320746/live_28046227_3518126.flv?wsSecret=5a57987578c27250e24bfde48e30d34e&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":4036239,"uid":101242935,"title":"王者,,,,坑,了解一下吧","uname":"雨季youyou","online":7,"user_cover":"https://i0.hdslb.com/bfs/live/f22672b27a7164f4058002c8727f69148ec08557.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/4036239.jpg?03020946","show_cover":false,"link":"/4036239","face":"https://i2.hdslb.com/bfs/face/20bf5098724f50e357a38507f82b7c463165e9f0.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/176213/live_101242935_2718900.flv?wsSecret=68df597274c6afbb224252ff45f79c77&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":3269664,"uid":77545560,"title":"好厉害的花木兰","uname":"海岛情话","online":4295,"user_cover":"https://i0.hdslb.com/bfs/live/23342613fb41f1cf9523e79404ef3c69a641c904.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/3269664.jpg?03020945","show_cover":false,"link":"/3269664","face":"https://i0.hdslb.com/bfs/face/ad1cfde69fc3afd79b6a21ddd0e3a7cd9992932e.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/453762/live_77545560_5747022.flv?wsSecret=a4108497e7509dc13c2926de1087bd37&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":9610655,"uid":296520363,"title":"永生之夜的直播间","uname":"永生之夜","online":29,"user_cover":"https://i0.hdslb.com/bfs/live/c5567f3923a7662753bf136a65f6f788b8916cb9.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/9610655.jpg?03020946","show_cover":false,"link":"/9610655","face":"https://i0.hdslb.com/bfs/face/d1c6b761b0de659aa3add519bdab0e510551150a.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/378600/live_296520363_1459790.flv?wsSecret=0cabcb12cdaa6794cbdb326f82705eec&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":6636042,"uid":16689737,"title":"都老师在线 (黑色幸存者)","uname":"中文丶丶丶","online":1099,"user_cover":"https://i0.hdslb.com/bfs/live/b7bada8de2138de4183093f01d741ed7928a6c1b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/6636042.jpg?03020945","show_cover":false,"link":"/6636042","face":"https://i1.hdslb.com/bfs/face/b7945826ec45a40785e593fbbc73b4648eda6fd1.jpg","parent_id":3,"parent_name":"手游","area_id":98,"area_name":"其他手游","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/606287/live_16689737_5840082.flv?wsSecret=4135a775eee475ae1df1f6939de05008&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":3054160,"uid":75593922,"title":"神奇女侠专场,抢先体验?!","uname":"羽为CHENG","online":11654,"user_cover":"https://i0.hdslb.com/bfs/live/5925758a0364d365d75233c544ef492cd30bdbd5.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/3054160.jpg?03020945","show_cover":false,"link":"/3054160","face":"https://i0.hdslb.com/bfs/face/0bf0bba23c6ce03ff3bffde3e97be02d9f4044cd.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/469985/live_75593922_5603101.flv?wsSecret=e3fd90584e3d0714498973d932595a48&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]},{"partition":{"id":4,"name":"绘画","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/4_3x.png?201709151052","height":"63","width":"63"},"count":67},"lives":[{"roomid":73945,"uid":5050136,"title":"【爽到】やっばり。小学生赛高だぜ!!!!","uname":"Kirito丶桐人君","online":869,"user_cover":"https://i0.hdslb.com/bfs/live/375e1b19a907b9cfa85dbd41f6ab98f6ac5a602a.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/73945.jpg?03020946","show_cover":false,"link":"/73945","face":"https://i2.hdslb.com/bfs/face/56157d60c8c2c0b8f7e137262bbb2e577c95c7a0.png","parent_id":4,"parent_name":"绘画","area_id":95,"area_name":"临摹绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/267298/live_5050136_7329209.flv?wsSecret=a85ef18a73794de63ba80732bf2d0ccc&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":3593269,"uid":44966419,"title":"教你怎么用鼠绘阿松们(伪)","uname":"那就叫ichi吧","online":14,"user_cover":"https://i0.hdslb.com/bfs/live/df748933bb924b479bbf77eb69302a5161c0a3e0.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/3593269.jpg?03020946","show_cover":false,"link":"/3593269","face":"https://i0.hdslb.com/bfs/face/754d6a58a695a9bf5738f0a253504c6941dbda78.jpg","parent_id":4,"parent_name":"绘画","area_id":94,"area_name":"同人绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/791676/live_44966419_4351969.flv?wsSecret=000a552750fa9243d6e1f97f981de7e8&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":95278,"uid":5030761,"title":"SAI 启动!","uname":"深井玑","online":2520,"user_cover":"https://i0.hdslb.com/bfs/live/86f52149ab7ced43cad509348c831f346608b8bd.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/95278.jpg?03020946","show_cover":false,"link":"/314","face":"https://i1.hdslb.com/bfs/face/2feef28d962b0e5c8bbd573cffe84d5e13277747.jpg","parent_id":4,"parent_name":"绘画","area_id":94,"area_name":"同人绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/520270/live_5030761_7103241.flv?wsSecret=3da3ddd8bd44a98152f44a824482dbea&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":5790845,"uid":35331809,"title":"睡不着来画个简单的指绘","uname":"深海菠萝屋中的海绵","online":1201,"user_cover":"https://i0.hdslb.com/bfs/live/8e6400f2c40050e010baaa92c6386b33f56aca74.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5790845.jpg?03020945","show_cover":false,"link":"/5790845","face":"https://i0.hdslb.com/bfs/face/04ba147d39ff7db59cf62bc959d28a48094f69df.jpg","parent_id":4,"parent_name":"绘画","area_id":95,"area_name":"临摹绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/195067/live_35331809_3420166.flv?wsSecret=94689ada71b574432d59350f3a1455cc&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":19582,"uid":1533649,"title":"胃疼!因为没有女朋友!","uname":"绪奈夏目子丶","online":1576,"user_cover":"https://i0.hdslb.com/bfs/live/34b45ab63d81fec05e4b8549c3798e59051d7ed2.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/19582.jpg?03020946","show_cover":false,"link":"/19582","face":"https://i1.hdslb.com/bfs/face/00544b5a80fb73b3b5d8f6001268238aa7f078d9.jpg","parent_id":4,"parent_name":"绘画","area_id":51,"area_name":"原创绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/506577/live_1533649_8481907.flv?wsSecret=5475d2b7ab65bd8a55e62d488af828bd&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":67223,"uid":4836885,"title":"摸鱼","uname":"酎六六六_","online":1698,"user_cover":"https://i0.hdslb.com/bfs/live/4162a6d4cadf4088a1e1fd7029bd40579dca8854.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/67223.jpg?03020945","show_cover":false,"link":"/310","face":"https://i2.hdslb.com/bfs/face/7ee4fc0d4e261badfd23460ffad4b003cb06deb7.jpg","parent_id":4,"parent_name":"绘画","area_id":51,"area_name":"原创绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/664283/live_4836885_1208886.flv?wsSecret=c71f698544d69ea97432985d01aca6a9&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]}],"star_show":{"partition":{"id":999,"name":"颜值领域","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-2_3x.png?201709151052","height":"63","width":"63"},"count":0,"hidden":0},"lives":[{"roomid":5495804,"uid":203267722,"title":"你点,我唱","uname":"花优er","online":1298,"user_cover":"https://i0.hdslb.com/bfs/live/8881fca2f4d0d3b937767f5cacb4117966b9fea6.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5495804.jpg?03020946","show_cover":"https://i0.hdslb.com/bfs/vc/4c5126739114bb441cb3c12460a471733b1fe25a.jpg","link":"/5495804","face":"https://i0.hdslb.com/bfs/face/a44d19265a7c3240122dbe36d598d75a00acffd5.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/923710/live_203267722_7185906.flv?wsSecret=455db153c50c8adab57aa793f3c82ce8&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":151159,"uid":463999,"title":"元宵快乐~","uname":"波喵喵喵","online":662,"user_cover":"https://i0.hdslb.com/bfs/live/76e08ebaa07fd12c80374447f0ea0691a920bb4c.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/151159.jpg?03020947","show_cover":"https://i0.hdslb.com/bfs/vc/463336c59f976123a4358d819f161c0455a84308.jpg","link":"/280","face":"https://i0.hdslb.com/bfs/face/25ca9cca4fa9522c08b12b7de48a2509734fcd9d.jpg","parent_id":1,"parent_name":"娱乐","area_id":139,"area_name":"美少女","web_pendent":"weekRank","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/510065/live_463999_8651963.flv?wsSecret=10711c5b09edb0e3fba6094742ec842f&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"娱乐分区No.3"},{"roomid":68612,"uid":3311852,"title":"元宵节快乐","uname":"璃猫タヌキ","online":13101,"user_cover":"https://i0.hdslb.com/bfs/live/fe4233635a6c1f207011bf0756a65f65695d0f65.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/68612.jpg?03020946","show_cover":"https://i0.hdslb.com/bfs/vc/73b0c3e319c6a30a737b77e1214df427334640cc.jpg","link":"/185","face":"https://i0.hdslb.com/bfs/face/232325726db9b91c85061686fc265f138ea7b544.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/921032/live_3311852_7248026.flv?wsSecret=9a220f6242a03b6e80dcd1e975ad40d8&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":8259977,"uid":278452410,"title":"别的小朋友都回家了你什么时候带我回家啊","uname":"橙子斯密达","online":464,"user_cover":"https://i0.hdslb.com/bfs/live/177871a2418067b0443f81e5080563d1026f8c6b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/8259977.jpg?02111210","show_cover":"https://i0.hdslb.com/bfs/vc/9f6735c702b86286af0e32649310e1067aad943b.jpg","link":"/8259977","face":"https://i1.hdslb.com/bfs/face/12242421082cc3263ba3415e10f957d7ba751d9a.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/369622/live_278452410_6809315.flv?wsSecret=aba1d0fc8fec64a437e5289a6956d570&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""}]},"recommend_data":{"partition":{"id":0,"name":"推荐主播","area":"hot","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052","height":"63","width":"63"},"count":3528},"banner_data":[{"cover":{"src":"https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png","height":180,"width":320},"title":"今天,你的小视频上榜了吗?","is_clip":1,"new_cover":{"src":"https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg","height":180,"width":320},"new_title":"B站大触竟然都在这里???","new_router":"https://h.bilibili.com/ywh/h5/index"}],"lives":[{"owner":{"face":"https://i2.hdslb.com/bfs/face/4a31c283b90fcd6fe49b7a12662a14e607236c52.jpg","mid":2715177,"name":"祥宁嫂嫂丶"},"cover":{"src":"https://i0.hdslb.com/bfs/live/3815b7eb6f5f15b61c8c7b6991f1b805495e7059.jpg","height":180,"width":320},"room_id":52658,"check_version":0,"online":2351,"area":"电子竞技","area_id":4,"title":"(新人推荐)全区免费首胜啦~","playurl":"http://xl.live-play.acgvideo.com/live-xl/882210/live_2715177_5087642.flv?wsSecret=39d9fd9a3f4a28eae0d8e9ce734313a0&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":86,"area_v2_name":"英雄联盟","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/f4c2ceae1988050e35201abafafed134b98195c7.jpg","mid":166584070,"name":"独上熹楼ヽ城主"},"cover":{"src":"https://i0.hdslb.com/bfs/live/54777c587d71c5eff7074f7e16a609a746379224.jpg","height":180,"width":320},"room_id":5469025,"check_version":0,"online":3419,"area":"唱见舞见","area_id":10,"title":"攻音受音陪你賴床 腐女慎入","playurl":"http://qn.live-play.acgvideo.com/live-qn/289198/live_166584070_2864596.flv?wsSecret=011980f56104608d1d1563488dddced9&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐","data_behavior_id":"a0d146db7e2beaf:a0d146db7e2beaf:0:0","data_source_id":"system"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/c489cebbd9cb5902b950ca819ab1980d3fd49f5c.jpg","mid":1597982,"name":"Richard_Price"},"cover":{"src":"https://i0.hdslb.com/bfs/live/c46554cb778ac9941bf39e4771ff75c944f60e39.jpg","height":180,"width":320},"room_id":869069,"check_version":0,"online":814,"area":"唱见舞见","area_id":10,"title":"KTV, 元宵节快乐","playurl":"http://live-play.acgvideo.com/live/993/live_1597982_9114881.flv?wsSecret=626dadef4ec70594d55e5e67c48f1508&wsTime=5a712ed7","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/303f46216ceed76e2e5360a9de0c239ec9e32379.jpg","mid":719049,"name":"卖火柴的可可亚"},"cover":{"src":"https://i0.hdslb.com/bfs/live/2be48255ad5cd5b212ae2108d1e998568ee5efb1.jpg","height":180,"width":320},"room_id":53428,"check_version":0,"online":2712,"area":"单机联机","area_id":1,"title":"【影之诗】休闲游戏何必上分","playurl":"http://xl.live-play.acgvideo.com/live-xl/342779/live_719049_5853792.flv?wsSecret=39d2799d5266e44e3e4d0c19ee34f4ef&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ca7aaba009c22adcd1071522f9fdc6a4f669d532.jpg","mid":9870438,"name":"阿运呀"},"cover":{"src":"https://i0.hdslb.com/bfs/live/ff3d7a4d7cbe3cad02b14df15f56da239727f576.jpg","height":180,"width":320},"room_id":93279,"check_version":0,"online":3615,"area":"单机联机","area_id":1,"title":"【阿运】神秘海域4之一个萌新","playurl":"http://txy.live-play.acgvideo.com/live-txy/312360/live_9870438_5301909.flv?wsSecret=eeb9a68c89eb6171b4ab5b5bf3663a67&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/6ca5366bede574a88683201db31735466fb7665c.jpg","mid":4790535,"name":"祈咔"},"cover":{"src":"https://i0.hdslb.com/bfs/live/0149b64df95f1f31af4032871f3cc8942115ed13.jpg","height":180,"width":320},"room_id":100849,"check_version":0,"online":2661,"area":"唱见舞见","area_id":10,"title":"【古风】孤寡古疯老唱见","playurl":"http://dl.live-play.acgvideo.com/live-dl/905519/live_4790535_6783016.flv?wsSecret=189cdfc6e1af1682c236b43c8f3300a4&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/ceaffc80b824f1d277034622fba809ff3a50db89.jpg","mid":4008909,"name":"KIM高能萌"},"cover":{"src":"https://i0.hdslb.com/bfs/live/1cf09a1a579e608a1284b637a2f784c3558b91c6.jpg","height":180,"width":320},"room_id":7365762,"check_version":0,"online":2168,"area":"单机联机","area_id":1,"title":"少男的绝地描边画来了解一下^^","playurl":"http://qn.live-play.acgvideo.com/live-qn/108838/live_4008909_3934891.flv?wsSecret=7c3c5503e406cdfcd65caf25ed0e8be3&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/56e342a20940346d7026af2ff72a9bb89001a197.jpg","mid":13610473,"name":"北极星丶清寒"},"cover":{"src":"https://i0.hdslb.com/bfs/live/d7f524a13e318769e77190ce7ee4002daf7206e0.jpg","height":180,"width":320},"room_id":402805,"check_version":0,"online":4227,"area":"单机联机","area_id":1,"title":"寒宾逊的1.12.2荒岛求生","playurl":"http://qn.live-play.acgvideo.com/live-qn/945345/live_13610473_8275609.flv?wsSecret=f5f547db01501929cdd424866b8a772f&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":56,"area_v2_name":"我的世界","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/9eb27d14a4b29e1aa32f645a5273a00796162c41.jpg","mid":19088449,"name":"猜十八"},"cover":{"src":"https://i0.hdslb.com/bfs/live/383c84bb6d3412ce8843209990b1aa4c2e4ea101.jpg","height":180,"width":320},"room_id":54912,"check_version":0,"online":4090,"area":"手游直播","area_id":12,"title":"手机吃鸡 人机大作战?","playurl":"http://qn.live-play.acgvideo.com/live-qn/488202/live_19088449_4499867.flv?wsSecret=349df85ace4fe1837a02d78e00e36678&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":98,"area_v2_name":"其他手游","area_v2_parent_id":3,"area_v2_parent_name":"手游"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/25ca9cca4fa9522c08b12b7de48a2509734fcd9d.jpg","mid":463999,"name":"波喵喵喵"},"cover":{"src":"https://i0.hdslb.com/bfs/live/76e08ebaa07fd12c80374447f0ea0691a920bb4c.jpg","height":180,"width":320},"room_id":151159,"check_version":0,"online":662,"area":"生活娱乐","area_id":6,"title":"元宵快乐~","playurl":"http://dl.live-play.acgvideo.com/live-dl/299784/live_463999_8651963.flv?wsSecret=21f8ca49261774740366a83ed591ab54&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"娱乐分区No.3","area_v2_id":139,"area_v2_name":"美少女","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/29ff8cea978d08989193f13146006a5b14e22784.jpg","mid":9165690,"name":"桐人ヽ"},"cover":{"src":"https://i0.hdslb.com/bfs/live/e8e88ba6d479acc6c39896ac2104d4d868a964f2.jpg","height":180,"width":320},"room_id":53100,"check_version":0,"online":3222,"area":"网络游戏","area_id":3,"title":"上午嘤嘤嘤下午夺命晚上吃鸡!","playurl":"http://qn.live-play.acgvideo.com/live-qn/359080/live_9165690_1198449.flv?wsSecret=8cfeafdf3b2cb6dd4cfc1b1308bc9644&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":84,"area_v2_name":"300英雄","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ce10c759df53720268b23ef8bd06150aa61834a5.jpg","mid":659965,"name":"基佬爱上熊"},"cover":{"src":"https://i0.hdslb.com/bfs/live/65b8641c7681faca6317314bc907edac984390f1.jpg","height":180,"width":320},"room_id":16101,"check_version":0,"online":4206,"area":"单机联机","area_id":1,"title":"【流放之路】一款继承暗黑2的游戏","playurl":"http://xl.live-play.acgvideo.com/live-xl/791352/live_659965_4719464.flv?wsSecret=38ef4f3b8dbd455b728d3c4d50bb0043&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"}]}} + */ + + @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 { + /** + * banner : [{"title":"直播周刊","img":"https://i0.hdslb.com/bfs/live/af17c8d882104370075f4fa5418343861ac3e540.png","remark":"直播周刊","link":"https://live.bilibili.com/AppBanner/index?id=746"}] + * entranceIcons : [{"id":9,"name":"绘画专区","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/9_big.png?20171116172700","height":"132","width":"132"}},{"id":8,"name":"萌宅推荐","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/8_big.png?20171116172700","height":"132","width":"132"}},{"id":3,"name":"网络游戏","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/3_big.png?20171116172700","height":"132","width":"132"}},{"id":1,"name":"单机联机","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/1_big.png?20171116172700","height":"132","width":"132"}},{"id":4,"name":"电子竞技","entrance_icon":{"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/4_big.png?20171116172700","height":"132","width":"132"}}] + * partitions : [{"partition":{"id":1,"name":"娱乐","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/1_3x.png?201709151052","height":"63","width":"63"},"count":1484},"lives":[{"roomid":7399897,"uid":7619276,"title":"包裹有免费B坷垃可送哦(点这看直播单)","uname":"星子弈风","online":145,"user_cover":"https://i0.hdslb.com/bfs/live/7fc54c49ed7db4bc53fe6e5c8888db3eb0c01d7c.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/7399897.jpg?03020945","show_cover":false,"link":"/7399897","face":"https://i2.hdslb.com/bfs/face/41c4b60b54795870ac4d209dc949a51ca7614062.jpg","parent_id":1,"parent_name":"娱乐","area_id":123,"area_name":"户外","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/415156/live_7619276_6963984.flv?wsSecret=26f02e69c2e01fc840da1f452d673f37&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":2802503,"uid":34993653,"title":"做个温柔读书哄睡的小姐姐","uname":"楚小芭","online":958,"user_cover":"https://i0.hdslb.com/bfs/live/33e9537f94545758035b14a59a68fd1b78f8184b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/2802503.jpg?03020945","show_cover":false,"link":"/2802503","face":"https://i0.hdslb.com/bfs/face/41a917cb13f546e62bfea4e06a7781d8118c676e.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/368878/live_34993653_4247645.flv?wsSecret=01587e645b73cfeec12992ac3f3b8288&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":910884,"uid":20165629,"title":"跟我走!","uname":"共青团中央","online":15974,"user_cover":"https://i0.hdslb.com/bfs/live/2591ba98c2db7da32dd40ac100322ab8d9a218c6.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/910884.jpg?03020946","show_cover":false,"link":"/910884","face":"https://i0.hdslb.com/bfs/face/3b4caf3ad325fd962bf98f90e4aac0b4ae4679c8.jpg","parent_id":1,"parent_name":"娱乐","area_id":123,"area_name":"户外","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/377121/live_20165629_5904889.flv?wsSecret=88113f81c6eb29be592c43d4cbaddc0c&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":30040,"uid":5480206,"title":"破产 弹到一半随时卖琴","uname":"桥白白白白","online":955,"user_cover":"https://i0.hdslb.com/bfs/live/f7ac32e981f4cd7b0bf6733ba79e705dd312e8f4.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/30040.jpg?03020946","show_cover":false,"link":"/5454","face":"https://i1.hdslb.com/bfs/face/67ba6957182bb865c8b4b5fd9006778af0cf9f71.jpg","parent_id":1,"parent_name":"娱乐","area_id":143,"area_name":"才艺","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/680310/live_5480206_332_c521e483.flv?wsSecret=0d2d608349a38973aaded375418ceca3&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":1338247,"uid":27894414,"title":"来呀来呀造人呀!造人人人人人人人!","uname":"露琪亚Rukiaルキア","online":78,"user_cover":"https://i0.hdslb.com/bfs/live/b5accf156795b0e24c406bb2debe3448032e13fd.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1338247.jpg?03020946","show_cover":false,"link":"/1338247","face":"https://i0.hdslb.com/bfs/face/b4dda315df2c9ffcc5f378b5871932e42122c567.jpg","parent_id":1,"parent_name":"娱乐","area_id":25,"area_name":"手工","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/558698/live_27894414_1428176.flv?wsSecret=1189d19dfda8cc47ae10d258ae9be26a&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":4346987,"uid":30580510,"title":"你来喵~一声,我也会喵~给你听哟~","uname":"是白米不是黑米","online":368,"user_cover":"https://i0.hdslb.com/bfs/live/4f10d04cfebc28bc48a7d9be2f9fb91d83c7226f.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/4346987.jpg?03020946","show_cover":false,"link":"/4346987","face":"https://i0.hdslb.com/bfs/face/f7e093a0613af8cf95ca684deb0fbfa7b2ab2ba3.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/723153/live_30580510_8427291.flv?wsSecret=cb1dd97e388bde304a3aedeab071ca87&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]},{"partition":{"id":2,"name":"游戏","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/2_3x.png?201709151052","height":"63","width":"63"},"count":1075},"lives":[{"roomid":34180,"uid":10404286,"title":"一枪一个嘤嘤宝","uname":"红发杰克丶","online":8502,"user_cover":"https://i0.hdslb.com/bfs/live/771bd280cc478e2816ff0d4dbd66c3e6709d6cc8.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/34180.jpg?03020946","show_cover":false,"link":"/260","face":"https://i2.hdslb.com/bfs/face/ea5235b1c9d9ce2604c37bcef2c0ef965d3b5589.jpg","parent_id":2,"parent_name":"游戏","area_id":80,"area_name":"绝地求生:大逃杀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/756124/live_10404286_9705271.flv?wsSecret=8dd39659dea6f9d0a0163330f50beda4&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":109950,"uid":28761888,"title":"莽夫の686天下无敌","uname":"女粉巨多的楠叔","online":6494,"user_cover":"https://i0.hdslb.com/bfs/live/017cc1afcb9ce8cfe253a8566070866db64762e7.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/109950.jpg?03020945","show_cover":false,"link":"/109950","face":"https://i1.hdslb.com/bfs/face/87b5dac33b652e9a15d5f4659ca2daf0e14cd29f.jpg","parent_id":2,"parent_name":"游戏","area_id":80,"area_name":"绝地求生:大逃杀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/406802/live_28761888_7951947.flv?wsSecret=2fb2a0316d5c07642a0b202e44a84fe2&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":34085,"uid":13376263,"title":"大家一起怂!!","uname":"国家一级loli饲养员","online":1805,"user_cover":"https://i0.hdslb.com/bfs/live/409d4b33bd89c63729b9a4721b7f7fa5063939ad.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/34085.jpg?03020946","show_cover":false,"link":"/34085","face":"https://i0.hdslb.com/bfs/face/a742e7a99884a070570f21e33854d10abbc3b8bb.jpg","parent_id":2,"parent_name":"游戏","area_id":107,"area_name":"其他游戏","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/331431/live_13376263_5317554.flv?wsSecret=d9337ad7717b7ea474443062759c1147&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":280446,"uid":8192168,"title":"大家元宵节快乐!记得吃汤圆!","uname":"叶落莫言","online":49474,"user_cover":"https://i0.hdslb.com/bfs/live/09356a3593cf0d67dee99aefe766ebac2a1d45f3.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/280446.jpg?03020945","show_cover":false,"link":"/387","face":"https://i1.hdslb.com/bfs/face/37bfd9a9f40eb9ff52b697e204386ab918ccd742.jpg","parent_id":2,"parent_name":"游戏","area_id":80,"area_name":"绝地求生:大逃杀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/563981/live_8192168_5923385.flv?wsSecret=d6f6edd11376d1601d5e14c31ede6f15&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":5600543,"uid":38353550,"title":"我的世界吸血鬼暮色星系生存~~~","uname":"丿灬丶落叶FL","online":994,"user_cover":"https://i0.hdslb.com/bfs/live/d782cb8221026b610d4759f214cc5d15d16251ef.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5600543.jpg?03020946","show_cover":false,"link":"/5600543","face":"https://i1.hdslb.com/bfs/face/cf290155d42fd8ca29818197bbda501b7b8656e0.jpg","parent_id":2,"parent_name":"游戏","area_id":56,"area_name":"我的世界","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/607990/live_38353550_9136170.flv?wsSecret=5f0bc0853e5c0cfcf9d36b6c3ed8fd1d&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":22237,"uid":1772434,"title":"饥荒联机智能敌对地狱模式。作死?嗯!","uname":"暮思橙月","online":19194,"user_cover":"https://i0.hdslb.com/bfs/live/0db51626ac6affae89e8e43345e5b8d6e6b95cfa.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/22237.jpg?03020946","show_cover":false,"link":"/531","face":"https://i1.hdslb.com/bfs/face/9e0333da3070d39de806c01106081098011b894e.jpg","parent_id":2,"parent_name":"游戏","area_id":107,"area_name":"其他游戏","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/672474/live_1772434_332_c521e483.flv?wsSecret=723497319c91e7a79c955de0132b431b&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]},{"partition":{"id":3,"name":"手游","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/3_3x.png?201709151052","height":"63","width":"63"},"count":473},"lives":[{"roomid":1218338,"uid":28046227,"title":"(乖巧)颜值主播不谈技术0-0","uname":"惆怅玉米头","online":1034,"user_cover":"https://i0.hdslb.com/bfs/live/41139d3b1a5e5e89aead6fb8d8b0e685633eb2c9.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1218338.jpg?03020945","show_cover":false,"link":"/1218338","face":"https://i2.hdslb.com/bfs/face/3da294e650d153612421142cf351266b3a0688c4.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://xl.live-play.acgvideo.com/live-xl/320746/live_28046227_3518126.flv?wsSecret=5a57987578c27250e24bfde48e30d34e&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":4036239,"uid":101242935,"title":"王者,,,,坑,了解一下吧","uname":"雨季youyou","online":7,"user_cover":"https://i0.hdslb.com/bfs/live/f22672b27a7164f4058002c8727f69148ec08557.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/4036239.jpg?03020946","show_cover":false,"link":"/4036239","face":"https://i2.hdslb.com/bfs/face/20bf5098724f50e357a38507f82b7c463165e9f0.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/176213/live_101242935_2718900.flv?wsSecret=68df597274c6afbb224252ff45f79c77&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":3269664,"uid":77545560,"title":"好厉害的花木兰","uname":"海岛情话","online":4295,"user_cover":"https://i0.hdslb.com/bfs/live/23342613fb41f1cf9523e79404ef3c69a641c904.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/3269664.jpg?03020945","show_cover":false,"link":"/3269664","face":"https://i0.hdslb.com/bfs/face/ad1cfde69fc3afd79b6a21ddd0e3a7cd9992932e.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/453762/live_77545560_5747022.flv?wsSecret=a4108497e7509dc13c2926de1087bd37&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":9610655,"uid":296520363,"title":"永生之夜的直播间","uname":"永生之夜","online":29,"user_cover":"https://i0.hdslb.com/bfs/live/c5567f3923a7662753bf136a65f6f788b8916cb9.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/9610655.jpg?03020946","show_cover":false,"link":"/9610655","face":"https://i0.hdslb.com/bfs/face/d1c6b761b0de659aa3add519bdab0e510551150a.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/378600/live_296520363_1459790.flv?wsSecret=0cabcb12cdaa6794cbdb326f82705eec&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":6636042,"uid":16689737,"title":"都老师在线 (黑色幸存者)","uname":"中文丶丶丶","online":1099,"user_cover":"https://i0.hdslb.com/bfs/live/b7bada8de2138de4183093f01d741ed7928a6c1b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/6636042.jpg?03020945","show_cover":false,"link":"/6636042","face":"https://i1.hdslb.com/bfs/face/b7945826ec45a40785e593fbbc73b4648eda6fd1.jpg","parent_id":3,"parent_name":"手游","area_id":98,"area_name":"其他手游","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/606287/live_16689737_5840082.flv?wsSecret=4135a775eee475ae1df1f6939de05008&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":3054160,"uid":75593922,"title":"神奇女侠专场,抢先体验?!","uname":"羽为CHENG","online":11654,"user_cover":"https://i0.hdslb.com/bfs/live/5925758a0364d365d75233c544ef492cd30bdbd5.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/3054160.jpg?03020945","show_cover":false,"link":"/3054160","face":"https://i0.hdslb.com/bfs/face/0bf0bba23c6ce03ff3bffde3e97be02d9f4044cd.jpg","parent_id":3,"parent_name":"手游","area_id":35,"area_name":"王者荣耀","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/469985/live_75593922_5603101.flv?wsSecret=e3fd90584e3d0714498973d932595a48&wsTime=1519957196","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]},{"partition":{"id":4,"name":"绘画","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/4_3x.png?201709151052","height":"63","width":"63"},"count":67},"lives":[{"roomid":73945,"uid":5050136,"title":"【爽到】やっばり。小学生赛高だぜ!!!!","uname":"Kirito丶桐人君","online":869,"user_cover":"https://i0.hdslb.com/bfs/live/375e1b19a907b9cfa85dbd41f6ab98f6ac5a602a.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/73945.jpg?03020946","show_cover":false,"link":"/73945","face":"https://i2.hdslb.com/bfs/face/56157d60c8c2c0b8f7e137262bbb2e577c95c7a0.png","parent_id":4,"parent_name":"绘画","area_id":95,"area_name":"临摹绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/267298/live_5050136_7329209.flv?wsSecret=a85ef18a73794de63ba80732bf2d0ccc&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":3593269,"uid":44966419,"title":"教你怎么用鼠绘阿松们(伪)","uname":"那就叫ichi吧","online":14,"user_cover":"https://i0.hdslb.com/bfs/live/df748933bb924b479bbf77eb69302a5161c0a3e0.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/3593269.jpg?03020946","show_cover":false,"link":"/3593269","face":"https://i0.hdslb.com/bfs/face/754d6a58a695a9bf5738f0a253504c6941dbda78.jpg","parent_id":4,"parent_name":"绘画","area_id":94,"area_name":"同人绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/791676/live_44966419_4351969.flv?wsSecret=000a552750fa9243d6e1f97f981de7e8&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":95278,"uid":5030761,"title":"SAI 启动!","uname":"深井玑","online":2520,"user_cover":"https://i0.hdslb.com/bfs/live/86f52149ab7ced43cad509348c831f346608b8bd.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/95278.jpg?03020946","show_cover":false,"link":"/314","face":"https://i1.hdslb.com/bfs/face/2feef28d962b0e5c8bbd573cffe84d5e13277747.jpg","parent_id":4,"parent_name":"绘画","area_id":94,"area_name":"同人绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/520270/live_5030761_7103241.flv?wsSecret=3da3ddd8bd44a98152f44a824482dbea&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":5790845,"uid":35331809,"title":"睡不着来画个简单的指绘","uname":"深海菠萝屋中的海绵","online":1201,"user_cover":"https://i0.hdslb.com/bfs/live/8e6400f2c40050e010baaa92c6386b33f56aca74.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5790845.jpg?03020945","show_cover":false,"link":"/5790845","face":"https://i0.hdslb.com/bfs/face/04ba147d39ff7db59cf62bc959d28a48094f69df.jpg","parent_id":4,"parent_name":"绘画","area_id":95,"area_name":"临摹绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/195067/live_35331809_3420166.flv?wsSecret=94689ada71b574432d59350f3a1455cc&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":19582,"uid":1533649,"title":"胃疼!因为没有女朋友!","uname":"绪奈夏目子丶","online":1576,"user_cover":"https://i0.hdslb.com/bfs/live/34b45ab63d81fec05e4b8549c3798e59051d7ed2.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/19582.jpg?03020946","show_cover":false,"link":"/19582","face":"https://i1.hdslb.com/bfs/face/00544b5a80fb73b3b5d8f6001268238aa7f078d9.jpg","parent_id":4,"parent_name":"绘画","area_id":51,"area_name":"原创绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/506577/live_1533649_8481907.flv?wsSecret=5475d2b7ab65bd8a55e62d488af828bd&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":67223,"uid":4836885,"title":"摸鱼","uname":"酎六六六_","online":1698,"user_cover":"https://i0.hdslb.com/bfs/live/4162a6d4cadf4088a1e1fd7029bd40579dca8854.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/67223.jpg?03020945","show_cover":false,"link":"/310","face":"https://i2.hdslb.com/bfs/face/7ee4fc0d4e261badfd23460ffad4b003cb06deb7.jpg","parent_id":4,"parent_name":"绘画","area_id":51,"area_name":"原创绘画","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/664283/live_4836885_1208886.flv?wsSecret=c71f698544d69ea97432985d01aca6a9&wsTime=1519957192","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}]}] + * star_show : {"partition":{"id":999,"name":"颜值领域","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-2_3x.png?201709151052","height":"63","width":"63"},"count":0,"hidden":0},"lives":[{"roomid":5495804,"uid":203267722,"title":"你点,我唱","uname":"花优er","online":1298,"user_cover":"https://i0.hdslb.com/bfs/live/8881fca2f4d0d3b937767f5cacb4117966b9fea6.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5495804.jpg?03020946","show_cover":"https://i0.hdslb.com/bfs/vc/4c5126739114bb441cb3c12460a471733b1fe25a.jpg","link":"/5495804","face":"https://i0.hdslb.com/bfs/face/a44d19265a7c3240122dbe36d598d75a00acffd5.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/923710/live_203267722_7185906.flv?wsSecret=455db153c50c8adab57aa793f3c82ce8&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":151159,"uid":463999,"title":"元宵快乐~","uname":"波喵喵喵","online":662,"user_cover":"https://i0.hdslb.com/bfs/live/76e08ebaa07fd12c80374447f0ea0691a920bb4c.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/151159.jpg?03020947","show_cover":"https://i0.hdslb.com/bfs/vc/463336c59f976123a4358d819f161c0455a84308.jpg","link":"/280","face":"https://i0.hdslb.com/bfs/face/25ca9cca4fa9522c08b12b7de48a2509734fcd9d.jpg","parent_id":1,"parent_name":"娱乐","area_id":139,"area_name":"美少女","web_pendent":"weekRank","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/510065/live_463999_8651963.flv?wsSecret=10711c5b09edb0e3fba6094742ec842f&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"娱乐分区No.3"},{"roomid":68612,"uid":3311852,"title":"元宵节快乐","uname":"璃猫タヌキ","online":13101,"user_cover":"https://i0.hdslb.com/bfs/live/fe4233635a6c1f207011bf0756a65f65695d0f65.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/68612.jpg?03020946","show_cover":"https://i0.hdslb.com/bfs/vc/73b0c3e319c6a30a737b77e1214df427334640cc.jpg","link":"/185","face":"https://i0.hdslb.com/bfs/face/232325726db9b91c85061686fc265f138ea7b544.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/921032/live_3311852_7248026.flv?wsSecret=9a220f6242a03b6e80dcd1e975ad40d8&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":8259977,"uid":278452410,"title":"别的小朋友都回家了你什么时候带我回家啊","uname":"橙子斯密达","online":464,"user_cover":"https://i0.hdslb.com/bfs/live/177871a2418067b0443f81e5080563d1026f8c6b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/8259977.jpg?02111210","show_cover":"https://i0.hdslb.com/bfs/vc/9f6735c702b86286af0e32649310e1067aad943b.jpg","link":"/8259977","face":"https://i1.hdslb.com/bfs/face/12242421082cc3263ba3415e10f957d7ba751d9a.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/369622/live_278452410_6809315.flv?wsSecret=aba1d0fc8fec64a437e5289a6956d570&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""}]} + * recommend_data : {"partition":{"id":0,"name":"推荐主播","area":"hot","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052","height":"63","width":"63"},"count":3528},"banner_data":[{"cover":{"src":"https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png","height":180,"width":320},"title":"今天,你的小视频上榜了吗?","is_clip":1,"new_cover":{"src":"https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg","height":180,"width":320},"new_title":"B站大触竟然都在这里???","new_router":"https://h.bilibili.com/ywh/h5/index"}],"lives":[{"owner":{"face":"https://i2.hdslb.com/bfs/face/4a31c283b90fcd6fe49b7a12662a14e607236c52.jpg","mid":2715177,"name":"祥宁嫂嫂丶"},"cover":{"src":"https://i0.hdslb.com/bfs/live/3815b7eb6f5f15b61c8c7b6991f1b805495e7059.jpg","height":180,"width":320},"room_id":52658,"check_version":0,"online":2351,"area":"电子竞技","area_id":4,"title":"(新人推荐)全区免费首胜啦~","playurl":"http://xl.live-play.acgvideo.com/live-xl/882210/live_2715177_5087642.flv?wsSecret=39d9fd9a3f4a28eae0d8e9ce734313a0&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":86,"area_v2_name":"英雄联盟","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/f4c2ceae1988050e35201abafafed134b98195c7.jpg","mid":166584070,"name":"独上熹楼ヽ城主"},"cover":{"src":"https://i0.hdslb.com/bfs/live/54777c587d71c5eff7074f7e16a609a746379224.jpg","height":180,"width":320},"room_id":5469025,"check_version":0,"online":3419,"area":"唱见舞见","area_id":10,"title":"攻音受音陪你賴床 腐女慎入","playurl":"http://qn.live-play.acgvideo.com/live-qn/289198/live_166584070_2864596.flv?wsSecret=011980f56104608d1d1563488dddced9&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐","data_behavior_id":"a0d146db7e2beaf:a0d146db7e2beaf:0:0","data_source_id":"system"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/c489cebbd9cb5902b950ca819ab1980d3fd49f5c.jpg","mid":1597982,"name":"Richard_Price"},"cover":{"src":"https://i0.hdslb.com/bfs/live/c46554cb778ac9941bf39e4771ff75c944f60e39.jpg","height":180,"width":320},"room_id":869069,"check_version":0,"online":814,"area":"唱见舞见","area_id":10,"title":"KTV, 元宵节快乐","playurl":"http://live-play.acgvideo.com/live/993/live_1597982_9114881.flv?wsSecret=626dadef4ec70594d55e5e67c48f1508&wsTime=5a712ed7","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/303f46216ceed76e2e5360a9de0c239ec9e32379.jpg","mid":719049,"name":"卖火柴的可可亚"},"cover":{"src":"https://i0.hdslb.com/bfs/live/2be48255ad5cd5b212ae2108d1e998568ee5efb1.jpg","height":180,"width":320},"room_id":53428,"check_version":0,"online":2712,"area":"单机联机","area_id":1,"title":"【影之诗】休闲游戏何必上分","playurl":"http://xl.live-play.acgvideo.com/live-xl/342779/live_719049_5853792.flv?wsSecret=39d2799d5266e44e3e4d0c19ee34f4ef&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ca7aaba009c22adcd1071522f9fdc6a4f669d532.jpg","mid":9870438,"name":"阿运呀"},"cover":{"src":"https://i0.hdslb.com/bfs/live/ff3d7a4d7cbe3cad02b14df15f56da239727f576.jpg","height":180,"width":320},"room_id":93279,"check_version":0,"online":3615,"area":"单机联机","area_id":1,"title":"【阿运】神秘海域4之一个萌新","playurl":"http://txy.live-play.acgvideo.com/live-txy/312360/live_9870438_5301909.flv?wsSecret=eeb9a68c89eb6171b4ab5b5bf3663a67&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/6ca5366bede574a88683201db31735466fb7665c.jpg","mid":4790535,"name":"祈咔"},"cover":{"src":"https://i0.hdslb.com/bfs/live/0149b64df95f1f31af4032871f3cc8942115ed13.jpg","height":180,"width":320},"room_id":100849,"check_version":0,"online":2661,"area":"唱见舞见","area_id":10,"title":"【古风】孤寡古疯老唱见","playurl":"http://dl.live-play.acgvideo.com/live-dl/905519/live_4790535_6783016.flv?wsSecret=189cdfc6e1af1682c236b43c8f3300a4&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/ceaffc80b824f1d277034622fba809ff3a50db89.jpg","mid":4008909,"name":"KIM高能萌"},"cover":{"src":"https://i0.hdslb.com/bfs/live/1cf09a1a579e608a1284b637a2f784c3558b91c6.jpg","height":180,"width":320},"room_id":7365762,"check_version":0,"online":2168,"area":"单机联机","area_id":1,"title":"少男的绝地描边画来了解一下^^","playurl":"http://qn.live-play.acgvideo.com/live-qn/108838/live_4008909_3934891.flv?wsSecret=7c3c5503e406cdfcd65caf25ed0e8be3&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/56e342a20940346d7026af2ff72a9bb89001a197.jpg","mid":13610473,"name":"北极星丶清寒"},"cover":{"src":"https://i0.hdslb.com/bfs/live/d7f524a13e318769e77190ce7ee4002daf7206e0.jpg","height":180,"width":320},"room_id":402805,"check_version":0,"online":4227,"area":"单机联机","area_id":1,"title":"寒宾逊的1.12.2荒岛求生","playurl":"http://qn.live-play.acgvideo.com/live-qn/945345/live_13610473_8275609.flv?wsSecret=f5f547db01501929cdd424866b8a772f&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":56,"area_v2_name":"我的世界","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/9eb27d14a4b29e1aa32f645a5273a00796162c41.jpg","mid":19088449,"name":"猜十八"},"cover":{"src":"https://i0.hdslb.com/bfs/live/383c84bb6d3412ce8843209990b1aa4c2e4ea101.jpg","height":180,"width":320},"room_id":54912,"check_version":0,"online":4090,"area":"手游直播","area_id":12,"title":"手机吃鸡 人机大作战?","playurl":"http://qn.live-play.acgvideo.com/live-qn/488202/live_19088449_4499867.flv?wsSecret=349df85ace4fe1837a02d78e00e36678&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":98,"area_v2_name":"其他手游","area_v2_parent_id":3,"area_v2_parent_name":"手游"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/25ca9cca4fa9522c08b12b7de48a2509734fcd9d.jpg","mid":463999,"name":"波喵喵喵"},"cover":{"src":"https://i0.hdslb.com/bfs/live/76e08ebaa07fd12c80374447f0ea0691a920bb4c.jpg","height":180,"width":320},"room_id":151159,"check_version":0,"online":662,"area":"生活娱乐","area_id":6,"title":"元宵快乐~","playurl":"http://dl.live-play.acgvideo.com/live-dl/299784/live_463999_8651963.flv?wsSecret=21f8ca49261774740366a83ed591ab54&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"娱乐分区No.3","area_v2_id":139,"area_v2_name":"美少女","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/29ff8cea978d08989193f13146006a5b14e22784.jpg","mid":9165690,"name":"桐人ヽ"},"cover":{"src":"https://i0.hdslb.com/bfs/live/e8e88ba6d479acc6c39896ac2104d4d868a964f2.jpg","height":180,"width":320},"room_id":53100,"check_version":0,"online":3222,"area":"网络游戏","area_id":3,"title":"上午嘤嘤嘤下午夺命晚上吃鸡!","playurl":"http://qn.live-play.acgvideo.com/live-qn/359080/live_9165690_1198449.flv?wsSecret=8cfeafdf3b2cb6dd4cfc1b1308bc9644&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":84,"area_v2_name":"300英雄","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ce10c759df53720268b23ef8bd06150aa61834a5.jpg","mid":659965,"name":"基佬爱上熊"},"cover":{"src":"https://i0.hdslb.com/bfs/live/65b8641c7681faca6317314bc907edac984390f1.jpg","height":180,"width":320},"room_id":16101,"check_version":0,"online":4206,"area":"单机联机","area_id":1,"title":"【流放之路】一款继承暗黑2的游戏","playurl":"http://xl.live-play.acgvideo.com/live-xl/791352/live_659965_4719464.flv?wsSecret=38ef4f3b8dbd455b728d3c4d50bb0043&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"}]} + */ + + @SerializedName("star_show") + private StarShow starShow; + @SerializedName("recommend_data") + private RecommendData recommendData; + @SerializedName("banner") + private List banner; + @SerializedName("entranceIcons") + private List entranceIcons; + @SerializedName("partitions") + private List partitions; + + public StarShow getStarShow() { + return starShow; + } + + public void setStarShow(StarShow starShow) { + this.starShow = starShow; + } + + public RecommendData getRecommendData() { + return recommendData; + } + + public void setRecommendData(RecommendData recommendData) { + this.recommendData = recommendData; + } + + public List getBanner() { + return banner; + } + + public void setBanner(List banner) { + this.banner = banner; + } + + public List getEntranceIcons() { + return entranceIcons; + } + + public void setEntranceIcons(List entranceIcons) { + this.entranceIcons = entranceIcons; + } + + public List getPartitions() { + return partitions; + } + + public void setPartitions(List partitions) { + this.partitions = partitions; + } + + public static class StarShow { + /** + * partition : {"id":999,"name":"颜值领域","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-2_3x.png?201709151052","height":"63","width":"63"},"count":0,"hidden":0} + * lives : [{"roomid":5495804,"uid":203267722,"title":"你点,我唱","uname":"花优er","online":1298,"user_cover":"https://i0.hdslb.com/bfs/live/8881fca2f4d0d3b937767f5cacb4117966b9fea6.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5495804.jpg?03020946","show_cover":"https://i0.hdslb.com/bfs/vc/4c5126739114bb441cb3c12460a471733b1fe25a.jpg","link":"/5495804","face":"https://i0.hdslb.com/bfs/face/a44d19265a7c3240122dbe36d598d75a00acffd5.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/923710/live_203267722_7185906.flv?wsSecret=455db153c50c8adab57aa793f3c82ce8&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":151159,"uid":463999,"title":"元宵快乐~","uname":"波喵喵喵","online":662,"user_cover":"https://i0.hdslb.com/bfs/live/76e08ebaa07fd12c80374447f0ea0691a920bb4c.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/151159.jpg?03020947","show_cover":"https://i0.hdslb.com/bfs/vc/463336c59f976123a4358d819f161c0455a84308.jpg","link":"/280","face":"https://i0.hdslb.com/bfs/face/25ca9cca4fa9522c08b12b7de48a2509734fcd9d.jpg","parent_id":1,"parent_name":"娱乐","area_id":139,"area_name":"美少女","web_pendent":"weekRank","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/510065/live_463999_8651963.flv?wsSecret=10711c5b09edb0e3fba6094742ec842f&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"娱乐分区No.3"},{"roomid":68612,"uid":3311852,"title":"元宵节快乐","uname":"璃猫タヌキ","online":13101,"user_cover":"https://i0.hdslb.com/bfs/live/fe4233635a6c1f207011bf0756a65f65695d0f65.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/68612.jpg?03020946","show_cover":"https://i0.hdslb.com/bfs/vc/73b0c3e319c6a30a737b77e1214df427334640cc.jpg","link":"/185","face":"https://i0.hdslb.com/bfs/face/232325726db9b91c85061686fc265f138ea7b544.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/921032/live_3311852_7248026.flv?wsSecret=9a220f6242a03b6e80dcd1e975ad40d8&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":8259977,"uid":278452410,"title":"别的小朋友都回家了你什么时候带我回家啊","uname":"橙子斯密达","online":464,"user_cover":"https://i0.hdslb.com/bfs/live/177871a2418067b0443f81e5080563d1026f8c6b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/8259977.jpg?02111210","show_cover":"https://i0.hdslb.com/bfs/vc/9f6735c702b86286af0e32649310e1067aad943b.jpg","link":"/8259977","face":"https://i1.hdslb.com/bfs/face/12242421082cc3263ba3415e10f957d7ba751d9a.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/369622/live_278452410_6809315.flv?wsSecret=aba1d0fc8fec64a437e5289a6956d570&wsTime=1519957201","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""}] + */ + + @SerializedName("partition") + private Partition partition; + @SerializedName("lives") + private List lives; + + public Partition getPartition() { + return partition; + } + + public void setPartition(Partition partition) { + this.partition = partition; + } + + public List getLives() { + return lives; + } + + public void setLives(List lives) { + this.lives = lives; + } + + public static class Partition { + /** + * id : 999 + * name : 颜值领域 + * sub_icon : {"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-2_3x.png?201709151052","height":"63","width":"63"} + * count : 0 + * hidden : 0 + */ + + @SerializedName("id") + private int id; + @SerializedName("name") + private String name; + @SerializedName("sub_icon") + private SubIcon subIcon; + @SerializedName("count") + private int count; + @SerializedName("hidden") + private int hidden; + + 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 SubIcon getSubIcon() { + return subIcon; + } + + public void setSubIcon(SubIcon subIcon) { + this.subIcon = subIcon; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getHidden() { + return hidden; + } + + public void setHidden(int hidden) { + this.hidden = hidden; + } + + public static class SubIcon { + /** + * src : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-2_3x.png?201709151052 + * height : 63 + * width : 63 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private String height; + @SerializedName("width") + private String width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public String getHeight() { + return height; + } + + public void setHeight(String height) { + this.height = height; + } + + public String getWidth() { + return width; + } + + public void setWidth(String width) { + this.width = width; + } + } + } + + public static class Lives { + /** + * roomid : 5495804 + * uid : 203267722 + * title : 你点,我唱 + * uname : 花优er + * online : 1298 + * user_cover : https://i0.hdslb.com/bfs/live/8881fca2f4d0d3b937767f5cacb4117966b9fea6.jpg + * user_cover_flag : 1 + * system_cover : https://i0.hdslb.com/bfs/live/5495804.jpg?03020946 + * show_cover : https://i0.hdslb.com/bfs/vc/4c5126739114bb441cb3c12460a471733b1fe25a.jpg + * link : /5495804 + * face : https://i0.hdslb.com/bfs/face/a44d19265a7c3240122dbe36d598d75a00acffd5.jpg + * parent_id : 1 + * parent_name : 娱乐 + * area_id : 32 + * area_name : 手机直播 + * web_pendent : + * cover_size : {"height":180,"width":320} + * play_url : http://qn.live-play.acgvideo.com/live-qn/923710/live_203267722_7185906.flv?wsSecret=455db153c50c8adab57aa793f3c82ce8&wsTime=1519957201 + * accept_quality_v2 : [4] + * current_quality : 0 + * accept_quality : 4 + * broadcast_type : 1 + * is_tv : 0 + * corner : + * pendent : + */ + + @SerializedName("roomid") + private int roomid; + @SerializedName("uid") + private int uid; + @SerializedName("title") + private String title; + @SerializedName("uname") + private String uname; + @SerializedName("online") + private int online; + @SerializedName("user_cover") + private String userCover; + @SerializedName("user_cover_flag") + private int userCoverFlag; + @SerializedName("system_cover") + private String systemCover; + @SerializedName("show_cover") + private String showCover; + @SerializedName("link") + private String link; + @SerializedName("face") + private String face; + @SerializedName("parent_id") + private int parentId; + @SerializedName("parent_name") + private String parentName; + @SerializedName("area_id") + private int areaId; + @SerializedName("area_name") + private String areaName; + @SerializedName("web_pendent") + private String webPendent; + @SerializedName("cover_size") + private CoverSize coverSize; + @SerializedName("play_url") + private String playUrl; + @SerializedName("current_quality") + private int currentQuality; + @SerializedName("accept_quality") + private String acceptQuality; + @SerializedName("broadcast_type") + private int broadcastType; + @SerializedName("is_tv") + private int isTv; + @SerializedName("corner") + private String corner; + @SerializedName("pendent") + private String pendent; + @SerializedName("accept_quality_v2") + private List acceptQualityV2; + + public int getRoomid() { + return roomid; + } + + public void setRoomid(int roomid) { + this.roomid = roomid; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUname() { + return uname; + } + + public void setUname(String uname) { + this.uname = uname; + } + + public int getOnline() { + return online; + } + + public void setOnline(int online) { + this.online = online; + } + + public String getUserCover() { + return userCover; + } + + public void setUserCover(String userCover) { + this.userCover = userCover; + } + + public int getUserCoverFlag() { + return userCoverFlag; + } + + public void setUserCoverFlag(int userCoverFlag) { + this.userCoverFlag = userCoverFlag; + } + + public String getSystemCover() { + return systemCover; + } + + public void setSystemCover(String systemCover) { + this.systemCover = systemCover; + } + + public String getShowCover() { + return showCover; + } + + public void setShowCover(String showCover) { + this.showCover = showCover; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getFace() { + return face; + } + + public void setFace(String face) { + this.face = face; + } + + public int getParentId() { + return parentId; + } + + public void setParentId(int parentId) { + this.parentId = parentId; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } + + public int getAreaId() { + return areaId; + } + + public void setAreaId(int areaId) { + this.areaId = areaId; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + public String getWebPendent() { + return webPendent; + } + + public void setWebPendent(String webPendent) { + this.webPendent = webPendent; + } + + public CoverSize getCoverSize() { + return coverSize; + } + + public void setCoverSize(CoverSize coverSize) { + this.coverSize = coverSize; + } + + public String getPlayUrl() { + return playUrl; + } + + public void setPlayUrl(String playUrl) { + this.playUrl = playUrl; + } + + public int getCurrentQuality() { + return currentQuality; + } + + public void setCurrentQuality(int currentQuality) { + this.currentQuality = currentQuality; + } + + public String getAcceptQuality() { + return acceptQuality; + } + + public void setAcceptQuality(String acceptQuality) { + this.acceptQuality = acceptQuality; + } + + public int getBroadcastType() { + return broadcastType; + } + + public void setBroadcastType(int broadcastType) { + this.broadcastType = broadcastType; + } + + public int getIsTv() { + return isTv; + } + + public void setIsTv(int isTv) { + this.isTv = isTv; + } + + public String getCorner() { + return corner; + } + + public void setCorner(String corner) { + this.corner = corner; + } + + public String getPendent() { + return pendent; + } + + public void setPendent(String pendent) { + this.pendent = pendent; + } + + public List getAcceptQualityV2() { + return acceptQualityV2; + } + + public void setAcceptQualityV2(List acceptQualityV2) { + this.acceptQualityV2 = acceptQualityV2; + } + + public static class CoverSize { + /** + * height : 180 + * width : 320 + */ + + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + } + } + + public static class RecommendData { + /** + * partition : {"id":0,"name":"推荐主播","area":"hot","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052","height":"63","width":"63"},"count":3528} + * banner_data : [{"cover":{"src":"https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png","height":180,"width":320},"title":"今天,你的小视频上榜了吗?","is_clip":1,"new_cover":{"src":"https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg","height":180,"width":320},"new_title":"B站大触竟然都在这里???","new_router":"https://h.bilibili.com/ywh/h5/index"}] + * lives : [{"owner":{"face":"https://i2.hdslb.com/bfs/face/4a31c283b90fcd6fe49b7a12662a14e607236c52.jpg","mid":2715177,"name":"祥宁嫂嫂丶"},"cover":{"src":"https://i0.hdslb.com/bfs/live/3815b7eb6f5f15b61c8c7b6991f1b805495e7059.jpg","height":180,"width":320},"room_id":52658,"check_version":0,"online":2351,"area":"电子竞技","area_id":4,"title":"(新人推荐)全区免费首胜啦~","playurl":"http://xl.live-play.acgvideo.com/live-xl/882210/live_2715177_5087642.flv?wsSecret=39d9fd9a3f4a28eae0d8e9ce734313a0&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":86,"area_v2_name":"英雄联盟","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/f4c2ceae1988050e35201abafafed134b98195c7.jpg","mid":166584070,"name":"独上熹楼ヽ城主"},"cover":{"src":"https://i0.hdslb.com/bfs/live/54777c587d71c5eff7074f7e16a609a746379224.jpg","height":180,"width":320},"room_id":5469025,"check_version":0,"online":3419,"area":"唱见舞见","area_id":10,"title":"攻音受音陪你賴床 腐女慎入","playurl":"http://qn.live-play.acgvideo.com/live-qn/289198/live_166584070_2864596.flv?wsSecret=011980f56104608d1d1563488dddced9&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐","data_behavior_id":"a0d146db7e2beaf:a0d146db7e2beaf:0:0","data_source_id":"system"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/c489cebbd9cb5902b950ca819ab1980d3fd49f5c.jpg","mid":1597982,"name":"Richard_Price"},"cover":{"src":"https://i0.hdslb.com/bfs/live/c46554cb778ac9941bf39e4771ff75c944f60e39.jpg","height":180,"width":320},"room_id":869069,"check_version":0,"online":814,"area":"唱见舞见","area_id":10,"title":"KTV, 元宵节快乐","playurl":"http://live-play.acgvideo.com/live/993/live_1597982_9114881.flv?wsSecret=626dadef4ec70594d55e5e67c48f1508&wsTime=5a712ed7","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/303f46216ceed76e2e5360a9de0c239ec9e32379.jpg","mid":719049,"name":"卖火柴的可可亚"},"cover":{"src":"https://i0.hdslb.com/bfs/live/2be48255ad5cd5b212ae2108d1e998568ee5efb1.jpg","height":180,"width":320},"room_id":53428,"check_version":0,"online":2712,"area":"单机联机","area_id":1,"title":"【影之诗】休闲游戏何必上分","playurl":"http://xl.live-play.acgvideo.com/live-xl/342779/live_719049_5853792.flv?wsSecret=39d2799d5266e44e3e4d0c19ee34f4ef&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ca7aaba009c22adcd1071522f9fdc6a4f669d532.jpg","mid":9870438,"name":"阿运呀"},"cover":{"src":"https://i0.hdslb.com/bfs/live/ff3d7a4d7cbe3cad02b14df15f56da239727f576.jpg","height":180,"width":320},"room_id":93279,"check_version":0,"online":3615,"area":"单机联机","area_id":1,"title":"【阿运】神秘海域4之一个萌新","playurl":"http://txy.live-play.acgvideo.com/live-txy/312360/live_9870438_5301909.flv?wsSecret=eeb9a68c89eb6171b4ab5b5bf3663a67&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/6ca5366bede574a88683201db31735466fb7665c.jpg","mid":4790535,"name":"祈咔"},"cover":{"src":"https://i0.hdslb.com/bfs/live/0149b64df95f1f31af4032871f3cc8942115ed13.jpg","height":180,"width":320},"room_id":100849,"check_version":0,"online":2661,"area":"唱见舞见","area_id":10,"title":"【古风】孤寡古疯老唱见","playurl":"http://dl.live-play.acgvideo.com/live-dl/905519/live_4790535_6783016.flv?wsSecret=189cdfc6e1af1682c236b43c8f3300a4&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/ceaffc80b824f1d277034622fba809ff3a50db89.jpg","mid":4008909,"name":"KIM高能萌"},"cover":{"src":"https://i0.hdslb.com/bfs/live/1cf09a1a579e608a1284b637a2f784c3558b91c6.jpg","height":180,"width":320},"room_id":7365762,"check_version":0,"online":2168,"area":"单机联机","area_id":1,"title":"少男的绝地描边画来了解一下^^","playurl":"http://qn.live-play.acgvideo.com/live-qn/108838/live_4008909_3934891.flv?wsSecret=7c3c5503e406cdfcd65caf25ed0e8be3&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/56e342a20940346d7026af2ff72a9bb89001a197.jpg","mid":13610473,"name":"北极星丶清寒"},"cover":{"src":"https://i0.hdslb.com/bfs/live/d7f524a13e318769e77190ce7ee4002daf7206e0.jpg","height":180,"width":320},"room_id":402805,"check_version":0,"online":4227,"area":"单机联机","area_id":1,"title":"寒宾逊的1.12.2荒岛求生","playurl":"http://qn.live-play.acgvideo.com/live-qn/945345/live_13610473_8275609.flv?wsSecret=f5f547db01501929cdd424866b8a772f&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":56,"area_v2_name":"我的世界","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/9eb27d14a4b29e1aa32f645a5273a00796162c41.jpg","mid":19088449,"name":"猜十八"},"cover":{"src":"https://i0.hdslb.com/bfs/live/383c84bb6d3412ce8843209990b1aa4c2e4ea101.jpg","height":180,"width":320},"room_id":54912,"check_version":0,"online":4090,"area":"手游直播","area_id":12,"title":"手机吃鸡 人机大作战?","playurl":"http://qn.live-play.acgvideo.com/live-qn/488202/live_19088449_4499867.flv?wsSecret=349df85ace4fe1837a02d78e00e36678&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":98,"area_v2_name":"其他手游","area_v2_parent_id":3,"area_v2_parent_name":"手游"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/25ca9cca4fa9522c08b12b7de48a2509734fcd9d.jpg","mid":463999,"name":"波喵喵喵"},"cover":{"src":"https://i0.hdslb.com/bfs/live/76e08ebaa07fd12c80374447f0ea0691a920bb4c.jpg","height":180,"width":320},"room_id":151159,"check_version":0,"online":662,"area":"生活娱乐","area_id":6,"title":"元宵快乐~","playurl":"http://dl.live-play.acgvideo.com/live-dl/299784/live_463999_8651963.flv?wsSecret=21f8ca49261774740366a83ed591ab54&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"娱乐分区No.3","area_v2_id":139,"area_v2_name":"美少女","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i1.hdslb.com/bfs/face/29ff8cea978d08989193f13146006a5b14e22784.jpg","mid":9165690,"name":"桐人ヽ"},"cover":{"src":"https://i0.hdslb.com/bfs/live/e8e88ba6d479acc6c39896ac2104d4d868a964f2.jpg","height":180,"width":320},"room_id":53100,"check_version":0,"online":3222,"area":"网络游戏","area_id":3,"title":"上午嘤嘤嘤下午夺命晚上吃鸡!","playurl":"http://qn.live-play.acgvideo.com/live-qn/359080/live_9165690_1198449.flv?wsSecret=8cfeafdf3b2cb6dd4cfc1b1308bc9644&wsTime=1519957201","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":84,"area_v2_name":"300英雄","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ce10c759df53720268b23ef8bd06150aa61834a5.jpg","mid":659965,"name":"基佬爱上熊"},"cover":{"src":"https://i0.hdslb.com/bfs/live/65b8641c7681faca6317314bc907edac984390f1.jpg","height":180,"width":320},"room_id":16101,"check_version":0,"online":4206,"area":"单机联机","area_id":1,"title":"【流放之路】一款继承暗黑2的游戏","playurl":"http://xl.live-play.acgvideo.com/live-xl/791352/live_659965_4719464.flv?wsSecret=38ef4f3b8dbd455b728d3c4d50bb0043&wsTime=1519957199","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"}] + */ + + @SerializedName("partition") + private PartitionX partition; + @SerializedName("banner_data") + private List bannerData; + @SerializedName("lives") + private List lives; + + public PartitionX getPartition() { + return partition; + } + + public void setPartition(PartitionX partition) { + this.partition = partition; + } + + public List getBannerData() { + return bannerData; + } + + public void setBannerData(List bannerData) { + this.bannerData = bannerData; + } + + public List getLives() { + return lives; + } + + public void setLives(List lives) { + this.lives = lives; + } + + public static class PartitionX { + /** + * id : 0 + * name : 推荐主播 + * area : hot + * sub_icon : {"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052","height":"63","width":"63"} + * count : 3528 + */ + + @SerializedName("id") + private int id; + @SerializedName("name") + private String name; + @SerializedName("area") + private String area; + @SerializedName("sub_icon") + private SubIconX subIcon; + @SerializedName("count") + private int count; + + 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 getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public SubIconX getSubIcon() { + return subIcon; + } + + public void setSubIcon(SubIconX subIcon) { + this.subIcon = subIcon; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public static class SubIconX { + /** + * src : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052 + * height : 63 + * width : 63 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private String height; + @SerializedName("width") + private String width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public String getHeight() { + return height; + } + + public void setHeight(String height) { + this.height = height; + } + + public String getWidth() { + return width; + } + + public void setWidth(String width) { + this.width = width; + } + } + } + + public static class BannerData { + /** + * cover : {"src":"https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png","height":180,"width":320} + * title : 今天,你的小视频上榜了吗? + * is_clip : 1 + * new_cover : {"src":"https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg","height":180,"width":320} + * new_title : B站大触竟然都在这里??? + * new_router : https://h.bilibili.com/ywh/h5/index + */ + + @SerializedName("cover") + private Cover cover; + @SerializedName("title") + private String title; + @SerializedName("is_clip") + private int isClip; + @SerializedName("new_cover") + private NewCover newCover; + @SerializedName("new_title") + private String newTitle; + @SerializedName("new_router") + private String newRouter; + + public Cover getCover() { + return cover; + } + + public void setCover(Cover cover) { + this.cover = cover; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getIsClip() { + return isClip; + } + + public void setIsClip(int isClip) { + this.isClip = isClip; + } + + public NewCover getNewCover() { + return newCover; + } + + public void setNewCover(NewCover newCover) { + this.newCover = newCover; + } + + public String getNewTitle() { + return newTitle; + } + + public void setNewTitle(String newTitle) { + this.newTitle = newTitle; + } + + public String getNewRouter() { + return newRouter; + } + + public void setNewRouter(String newRouter) { + this.newRouter = newRouter; + } + + public static class Cover { + /** + * src : https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png + * height : 180 + * width : 320 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + + public static class NewCover { + /** + * src : https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg + * height : 180 + * width : 320 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + } + + public static class LivesX { + /** + * owner : {"face":"https://i2.hdslb.com/bfs/face/4a31c283b90fcd6fe49b7a12662a14e607236c52.jpg","mid":2715177,"name":"祥宁嫂嫂丶"} + * cover : {"src":"https://i0.hdslb.com/bfs/live/3815b7eb6f5f15b61c8c7b6991f1b805495e7059.jpg","height":180,"width":320} + * room_id : 52658 + * check_version : 0 + * online : 2351 + * area : 电子竞技 + * area_id : 4 + * title : (新人推荐)全区免费首胜啦~ + * playurl : http://xl.live-play.acgvideo.com/live-xl/882210/live_2715177_5087642.flv?wsSecret=39d9fd9a3f4a28eae0d8e9ce734313a0&wsTime=1519957201 + * accept_quality_v2 : [] + * current_quality : 4 + * accept_quality : 4 + * broadcast_type : 0 + * is_tv : 0 + * corner : + * pendent : + * area_v2_id : 86 + * area_v2_name : 英雄联盟 + * area_v2_parent_id : 2 + * area_v2_parent_name : 游戏 + * data_behavior_id : a0d146db7e2beaf:a0d146db7e2beaf:0:0 + * data_source_id : system + */ + + @SerializedName("owner") + private Owner owner; + @SerializedName("cover") + private CoverX cover; + @SerializedName("room_id") + private int roomId; + @SerializedName("check_version") + private int checkVersion; + @SerializedName("online") + private int online; + @SerializedName("area") + private String area; + @SerializedName("area_id") + private int areaId; + @SerializedName("title") + private String title; + @SerializedName("playurl") + private String playurl; + @SerializedName("current_quality") + private int currentQuality; + @SerializedName("accept_quality") + private String acceptQuality; + @SerializedName("broadcast_type") + private int broadcastType; + @SerializedName("is_tv") + private int isTv; + @SerializedName("corner") + private String corner; + @SerializedName("pendent") + private String pendent; + @SerializedName("area_v2_id") + private int areaV2Id; + @SerializedName("area_v2_name") + private String areaV2Name; + @SerializedName("area_v2_parent_id") + private int areaV2ParentId; + @SerializedName("area_v2_parent_name") + private String areaV2ParentName; + @SerializedName("data_behavior_id") + private String dataBehaviorId; + @SerializedName("data_source_id") + private String dataSourceId; + @SerializedName("accept_quality_v2") + private List acceptQualityV2; + + public Owner getOwner() { + return owner; + } + + public void setOwner(Owner owner) { + this.owner = owner; + } + + public CoverX getCover() { + return cover; + } + + public void setCover(CoverX cover) { + this.cover = cover; + } + + public int getRoomId() { + return roomId; + } + + public void setRoomId(int roomId) { + this.roomId = roomId; + } + + public int getCheckVersion() { + return checkVersion; + } + + public void setCheckVersion(int checkVersion) { + this.checkVersion = checkVersion; + } + + public int getOnline() { + return online; + } + + public void setOnline(int online) { + this.online = online; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public int getAreaId() { + return areaId; + } + + public void setAreaId(int areaId) { + this.areaId = areaId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getPlayurl() { + return playurl; + } + + public void setPlayurl(String playurl) { + this.playurl = playurl; + } + + public int getCurrentQuality() { + return currentQuality; + } + + public void setCurrentQuality(int currentQuality) { + this.currentQuality = currentQuality; + } + + public String getAcceptQuality() { + return acceptQuality; + } + + public void setAcceptQuality(String acceptQuality) { + this.acceptQuality = acceptQuality; + } + + public int getBroadcastType() { + return broadcastType; + } + + public void setBroadcastType(int broadcastType) { + this.broadcastType = broadcastType; + } + + public int getIsTv() { + return isTv; + } + + public void setIsTv(int isTv) { + this.isTv = isTv; + } + + public String getCorner() { + return corner; + } + + public void setCorner(String corner) { + this.corner = corner; + } + + public String getPendent() { + return pendent; + } + + public void setPendent(String pendent) { + this.pendent = pendent; + } + + public int getAreaV2Id() { + return areaV2Id; + } + + public void setAreaV2Id(int areaV2Id) { + this.areaV2Id = areaV2Id; + } + + public String getAreaV2Name() { + return areaV2Name; + } + + public void setAreaV2Name(String areaV2Name) { + this.areaV2Name = areaV2Name; + } + + public int getAreaV2ParentId() { + return areaV2ParentId; + } + + public void setAreaV2ParentId(int areaV2ParentId) { + this.areaV2ParentId = areaV2ParentId; + } + + public String getAreaV2ParentName() { + return areaV2ParentName; + } + + public void setAreaV2ParentName(String areaV2ParentName) { + this.areaV2ParentName = areaV2ParentName; + } + + public String getDataBehaviorId() { + return dataBehaviorId; + } + + public void setDataBehaviorId(String dataBehaviorId) { + this.dataBehaviorId = dataBehaviorId; + } + + public String getDataSourceId() { + return dataSourceId; + } + + public void setDataSourceId(String dataSourceId) { + this.dataSourceId = dataSourceId; + } + + public List getAcceptQualityV2() { + return acceptQualityV2; + } + + public void setAcceptQualityV2(List acceptQualityV2) { + this.acceptQualityV2 = acceptQualityV2; + } + + public static class Owner { + /** + * face : https://i2.hdslb.com/bfs/face/4a31c283b90fcd6fe49b7a12662a14e607236c52.jpg + * mid : 2715177 + * name : 祥宁嫂嫂丶 + */ + + @SerializedName("face") + private String face; + @SerializedName("mid") + private int mid; + @SerializedName("name") + private String name; + + public String getFace() { + return face; + } + + public void setFace(String face) { + this.face = face; + } + + public int getMid() { + return mid; + } + + public void setMid(int mid) { + this.mid = mid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class CoverX { + /** + * src : https://i0.hdslb.com/bfs/live/3815b7eb6f5f15b61c8c7b6991f1b805495e7059.jpg + * height : 180 + * width : 320 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + } + } + + public static class Banner { + /** + * title : 直播周刊 + * img : https://i0.hdslb.com/bfs/live/af17c8d882104370075f4fa5418343861ac3e540.png + * remark : 直播周刊 + * link : https://live.bilibili.com/AppBanner/index?id=746 + */ + + @SerializedName("title") + private String title; + @SerializedName("img") + private String img; + @SerializedName("remark") + private String remark; + @SerializedName("link") + private String link; + + 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 String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + } + + public static class EntranceIcons { + /** + * id : 9 + * name : 绘画专区 + * entrance_icon : {"src":"https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/9_big.png?20171116172700","height":"132","width":"132"} + */ + + @SerializedName("id") + private int id; + @SerializedName("name") + private String name; + @SerializedName("entrance_icon") + private EntranceIcon entranceIcon; + + 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 EntranceIcon getEntranceIcon() { + return entranceIcon; + } + + public void setEntranceIcon(EntranceIcon entranceIcon) { + this.entranceIcon = entranceIcon; + } + + public static class EntranceIcon { + /** + * src : https://static.hdslb.com/live-static/images/mobile/android/big/xxhdpi/9_big.png?20171116172700 + * height : 132 + * width : 132 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private String height; + @SerializedName("width") + private String width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public String getHeight() { + return height; + } + + public void setHeight(String height) { + this.height = height; + } + + public String getWidth() { + return width; + } + + public void setWidth(String width) { + this.width = width; + } + } + } + + public static class Partitions { + /** + * partition : {"id":1,"name":"娱乐","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/1_3x.png?201709151052","height":"63","width":"63"},"count":1484} + * lives : [{"roomid":7399897,"uid":7619276,"title":"包裹有免费B坷垃可送哦(点这看直播单)","uname":"星子弈风","online":145,"user_cover":"https://i0.hdslb.com/bfs/live/7fc54c49ed7db4bc53fe6e5c8888db3eb0c01d7c.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/7399897.jpg?03020945","show_cover":false,"link":"/7399897","face":"https://i2.hdslb.com/bfs/face/41c4b60b54795870ac4d209dc949a51ca7614062.jpg","parent_id":1,"parent_name":"娱乐","area_id":123,"area_name":"户外","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/415156/live_7619276_6963984.flv?wsSecret=26f02e69c2e01fc840da1f452d673f37&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":2802503,"uid":34993653,"title":"做个温柔读书哄睡的小姐姐","uname":"楚小芭","online":958,"user_cover":"https://i0.hdslb.com/bfs/live/33e9537f94545758035b14a59a68fd1b78f8184b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/2802503.jpg?03020945","show_cover":false,"link":"/2802503","face":"https://i0.hdslb.com/bfs/face/41a917cb13f546e62bfea4e06a7781d8118c676e.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/368878/live_34993653_4247645.flv?wsSecret=01587e645b73cfeec12992ac3f3b8288&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":910884,"uid":20165629,"title":"跟我走!","uname":"共青团中央","online":15974,"user_cover":"https://i0.hdslb.com/bfs/live/2591ba98c2db7da32dd40ac100322ab8d9a218c6.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/910884.jpg?03020946","show_cover":false,"link":"/910884","face":"https://i0.hdslb.com/bfs/face/3b4caf3ad325fd962bf98f90e4aac0b4ae4679c8.jpg","parent_id":1,"parent_name":"娱乐","area_id":123,"area_name":"户外","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/377121/live_20165629_5904889.flv?wsSecret=88113f81c6eb29be592c43d4cbaddc0c&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":30040,"uid":5480206,"title":"破产 弹到一半随时卖琴","uname":"桥白白白白","online":955,"user_cover":"https://i0.hdslb.com/bfs/live/f7ac32e981f4cd7b0bf6733ba79e705dd312e8f4.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/30040.jpg?03020946","show_cover":false,"link":"/5454","face":"https://i1.hdslb.com/bfs/face/67ba6957182bb865c8b4b5fd9006778af0cf9f71.jpg","parent_id":1,"parent_name":"娱乐","area_id":143,"area_name":"才艺","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/680310/live_5480206_332_c521e483.flv?wsSecret=0d2d608349a38973aaded375418ceca3&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":1338247,"uid":27894414,"title":"来呀来呀造人呀!造人人人人人人人!","uname":"露琪亚Rukiaルキア","online":78,"user_cover":"https://i0.hdslb.com/bfs/live/b5accf156795b0e24c406bb2debe3448032e13fd.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1338247.jpg?03020946","show_cover":false,"link":"/1338247","face":"https://i0.hdslb.com/bfs/face/b4dda315df2c9ffcc5f378b5871932e42122c567.jpg","parent_id":1,"parent_name":"娱乐","area_id":25,"area_name":"手工","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/558698/live_27894414_1428176.flv?wsSecret=1189d19dfda8cc47ae10d258ae9be26a&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":4346987,"uid":30580510,"title":"你来喵~一声,我也会喵~给你听哟~","uname":"是白米不是黑米","online":368,"user_cover":"https://i0.hdslb.com/bfs/live/4f10d04cfebc28bc48a7d9be2f9fb91d83c7226f.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/4346987.jpg?03020946","show_cover":false,"link":"/4346987","face":"https://i0.hdslb.com/bfs/face/f7e093a0613af8cf95ca684deb0fbfa7b2ab2ba3.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/723153/live_30580510_8427291.flv?wsSecret=cb1dd97e388bde304a3aedeab071ca87&wsTime=1519957197","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}] + */ + + @SerializedName("partition") + private PartitionXX partition; + @SerializedName("lives") + private List lives; + + public PartitionXX getPartition() { + return partition; + } + + public void setPartition(PartitionXX partition) { + this.partition = partition; + } + + public List getLives() { + return lives; + } + + public void setLives(List lives) { + this.lives = lives; + } + + public static class PartitionXX { + /** + * id : 1 + * name : 娱乐 + * sub_icon : {"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/1_3x.png?201709151052","height":"63","width":"63"} + * count : 1484 + */ + + @SerializedName("id") + private int id; + @SerializedName("name") + private String name; + @SerializedName("sub_icon") + private SubIconXX subIcon; + @SerializedName("count") + private int count; + + 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 SubIconXX getSubIcon() { + return subIcon; + } + + public void setSubIcon(SubIconXX subIcon) { + this.subIcon = subIcon; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public static class SubIconXX { + /** + * src : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/1_3x.png?201709151052 + * height : 63 + * width : 63 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private String height; + @SerializedName("width") + private String width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public String getHeight() { + return height; + } + + public void setHeight(String height) { + this.height = height; + } + + public String getWidth() { + return width; + } + + public void setWidth(String width) { + this.width = width; + } + } + } + + public static class LivesXX { + /** + * roomid : 7399897 + * uid : 7619276 + * title : 包裹有免费B坷垃可送哦(点这看直播单) + * uname : 星子弈风 + * online : 145 + * user_cover : https://i0.hdslb.com/bfs/live/7fc54c49ed7db4bc53fe6e5c8888db3eb0c01d7c.jpg + * user_cover_flag : 1 + * system_cover : https://i0.hdslb.com/bfs/live/7399897.jpg?03020945 + * show_cover : false + * link : /7399897 + * face : https://i2.hdslb.com/bfs/face/41c4b60b54795870ac4d209dc949a51ca7614062.jpg + * parent_id : 1 + * parent_name : 娱乐 + * area_id : 123 + * area_name : 户外 + * web_pendent : + * cover_size : {"height":180,"width":320} + * play_url : http://js.live-play.acgvideo.com/live-js/415156/live_7619276_6963984.flv?wsSecret=26f02e69c2e01fc840da1f452d673f37&wsTime=1519957197 + * accept_quality_v2 : [4] + * current_quality : 0 + * accept_quality : 4 + * broadcast_type : 0 + * is_tv : 0 + * corner : + * pendent : + */ + + @SerializedName("roomid") + private int roomid; + @SerializedName("uid") + private int uid; + @SerializedName("title") + private String title; + @SerializedName("uname") + private String uname; + @SerializedName("online") + private int online; + @SerializedName("user_cover") + private String userCover; + @SerializedName("user_cover_flag") + private int userCoverFlag; + @SerializedName("system_cover") + private String systemCover; + @SerializedName("show_cover") + private boolean showCover; + @SerializedName("link") + private String link; + @SerializedName("face") + private String face; + @SerializedName("parent_id") + private int parentId; + @SerializedName("parent_name") + private String parentName; + @SerializedName("area_id") + private int areaId; + @SerializedName("area_name") + private String areaName; + @SerializedName("web_pendent") + private String webPendent; + @SerializedName("cover_size") + private CoverSizeX coverSize; + @SerializedName("play_url") + private String playUrl; + @SerializedName("current_quality") + private int currentQuality; + @SerializedName("accept_quality") + private String acceptQuality; + @SerializedName("broadcast_type") + private int broadcastType; + @SerializedName("is_tv") + private int isTv; + @SerializedName("corner") + private String corner; + @SerializedName("pendent") + private String pendent; + @SerializedName("accept_quality_v2") + private List acceptQualityV2; + + public int getRoomid() { + return roomid; + } + + public void setRoomid(int roomid) { + this.roomid = roomid; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUname() { + return uname; + } + + public void setUname(String uname) { + this.uname = uname; + } + + public int getOnline() { + return online; + } + + public void setOnline(int online) { + this.online = online; + } + + public String getUserCover() { + return userCover; + } + + public void setUserCover(String userCover) { + this.userCover = userCover; + } + + public int getUserCoverFlag() { + return userCoverFlag; + } + + public void setUserCoverFlag(int userCoverFlag) { + this.userCoverFlag = userCoverFlag; + } + + public String getSystemCover() { + return systemCover; + } + + public void setSystemCover(String systemCover) { + this.systemCover = systemCover; + } + + public boolean isShowCover() { + return showCover; + } + + public void setShowCover(boolean showCover) { + this.showCover = showCover; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getFace() { + return face; + } + + public void setFace(String face) { + this.face = face; + } + + public int getParentId() { + return parentId; + } + + public void setParentId(int parentId) { + this.parentId = parentId; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } + + public int getAreaId() { + return areaId; + } + + public void setAreaId(int areaId) { + this.areaId = areaId; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + public String getWebPendent() { + return webPendent; + } + + public void setWebPendent(String webPendent) { + this.webPendent = webPendent; + } + + public CoverSizeX getCoverSize() { + return coverSize; + } + + public void setCoverSize(CoverSizeX coverSize) { + this.coverSize = coverSize; + } + + public String getPlayUrl() { + return playUrl; + } + + public void setPlayUrl(String playUrl) { + this.playUrl = playUrl; + } + + public int getCurrentQuality() { + return currentQuality; + } + + public void setCurrentQuality(int currentQuality) { + this.currentQuality = currentQuality; + } + + public String getAcceptQuality() { + return acceptQuality; + } + + public void setAcceptQuality(String acceptQuality) { + this.acceptQuality = acceptQuality; + } + + public int getBroadcastType() { + return broadcastType; + } + + public void setBroadcastType(int broadcastType) { + this.broadcastType = broadcastType; + } + + public int getIsTv() { + return isTv; + } + + public void setIsTv(int isTv) { + this.isTv = isTv; + } + + public String getCorner() { + return corner; + } + + public void setCorner(String corner) { + this.corner = corner; + } + + public String getPendent() { + return pendent; + } + + public void setPendent(String pendent) { + this.pendent = pendent; + } + + public List getAcceptQualityV2() { + return acceptQualityV2; + } + + public void setAcceptQualityV2(List acceptQualityV2) { + this.acceptQualityV2 = acceptQualityV2; + } + + public static class CoverSizeX { + /** + * height : 180 + * width : 320 + */ + + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/CapsuleInfoEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/CapsuleInfoEntity.java new file mode 100644 index 0000000..d432597 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/CapsuleInfoEntity.java @@ -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; + @SerializedName("list") + private List 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 getGift() { + return gift; + } + + public void setGift(List gift) { + this.gift = gift; + } + + public List getWinners() { + return winners; + } + + public void setWinners(List 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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/HistoryEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/HistoryEntity.java new file mode 100644 index 0000000..3cc90d4 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/HistoryEntity.java @@ -0,0 +1,232 @@ +package com.hiczp.bilibili.api.live.entity; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class HistoryEntity { + /** + * code : 0 + * message : OK + * data : {"page":1,"pagesize":20,"list":[{"name":"czp3009","face":"https://i1.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg","roomid":1110317,"areaName":"生活娱乐","live_status":0,"round_status":0,"fansNum":44,"area_v2_id":"27","area_v2_name":"学习","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["编程"]},{"name":"3号直播间","face":"https://i1.hdslb.com/bfs/face/5d35da6e93fbfb1a77ad6d1f1004b08413913f9a.jpg","roomid":3,"areaName":"放映厅","live_status":1,"round_status":0,"fansNum":314211,"area_v2_id":"34","area_v2_name":"音乐台","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["ACG音乐"]},{"name":"青衣才不是御姐呢","face":"https://i1.hdslb.com/bfs/face/025fa73e3f1be9d7f4c2b10678d6a0a5a89addee.jpg","roomid":526,"areaName":"生活娱乐","live_status":0,"round_status":0,"fansNum":139168,"area_v2_id":"139","area_v2_name":"美少女","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["御姐","电台","声控","声优"]},{"name":"宫本狗雨","face":"https://i0.hdslb.com/bfs/face/8c49a758216f9bd14b0046afe48a3514f44126f0.jpg","roomid":102,"areaName":"单机联机","live_status":1,"round_status":0,"fansNum":582323,"area_v2_id":"80","area_v2_name":"绝地求生:大逃杀","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["英雄联盟","守望麦克雷","黄金矿工","灵魂唱见"]},{"name":"Tocci椭奇","face":"https://i2.hdslb.com/bfs/face/c67d599dffb6911fdfc3d70c41204363ee41d1bd.jpg","roomid":519,"areaName":"生活娱乐","live_status":0,"round_status":0,"fansNum":124306,"area_v2_id":"32","area_v2_name":"手机直播","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["英雄联盟","宅舞"]},{"name":"叶落莫言","face":"https://i1.hdslb.com/bfs/face/37bfd9a9f40eb9ff52b697e204386ab918ccd742.jpg","roomid":387,"areaName":"单机联机","live_status":1,"round_status":0,"fansNum":143357,"area_v2_id":"80","area_v2_name":"绝地求生:大逃杀","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["守望先锋","绝地求生","唱见","古风翻唱"]},{"name":"Alessa0","face":"https://i2.hdslb.com/bfs/face/c1cd432957bbd9bbb98d2c3c36849b5ad7ece7d5.jpg","roomid":1013,"areaName":"单机联机","live_status":1,"round_status":0,"fansNum":257534,"area_v2_id":"107","area_v2_name":"其他游戏","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":[]},{"name":"游戏彩笔","face":"https://i2.hdslb.com/bfs/face/0433055d4eac3b2314faadb47de64be114571d4c.jpg","roomid":461,"areaName":"手游直播","live_status":0,"round_status":0,"fansNum":91385,"area_v2_id":"40","area_v2_name":"崩坏3","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":["崩坏3","绝地求生大逃杀","300英雄"]},{"name":"就决定是你了长生","face":"https://i0.hdslb.com/bfs/face/941f199204fd885cca123cbe8be6eedb6639d0e0.jpg","roomid":1170236,"areaName":"唱见舞见","live_status":1,"round_status":0,"fansNum":3461,"area_v2_id":"21","area_v2_name":"唱见","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["就决定是你了老头"]},{"name":"大大叔菜的抠脚","face":"https://i1.hdslb.com/bfs/face/f8da5f279cfd1ea08c46f15f4dc0c9ca81647cae.jpg","roomid":7733281,"areaName":"手游直播","live_status":1,"round_status":0,"fansNum":2655,"area_v2_id":"98","area_v2_name":"其他手游","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":[]},{"name":"MURDO-木木","face":"https://i2.hdslb.com/bfs/face/11e653115be367111729e26b71c7a95e2e50a5a4.jpg","roomid":5983722,"areaName":"绘画专区","live_status":0,"round_status":0,"fansNum":2473,"area_v2_id":"51","area_v2_name":"原创绘画","area_v2_parent_name":"绘画","area_v2_parent_id":"4","roomTags":[]},{"name":"hyx5020","face":"https://i0.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg","roomid":29434,"areaName":"放映厅","live_status":0,"round_status":0,"fansNum":548,"area_v2_id":"33","area_v2_name":"映评馆","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["SpaceX","Falcon","重型猎鹰","发射"]},{"name":"两仪滚","face":"https://i1.hdslb.com/bfs/face/4a91427ef035836b1937244bc559ed03f244bfa9.jpg","roomid":388,"areaName":"单机联机","live_status":0,"round_status":1,"fansNum":310591,"area_v2_id":"107","area_v2_name":"其他游戏","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["二五仔","猛男","B站恶霸","吃鸡"]},{"name":"污污_永远的魔法师_","face":"https://i0.hdslb.com/bfs/face/effbe54414657ed89b2a48fd822abeed90d67f67.jpg","roomid":255,"areaName":"绘画专区","live_status":0,"round_status":0,"fansNum":129145,"area_v2_id":"94","area_v2_name":"同人绘画","area_v2_parent_name":"绘画","area_v2_parent_id":"4","roomTags":["绘画","板绘"]},{"name":"Kano_Amigo乐队键盘手","face":"https://i1.hdslb.com/bfs/face/0e8dc590bcbcb986f7898d9eb77cdadbf061fc64.jpg","roomid":673794,"areaName":"御宅文化","live_status":0,"round_status":1,"fansNum":4266,"area_v2_id":"143","area_v2_name":"才艺","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":[]},{"name":"棉花大哥哥","face":"https://i2.hdslb.com/bfs/face/9fc16093743b2692a1a6d4dee19eede911e6712f.jpg","roomid":103,"areaName":"生活娱乐","live_status":0,"round_status":1,"fansNum":116498,"area_v2_id":"145","area_v2_name":"聊天室","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["王者荣耀","声控","颜控"]},{"name":"萌萌哒条码","face":"https://i1.hdslb.com/bfs/face/14b69433ef566f39a236991cbb0ff5ef95cc82f2.jpg","roomid":1325308,"areaName":"手游直播","live_status":0,"round_status":0,"fansNum":23679,"area_v2_id":"98","area_v2_name":"其他手游","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":["minecraft 我的世界","Hypixel 炉石传说","守望先锋 绝地求生","单机游戏 星际争霸"]},{"name":"某幻君","face":"https://i1.hdslb.com/bfs/face/9ed5ebf1e3694d9cd2b4fcd1d353759ee83b3dfe.jpg","roomid":271744,"areaName":"单机联机","live_status":0,"round_status":1,"fansNum":1521416,"area_v2_id":"107","area_v2_name":"其他游戏","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["绝地求生大逃杀"]},{"name":"池田天天","face":"https://i0.hdslb.com/bfs/face/fdb8593ca8a578f5aff6bb744fa1df6fa149d9f1.jpg","roomid":13924,"areaName":"唱见舞见","live_status":0,"round_status":1,"fansNum":48799,"area_v2_id":"21","area_v2_name":"唱见","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["天天","少年音","唱歌"]},{"name":"我就是FISH","face":"https://i1.hdslb.com/bfs/face/a076329348d82164c3f54598ee90239c17817d21.jpg","roomid":4716742,"areaName":"手游直播","live_status":0,"round_status":0,"fansNum":8,"area_v2_id":"98","area_v2_name":"其他手游","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":[]}],"total_page":1} + */ + + @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 { + /** + * page : 1 + * pagesize : 20 + * list : [{"name":"czp3009","face":"https://i1.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg","roomid":1110317,"areaName":"生活娱乐","live_status":0,"round_status":0,"fansNum":44,"area_v2_id":"27","area_v2_name":"学习","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["编程"]},{"name":"3号直播间","face":"https://i1.hdslb.com/bfs/face/5d35da6e93fbfb1a77ad6d1f1004b08413913f9a.jpg","roomid":3,"areaName":"放映厅","live_status":1,"round_status":0,"fansNum":314211,"area_v2_id":"34","area_v2_name":"音乐台","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["ACG音乐"]},{"name":"青衣才不是御姐呢","face":"https://i1.hdslb.com/bfs/face/025fa73e3f1be9d7f4c2b10678d6a0a5a89addee.jpg","roomid":526,"areaName":"生活娱乐","live_status":0,"round_status":0,"fansNum":139168,"area_v2_id":"139","area_v2_name":"美少女","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["御姐","电台","声控","声优"]},{"name":"宫本狗雨","face":"https://i0.hdslb.com/bfs/face/8c49a758216f9bd14b0046afe48a3514f44126f0.jpg","roomid":102,"areaName":"单机联机","live_status":1,"round_status":0,"fansNum":582323,"area_v2_id":"80","area_v2_name":"绝地求生:大逃杀","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["英雄联盟","守望麦克雷","黄金矿工","灵魂唱见"]},{"name":"Tocci椭奇","face":"https://i2.hdslb.com/bfs/face/c67d599dffb6911fdfc3d70c41204363ee41d1bd.jpg","roomid":519,"areaName":"生活娱乐","live_status":0,"round_status":0,"fansNum":124306,"area_v2_id":"32","area_v2_name":"手机直播","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["英雄联盟","宅舞"]},{"name":"叶落莫言","face":"https://i1.hdslb.com/bfs/face/37bfd9a9f40eb9ff52b697e204386ab918ccd742.jpg","roomid":387,"areaName":"单机联机","live_status":1,"round_status":0,"fansNum":143357,"area_v2_id":"80","area_v2_name":"绝地求生:大逃杀","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["守望先锋","绝地求生","唱见","古风翻唱"]},{"name":"Alessa0","face":"https://i2.hdslb.com/bfs/face/c1cd432957bbd9bbb98d2c3c36849b5ad7ece7d5.jpg","roomid":1013,"areaName":"单机联机","live_status":1,"round_status":0,"fansNum":257534,"area_v2_id":"107","area_v2_name":"其他游戏","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":[]},{"name":"游戏彩笔","face":"https://i2.hdslb.com/bfs/face/0433055d4eac3b2314faadb47de64be114571d4c.jpg","roomid":461,"areaName":"手游直播","live_status":0,"round_status":0,"fansNum":91385,"area_v2_id":"40","area_v2_name":"崩坏3","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":["崩坏3","绝地求生大逃杀","300英雄"]},{"name":"就决定是你了长生","face":"https://i0.hdslb.com/bfs/face/941f199204fd885cca123cbe8be6eedb6639d0e0.jpg","roomid":1170236,"areaName":"唱见舞见","live_status":1,"round_status":0,"fansNum":3461,"area_v2_id":"21","area_v2_name":"唱见","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["就决定是你了老头"]},{"name":"大大叔菜的抠脚","face":"https://i1.hdslb.com/bfs/face/f8da5f279cfd1ea08c46f15f4dc0c9ca81647cae.jpg","roomid":7733281,"areaName":"手游直播","live_status":1,"round_status":0,"fansNum":2655,"area_v2_id":"98","area_v2_name":"其他手游","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":[]},{"name":"MURDO-木木","face":"https://i2.hdslb.com/bfs/face/11e653115be367111729e26b71c7a95e2e50a5a4.jpg","roomid":5983722,"areaName":"绘画专区","live_status":0,"round_status":0,"fansNum":2473,"area_v2_id":"51","area_v2_name":"原创绘画","area_v2_parent_name":"绘画","area_v2_parent_id":"4","roomTags":[]},{"name":"hyx5020","face":"https://i0.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg","roomid":29434,"areaName":"放映厅","live_status":0,"round_status":0,"fansNum":548,"area_v2_id":"33","area_v2_name":"映评馆","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["SpaceX","Falcon","重型猎鹰","发射"]},{"name":"两仪滚","face":"https://i1.hdslb.com/bfs/face/4a91427ef035836b1937244bc559ed03f244bfa9.jpg","roomid":388,"areaName":"单机联机","live_status":0,"round_status":1,"fansNum":310591,"area_v2_id":"107","area_v2_name":"其他游戏","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["二五仔","猛男","B站恶霸","吃鸡"]},{"name":"污污_永远的魔法师_","face":"https://i0.hdslb.com/bfs/face/effbe54414657ed89b2a48fd822abeed90d67f67.jpg","roomid":255,"areaName":"绘画专区","live_status":0,"round_status":0,"fansNum":129145,"area_v2_id":"94","area_v2_name":"同人绘画","area_v2_parent_name":"绘画","area_v2_parent_id":"4","roomTags":["绘画","板绘"]},{"name":"Kano_Amigo乐队键盘手","face":"https://i1.hdslb.com/bfs/face/0e8dc590bcbcb986f7898d9eb77cdadbf061fc64.jpg","roomid":673794,"areaName":"御宅文化","live_status":0,"round_status":1,"fansNum":4266,"area_v2_id":"143","area_v2_name":"才艺","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":[]},{"name":"棉花大哥哥","face":"https://i2.hdslb.com/bfs/face/9fc16093743b2692a1a6d4dee19eede911e6712f.jpg","roomid":103,"areaName":"生活娱乐","live_status":0,"round_status":1,"fansNum":116498,"area_v2_id":"145","area_v2_name":"聊天室","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["王者荣耀","声控","颜控"]},{"name":"萌萌哒条码","face":"https://i1.hdslb.com/bfs/face/14b69433ef566f39a236991cbb0ff5ef95cc82f2.jpg","roomid":1325308,"areaName":"手游直播","live_status":0,"round_status":0,"fansNum":23679,"area_v2_id":"98","area_v2_name":"其他手游","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":["minecraft 我的世界","Hypixel 炉石传说","守望先锋 绝地求生","单机游戏 星际争霸"]},{"name":"某幻君","face":"https://i1.hdslb.com/bfs/face/9ed5ebf1e3694d9cd2b4fcd1d353759ee83b3dfe.jpg","roomid":271744,"areaName":"单机联机","live_status":0,"round_status":1,"fansNum":1521416,"area_v2_id":"107","area_v2_name":"其他游戏","area_v2_parent_name":"游戏","area_v2_parent_id":"2","roomTags":["绝地求生大逃杀"]},{"name":"池田天天","face":"https://i0.hdslb.com/bfs/face/fdb8593ca8a578f5aff6bb744fa1df6fa149d9f1.jpg","roomid":13924,"areaName":"唱见舞见","live_status":0,"round_status":1,"fansNum":48799,"area_v2_id":"21","area_v2_name":"唱见","area_v2_parent_name":"娱乐","area_v2_parent_id":"1","roomTags":["天天","少年音","唱歌"]},{"name":"我就是FISH","face":"https://i1.hdslb.com/bfs/face/a076329348d82164c3f54598ee90239c17817d21.jpg","roomid":4716742,"areaName":"手游直播","live_status":0,"round_status":0,"fansNum":8,"area_v2_id":"98","area_v2_name":"其他手游","area_v2_parent_name":"手游","area_v2_parent_id":"3","roomTags":[]}] + * total_page : 1 + */ + + @SerializedName("page") + private int page; + @SerializedName("pagesize") + private int pagesize; + @SerializedName("total_page") + private int totalPage; + @SerializedName("list") + private List rooms; + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getPagesize() { + return pagesize; + } + + public void setPagesize(int pagesize) { + this.pagesize = pagesize; + } + + public int getTotalPage() { + return totalPage; + } + + public void setTotalPage(int totalPage) { + this.totalPage = totalPage; + } + + public List getRooms() { + return rooms; + } + + public void setRooms(List rooms) { + this.rooms = rooms; + } + + public static class Room { + /** + * name : czp3009 + * face : https://i1.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg + * roomid : 1110317 + * areaName : 生活娱乐 + * live_status : 0 + * round_status : 0 + * fansNum : 44 + * area_v2_id : 27 + * area_v2_name : 学习 + * area_v2_parent_name : 娱乐 + * area_v2_parent_id : 1 + * roomTags : ["编程"] + */ + + @SerializedName("name") + private String name; + @SerializedName("face") + private String face; + @SerializedName("roomid") + private long roomid; + @SerializedName("areaName") + private String areaName; + @SerializedName("live_status") + private int liveStatus; + @SerializedName("round_status") + private int roundStatus; + @SerializedName("fansNum") + private long fansNum; + @SerializedName("area_v2_id") + private String areaV2Id; + @SerializedName("area_v2_name") + private String areaV2Name; + @SerializedName("area_v2_parent_name") + private String areaV2ParentName; + @SerializedName("area_v2_parent_id") + private String areaV2ParentId; + @SerializedName("roomTags") + private List roomTags; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getFace() { + return face; + } + + public void setFace(String face) { + this.face = face; + } + + public long getRoomid() { + return roomid; + } + + public void setRoomid(long roomid) { + this.roomid = roomid; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + public int getLiveStatus() { + return liveStatus; + } + + public void setLiveStatus(int liveStatus) { + this.liveStatus = liveStatus; + } + + public int getRoundStatus() { + return roundStatus; + } + + public void setRoundStatus(int roundStatus) { + this.roundStatus = roundStatus; + } + + public long getFansNum() { + return fansNum; + } + + public void setFansNum(long fansNum) { + this.fansNum = fansNum; + } + + public String getAreaV2Id() { + return areaV2Id; + } + + public void setAreaV2Id(String areaV2Id) { + this.areaV2Id = areaV2Id; + } + + public String getAreaV2Name() { + return areaV2Name; + } + + public void setAreaV2Name(String areaV2Name) { + this.areaV2Name = areaV2Name; + } + + public String getAreaV2ParentName() { + return areaV2ParentName; + } + + public void setAreaV2ParentName(String areaV2ParentName) { + this.areaV2ParentName = areaV2ParentName; + } + + public String getAreaV2ParentId() { + return areaV2ParentId; + } + + public void setAreaV2ParentId(String areaV2ParentId) { + this.areaV2ParentId = areaV2ParentId; + } + + public List getRoomTags() { + return roomTags; + } + + public void setRoomTags(List roomTags) { + this.roomTags = roomTags; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/MyMedalListEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/MyMedalListEntity.java new file mode 100644 index 0000000..82c51e4 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/MyMedalListEntity.java @@ -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 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; + } + + 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; + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/OpenCapsuleResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/OpenCapsuleResponseEntity.java new file mode 100644 index 0000000..e68fb77 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/OpenCapsuleResponseEntity.java @@ -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 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 getGifts() { + return gifts; + } + + public void setGifts(List 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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleEntity.java new file mode 100644 index 0000000..a36857b --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleEntity.java @@ -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 level; + @SerializedName("category") + private List category; + @SerializedName("pic") + private List 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 getLevel() { + return level; + } + + public void setLevel(List level) { + this.level = level; + } + + public List getCategory() { + return category; + } + + public void setCategory(List category) { + this.category = category; + } + + public List getPic() { + return pic; + } + + public void setPic(List 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; + } + } + } +} From 827eb9abb1d61a5d821896213a5f3fbdcfdfb60c Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 2 Mar 2018 14:30:19 +0800 Subject: [PATCH 14/73] =?UTF-8?q?UserInfoEntity=20=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BB=93=E6=9E=84=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/live/entity/UserInfoEntity.java | 170 +++++++++++++----- 1 file changed, 121 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/UserInfoEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/UserInfoEntity.java index a0b4d2a..94e5570 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/UserInfoEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/UserInfoEntity.java @@ -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") From 36848182f2df4900df538b62f6f72f33866df087 Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 2 Mar 2018 16:31:44 +0800 Subject: [PATCH 15/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 40 ++++++++++++++++++- .../com/hiczp/bilibili/api/BilibiliAPI.java | 2 +- .../api/{ => web}/cookie/SimpleCookieJar.java | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) rename src/main/java/com/hiczp/bilibili/api/{ => web}/cookie/SimpleCookieJar.java (97%) diff --git a/README.md b/README.md index 42aa4cc..56ff7d8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 由于B站即使更新客户端, 也会继续兼容以前的旧版本客户端, 所以短期内不用担心 API 失效的问题. -注意, 该项目使用 Bilibili Android 客户端协议, 与 Web 端的协议有差异, 不要提交 Web 端有关的 API. +对于一些 Bilibili Android APP 上没有的功能, 可以先[将 token 转换为 cookie](#SSO), 然后再去调用 Bilibili Web API. # API 不完全 由于本项目还在开发初期, 大量 API 没有完成, 所以很可能没有你想要的 API. @@ -333,5 +333,43 @@ room_id 的获取要通过 (B站所有 API 无论是否执行成功, HttpStatus 都是 200, 判断 HTTP 状态码是无用的, 必须通过 JSON 中的 code 字段来知道 API 是否执行成功). +# 继续开发 +如果您想加入到开发中, 欢迎提交 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 lists + +因此必须要为内层元素指定一个具有语义的名称, 例如 Name, 此时类型变为 + + List names + +API 尽可能按照 UI 位置来排序, 例如 + + 侧拉抽屉 -> 直播中心 -> 我的关注 + +这是 "直播中心" 页面的第一个可点击控件, 那么下一个 API 或 API 组就应该是第二个可点击组件 "观看历史". + +和 UI 不对应的 API, 按照执行顺序排序, 例如进入直播间会按顺序访问一系列 API, 这些 API 就按照时间顺序排序. + +对于不知道怎么排的 API, 瞎鸡巴排就好了. + # License GPL V3 diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 141c91b..22fc167 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -1,6 +1,5 @@ package com.hiczp.bilibili.api; -import com.hiczp.bilibili.api.cookie.SimpleCookieJar; import com.hiczp.bilibili.api.interceptor.*; import com.hiczp.bilibili.api.live.LiveService; import com.hiczp.bilibili.api.live.socket.LiveClient; @@ -15,6 +14,7 @@ import com.hiczp.bilibili.api.passport.exception.CaptchaMismatchException; import com.hiczp.bilibili.api.provider.BilibiliCaptchaProvider; import com.hiczp.bilibili.api.provider.BilibiliServiceProvider; import com.hiczp.bilibili.api.provider.BilibiliSsoProvider; +import com.hiczp.bilibili.api.web.cookie.SimpleCookieJar; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; import org.slf4j.Logger; diff --git a/src/main/java/com/hiczp/bilibili/api/cookie/SimpleCookieJar.java b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java similarity index 97% rename from src/main/java/com/hiczp/bilibili/api/cookie/SimpleCookieJar.java rename to src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java index 24998bf..af2bf80 100644 --- a/src/main/java/com/hiczp/bilibili/api/cookie/SimpleCookieJar.java +++ b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java @@ -1,4 +1,4 @@ -package com.hiczp.bilibili.api.cookie; +package com.hiczp.bilibili.api.web.cookie; import okhttp3.Cookie; import okhttp3.CookieJar; From a0e19cbb428622f086249f34ac43737ebd4b6fa9 Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 2 Mar 2018 17:44:40 +0800 Subject: [PATCH 16/73] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B8=80=E4=B8=AA=20We?= =?UTF-8?q?b=20API(=E5=8F=91=E9=80=81=E7=9B=B4=E6=92=AD=E9=97=B4=E5=BF=83?= =?UTF-8?q?=E8=B7=B3=E5=8C=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../com/hiczp/bilibili/api/BilibiliAPI.java | 17 +++- .../api/provider/BilibiliWebAPIProvider.java | 9 ++ .../{ => provider}/LiveClientProvider.java | 2 +- .../bilibili/api/web/BilibiliWebAPI.java | 74 +++++++++++++++ .../bilibili/api/web/BrowserProperties.java | 22 +++++ .../api/web/cookie/SimpleCookieJar.java | 7 ++ .../bilibili/api/web/live/LiveService.java | 18 ++++ .../entity/SendHeartBeatResponseEntity.java | 92 +++++++++++++++++++ 9 files changed, 237 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java rename src/main/java/com/hiczp/bilibili/api/{ => provider}/LiveClientProvider.java (77%) create mode 100644 src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java create mode 100644 src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java create mode 100644 src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java create mode 100644 src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java diff --git a/README.md b/README.md index 56ff7d8..050b5ae 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 由于B站即使更新客户端, 也会继续兼容以前的旧版本客户端, 所以短期内不用担心 API 失效的问题. -对于一些 Bilibili Android APP 上没有的功能, 可以先[将 token 转换为 cookie](#SSO), 然后再去调用 Bilibili Web API. +对于一些 Bilibili Android APP 上没有的功能, 可以先[将 token 转换为 cookie](#sso), 然后再去调用 Bilibili Web API. # API 不完全 由于本项目还在开发初期, 大量 API 没有完成, 所以很可能没有你想要的 API. diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 22fc167..1f721a7 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -11,9 +11,9 @@ 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 com.hiczp.bilibili.api.provider.BilibiliCaptchaProvider; -import com.hiczp.bilibili.api.provider.BilibiliServiceProvider; -import com.hiczp.bilibili.api.provider.BilibiliSsoProvider; +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 okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; @@ -33,7 +33,7 @@ import java.util.Date; import java.util.List; import java.util.Map; -public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProvider, BilibiliSsoProvider, 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(); //记录当前类被实例化的时间 @@ -250,6 +250,15 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv return simpleCookieJar.getCookiesMap(); } + @Override + public BilibiliWebAPI getBilibiliWebAPI() throws IOException { + return new BilibiliWebAPI(toCookies()); + } + + public BilibiliWebAPI getBilibiliWebAPI(BrowserProperties browserProperties) throws IOException { + return new BilibiliWebAPI(browserProperties, toCookies()); + } + public LoginResponseEntity login(@Nonnull String username, @Nonnull String password) throws IOException, LoginException, CaptchaMismatchException { return login(username, password, null, null); } diff --git a/src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java new file mode 100644 index 0000000..d4b33b1 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/provider/BilibiliWebAPIProvider.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.provider; + +import com.hiczp.bilibili.api.web.BilibiliWebAPI; + +import java.io.IOException; + +public interface BilibiliWebAPIProvider { + BilibiliWebAPI getBilibiliWebAPI() throws IOException; +} diff --git a/src/main/java/com/hiczp/bilibili/api/LiveClientProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java similarity index 77% rename from src/main/java/com/hiczp/bilibili/api/LiveClientProvider.java rename to src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java index d623873..b1935a0 100644 --- a/src/main/java/com/hiczp/bilibili/api/LiveClientProvider.java +++ b/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java @@ -1,4 +1,4 @@ -package com.hiczp.bilibili.api; +package com.hiczp.bilibili.api.provider; import com.hiczp.bilibili.api.live.socket.LiveClient; diff --git a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java new file mode 100644 index 0000000..d5a6f89 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java @@ -0,0 +1,74 @@ +package com.hiczp.bilibili.api.web; + +import com.hiczp.bilibili.api.BaseUrlDefinition; +import com.hiczp.bilibili.api.interceptor.AddFixedHeadersInterceptor; +import com.hiczp.bilibili.api.web.cookie.SimpleCookieJar; +import com.hiczp.bilibili.api.web.live.LiveService; +import okhttp3.Cookie; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class BilibiliWebAPI { + private final BrowserProperties browserProperties; + private final SimpleCookieJar simpleCookieJar; + + private LiveService liveService; + + public BilibiliWebAPI(BrowserProperties browserProperties, SimpleCookieJar simpleCookieJar) { + this.browserProperties = browserProperties; + this.simpleCookieJar = simpleCookieJar; + } + + public BilibiliWebAPI(SimpleCookieJar simpleCookieJar) { + this(BrowserProperties.defaultSetting(), simpleCookieJar); + } + + public BilibiliWebAPI(BrowserProperties browserProperties, Map> cookiesMap) { + this(browserProperties, new SimpleCookieJar(cookiesMap)); + } + + public BilibiliWebAPI(Map> cookiesMap) { + this(BrowserProperties.defaultSetting(), new SimpleCookieJar(cookiesMap)); + } + + public LiveService getLiveService() { + if (liveService == null) { + liveService = getLiveService(Collections.emptyList(), HttpLoggingInterceptor.Level.BASIC); + } + return liveService; + } + + public LiveService getLiveService(@Nonnull List interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) { + OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); + + okHttpClientBuilder + .cookieJar(simpleCookieJar) + .addInterceptor(new AddFixedHeadersInterceptor( + "User-Agent", browserProperties.getUserAgent() + )); + + interceptors.forEach(okHttpClientBuilder::addInterceptor); + + okHttpClientBuilder + .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(logLevel)); + + return new Retrofit.Builder() + .baseUrl(BaseUrlDefinition.LIVE) + .addConverterFactory(GsonConverterFactory.create()) + .client(okHttpClientBuilder.build()) + .build() + .create(LiveService.class); + } + + public SimpleCookieJar getSimpleCookieJar() { + return simpleCookieJar; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java b/src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java new file mode 100644 index 0000000..2705f98 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/BrowserProperties.java @@ -0,0 +1,22 @@ +package com.hiczp.bilibili.api.web; + +public class BrowserProperties { + private String userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"; + + private BrowserProperties() { + + } + + public static BrowserProperties defaultSetting() { + return new BrowserProperties(); + } + + public String getUserAgent() { + return userAgent; + } + + public BrowserProperties setUserAgent(String userAgent) { + this.userAgent = userAgent; + return this; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java index af2bf80..7c29070 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java +++ b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class SimpleCookieJar implements CookieJar { private Map> cookiesMap; @@ -61,6 +62,12 @@ public class SimpleCookieJar implements CookieJar { return cookieList; } + public String getCookiesStringForHost(String host) { + return getCookiesForHost(host).stream() + .map(cookie -> String.format("%s=%s", cookie.name(), cookie.value())) + .collect(Collectors.joining(";")); + } + public Map> getCookiesMap() { return cookiesMap; } diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java new file mode 100644 index 0000000..def0680 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java @@ -0,0 +1,18 @@ +package com.hiczp.bilibili.api.web.live; + +import com.hiczp.bilibili.api.web.live.entity.SendHeartBeatResponseEntity; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface LiveService { + //直播间心跳包 + //参数为时间戳(不是 unix 时间戳) + //未登录时返回 401 + @GET("feed/v1/feed/heartBeat") + Call sendHeartBeat(@Query("_") long timestamp); + + default Call sendHeartBeat() { + return sendHeartBeat(System.currentTimeMillis()); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java new file mode 100644 index 0000000..df95cde --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/live/entity/SendHeartBeatResponseEntity.java @@ -0,0 +1,92 @@ +package com.hiczp.bilibili.api.web.live.entity; + +import com.google.gson.annotations.SerializedName; + +public class SendHeartBeatResponseEntity { + /** + * code : 0 + * msg : success + * message : success + * data : {"open":1,"has_new":0,"count":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 { + /** + * open : 1 + * has_new : 0 + * count : 0 + */ + + @SerializedName("open") + private int open; + @SerializedName("has_new") + private int hasNew; + @SerializedName("count") + private int count; + + public int getOpen() { + return open; + } + + public void setOpen(int open) { + this.open = open; + } + + public int getHasNew() { + return hasNew; + } + + public void setHasNew(int hasNew) { + this.hasNew = hasNew; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + } +} From 21e106030d27000c894b9980b8c0f67a57094a7f Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 3 Mar 2018 01:26:59 +0800 Subject: [PATCH 17/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 37 ++++++++++++++++++- .../bilibili/api/web/BilibiliWebAPI.java | 16 ++++---- .../api/web/cookie/SimpleCookieJar.java | 6 +-- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 050b5ae..8a07eda 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ CaptchaMismatchException 在验证码不正确时抛出, 见下文 [验证码问 login 方法的返回值为 LoginResponseEntity 类型, 使用 - loginResponseEntity.toBilibiliAccount() + BilibiliAccount bilibiliAccount = loginResponseEntity.toBilibiliAccount(); 来获得一个 BilibiliAccount 实例, 其中包含了 OAuth2 的用户凭证, 如果有需要, 可以将其持久化保存. @@ -67,6 +67,10 @@ IOException 在网络故障时抛出 LoginException 在 token 错误,或者 refreshToken 错误或过期时抛出. +refreshToken 操作在正常情况下将在服务器返回 401(实际上 B站 不用 401 来表示未登录)时自动进行, 因此 BilibiliAPI 内部持有的 BilibiliAccount 的实例的内容可能会发生改变, 如果需要在应用关闭时持久化用户 token, 需要这样来取得最后的 BilibiliAccount 状态 + + BilibiliAccount bilibiliAccount = bilibiliAPI.getBilibiliAccount(); + ### 登出 bilibiliAPI.logout(); @@ -166,6 +170,37 @@ B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访 如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址). +### 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> 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 调用示例 打印一个直播间的历史弹幕 diff --git a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java index d5a6f89..b3b0cfc 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java @@ -18,17 +18,17 @@ import java.util.Map; public class BilibiliWebAPI { private final BrowserProperties browserProperties; - private final SimpleCookieJar simpleCookieJar; + private final SimpleCookieJar cookieJar; private LiveService liveService; - public BilibiliWebAPI(BrowserProperties browserProperties, SimpleCookieJar simpleCookieJar) { + public BilibiliWebAPI(BrowserProperties browserProperties, SimpleCookieJar cookieJar) { this.browserProperties = browserProperties; - this.simpleCookieJar = simpleCookieJar; + this.cookieJar = cookieJar; } - public BilibiliWebAPI(SimpleCookieJar simpleCookieJar) { - this(BrowserProperties.defaultSetting(), simpleCookieJar); + public BilibiliWebAPI(SimpleCookieJar cookieJar) { + this(BrowserProperties.defaultSetting(), cookieJar); } public BilibiliWebAPI(BrowserProperties browserProperties, Map> cookiesMap) { @@ -50,7 +50,7 @@ public class BilibiliWebAPI { OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); okHttpClientBuilder - .cookieJar(simpleCookieJar) + .cookieJar(cookieJar) .addInterceptor(new AddFixedHeadersInterceptor( "User-Agent", browserProperties.getUserAgent() )); @@ -68,7 +68,7 @@ public class BilibiliWebAPI { .create(LiveService.class); } - public SimpleCookieJar getSimpleCookieJar() { - return simpleCookieJar; + public SimpleCookieJar getCookieJar() { + return cookieJar; } } diff --git a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java index 7c29070..c655da3 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java +++ b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java @@ -5,20 +5,20 @@ import okhttp3.CookieJar; import okhttp3.HttpUrl; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; public class SimpleCookieJar implements CookieJar { private Map> cookiesMap; public SimpleCookieJar() { - cookiesMap = new HashMap<>(); + cookiesMap = new ConcurrentHashMap<>(); } public SimpleCookieJar(Map> cookiesMap) { - this.cookiesMap = new HashMap<>(cookiesMap); + this.cookiesMap = new ConcurrentHashMap<>(cookiesMap); } @Override From a182d56fc669d3012c7f1a03ad8864b7384e0682 Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 3 Mar 2018 03:09:34 +0800 Subject: [PATCH 18/73] =?UTF-8?q?=E4=BD=BF=20SimpleCookieJar=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=B9=B6=E5=8F=91=E8=AF=BB=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ErrorResponseConverterInterceptor.java | 9 +- .../bilibili/api/web/BilibiliWebAPI.java | 4 +- .../api/web/cookie/SimpleCookieJar.java | 46 +++-- .../bilibili/api/web/live/LiveService.java | 11 + .../api/web/live/entity/UserInfoEntity.java | 191 ++++++++++++++++++ .../hiczp/bilibili/api/test/RuleSuite.java | 1 + .../hiczp/bilibili/api/test/WebAPITest.java | 33 +++ 7 files changed, 274 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/web/live/entity/UserInfoEntity.java create mode 100644 src/test/java/com/hiczp/bilibili/api/test/WebAPITest.java diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java index 4cdb1e0..c0cf386 100644 --- a/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java @@ -24,13 +24,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() diff --git a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java index b3b0cfc..938fcf4 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java @@ -2,6 +2,7 @@ package com.hiczp.bilibili.api.web; import com.hiczp.bilibili.api.BaseUrlDefinition; import com.hiczp.bilibili.api.interceptor.AddFixedHeadersInterceptor; +import com.hiczp.bilibili.api.interceptor.ErrorResponseConverterInterceptor; import com.hiczp.bilibili.api.web.cookie.SimpleCookieJar; import com.hiczp.bilibili.api.web.live.LiveService; import okhttp3.Cookie; @@ -53,7 +54,8 @@ public class BilibiliWebAPI { .cookieJar(cookieJar) .addInterceptor(new AddFixedHeadersInterceptor( "User-Agent", browserProperties.getUserAgent() - )); + )) + .addInterceptor(new ErrorResponseConverterInterceptor()); interceptors.forEach(okHttpClientBuilder::addInterceptor); diff --git a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java index c655da3..0ad96f6 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java +++ b/src/main/java/com/hiczp/bilibili/api/web/cookie/SimpleCookieJar.java @@ -4,41 +4,49 @@ import okhttp3.Cookie; import okhttp3.CookieJar; import okhttp3.HttpUrl; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; public class SimpleCookieJar implements CookieJar { - private Map> cookiesMap; + private final Map> cookiesMap; public SimpleCookieJar() { cookiesMap = new ConcurrentHashMap<>(); } - public SimpleCookieJar(Map> cookiesMap) { - this.cookiesMap = new ConcurrentHashMap<>(cookiesMap); + public SimpleCookieJar(@Nonnull Map> cookiesMap) { + this(); + cookiesMap.forEach((domain, cookies) -> + this.cookiesMap.put(domain, new Vector<>(cookies)) + ); } @Override public void saveFromResponse(HttpUrl url, List cookies) { cookies.forEach(cookie -> { String domain = cookie.domain(); - List savedCookies = cookiesMap.get(domain); - if (savedCookies == null) { - savedCookies = new ArrayList<>(); - savedCookies.add(cookie); - cookiesMap.put(domain, savedCookies); - } else { - for (Cookie savedCookie : savedCookies) { - if (savedCookie.name().equals(cookie.name())) { - savedCookies.remove(savedCookie); - break; - } + List savedCookies; + synchronized (cookiesMap) { + savedCookies = cookiesMap.get(domain); + if (savedCookies == null) { + savedCookies = new Vector<>(); + savedCookies.add(cookie); + cookiesMap.put(domain, savedCookies); + return; } - savedCookies.add(cookie); } + for (int i = savedCookies.size() - 1; i >= 0; i--) { + Cookie current = savedCookies.get(i); + if (current.name().equals(cookie.name())) { + savedCookies.remove(current); + } + } + savedCookies.add(cookie); }); } @@ -47,13 +55,15 @@ public class SimpleCookieJar implements CookieJar { return getCookiesForHost(url.host()); } - public List getCookiesForHost(String host) { + public List getCookiesForHost(@Nonnull String host) { List cookieList = new ArrayList<>(); cookiesMap.forEach((domain, cookies) -> { if (host.endsWith(domain)) { + //移除过期的 cookies for (int i = cookies.size() - 1; i >= 0; i--) { - if (cookies.get(i).expiresAt() < System.currentTimeMillis()) { - cookies.remove(i); + Cookie current = cookies.get(i); + if (current.expiresAt() < System.currentTimeMillis()) { + cookies.remove(current); } } cookieList.addAll(cookies); diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java index def0680..23b620e 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java @@ -1,6 +1,7 @@ package com.hiczp.bilibili.api.web.live; import com.hiczp.bilibili.api.web.live.entity.SendHeartBeatResponseEntity; +import com.hiczp.bilibili.api.web.live.entity.UserInfoEntity; import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Query; @@ -15,4 +16,14 @@ public interface LiveService { default Call sendHeartBeat() { return sendHeartBeat(System.currentTimeMillis()); } + + //获取用户信息 + //成功时, code 为 "REPONSE_OK" + //未登录时返回 500 + @GET("User/getUserInfo") + Call getUserInfo(@Query("ts") long timestamp); + + default Call getUserInfo() { + return getUserInfo(System.currentTimeMillis()); + } } diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/entity/UserInfoEntity.java b/src/main/java/com/hiczp/bilibili/api/web/live/entity/UserInfoEntity.java new file mode 100644 index 0000000..9153de4 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/web/live/entity/UserInfoEntity.java @@ -0,0 +1,191 @@ +package com.hiczp.bilibili.api.web.live.entity; + +import com.google.gson.annotations.SerializedName; + +public class UserInfoEntity { + /** + * code : REPONSE_OK + * msg : ok + * data : {"uname":"czp3009","face":"http://i2.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg","silver":22528,"gold":0,"achieve":135,"vip":0,"svip":0,"user_level":25,"user_next_level":26,"user_intimacy":926000,"user_next_intimacy":10000000,"user_level_rank":">50000","billCoin":699} + */ + + @SerializedName("code") + private String code; + @SerializedName("msg") + private String msg; + @SerializedName("data") + private Data data; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + 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 { + /** + * uname : czp3009 + * face : http://i2.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg + * silver : 22528 + * gold : 0 + * achieve : 135 + * vip : 0 + * svip : 0 + * user_level : 25 + * user_next_level : 26 + * user_intimacy : 926000 + * user_next_intimacy : 10000000 + * user_level_rank : >50000 + * billCoin : 699 + */ + + @SerializedName("uname") + private String uname; + @SerializedName("face") + private String face; + @SerializedName("silver") + private int silver; + @SerializedName("gold") + private int gold; + @SerializedName("achieve") + private int achieve; + @SerializedName("vip") + private int vip; + @SerializedName("svip") + private int svip; + @SerializedName("user_level") + private int userLevel; + @SerializedName("user_next_level") + private int userNextLevel; + @SerializedName("user_intimacy") + private int userIntimacy; + @SerializedName("user_next_intimacy") + private int userNextIntimacy; + @SerializedName("user_level_rank") + private String userLevelRank; + @SerializedName("billCoin") + private int billCoin; + + 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 int getSilver() { + return silver; + } + + public void setSilver(int silver) { + this.silver = silver; + } + + public int getGold() { + return gold; + } + + public void setGold(int gold) { + this.gold = gold; + } + + public int getAchieve() { + return achieve; + } + + public void setAchieve(int achieve) { + this.achieve = achieve; + } + + public int getVip() { + return vip; + } + + public void setVip(int vip) { + this.vip = vip; + } + + public int getSvip() { + return svip; + } + + public void setSvip(int svip) { + this.svip = svip; + } + + public int getUserLevel() { + return userLevel; + } + + public void setUserLevel(int userLevel) { + this.userLevel = userLevel; + } + + public int getUserNextLevel() { + return userNextLevel; + } + + public void setUserNextLevel(int userNextLevel) { + this.userNextLevel = userNextLevel; + } + + public int getUserIntimacy() { + return userIntimacy; + } + + public void setUserIntimacy(int userIntimacy) { + this.userIntimacy = userIntimacy; + } + + public int getUserNextIntimacy() { + return userNextIntimacy; + } + + public void setUserNextIntimacy(int userNextIntimacy) { + this.userNextIntimacy = userNextIntimacy; + } + + public String getUserLevelRank() { + return userLevelRank; + } + + public void setUserLevelRank(String userLevelRank) { + this.userLevelRank = userLevelRank; + } + + public int getBillCoin() { + return billCoin; + } + + public void setBillCoin(int billCoin) { + this.billCoin = billCoin; + } + } +} diff --git a/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java b/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java index 26aab17..0e63997 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java +++ b/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java @@ -22,6 +22,7 @@ import java.nio.file.Paths; SendBulletScreenTest.class, SecurityHelperTest.class, AuthenticatorTest.class, + WebAPITest.class, LogoutTest.class }) public class RuleSuite { diff --git a/src/test/java/com/hiczp/bilibili/api/test/WebAPITest.java b/src/test/java/com/hiczp/bilibili/api/test/WebAPITest.java new file mode 100644 index 0000000..a9e8803 --- /dev/null +++ b/src/test/java/com/hiczp/bilibili/api/test/WebAPITest.java @@ -0,0 +1,33 @@ +package com.hiczp.bilibili.api.test; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.hiczp.bilibili.api.web.BilibiliWebAPI; +import com.hiczp.bilibili.api.web.live.entity.UserInfoEntity; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class WebAPITest { + private static final Logger LOGGER = LoggerFactory.getLogger(WebAPITest.class); + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + private BilibiliWebAPI bilibiliWebAPI; + + public WebAPITest() { + try { + this.bilibiliWebAPI = Config.getBilibiliAPI().getBilibiliWebAPI(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Test + public void getUserInfo() throws IOException { + UserInfoEntity userInfoEntity = bilibiliWebAPI.getLiveService().getUserInfo() + .execute() + .body(); + LOGGER.info("User info below: \n{}", GSON.toJson(userInfoEntity)); + } +} From c6521704c2804454bba92cb71f9e1809180c1d45 Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 3 Mar 2018 03:12:41 +0800 Subject: [PATCH 19/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a07eda..75146d7 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ # 添加依赖 ## Gradle - compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.5' + compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.6' # 名词解释 B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一些常见参数对应的含义 From 286628e848376b912c5b17a24de0750bb4674e77 Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 3 Mar 2018 14:12:12 +0800 Subject: [PATCH 20/73] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 75146d7..c5cb342 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ LoginException 在 accessToken 错误或过期时抛出 这个带验证码的登录接口也会继续抛出 CaptchaMismatchException, 如果验证码输入错误的话. ### SSO -通过 SSO API 可以将 accessToken 转为 cookie, 用 cookie 就可以访问 B站的 Web API. +通过 SSO API 可以将 accessToken 转为 cookie, 用 cookie 就可以访问B站的 Web API. B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访问页面时, 处于登录状态). @@ -160,15 +160,15 @@ B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访 如果只想得到用于进行 SSO 操作的那条 URL, 可以这么做 final String goUrl = "https://account.bilibili.com/account/home"; - bilibiliAPI.getSsoUrl(); +    bilibiliAPI.getSsoUrl(goUrl); 返回值是一个 HttpUrl, 里面 url 的值差不多是这样的 - https://passport.bilibili.com/api/login/sso?access_key=13c346c203de77dfac8b67b169f3029b&appkey=1d8b6e7d45233436&build=515000&mobi_app=android&platform=android&ts=1519895404&sign=ee05f96c636e7745c38918fe343469ee +    https://passport.bilibili.com/api/login/sso?access_key=13c346c203de77dfac8b67b169f3029b&appkey=1d8b6e7d45233436&build=515000&gourl=xxx&mobi_app=android&platform=android&ts=1519895404&sign=ee05f96c636e7745c38918fe343469ee 如果 access_key 是正确的话, 这个 url 访问一下就登录 B站 了. -如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址). +如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址, 如果 goUrl 不存在或为空则将跳转到B站首页). ### Web API 上文讲到, 通过 SSO API, 可以将 token 转为 cookie, 在本项目中, Web API 封装在 BilibiliWebAPI 中, 可以通过如下方式得到一个已经登录了的 BilibiliWebAPI 实例 From f77513f3e3b92a31418b5d746a7f40fb3dcabe5e Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 3 Mar 2018 20:08:03 +0800 Subject: [PATCH 21/73] Revert "Update README.md" This reverts commit 286628e --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c5cb342..75146d7 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ LoginException 在 accessToken 错误或过期时抛出 这个带验证码的登录接口也会继续抛出 CaptchaMismatchException, 如果验证码输入错误的话. ### SSO -通过 SSO API 可以将 accessToken 转为 cookie, 用 cookie 就可以访问B站的 Web API. +通过 SSO API 可以将 accessToken 转为 cookie, 用 cookie 就可以访问 B站的 Web API. B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访问页面时, 处于登录状态). @@ -160,15 +160,15 @@ B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访 如果只想得到用于进行 SSO 操作的那条 URL, 可以这么做 final String goUrl = "https://account.bilibili.com/account/home"; -    bilibiliAPI.getSsoUrl(goUrl); + bilibiliAPI.getSsoUrl(); 返回值是一个 HttpUrl, 里面 url 的值差不多是这样的 -    https://passport.bilibili.com/api/login/sso?access_key=13c346c203de77dfac8b67b169f3029b&appkey=1d8b6e7d45233436&build=515000&gourl=xxx&mobi_app=android&platform=android&ts=1519895404&sign=ee05f96c636e7745c38918fe343469ee + https://passport.bilibili.com/api/login/sso?access_key=13c346c203de77dfac8b67b169f3029b&appkey=1d8b6e7d45233436&build=515000&mobi_app=android&platform=android&ts=1519895404&sign=ee05f96c636e7745c38918fe343469ee 如果 access_key 是正确的话, 这个 url 访问一下就登录 B站 了. -如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址, 如果 goUrl 不存在或为空则将跳转到B站首页). +如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址). ### Web API 上文讲到, 通过 SSO API, 可以将 token 转为 cookie, 在本项目中, Web API 封装在 BilibiliWebAPI 中, 可以通过如下方式得到一个已经登录了的 BilibiliWebAPI 实例 From 43c152d8eb2ad9de7082b6cee0a2d5ae8c19d21a Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 3 Mar 2018 20:36:03 +0800 Subject: [PATCH 22/73] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20BilibiliAPI.getSsoUr?= =?UTF-8?q?l=20=E6=97=A0=E6=B3=95=E6=AD=A3=E5=B8=B8=E8=A3=85=E5=A1=AB?= =?UTF-8?q?=E5=8F=82=E6=95=B0=20gourl=20=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java | 3 ++- .../java/com/hiczp/bilibili/api/passport/SsoService.java | 1 + src/test/java/com/hiczp/bilibili/api/test/SsoTest.java | 7 ++++++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 75146d7..4bb1a43 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ LoginException 在 accessToken 错误或过期时抛出 这个带验证码的登录接口也会继续抛出 CaptchaMismatchException, 如果验证码输入错误的话. ### SSO -通过 SSO API 可以将 accessToken 转为 cookie, 用 cookie 就可以访问 B站的 Web API. +通过 SSO API 可以将 accessToken 转为 cookie, 用 cookie 就可以访问 B站 的 Web API. B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访问页面时, 处于登录状态). @@ -160,15 +160,15 @@ B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访 如果只想得到用于进行 SSO 操作的那条 URL, 可以这么做 final String goUrl = "https://account.bilibili.com/account/home"; - bilibiliAPI.getSsoUrl(); + bilibiliAPI.getSsoUrl(goUrl); 返回值是一个 HttpUrl, 里面 url 的值差不多是这样的 - https://passport.bilibili.com/api/login/sso?access_key=13c346c203de77dfac8b67b169f3029b&appkey=1d8b6e7d45233436&build=515000&mobi_app=android&platform=android&ts=1519895404&sign=ee05f96c636e7745c38918fe343469ee + 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 重定向完成后将进入这个地址). +如果想跟 B站 客户端一样弄一个什么内嵌 WebView 的话, 这个 API 就可以派上用场(只需要在 WebView 初始化完毕后让 WebView 去访问这个 url, 就登陆了)(goUrl 可以是任意值, 全部的 302 重定向完成后将进入这个地址, 如果 goUrl 不存在或为空则将跳转到B站首页). ### Web API 上文讲到, 通过 SSO API, 可以将 token 转为 cookie, 在本项目中, Web API 封装在 BilibiliWebAPI 中, 可以通过如下方式得到一个已经登录了的 BilibiliWebAPI 实例 diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 1f721a7..e25256d 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -231,7 +231,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv CancelRequestInterceptor cancelRequestInterceptor = new CancelRequestInterceptor(); try { getSsoService(new SimpleCookieJar(), Collections.singletonList(cancelRequestInterceptor), HttpLoggingInterceptor.Level.BASIC) - .sso(null) + .sso(goUrl) .execute(); } catch (IOException ignored) { @@ -241,6 +241,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv @Override public Map> toCookies() throws IOException { + //用这个地址是因为这个地址一定不会改变(在 B站 未来的更新中)并且很省流量 return toCookies(BaseUrlDefinition.PASSPORT + "api/oauth2/getKey"); } diff --git a/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java index 51990d9..0b46ff7 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java @@ -9,6 +9,7 @@ import javax.annotation.Nullable; //sso 很特别, 它可能返回的是一个 HTML 页面, 所以单独分出来 //sso 会经过两次 302 跳转, 需要保存其中的 cookie, 然后才能抵达最终页面并且进入 cookie 登录状态 +//如果 gourl 为 null, 则会跳转到 B站 首页 public interface SsoService { @GET("api/login/sso") Call sso(@Nullable @Query("gourl") String goUrl); diff --git a/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java b/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java index f2ce613..bd3007a 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/SsoTest.java @@ -14,7 +14,12 @@ public class SsoTest { private static final BilibiliAPI BILIBILI_API = Config.getBilibiliAPI(); @Test - public void test() throws Exception { + public void getSsoUrlTest() { + LOGGER.info("SSO Url: {}", BILIBILI_API.getSsoUrl("https://account.bilibili.com/account/home")); + } + + @Test + public void toCookiesTest() throws Exception { Map> cookiesMap = BILIBILI_API.toCookies(); StringBuilder stringBuilder = new StringBuilder(); cookiesMap.forEach((domain, cookies) -> { From 7d4853e2c5498759dd606e2bd8bfc4243748da8b Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 5 Mar 2018 09:21:16 +0800 Subject: [PATCH 23/73] =?UTF-8?q?=E4=BD=BF=20BilibiliWebAPI=20=E6=8C=81?= =?UTF-8?q?=E6=9C=89=E7=9A=84=20CookieJar=20=E6=98=AF=E4=BC=A0=E5=85=A5?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E6=8B=B7=E8=B4=9D=E8=80=8C=E9=9D=9E=E5=BC=95?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/web/BilibiliWebAPI.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java index 938fcf4..1e744b1 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/web/BilibiliWebAPI.java @@ -23,21 +23,21 @@ public class BilibiliWebAPI { private LiveService liveService; - public BilibiliWebAPI(BrowserProperties browserProperties, SimpleCookieJar cookieJar) { + public BilibiliWebAPI(BrowserProperties browserProperties, Map> cookiesMap) { this.browserProperties = browserProperties; - this.cookieJar = cookieJar; + this.cookieJar = new SimpleCookieJar(cookiesMap); } public BilibiliWebAPI(SimpleCookieJar cookieJar) { - this(BrowserProperties.defaultSetting(), cookieJar); - } - - public BilibiliWebAPI(BrowserProperties browserProperties, Map> cookiesMap) { - this(browserProperties, new SimpleCookieJar(cookiesMap)); + this(BrowserProperties.defaultSetting(), cookieJar.getCookiesMap()); } public BilibiliWebAPI(Map> cookiesMap) { - this(BrowserProperties.defaultSetting(), new SimpleCookieJar(cookiesMap)); + this(BrowserProperties.defaultSetting(), cookiesMap); + } + + public BilibiliWebAPI(BrowserProperties browserProperties, SimpleCookieJar cookieJar) { + this(browserProperties, cookieJar.getCookiesMap()); } public LiveService getLiveService() { From 66abefd0a95851fbf21d7876659985ab3a6d19c7 Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 5 Mar 2018 10:44:32 +0800 Subject: [PATCH 24/73] =?UTF-8?q?=E8=B0=83=E6=95=B4=20RSA=20=E5=8A=A0?= =?UTF-8?q?=E5=AF=86=E7=9A=84=E5=86=99=E6=B3=95=E4=BB=A5=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=20Android?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- .../java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 19ab67e..6380e55 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group = 'com.hiczp' -version = '0.0.6' +version = '0.0.7' description = 'Bilibili android client API library written in Java' apply plugin: 'idea' diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java b/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java index b8f0cc6..ca89c96 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java @@ -47,7 +47,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( From 66187c427a6ac9934779645934631bd63a6a7683 Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 5 Mar 2018 10:45:26 +0800 Subject: [PATCH 25/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bb1a43..8e925ba 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ # 添加依赖 ## Gradle - compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.6' + compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.7' # 名词解释 B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一些常见参数对应的含义 From abf256876cf959fd20a6df676596af39121f859a Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 5 Mar 2018 23:53:59 +0800 Subject: [PATCH 26/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20live=20=E6=9C=89?= =?UTF-8?q?=E5=85=B3=20API=20AppExchange/silver2coin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- .../hiczp/bilibili/api/ServerErrorCode.java | 2 + .../hiczp/bilibili/api/live/LiveService.java | 11 +- .../entity/Silver2CoinResponseEntity.java | 103 ++++++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/Silver2CoinResponseEntity.java diff --git a/build.gradle b/build.gradle index 6380e55..c6c37e4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group = 'com.hiczp' -version = '0.0.7' +version = '0.0.8' description = 'Bilibili android client API library written in Java' apply plugin: 'idea' diff --git a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java index 2445a46..be89649 100644 --- a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java +++ b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java @@ -38,6 +38,8 @@ public class ServerErrorCode { public static final int USER_NO_LOGIN = 3; //"请登录" public static final int PLEASE_LOGIN = 401; + //"每天最多能兑换 1 个" + public static final int FORBIDDEN = 403; //"请登录" public static final int PLEASE_LOGIN0 = 32205; //"请先登录" diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 057ca49..f60b4be 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -214,12 +214,21 @@ public interface LiveService { //是的, 你没看错, 是 GET 方式 @GET("AppUser/wearTitle") Call wearTitle(@Query("title") String title); + //TODO 取消佩戴 //TODO 获奖记录 - //TODO 瓜子商店 + //瓜子商店 //侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币 //将 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次 + //actionKey 是固定值, 为 "appkey" + //已经兑换过时返回 403 + @POST("AppExchange/silver2coin") + Call silver2Coin(@Query("actionKey") String actionKey); + + default Call silver2Coin() { + return silver2Coin("appkey"); + } //扭蛋机 //侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/Silver2CoinResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/Silver2CoinResponseEntity.java new file mode 100644 index 0000000..9b6260c --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/Silver2CoinResponseEntity.java @@ -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; + } + } +} From 4d2ae98561eed049c8f14dbca2f7ad090dfe5bfc Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 6 Mar 2018 00:05:57 +0800 Subject: [PATCH 27/73] =?UTF-8?q?UA=20=E4=B8=AD=E7=9A=84=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E8=B7=9F=E9=9A=8F=20ClientProperties?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/hiczp/bilibili/api/BilibiliAPI.java | 2 +- .../bilibili/api/BilibiliClientProperties.java | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index e25256d..f5bc25e 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -120,7 +120,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv 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( diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliClientProperties.java b/src/main/java/com/hiczp/bilibili/api/BilibiliClientProperties.java index 981dbab..54eb164 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliClientProperties.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliClientProperties.java @@ -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; } From 72ea245c7f06c861406eea5f8ab682f092d5afbb Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 7 Mar 2018 09:31:44 +0800 Subject: [PATCH 28/73] =?UTF-8?q?BilibiliAPI=20=E7=8E=B0=E5=9C=A8=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E8=87=AA=E5=AE=9A=E4=B9=89=E6=98=AF=E5=90=A6=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=B7=E6=96=B0=20Token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hiczp/bilibili/api/BilibiliAPI.java | 14 ++- ....java => AutoRefreshTokenInterceptor.java} | 12 +- .../hiczp/bilibili/api/live/LiveService.java | 11 +- .../api/live/entity/AppSmallTVEntity.java | 119 +++++++++++++++--- .../api/live/entity/BulletScreenEntity.java | 3 +- 5 files changed, 136 insertions(+), 23 deletions(-) rename src/main/java/com/hiczp/bilibili/api/interceptor/{RefreshTokenInterceptor.java => AutoRefreshTokenInterceptor.java} (80%) diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index f5bc25e..1d647d1 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -40,6 +40,8 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv private final BilibiliClientProperties bilibiliClientProperties; private final BilibiliAccount bilibiliAccount; + private Boolean autoRefreshToken = true; + //用于阻止进行多次错误的 refreshToken 操作 private String invalidToken; private String invalidRefreshToken; @@ -142,8 +144,9 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv () -> "trace_id", () -> new SimpleDateFormat("yyyyMMddHHmm000ss").format(new Date()) )) .addInterceptor(new AddAppKeyInterceptor(bilibiliClientProperties)) - .addInterceptor(new RefreshTokenInterceptor( + .addInterceptor(new AutoRefreshTokenInterceptor( this, + autoRefreshToken, ServerErrorCode.Common.UNAUTHORIZED, ServerErrorCode.Live.USER_NO_LOGIN, ServerErrorCode.Live.PLEASE_LOGIN, @@ -401,4 +404,13 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv public BilibiliAccount getBilibiliAccount() { return bilibiliAccount; } + + public boolean isAutoRefreshToken() { + return autoRefreshToken; + } + + public BilibiliAPI setAutoRefreshToken(boolean autoRefreshToken) { + this.autoRefreshToken = autoRefreshToken; + return this; + } } diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/RefreshTokenInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java similarity index 80% rename from src/main/java/com/hiczp/bilibili/api/interceptor/RefreshTokenInterceptor.java rename to src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java index e30db62..87df1d3 100644 --- a/src/main/java/com/hiczp/bilibili/api/interceptor/RefreshTokenInterceptor.java +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java @@ -13,14 +13,16 @@ import java.io.IOException; import java.util.stream.IntStream; //自动刷新 token -public class RefreshTokenInterceptor implements Interceptor { - private static final Logger LOGGER = LoggerFactory.getLogger(RefreshTokenInterceptor.class); +public class AutoRefreshTokenInterceptor implements Interceptor { + private static final Logger LOGGER = LoggerFactory.getLogger(AutoRefreshTokenInterceptor.class); private BilibiliAPI bilibiliAPI; + private Boolean autoRefreshToken; private int[] codes; - public RefreshTokenInterceptor(BilibiliAPI bilibiliAPI, int... codes) { + public AutoRefreshTokenInterceptor(BilibiliAPI bilibiliAPI, Boolean autoRefreshToken, int... codes) { this.bilibiliAPI = bilibiliAPI; + this.autoRefreshToken = autoRefreshToken; this.codes = codes; } @@ -28,6 +30,10 @@ public class RefreshTokenInterceptor implements Interceptor { public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); + if (!autoRefreshToken) { + return response; + } + JsonObject jsonObject = InterceptorHelper.getJsonInBody(response); JsonElement codeElement = jsonObject.get("code"); if (codeElement == null) { diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index f60b4be..24b4c59 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -32,7 +32,7 @@ public interface LiveService { @POST("feed/v1/feed/isFollowed") Call isFollowed(@Query("follow") long hostUserId); - //该 API 意义不明 + //该 API 意义不明(似乎跟什么 每日背包任务 有关) @GET("AppBag/sendDaily") Call sendDaily(); @@ -40,16 +40,19 @@ public interface LiveService { @GET("AppIndex/getAllItem") Call getAllItem(); - //该 API 的返回值意义不明确, 所有房间似乎都一样, 且返回的 code 为 -400 + //查看可用的小电视抽奖 + //当目标房间没有可用的小电视抽奖时返回 -400 @GET("AppSmallTV/index") - Call getAppSmallTV(); + Call getAppSmallTV(@Query("roomid") long roomId); + //TODO 参与抽奖 + //TODO 查看抽奖结果 //获得所有头衔的列表 //这里的 Title 是头衔的意思 @GET("appUser/getTitle") Call getTitle(); - //这个 API 不是很明确, 所有房间都一样, 可能和什么活动有关 + //这个 API 不是很明确, 似乎和 节奏风暴 有关系 @GET("SpecialGift/room/{roomId}") Call getSpecialGift(@Path("roomId") long roomId); diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java index 004ccaa..dad6391 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java @@ -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 int lastid; + @SerializedName("join") + private List join; + @SerializedName("unjoin") + private List unjoin; - public int getStatus() { - return status; + public int getLastid() { + return lastid; } - public void setStatus(int status) { - this.status = status; + public void setLastid(int lastid) { + this.lastid = lastid; + } + + public List getJoin() { + return join; + } + + public void setJoin(List join) { + this.join = join; + } + + public List getUnjoin() { + return unjoin; + } + + public void setUnjoin(List unjoin) { + this.unjoin = unjoin; + } + + public static class Join { + /** + * id : 39674 + * dtime : 32 + */ + + @SerializedName("id") + private int id; + @SerializedName("dtime") + private int dtime; + + public int getId() { + return id; + } + + public void setId(int 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 int id; + @SerializedName("dtime") + private int dtime; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getDtime() { + return dtime; + } + + public void setDtime(int dtime) { + this.dtime = dtime; + } } } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java index b20d267..636441f 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java @@ -7,7 +7,8 @@ public class BulletScreenEntity { private long mid; - //弹幕长度限制为 LiveRoomInfoEntity.getData().getMsgLength(), 但是实际上所有房间的弹幕长度限制都是 20 + //弹幕长度限制为 LiveRoomInfoEntity.getData().getMsgLength(), 对于每个用户而言, 每个房间都一样 + //通过完成 B站 有关任务, 获得成就, 可以加大这个限制(舰长, 老爷等可以直接加大限制), 最长好像是 40 个字 @SerializedName("msg") private String message; From ee3460bb95b176418007f67ca04baf6010cff5a9 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 7 Mar 2018 10:14:33 +0800 Subject: [PATCH 29/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=20=E8=8E=B7?= =?UTF-8?q?=E5=A5=96=E8=AE=B0=E5=BD=95=20=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PrintResponseBodyInterceptor.java | 26 ++++++ .../hiczp/bilibili/api/live/LiveService.java | 2 + .../api/live/entity/AwardsEntity.java | 84 +++++++++++++++++++ .../bilibili/api/test/GetAwardsTest.java | 21 +++++ .../hiczp/bilibili/api/test/RuleSuite.java | 1 + 5 files changed, 134 insertions(+) create mode 100644 src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java create mode 100644 src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java new file mode 100644 index 0000000..648e2cb --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java @@ -0,0 +1,26 @@ +package com.hiczp.bilibili.api.interceptor; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import okhttp3.Interceptor; +import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class PrintResponseBodyInterceptor implements Interceptor { + private static final Logger LOGGER = LoggerFactory.getLogger(PrintResponseBodyInterceptor.class); + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + @Override + public Response intercept(Chain chain) throws IOException { + Response response = chain.proceed(chain.request()); + + JsonObject jsonObject = InterceptorHelper.getJsonInBody(response); + LOGGER.info(GSON.toJson(jsonObject)); + + return response; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 24b4c59..b75b7a0 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -220,6 +220,8 @@ public interface LiveService { //TODO 取消佩戴 //TODO 获奖记录 + @GET("AppUser/awards") + Call getAwards(); //瓜子商店 //侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币 diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java new file mode 100644 index 0000000..7e81926 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java @@ -0,0 +1,84 @@ +package com.hiczp.bilibili.api.live.entity; + +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class AwardsEntity { + /** + * code : 0 + * message : OK + * data : {"list":[],"use_count":0,"count":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 { + /** + * list : [] + * use_count : 0 + * count : 0 + */ + + @SerializedName("use_count") + private int useCount; + @SerializedName("count") + private int count; + @SerializedName("list") + private List list; + + 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 getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + } +} diff --git a/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java b/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java new file mode 100644 index 0000000..ba09358 --- /dev/null +++ b/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java @@ -0,0 +1,21 @@ +package com.hiczp.bilibili.api.test; + +import com.hiczp.bilibili.api.BilibiliAPI; +import com.hiczp.bilibili.api.interceptor.PrintResponseBodyInterceptor; +import okhttp3.logging.HttpLoggingInterceptor; +import org.junit.Test; + +import java.util.Collections; + +public class GetAwardsTest { + private static final BilibiliAPI BILIBILI_API = Config.getBilibiliAPI(); + + @Test + public void getAwards() throws Exception { + BILIBILI_API + .getLiveService(Collections.singletonList(new PrintResponseBodyInterceptor()), HttpLoggingInterceptor.Level.BODY) + .getAwards() + .execute() + .body(); + } +} diff --git a/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java b/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java index 0e63997..d36f1bd 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java +++ b/src/test/java/com/hiczp/bilibili/api/test/RuleSuite.java @@ -23,6 +23,7 @@ import java.nio.file.Paths; SecurityHelperTest.class, AuthenticatorTest.class, WebAPITest.class, + GetAwardsTest.class, LogoutTest.class }) public class RuleSuite { From 92aec9baf5edd3698403efa574fc10172eec238e Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 7 Mar 2018 10:19:47 +0800 Subject: [PATCH 30/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/hiczp/bilibili/api/live/LiveService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index b75b7a0..790c59f 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -32,6 +32,7 @@ public interface LiveService { @POST("feed/v1/feed/isFollowed") Call isFollowed(@Query("follow") long hostUserId); + //TODO 每日背包任务 //该 API 意义不明(似乎跟什么 每日背包任务 有关) @GET("AppBag/sendDaily") Call sendDaily(); @@ -40,6 +41,7 @@ public interface LiveService { @GET("AppIndex/getAllItem") Call getAllItem(); + //TODO 小电视 //查看可用的小电视抽奖 //当目标房间没有可用的小电视抽奖时返回 -400 @GET("AppSmallTV/index") @@ -52,6 +54,7 @@ public interface LiveService { @GET("appUser/getTitle") Call getTitle(); + //TODO 节奏风暴 //这个 API 不是很明确, 似乎和 节奏风暴 有关系 @GET("SpecialGift/room/{roomId}") Call getSpecialGift(@Path("roomId") long roomId); @@ -220,6 +223,7 @@ public interface LiveService { //TODO 取消佩戴 //TODO 获奖记录 + //侧拉抽屉 -> 直播中心 -> 获奖记录 @GET("AppUser/awards") Call getAwards(); From 84ca03862f420469dd4f09f1cb287f431392b2fe Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 7 Mar 2018 10:26:31 +0800 Subject: [PATCH 31/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 8e925ba..1fe9a8e 100644 --- a/README.md +++ b/README.md @@ -368,6 +368,15 @@ 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. From 4e7b89f4ee808a3f5b5cf9b07d6a1456e9130b2a Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 7 Mar 2018 11:13:37 +0800 Subject: [PATCH 32/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../live/socket/handler/LiveClientHandler.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 1738c27..c4d1fee 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -87,58 +87,73 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { .getAsString(); Supplier eventCreationExpression; //try 不能写在 switch 外面, 用 lambda 来延迟执行 switch (cmd) { + //弹幕消息 case "DANMU_MSG": { eventCreationExpression = () -> new DanMuMsgPackageEvent(this, GSON.fromJson(content, DanMuMsgEntity.class)); } break; + //送礼 case "SEND_GIFT": { eventCreationExpression = () -> new SendGiftPackageEvent(this, GSON.fromJson(content, SendGiftEntity.class)); } break; + //系统礼物(丰收庆典, 新春抽奖等) case "SYS_GIFT": { eventCreationExpression = () -> new SysGiftPackageEvent(this, GSON.fromJson(content, SysGiftEntity.class)); } break; + //系统消息(小电视等) case "SYS_MSG": { eventCreationExpression = () -> new SysMsgPackageEvent(this, GSON.fromJson(content, SysMsgEntity.class)); } break; + //欢迎 case "WELCOME": { eventCreationExpression = () -> new WelcomePackageEvent(this, GSON.fromJson(content, WelcomeEntity.class)); } break; + //欢迎(舰队) case "WELCOME_GUARD": { eventCreationExpression = () -> new WelcomeGuardPackageEvent(this, GSON.fromJson(content, WelcomeGuardEntity.class)); } break; + //开始直播 case "LIVE": { eventCreationExpression = () -> new LivePackageEvent(this, GSON.fromJson(content, LiveEntity.class)); } break; + //停止直播 case "PREPARING": { eventCreationExpression = () -> new PreparingPackageEvent(this, GSON.fromJson(content, PreparingEntity.class)); } break; + //活动事件 case "ACTIVITY_EVENT": { eventCreationExpression = () -> new ActivityEventPackageEvent(this, GSON.fromJson(content, ActivityEventEntity.class)); } break; + //许愿瓶 case "WISH_BOTTLE": { eventCreationExpression = () -> new WishBottlePackageEvent(this, GSON.fromJson(content, WishBottleEntity.class)); } break; + //房间黑名单(添加了一个用户到黑名单) case "ROOM_BLOCK_MSG": { eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(content, RoomBlockMsgEntity.class)); } break; + //TODO ROOM_SILENT_ON(禁止某一等级以下的用户发言) + //房间结束禁言 case "ROOM_SILENT_OFF": { eventCreationExpression = () -> new RoomSilentOffPackageEvent(this, GSON.fromJson(content, RoomSilentOffEntity.class)); } break; + //舰队消息(登船) case "GUARD_MSG": { eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(content, GuardMsgEntity.class)); } break; + //小电视抽奖结束(大奖的获得者信息) case "TV_END": { eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(content, TVEndEntity.class)); } From 4366bb2420a88f7cf7b503e1a8842115327b0920 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 7 Mar 2018 18:11:43 +0800 Subject: [PATCH 33/73] =?UTF-8?q?=E5=B0=86=20actionKey=20=E8=AE=BE?= =?UTF-8?q?=E4=B8=BA=E5=9B=BA=E5=AE=9A=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java | 1 + src/main/java/com/hiczp/bilibili/api/live/LiveService.java | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 1d647d1..2e79c35 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -132,6 +132,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv .addInterceptor(new AddFixedParamsInterceptor( "_device", "android", "_hwid", bilibiliClientProperties.getHardwareId(), + "actionKey", "appkey", "build", bilibiliClientProperties.getBuild(), "mobi_app", "android", "platform", "android", diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 790c59f..f62e15b 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -230,14 +230,9 @@ public interface LiveService { //瓜子商店 //侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币 //将 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次 - //actionKey 是固定值, 为 "appkey" //已经兑换过时返回 403 @POST("AppExchange/silver2coin") - Call silver2Coin(@Query("actionKey") String actionKey); - - default Call silver2Coin() { - return silver2Coin("appkey"); - } + Call silver2Coin(); //扭蛋机 //侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 From f154d0b4f3fae9f432280ce18cdf49b7793665c6 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 09:38:35 +0800 Subject: [PATCH 34/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E6=89=AD=20?= =?UTF-8?q?=E6=A2=A6=E5=B9=BB=E6=89=AD=E8=9B=8B=20=E7=9A=84=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hiczp/bilibili/api/live/LiveService.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index f62e15b..504aeaa 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -74,7 +74,8 @@ public interface LiveService { return getPlayUrl(cid, "json"); } - //发送一个 Restful 的心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级 + //发送一个 Restful 心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级 + //2018-03-06 开始, 只有老爷才能通过观看直播获得经验 //未登录时返回 3 @POST("mobile/userOnlineHeart") @FormUrlEncoded @@ -244,16 +245,19 @@ public interface LiveService { //count 只能为 1, 10, 100 @POST("AppUser/capsuleInfoOpen") @FormUrlEncoded - Call openCapsule(@Field("count") long count, @Field("type") String type); + Call openCapsule(@Field("count") int count, @Field("type") String type); //抽普通扭蛋 //侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 -> 扭 //普通扭蛋的 type 为 "normal" - default Call openNormalCapsule(long count) { + default Call openNormalCapsule(int count) { return openCapsule(count, "normal"); } - //TODO 梦幻扭蛋(没抽过, 不知道 type 的值) + //梦幻扭蛋 + default Call openColorfulCapsule(int count) { + return openCapsule(count, "colorful"); + } //房间设置 //侧拉抽屉 -> 直播中心 -> 房间设置 -> (上面的个人信息, 包括 房间号, 粉丝数, UP 经验) From 6e12feb1f13d7e33948d5d35a4142feddc970441 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 11:22:26 +0800 Subject: [PATCH 35/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=20GUARD=5FBUY,=20ROOM=5FADMINS,=20ROOM=5FSILENT=5FON?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 + .../bullet_screen_stream_json/GUARD_BUY.json | 10 ++ .../ROOM_ADMINS.json | 14 +++ .../ROOM_SILENT_ON.json | 9 ++ .../live/socket/entity/GuardBuyEntity.java | 93 +++++++++++++++++++ .../live/socket/entity/RoomAdminsEntity.java | 45 +++++++++ .../socket/entity/RoomSilentOnEntity.java | 82 ++++++++++++++++ .../socket/event/GuardBuyPackageEvent.java | 9 ++ .../socket/event/RoomAdminsPackageEvent.java | 9 ++ .../event/RoomSilentOnPackageEvent.java | 9 ++ .../socket/handler/LiveClientHandler.java | 16 +++- 11 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 record/bullet_screen_stream_json/GUARD_BUY.json create mode 100644 record/bullet_screen_stream_json/ROOM_ADMINS.json create mode 100644 record/bullet_screen_stream_json/ROOM_SILENT_ON.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardBuyEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomAdminsEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOnEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java diff --git a/README.md b/README.md index 1fe9a8e..560219f 100644 --- a/README.md +++ b/README.md @@ -296,11 +296,14 @@ API 文档 | ConnectionCloseEvent | 连接断开(主动或被动) | | ConnectSucceedEvent | 进房成功 | | DanMuMsgPackageEvent | 收到 DANMU_MSG 数据包 | +| GuardBuyPackageEvent | 收到 GUARD_BUY 数据包 | | GuardMsgPackageEvent | 收到 GUARD_MSG 数据包 | | LivePackageEvent | 收到 LIVE 数据包 | | PreparingPackageEvent | 收到 PREPARING 数据包 | +| RoomAdminsPackageEvent | 收到 ROOM_ADMINS 数据包 | | RoomBlockMsgPackageEvent | 收到 ROOM_BLOCK_MSG 数据包 | | RoomSilentOffPackageEvent | 收到 ROOM_SILENT_OFF 数据包 | +| RoomSilentOnPackageEvent | 收到 ROOM_SILENT_ON 数据包 | | SendGiftPackageEvent | 收到 SEND_GIFT 数据包 | | SendHeartBeatPackageEvent | 每次发送心跳包后触发一次 | | SysGiftPackageEvent | 收到 SYS_GIFT 数据包 | diff --git a/record/bullet_screen_stream_json/GUARD_BUY.json b/record/bullet_screen_stream_json/GUARD_BUY.json new file mode 100644 index 0000000..0ae435d --- /dev/null +++ b/record/bullet_screen_stream_json/GUARD_BUY.json @@ -0,0 +1,10 @@ +{ + "cmd": "GUARD_BUY", + "data": { + "uid": 4561799, + "username": "微笑The迪妮莎", + "guard_level": 1, + "num": 1 + }, + "roomid": "5279" +} diff --git a/record/bullet_screen_stream_json/ROOM_ADMINS.json b/record/bullet_screen_stream_json/ROOM_ADMINS.json new file mode 100644 index 0000000..e44f830 --- /dev/null +++ b/record/bullet_screen_stream_json/ROOM_ADMINS.json @@ -0,0 +1,14 @@ +{ + "cmd": "ROOM_ADMINS", + "uids": [ + 4561799, + 432672, + 2179804, + 7928207, + 94380, + 1626161, + 3168349, + 13182672 + ], + "roomid": 5279 +} diff --git a/record/bullet_screen_stream_json/ROOM_SILENT_ON.json b/record/bullet_screen_stream_json/ROOM_SILENT_ON.json new file mode 100644 index 0000000..c17efff --- /dev/null +++ b/record/bullet_screen_stream_json/ROOM_SILENT_ON.json @@ -0,0 +1,9 @@ +{ + "cmd": "ROOM_SILENT_ON", + "data": { + "type": "level", + "level": 1, + "second": 1520424615 + }, + "roomid": 5279 +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardBuyEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardBuyEntity.java new file mode 100644 index 0000000..f34a99d --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/GuardBuyEntity.java @@ -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; + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomAdminsEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomAdminsEntity.java new file mode 100644 index 0000000..a8cd8f4 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomAdminsEntity.java @@ -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 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 getUids() { + return uids; + } + + public void setUids(List uids) { + this.uids = uids; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOnEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOnEntity.java new file mode 100644 index 0000000..14eef57 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomSilentOnEntity.java @@ -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; + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java new file mode 100644 index 0000000..9f84401 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.GuardBuyEntity; + +public class GuardBuyPackageEvent extends ReceiveDataPackageEvent { + public GuardBuyPackageEvent(Object source, GuardBuyEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java new file mode 100644 index 0000000..88dd723 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.RoomAdminsEntity; + +public class RoomAdminsPackageEvent extends ReceiveDataPackageEvent { + public RoomAdminsPackageEvent(Object source, RoomAdminsEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java new file mode 100644 index 0000000..d0681d5 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.RoomSilentOnEntity; + +public class RoomSilentOnPackageEvent extends ReceiveDataPackageEvent { + public RoomSilentOnPackageEvent(Object source, RoomSilentOnEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index c4d1fee..bedbd71 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -142,17 +142,31 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(content, RoomBlockMsgEntity.class)); } break; - //TODO ROOM_SILENT_ON(禁止某一等级以下的用户发言) + //房间开启了禁言(禁止某一等级以下的用户发言) + case "ROOM_SILENT_ON": { + eventCreationExpression = () -> new RoomSilentOnPackageEvent(this, GSON.fromJson(content, RoomSilentOnEntity.class)); + } + break; //房间结束禁言 case "ROOM_SILENT_OFF": { eventCreationExpression = () -> new RoomSilentOffPackageEvent(this, GSON.fromJson(content, RoomSilentOffEntity.class)); } break; + //船票购买 + case "GUARD_BUY": { + eventCreationExpression = () -> new GuardBuyPackageEvent(this, GSON.fromJson(content, GuardBuyEntity.class)); + } + break; //舰队消息(登船) case "GUARD_MSG": { eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(content, GuardMsgEntity.class)); } break; + //房管变更 + case "ROOM_ADMINS": { + eventCreationExpression = () -> new RoomAdminsPackageEvent(this, GSON.fromJson(content, RoomAdminsEntity.class)); + } + break; //小电视抽奖结束(大奖的获得者信息) case "TV_END": { eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(content, TVEndEntity.class)); From 02c0e11fee1ac790e12b313b579f4bca78d00a65 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 14:04:30 +0800 Subject: [PATCH 36/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20live=20=E6=9C=89?= =?UTF-8?q?=E5=85=B3=20API=20=E6=9F=A5=E7=9C=8B=E7=B2=89=E4=B8=9D=E5=8B=8B?= =?UTF-8?q?=E7=AB=A0,=20=E4=BD=A9=E6=88=B4=E7=B2=89=E4=B8=9D=E5=8B=8B?= =?UTF-8?q?=E7=AB=A0,=20=E5=8F=96=E6=B6=88=E4=BD=A9=E6=88=B4=E7=B2=89?= =?UTF-8?q?=E4=B8=9D=E5=8B=8B=E7=AB=A0=20=E6=9F=A5=E7=9C=8B=E5=A4=B4?= =?UTF-8?q?=E8=A1=94,=20=E8=8E=B7=E5=BE=97=E5=BD=93=E5=89=8D=E4=BD=A9?= =?UTF-8?q?=E6=88=B4=E7=9A=84=E5=A4=B4=E8=A1=94=E7=9A=84=E4=BF=A1=E6=81=AF?= =?UTF-8?q?,=20=E4=BD=A9=E6=88=B4=E5=A4=B4=E8=A1=94,=20=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E4=BD=A9=E6=88=B4=E5=A4=B4=E8=A1=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/live/LiveService.java | 26 ++++++--- .../entity/CancelMedalResponseEntity.java | 44 +++++++++++++++ .../entity/CancelTitleResponseEntity.java | 55 +++++++++++++++++++ .../live/entity/WearMedalResponseEntity.java | 44 +++++++++++++++ .../live/entity/WearTitleResponseEntity.java | 13 ++++- 5 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/CancelMedalResponseEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/CancelTitleResponseEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/WearMedalResponseEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 504aeaa..bcf9db5 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -198,16 +198,22 @@ public interface LiveService { @GET("AppUser/history") Call getHistory(@Query("page") long page, @Query("pagesize") long pageSize); - //TODO 佩戴中心 + //佩戴中心 //侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 粉丝勋章 //获得用户拥有的粉丝勋章 @GET("AppUser/medal") Call getMyMedalList(); - //TODO 佩戴粉丝勋章 - //TODO 删除粉丝勋章 + //佩戴粉丝勋章 + @POST("AppUser/wearMedal") + Call wearMedal(@Query("medal_id") int medalId); - //侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 我的头衔 -> 佩戴头衔 + //取消佩戴粉丝勋章(取消佩戴当前佩戴着的粉丝勋章) + //URL 上的 canel 不是拼写错误, 它原本就是这样的 + @GET("AppUser/canelMedal") + Call cancelMedal(); + + //侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 我的头衔 //获得用户拥有的头衔 @GET("appUser/myTitleList") Call getMyTitleList(); @@ -218,12 +224,16 @@ public interface LiveService { Call getWearTitle(); //佩戴头衔 - //是的, 你没看错, 是 GET 方式 - @GET("AppUser/wearTitle") + @POST("AppUser/wearTitle") Call wearTitle(@Query("title") String title); - //TODO 取消佩戴 - //TODO 获奖记录 + //取消佩戴头衔(取消佩戴当前佩戴着的头衔) + @GET("appUser/cancelTitle") + Call cancelTitle(); + + //TODO 头衔工坊(没有可升级头衔, 暂不明确此 API) + + //TODO 获奖记录(没有获奖记录, 暂不明确返回值) //侧拉抽屉 -> 直播中心 -> 获奖记录 @GET("AppUser/awards") Call getAwards(); diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/CancelMedalResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/CancelMedalResponseEntity.java new file mode 100644 index 0000000..ec43108 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/CancelMedalResponseEntity.java @@ -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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/CancelTitleResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/CancelTitleResponseEntity.java new file mode 100644 index 0000000..2f4145b --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/CancelTitleResponseEntity.java @@ -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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/WearMedalResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/WearMedalResponseEntity.java new file mode 100644 index 0000000..9d77496 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/WearMedalResponseEntity.java @@ -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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleResponseEntity.java index aa03ded..b4efa8a 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleResponseEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/WearTitleResponseEntity.java @@ -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; } From b0891e5876f8836d659c570dc88a6fe54bab99d7 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 15:46:29 +0800 Subject: [PATCH 37/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E7=9B=B4=E6=92=AD?= =?UTF-8?q?=20=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=88=BF=E9=97=B4=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=98=BE=E7=A4=BA=E5=92=8C=E5=88=B7=E6=96=B0=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/live/LiveService.java | 72 +- .../RecommendRoomRefreshResponseEntity.java | 670 ++++++++++++++++++ .../api/live/entity/RoomListEntity.java | 364 ++++++++++ 3 files changed, 1092 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/RecommendRoomRefreshResponseEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/RoomListEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index bcf9db5..b7b8151 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -157,6 +157,64 @@ public interface LiveService { @GET("AppRoom/getGiftTop") Call getGiftTop(@Query("room_id") int roomId); + //"直播" 页面(这个页面对应的后台数据, 包括 banner, 推荐主播, 各种分区的推荐等) + //这个 API 会读取 "_device"(固定参数) 或者 "device" 来判断平台, 只需要有一个就能正常工作, 客户端上是两个都有, 且值都为 "android" + @GET("room/v1/AppIndex/getAllList") + Call getAllList(@Query("device") String device); + + default Call getAllList() { + return getAllList("android"); + } + + //刷新 "推荐主播" 区域, 必须有 device, platform, scala + //scala 为 xxhdpi 时返回 12 个, 客户端显示六个, 刷新两次后再次访问该 API + //该 API 返回的内容结构与 getAllList 返回的内容中的 recommend_data 字段是一样的 + //该 API 返回的 banner_data 是在普通分区的推荐的上面的那个 banner, 在新版 APP 中, 点击这个 banner 会固定的跳转到 bilibili 相簿的 画友 标签页 + @GET("room/v1/AppIndex/recRefresh") + Call recommendRefresh(@Query("device") String device); + + default Call recommendRefresh() { + return recommendRefresh("android"); + } + + //直播页面 下面的 普通分区(复数) 的刷新, 一次会返回 20 个结果, 客户端显示 6 个, 数据用完了之后再次访问该 API + //area_id 和 cate_id 不明确其含义 + @GET("room/v1/Area/getRoomList") + Call getRoomList( + @Query("area_id") int areaId, + @Query("cate_id") int categoryId, + @Query("parent_area_id") int parentAreaId, + @Query("sort_type") String sortType + ); + + default Call getRoomList(int parentAreaId) { + return getRoomList(0, 0, parentAreaId, "dynamic"); + } + + //直播 -> 全部直播(直播页面的最下面的一个按钮) + @GET("mobile/rooms") + Call getRooms(@Query("area_id") int areaId, @Query("page") int page, @Query("sort") String sort); + + //推荐直播 + default Call getSuggestionRooms(int page) { + return getRooms(0, page, "suggestion"); + } + + //最热直播 + default Call getHottestRooms(int page) { + return getRooms(0, page, "hottest"); + } + + //最新直播 + default Call getLatestRooms(int page) { + return getRooms(0, page, "latest"); + } + + //视频轮播 + default Call getRoundRooms(int page) { + return getRooms(0, page, "roundroom"); + } + //live 站的搜索("直播" 页面) //type 为 room 时只返回 房间 的搜索结果 //type 为 user 时只返回 用户 的搜索结果 @@ -168,20 +226,6 @@ public interface LiveService { return search(keyword, page, pageSize, "all"); } - //"直播" 页面(这个页面对应的后台数据, 包括 banner, 推荐主播, 各种分区的推荐等) - //这个 API 会读取 "_device"(固定参数) 或者 "device" 来判断平台, 只需要有一个就能正常工作, 客户端上是两个都有, 且值都为 "android" - @GET("room/v1/AppIndex/getAllList") - Call getAllList(@Query("device") String device); - - default Call getAllList() { - return getAllList("android"); - } - - //直播 -> 全部直播 -> 推荐直播 - //似乎 推荐直播 与 最热直播 的返回值是一样的 - @GET("mobile/rooms") - Call getRooms(); - //侧拉抽屉 -> 直播中心 -> 右上角日历图标 //签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能)) //无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign() diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/RecommendRoomRefreshResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/RecommendRoomRefreshResponseEntity.java new file mode 100644 index 0000000..e74647e --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/RecommendRoomRefreshResponseEntity.java @@ -0,0 +1,670 @@ +package com.hiczp.bilibili.api.live.entity; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class RecommendRoomRefreshResponseEntity { + /** + * code : 0 + * msg : ok + * message : ok + * data : {"partition":{"id":0,"name":"推荐主播","area":"hot","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052","height":"63","width":"63"},"count":5412},"banner_data":[{"cover":{"src":"https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png","height":180,"width":320},"title":"今天,你的小视频上榜了吗?","is_clip":1,"new_cover":{"src":"https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg","height":180,"width":320},"new_title":"B站大触竟然都在这里???","new_router":"https://h.bilibili.com/ywh/h5/index"}],"lives":[{"owner":{"face":"https://i1.hdslb.com/bfs/face/8ed8e486437b5053628248dd3c031b109b4cefcd.jpg","mid":218972880,"name":"萌萌の糖酱"},"cover":{"src":"https://i0.hdslb.com/bfs/live/d5805bf0e4cb51b50ad4cbe209ae328aedaeeeda.jpg","height":180,"width":320},"room_id":5619438,"check_version":0,"online":9736,"area":"御宅文化","area_id":2,"title":"ASMR温柔哄睡【软妹音】欧尼酱,睡觉吗","playurl":"http://xl.live-play.acgvideo.com/live-xl/635191/live_218972880_9269900.flv?wsSecret=1d446f8efd39fe766fbf13db9dddc01b&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":30,"area_v2_name":"ASMR ","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/ad1cfde69fc3afd79b6a21ddd0e3a7cd9992932e.jpg","mid":77545560,"name":"海岛情话"},"cover":{"src":"https://i0.hdslb.com/bfs/live/23342613fb41f1cf9523e79404ef3c69a641c904.jpg","height":180,"width":320},"room_id":3269664,"check_version":0,"online":4388,"area":"手游直播","area_id":12,"title":"小号98胜率木兰星耀上王者","playurl":"http://qn.live-play.acgvideo.com/live-qn/695751/live_77545560_5747022.flv?wsSecret=2e100446f6efded8287e90cc52ca946e&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":35,"area_v2_name":"王者荣耀","area_v2_parent_id":3,"area_v2_parent_name":"手游"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/0aec19109c04808e28222d18cd3aa7bf3c919629.jpg","mid":592761,"name":"可樂C"},"cover":{"src":"https://i0.hdslb.com/bfs/live/882c7265ee8b4d05f2411386f8be3545dca0a105.jpg","height":180,"width":320},"room_id":5170,"check_version":0,"online":1477,"area":"单机联机","area_id":1,"title":"【可乐C】彩虹六号夕阳红黑车被锤爆","playurl":"http://qn.live-play.acgvideo.com/live-qn/182029/live_592761_3949639.flv?wsSecret=1f70ceec292b5dd37ff8adee42b01d60&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":65,"area_v2_name":"彩虹六号","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/5bb4ce5bf2511dd3e0e36c3f8f77dcb865feb20e.jpg","mid":16653477,"name":"糕糕糕糕呀"},"cover":{"src":"https://i0.hdslb.com/bfs/live/146049c2307491eeece0dde3716023c9efedbd0a.jpg","height":180,"width":320},"room_id":5459316,"check_version":0,"online":5366,"area":"唱见舞见","area_id":10,"title":"安静唱歌","playurl":"http://qn.live-play.acgvideo.com/live-qn/526949/live_16653477_6713858.flv?wsSecret=e6f3367988bf1932dc8da37f959945df&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐","data_behavior_id":"2f2e76a7eee721b:2f2e76a7eee721b:0:0","data_source_id":"system"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/024dd9476a0c8e7f5888a636a635f55714d4ea57.jpg","mid":301940,"name":"Gluneko"},"cover":{"src":"https://i0.hdslb.com/bfs/live/83ee0d684ab37ca50faef33935a550b2b77ed7be.jpg","height":180,"width":320},"room_id":10401,"check_version":0,"online":64052,"area":"单机联机","area_id":1,"title":"摸鱼的世界","playurl":"http://qn.live-play.acgvideo.com/live-qn/875128/live_301940_3118084.flv?wsSecret=6f6c25eda34d9178df6136979fbdfd08&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":56,"area_v2_name":"我的世界","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/9f9d0db52e8317c0d7d6eb5c679a614b87ba2deb.jpg","mid":26424461,"name":"小天不是受QAQ"},"cover":{"src":"https://i0.hdslb.com/bfs/live/2c325abf7019d85bbe469e6a6ce48532d7ca1ab0.jpg","height":180,"width":320},"room_id":92075,"check_version":0,"online":33334,"area":"单机联机","area_id":1,"title":"(ฅ´ω`ฅ)","playurl":"http://qn.live-play.acgvideo.com/live-qn/979857/live_26424461_5746903.flv?wsSecret=df79865e2b6cedab0b642c36393a3ccc&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/bc0f90d01610b619458c502b8fc6a6b493bc73f1.jpg","mid":27156703,"name":"萌萌哒的苍云丶"},"cover":{"src":"https://i0.hdslb.com/bfs/live/7b9d4eb54cef2069853dc41241dc41b2895583a2.jpg","height":180,"width":320},"room_id":4048839,"check_version":0,"online":8675,"area":"网络游戏","area_id":3,"title":"认真伏笔,拒绝打牌","playurl":"http://dl.live-play.acgvideo.com/live-dl/727680/live_27156703_9775611.flv?wsSecret=fc3c6b4a38c503e78f5f5577351085ec&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":91,"area_v2_name":"炉石传说","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/450e0df5c7104f2682218401bfa3ea3d35556261.jpg","mid":4344862,"name":"楚小月嘟嘟嘟"},"cover":{"src":"https://i0.hdslb.com/bfs/live/105ef448e1cd2d69c52d6132c1fba1218aecb998.jpg","height":180,"width":320},"room_id":8571156,"check_version":0,"online":5538,"area":"单机联机","area_id":1,"title":"【职业声优】男神音恐怖游戏了解一下","playurl":"http://txy.live-play.acgvideo.com/live-txy/389996/live_4344862_9497566.flv?wsSecret=87000ab2ff112eda49cf687e5327748b&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/2f58afd7ab3f6bd2f98322c1ea1537803c8ebddb.jpg","mid":464276,"name":"天使菌_"},"cover":{"src":"https://i0.hdslb.com/bfs/live/ea0e1300c9a78289d84989cb2d65866e091b6c52.jpg","height":180,"width":320},"room_id":14382,"check_version":0,"online":612,"area":"单机联机","area_id":1,"title":"【天使菌_】妇女节快乐下午1点-5点直播","playurl":"http://xl.live-play.acgvideo.com/live-xl/208069/live_464276_332_c521e483.flv?wsSecret=d77952dde26ed755949818c5523467b0&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/0433055d4eac3b2314faadb47de64be114571d4c.jpg","mid":1320581,"name":"游戏彩笔"},"cover":{"src":"https://i0.hdslb.com/bfs/live/6cc54d0b290021068dcfaa82c02cf407a588e0f9.jpg","height":180,"width":320},"room_id":17778,"check_version":0,"online":13094,"area":"手游直播","area_id":12,"title":"【彩笔崩坏3】肝完崩坏去狩猎!","playurl":"http://xl.live-play.acgvideo.com/live-xl/653913/live_1320581_332_c521e483.flv?wsSecret=7d53496570da595fbdebd21c699ccab7&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":40,"area_v2_name":"崩坏3","area_v2_parent_id":3,"area_v2_parent_name":"手游"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/4a91427ef035836b1937244bc559ed03f244bfa9.jpg","mid":183430,"name":"两仪滚"},"cover":{"src":"https://i0.hdslb.com/bfs/live/e64902520ab6e0aaeb6e2d1b721cccbf241045d3.jpg","height":180,"width":320},"room_id":5096,"check_version":0,"online":102641,"area":"单机联机","area_id":1,"title":"【滚】节日快乐","playurl":"http://js.live-play.acgvideo.com/live-js/292971/live_183430_5743361.flv?wsSecret=6e6388c531a84028dee052c867828a93&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ae8aea930b21e86a83313dd3ad12cd8192e8bf49.jpg","mid":6810019,"name":"AnKe-Poi"},"cover":{"src":"https://i0.hdslb.com/bfs/live/656172a98c80d2eb67c91b2279958e4eea772d7c.jpg","height":180,"width":320},"room_id":79558,"check_version":0,"online":17085,"area":"单机联机","area_id":1,"title":"【安可】终于不修路了上来玩会","playurl":"http://qn.live-play.acgvideo.com/live-qn/780558/live_6810019_9448733.flv?wsSecret=bff5414e04a1de2eb8260aa1409b8db6&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"}]} + */ + + @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 { + /** + * partition : {"id":0,"name":"推荐主播","area":"hot","sub_icon":{"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052","height":"63","width":"63"},"count":5412} + * banner_data : [{"cover":{"src":"https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png","height":180,"width":320},"title":"今天,你的小视频上榜了吗?","is_clip":1,"new_cover":{"src":"https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg","height":180,"width":320},"new_title":"B站大触竟然都在这里???","new_router":"https://h.bilibili.com/ywh/h5/index"}] + * lives : [{"owner":{"face":"https://i1.hdslb.com/bfs/face/8ed8e486437b5053628248dd3c031b109b4cefcd.jpg","mid":218972880,"name":"萌萌の糖酱"},"cover":{"src":"https://i0.hdslb.com/bfs/live/d5805bf0e4cb51b50ad4cbe209ae328aedaeeeda.jpg","height":180,"width":320},"room_id":5619438,"check_version":0,"online":9736,"area":"御宅文化","area_id":2,"title":"ASMR温柔哄睡【软妹音】欧尼酱,睡觉吗","playurl":"http://xl.live-play.acgvideo.com/live-xl/635191/live_218972880_9269900.flv?wsSecret=1d446f8efd39fe766fbf13db9dddc01b&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":30,"area_v2_name":"ASMR ","area_v2_parent_id":1,"area_v2_parent_name":"娱乐"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/ad1cfde69fc3afd79b6a21ddd0e3a7cd9992932e.jpg","mid":77545560,"name":"海岛情话"},"cover":{"src":"https://i0.hdslb.com/bfs/live/23342613fb41f1cf9523e79404ef3c69a641c904.jpg","height":180,"width":320},"room_id":3269664,"check_version":0,"online":4388,"area":"手游直播","area_id":12,"title":"小号98胜率木兰星耀上王者","playurl":"http://qn.live-play.acgvideo.com/live-qn/695751/live_77545560_5747022.flv?wsSecret=2e100446f6efded8287e90cc52ca946e&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":35,"area_v2_name":"王者荣耀","area_v2_parent_id":3,"area_v2_parent_name":"手游"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/0aec19109c04808e28222d18cd3aa7bf3c919629.jpg","mid":592761,"name":"可樂C"},"cover":{"src":"https://i0.hdslb.com/bfs/live/882c7265ee8b4d05f2411386f8be3545dca0a105.jpg","height":180,"width":320},"room_id":5170,"check_version":0,"online":1477,"area":"单机联机","area_id":1,"title":"【可乐C】彩虹六号夕阳红黑车被锤爆","playurl":"http://qn.live-play.acgvideo.com/live-qn/182029/live_592761_3949639.flv?wsSecret=1f70ceec292b5dd37ff8adee42b01d60&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":65,"area_v2_name":"彩虹六号","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/5bb4ce5bf2511dd3e0e36c3f8f77dcb865feb20e.jpg","mid":16653477,"name":"糕糕糕糕呀"},"cover":{"src":"https://i0.hdslb.com/bfs/live/146049c2307491eeece0dde3716023c9efedbd0a.jpg","height":180,"width":320},"room_id":5459316,"check_version":0,"online":5366,"area":"唱见舞见","area_id":10,"title":"安静唱歌","playurl":"http://qn.live-play.acgvideo.com/live-qn/526949/live_16653477_6713858.flv?wsSecret=e6f3367988bf1932dc8da37f959945df&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":21,"area_v2_name":"唱见","area_v2_parent_id":1,"area_v2_parent_name":"娱乐","data_behavior_id":"2f2e76a7eee721b:2f2e76a7eee721b:0:0","data_source_id":"system"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/024dd9476a0c8e7f5888a636a635f55714d4ea57.jpg","mid":301940,"name":"Gluneko"},"cover":{"src":"https://i0.hdslb.com/bfs/live/83ee0d684ab37ca50faef33935a550b2b77ed7be.jpg","height":180,"width":320},"room_id":10401,"check_version":0,"online":64052,"area":"单机联机","area_id":1,"title":"摸鱼的世界","playurl":"http://qn.live-play.acgvideo.com/live-qn/875128/live_301940_3118084.flv?wsSecret=6f6c25eda34d9178df6136979fbdfd08&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":56,"area_v2_name":"我的世界","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/9f9d0db52e8317c0d7d6eb5c679a614b87ba2deb.jpg","mid":26424461,"name":"小天不是受QAQ"},"cover":{"src":"https://i0.hdslb.com/bfs/live/2c325abf7019d85bbe469e6a6ce48532d7ca1ab0.jpg","height":180,"width":320},"room_id":92075,"check_version":0,"online":33334,"area":"单机联机","area_id":1,"title":"(ฅ´ω`ฅ)","playurl":"http://qn.live-play.acgvideo.com/live-qn/979857/live_26424461_5746903.flv?wsSecret=df79865e2b6cedab0b642c36393a3ccc&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/bc0f90d01610b619458c502b8fc6a6b493bc73f1.jpg","mid":27156703,"name":"萌萌哒的苍云丶"},"cover":{"src":"https://i0.hdslb.com/bfs/live/7b9d4eb54cef2069853dc41241dc41b2895583a2.jpg","height":180,"width":320},"room_id":4048839,"check_version":0,"online":8675,"area":"网络游戏","area_id":3,"title":"认真伏笔,拒绝打牌","playurl":"http://dl.live-play.acgvideo.com/live-dl/727680/live_27156703_9775611.flv?wsSecret=fc3c6b4a38c503e78f5f5577351085ec&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":91,"area_v2_name":"炉石传说","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/450e0df5c7104f2682218401bfa3ea3d35556261.jpg","mid":4344862,"name":"楚小月嘟嘟嘟"},"cover":{"src":"https://i0.hdslb.com/bfs/live/105ef448e1cd2d69c52d6132c1fba1218aecb998.jpg","height":180,"width":320},"room_id":8571156,"check_version":0,"online":5538,"area":"单机联机","area_id":1,"title":"【职业声优】男神音恐怖游戏了解一下","playurl":"http://txy.live-play.acgvideo.com/live-txy/389996/live_4344862_9497566.flv?wsSecret=87000ab2ff112eda49cf687e5327748b&wsTime=1520493001","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":107,"area_v2_name":"其他游戏","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/2f58afd7ab3f6bd2f98322c1ea1537803c8ebddb.jpg","mid":464276,"name":"天使菌_"},"cover":{"src":"https://i0.hdslb.com/bfs/live/ea0e1300c9a78289d84989cb2d65866e091b6c52.jpg","height":180,"width":320},"room_id":14382,"check_version":0,"online":612,"area":"单机联机","area_id":1,"title":"【天使菌_】妇女节快乐下午1点-5点直播","playurl":"http://xl.live-play.acgvideo.com/live-xl/208069/live_464276_332_c521e483.flv?wsSecret=d77952dde26ed755949818c5523467b0&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/0433055d4eac3b2314faadb47de64be114571d4c.jpg","mid":1320581,"name":"游戏彩笔"},"cover":{"src":"https://i0.hdslb.com/bfs/live/6cc54d0b290021068dcfaa82c02cf407a588e0f9.jpg","height":180,"width":320},"room_id":17778,"check_version":0,"online":13094,"area":"手游直播","area_id":12,"title":"【彩笔崩坏3】肝完崩坏去狩猎!","playurl":"http://xl.live-play.acgvideo.com/live-xl/653913/live_1320581_332_c521e483.flv?wsSecret=7d53496570da595fbdebd21c699ccab7&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":40,"area_v2_name":"崩坏3","area_v2_parent_id":3,"area_v2_parent_name":"手游"},{"owner":{"face":"https://i0.hdslb.com/bfs/face/4a91427ef035836b1937244bc559ed03f244bfa9.jpg","mid":183430,"name":"两仪滚"},"cover":{"src":"https://i0.hdslb.com/bfs/live/e64902520ab6e0aaeb6e2d1b721cccbf241045d3.jpg","height":180,"width":320},"room_id":5096,"check_version":0,"online":102641,"area":"单机联机","area_id":1,"title":"【滚】节日快乐","playurl":"http://js.live-play.acgvideo.com/live-js/292971/live_183430_5743361.flv?wsSecret=6e6388c531a84028dee052c867828a93&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"},{"owner":{"face":"https://i2.hdslb.com/bfs/face/ae8aea930b21e86a83313dd3ad12cd8192e8bf49.jpg","mid":6810019,"name":"AnKe-Poi"},"cover":{"src":"https://i0.hdslb.com/bfs/live/656172a98c80d2eb67c91b2279958e4eea772d7c.jpg","height":180,"width":320},"room_id":79558,"check_version":0,"online":17085,"area":"单机联机","area_id":1,"title":"【安可】终于不修路了上来玩会","playurl":"http://qn.live-play.acgvideo.com/live-qn/780558/live_6810019_9448733.flv?wsSecret=bff5414e04a1de2eb8260aa1409b8db6&wsTime=1520493000","accept_quality_v2":[],"current_quality":4,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":"","area_v2_id":80,"area_v2_name":"绝地求生:大逃杀","area_v2_parent_id":2,"area_v2_parent_name":"游戏"}] + */ + + @SerializedName("partition") + private Partition partition; + @SerializedName("banner_data") + private List bannerData; + @SerializedName("lives") + private List lives; + + public Partition getPartition() { + return partition; + } + + public void setPartition(Partition partition) { + this.partition = partition; + } + + public List getBannerData() { + return bannerData; + } + + public void setBannerData(List bannerData) { + this.bannerData = bannerData; + } + + public List getLives() { + return lives; + } + + public void setLives(List lives) { + this.lives = lives; + } + + public static class Partition { + /** + * id : 0 + * name : 推荐主播 + * area : hot + * sub_icon : {"src":"https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052","height":"63","width":"63"} + * count : 5412 + */ + + @SerializedName("id") + private int id; + @SerializedName("name") + private String name; + @SerializedName("area") + private String area; + @SerializedName("sub_icon") + private SubIcon subIcon; + @SerializedName("count") + private int count; + + 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 getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public SubIcon getSubIcon() { + return subIcon; + } + + public void setSubIcon(SubIcon subIcon) { + this.subIcon = subIcon; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public static class SubIcon { + /** + * src : https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/android/android/-1_3x.png?201709151052 + * height : 63 + * width : 63 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private String height; + @SerializedName("width") + private String width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public String getHeight() { + return height; + } + + public void setHeight(String height) { + this.height = height; + } + + public String getWidth() { + return width; + } + + public void setWidth(String width) { + this.width = width; + } + } + } + + public static class BannerData { + /** + * cover : {"src":"https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png","height":180,"width":320} + * title : 今天,你的小视频上榜了吗? + * is_clip : 1 + * new_cover : {"src":"https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg","height":180,"width":320} + * new_title : B站大触竟然都在这里??? + * new_router : https://h.bilibili.com/ywh/h5/index + */ + + @SerializedName("cover") + private Cover cover; + @SerializedName("title") + private String title; + @SerializedName("is_clip") + private int isClip; + @SerializedName("new_cover") + private NewCover newCover; + @SerializedName("new_title") + private String newTitle; + @SerializedName("new_router") + private String newRouter; + + public Cover getCover() { + return cover; + } + + public void setCover(Cover cover) { + this.cover = cover; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getIsClip() { + return isClip; + } + + public void setIsClip(int isClip) { + this.isClip = isClip; + } + + public NewCover getNewCover() { + return newCover; + } + + public void setNewCover(NewCover newCover) { + this.newCover = newCover; + } + + public String getNewTitle() { + return newTitle; + } + + public void setNewTitle(String newTitle) { + this.newTitle = newTitle; + } + + public String getNewRouter() { + return newRouter; + } + + public void setNewRouter(String newRouter) { + this.newRouter = newRouter; + } + + public static class Cover { + /** + * src : https://i0.hdslb.com/bfs/live/348fbbc30ca1578d900b44dda64acd1310b1d05e.png + * height : 180 + * width : 320 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + + public static class NewCover { + /** + * src : https://i0.hdslb.com/bfs/live/b6ac78b2ad96cdc9a4d59719b1f8b3b8d1893e6d.jpg + * height : 180 + * width : 320 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + } + + public static class Lives { + /** + * owner : {"face":"https://i1.hdslb.com/bfs/face/8ed8e486437b5053628248dd3c031b109b4cefcd.jpg","mid":218972880,"name":"萌萌の糖酱"} + * cover : {"src":"https://i0.hdslb.com/bfs/live/d5805bf0e4cb51b50ad4cbe209ae328aedaeeeda.jpg","height":180,"width":320} + * room_id : 5619438 + * check_version : 0 + * online : 9736 + * area : 御宅文化 + * area_id : 2 + * title : ASMR温柔哄睡【软妹音】欧尼酱,睡觉吗 + * playurl : http://xl.live-play.acgvideo.com/live-xl/635191/live_218972880_9269900.flv?wsSecret=1d446f8efd39fe766fbf13db9dddc01b&wsTime=1520493001 + * accept_quality_v2 : [] + * current_quality : 4 + * accept_quality : 4 + * broadcast_type : 0 + * is_tv : 0 + * corner : + * pendent : + * area_v2_id : 30 + * area_v2_name : ASMR + * area_v2_parent_id : 1 + * area_v2_parent_name : 娱乐 + * data_behavior_id : 2f2e76a7eee721b:2f2e76a7eee721b:0:0 + * data_source_id : system + */ + + @SerializedName("owner") + private Owner owner; + @SerializedName("cover") + private CoverX cover; + @SerializedName("room_id") + private int roomId; + @SerializedName("check_version") + private int checkVersion; + @SerializedName("online") + private int online; + @SerializedName("area") + private String area; + @SerializedName("area_id") + private int areaId; + @SerializedName("title") + private String title; + @SerializedName("playurl") + private String playurl; + @SerializedName("current_quality") + private int currentQuality; + @SerializedName("accept_quality") + private String acceptQuality; + @SerializedName("broadcast_type") + private int broadcastType; + @SerializedName("is_tv") + private int isTv; + @SerializedName("corner") + private String corner; + @SerializedName("pendent") + private String pendent; + @SerializedName("area_v2_id") + private int areaV2Id; + @SerializedName("area_v2_name") + private String areaV2Name; + @SerializedName("area_v2_parent_id") + private int areaV2ParentId; + @SerializedName("area_v2_parent_name") + private String areaV2ParentName; + @SerializedName("data_behavior_id") + private String dataBehaviorId; + @SerializedName("data_source_id") + private String dataSourceId; + @SerializedName("accept_quality_v2") + private List acceptQualityV2; + + public Owner getOwner() { + return owner; + } + + public void setOwner(Owner owner) { + this.owner = owner; + } + + public CoverX getCover() { + return cover; + } + + public void setCover(CoverX cover) { + this.cover = cover; + } + + public int getRoomId() { + return roomId; + } + + public void setRoomId(int roomId) { + this.roomId = roomId; + } + + public int getCheckVersion() { + return checkVersion; + } + + public void setCheckVersion(int checkVersion) { + this.checkVersion = checkVersion; + } + + public int getOnline() { + return online; + } + + public void setOnline(int online) { + this.online = online; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public int getAreaId() { + return areaId; + } + + public void setAreaId(int areaId) { + this.areaId = areaId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getPlayurl() { + return playurl; + } + + public void setPlayurl(String playurl) { + this.playurl = playurl; + } + + public int getCurrentQuality() { + return currentQuality; + } + + public void setCurrentQuality(int currentQuality) { + this.currentQuality = currentQuality; + } + + public String getAcceptQuality() { + return acceptQuality; + } + + public void setAcceptQuality(String acceptQuality) { + this.acceptQuality = acceptQuality; + } + + public int getBroadcastType() { + return broadcastType; + } + + public void setBroadcastType(int broadcastType) { + this.broadcastType = broadcastType; + } + + public int getIsTv() { + return isTv; + } + + public void setIsTv(int isTv) { + this.isTv = isTv; + } + + public String getCorner() { + return corner; + } + + public void setCorner(String corner) { + this.corner = corner; + } + + public String getPendent() { + return pendent; + } + + public void setPendent(String pendent) { + this.pendent = pendent; + } + + public int getAreaV2Id() { + return areaV2Id; + } + + public void setAreaV2Id(int areaV2Id) { + this.areaV2Id = areaV2Id; + } + + public String getAreaV2Name() { + return areaV2Name; + } + + public void setAreaV2Name(String areaV2Name) { + this.areaV2Name = areaV2Name; + } + + public int getAreaV2ParentId() { + return areaV2ParentId; + } + + public void setAreaV2ParentId(int areaV2ParentId) { + this.areaV2ParentId = areaV2ParentId; + } + + public String getAreaV2ParentName() { + return areaV2ParentName; + } + + public void setAreaV2ParentName(String areaV2ParentName) { + this.areaV2ParentName = areaV2ParentName; + } + + public String getDataBehaviorId() { + return dataBehaviorId; + } + + public void setDataBehaviorId(String dataBehaviorId) { + this.dataBehaviorId = dataBehaviorId; + } + + public String getDataSourceId() { + return dataSourceId; + } + + public void setDataSourceId(String dataSourceId) { + this.dataSourceId = dataSourceId; + } + + public List getAcceptQualityV2() { + return acceptQualityV2; + } + + public void setAcceptQualityV2(List acceptQualityV2) { + this.acceptQualityV2 = acceptQualityV2; + } + + public static class Owner { + /** + * face : https://i1.hdslb.com/bfs/face/8ed8e486437b5053628248dd3c031b109b4cefcd.jpg + * mid : 218972880 + * name : 萌萌の糖酱 + */ + + @SerializedName("face") + private String face; + @SerializedName("mid") + private int mid; + @SerializedName("name") + private String name; + + public String getFace() { + return face; + } + + public void setFace(String face) { + this.face = face; + } + + public int getMid() { + return mid; + } + + public void setMid(int mid) { + this.mid = mid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class CoverX { + /** + * src : https://i0.hdslb.com/bfs/live/d5805bf0e4cb51b50ad4cbe209ae328aedaeeeda.jpg + * height : 180 + * width : 320 + */ + + @SerializedName("src") + private String src; + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/RoomListEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/RoomListEntity.java new file mode 100644 index 0000000..4bda933 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/RoomListEntity.java @@ -0,0 +1,364 @@ +package com.hiczp.bilibili.api.live.entity; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class RoomListEntity { + /** + * code : 0 + * msg : success + * message : success + * data : [{"roomid":919991,"uid":2948981,"title":"东京上野瞎逛","uname":"冷水煮乐器","online":22728,"user_cover":"https://i0.hdslb.com/bfs/live/a704b2150ebdda4afb49a4c153c9116fd04c191e.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/919991.jpg?03081511","show_cover":false,"link":"/606","face":"https://i2.hdslb.com/bfs/face/1ffdec7cfef14b79f782f94710bf6c427ae201dd.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/552875/live_2948981_9513554.flv?wsSecret=db4b54fcc5ea0c4089f46067f1c17c36&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":4698971,"uid":152382234,"title":"原来是小一呀的直播间","uname":"原来是小一呀","online":1320,"user_cover":"https://i0.hdslb.com/bfs/live/3bceded04a5d7df3437eaeca79f8de4a62840ac4.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/4698971.jpg?03071300","show_cover":false,"link":"/4698971","face":"https://i0.hdslb.com/bfs/face/dc1996e4f8b850b5bf8e1a2b1518093cdd0ea80c.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://txy.live-play.acgvideo.com/live-txy/770269/live_152382234_1119709.flv?wsSecret=b5f789ee9d09cfaf983cc0f862e29aad&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":8711188,"uid":284701760,"title":"女孩子今天不过节❤️","uname":"小蔚云","online":916,"user_cover":"https://i0.hdslb.com/bfs/live/faf6d79c26ce76a5ada2274fbe7c4af003a67f05.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/8711188.jpg?03081511","show_cover":"https://i0.hdslb.com/bfs/vc/c4262240642917432b8c403efca2f92e0f6cba43.jpg","link":"/8711188","face":"https://i0.hdslb.com/bfs/face/6cdd8c582bfb39544a9947283b33fe5d51778adf.jpg","parent_id":1,"parent_name":"娱乐","area_id":145,"area_name":"聊天室","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/180773/live_284701760_5649564.flv?wsSecret=a9c48e22b18081898a4729336f122ce3&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":5459316,"uid":16653477,"title":"血统测试 抽奖点歌","uname":"糕糕糕糕呀","online":4812,"user_cover":"https://i0.hdslb.com/bfs/live/146049c2307491eeece0dde3716023c9efedbd0a.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5459316.jpg?03081510","show_cover":false,"link":"/5459316","face":"https://i2.hdslb.com/bfs/face/5bb4ce5bf2511dd3e0e36c3f8f77dcb865feb20e.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/495889/live_16653477_6713858.flv?wsSecret=93983859f778e1872d0116cf69955047&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":7813816,"uid":250028724,"title":"❤️小白羊了解一下","uname":"蜜桃姐姐w","online":296,"user_cover":"https://i0.hdslb.com/bfs/live/74dd7aed3378788f9ac7b5698f0a0f0147536aea.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/7813816.jpg?03081511","show_cover":"https://i0.hdslb.com/bfs/vc/7e4f8c67416e18c10592151a516e3e3ef0738f72.jpg","link":"/7813816","face":"https://i1.hdslb.com/bfs/face/0eca69c4a0022102afb8e4c822f91033dcfe7529.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/338838/live_250028724_8476215.flv?wsSecret=6493558385047256f98a2415b1df3ddd&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":54572,"uid":232150,"title":"你是来暗中观察养猪的小可爱吗?","uname":"下限酱Orz","online":4658,"user_cover":"https://i0.hdslb.com/bfs/live/b222df524419844956d2a9d556955c7f927e0789.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/54572.jpg?03081510","show_cover":false,"link":"/149","face":"https://i1.hdslb.com/bfs/face/51402437ff06fb798835a966ce9c0896620ffb57.jpg","parent_id":1,"parent_name":"娱乐","area_id":28,"area_name":"萌宠","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/354172/live_232150_1148035.flv?wsSecret=d1211de9579d89426bb2b75ccfcb2255&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":1313362,"uid":11300631,"title":"【治愈萌音】手控福利❤可以做你的小公举吗","uname":"阿嗔想要抱抱喵","online":783,"user_cover":"https://i0.hdslb.com/bfs/live/c339c3a74044259b10d0896d661920f1f828fbcf.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1313362.jpg?03081511","show_cover":false,"link":"/1313362","face":"https://i0.hdslb.com/bfs/face/4c00951c5f837de7af061589d8fd9a01a36df2fe.jpg","parent_id":1,"parent_name":"娱乐","area_id":145,"area_name":"聊天室","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/877237/live_11300631_2817990.flv?wsSecret=87509af6c52685e7a7afbd02261e10dd&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":1271863,"uid":40275904,"title":"【温油小姐姐】进来听歌哇~","uname":"北有泽兮丶","online":256,"user_cover":"https://i0.hdslb.com/bfs/live/a6e41aae7f9aab76a660c4275323b85c1cfd6842.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1271863.jpg?03081507","show_cover":false,"link":"/1271863","face":"https://i1.hdslb.com/bfs/face/b34acbf8886aa32018dbde21a35b178454c884b5.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://live-play.acgvideo.com/live/962/live_40275904_1507293.flv?wsSecret=28ec4cb70ff9e0632fa4f105a0a00cde&wsTime=5a796354","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":9609987,"uid":16006274,"title":"myachien的直播间","uname":"myachien","online":57,"user_cover":"https://i0.hdslb.com/bfs/live/c6d8b2b6b766ef11e8af4f721feae0e2aaf7e39c.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/9609987.jpg?03081511","show_cover":false,"link":"/9609987","face":"https://i0.hdslb.com/bfs/face/b9b2f5552a1e027bbc51c51bcd8a60cb71948f9f.jpg","parent_id":1,"parent_name":"娱乐","area_id":145,"area_name":"聊天室","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/465160/live_16006274_1597898.flv?wsSecret=4e1f5d85f8fe7780751e3a1e50214ebc&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":8084310,"uid":275563061,"title":"知心小可爱上线了今天做啥呢","uname":"巧克力宝宝呀","online":1347,"user_cover":"https://i0.hdslb.com/bfs/live/10cdf58a8a719b5bfaed52bd97b01f0ac71002a8.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/8084310.jpg?03081510","show_cover":"https://i0.hdslb.com/bfs/vc/8333997ed17a55c9dd61c8bfc58cd0aadc772169.jpg","link":"/8084310","face":"https://i1.hdslb.com/bfs/face/34732fa6ae9207e0be7e4512a092b8c2acf6a564.jpg","parent_id":1,"parent_name":"娱乐","area_id":145,"area_name":"聊天室","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/404906/live_275563061_5849823.flv?wsSecret=b1bbc6e58888af9ac5463dc7113e76a8&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":18975,"uid":1864036,"title":"【玄凤鹦鹉】手养20多天大鹦鹉宝宝的日常","uname":"丢小喵了个丢小喵","online":2112,"user_cover":"https://i0.hdslb.com/bfs/live/ad3255f6b5931be9f38ec116f52aae78b3f48230.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/18975.jpg?03081511","show_cover":false,"link":"/18975","face":"https://i0.hdslb.com/bfs/face/3961857dbc9c1371a553a785884042f52c20efb3.jpg","parent_id":1,"parent_name":"娱乐","area_id":32,"area_name":"手机直播","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/789434/live_1864036_332_c521e483.flv?wsSecret=c9dc986c18120a31614e31174618985a&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":635644,"uid":6372029,"title":"这是一个隐藏的直播间","uname":"桜嵐karu","online":12792,"user_cover":"https://i0.hdslb.com/bfs/live/63ede64ee5fa35f34fbf30d98b09e22c6636f05a.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/635644.jpg?03081511","show_cover":"https://i0.hdslb.com/bfs/vc/d05d6c56f5b84276b3322c8363ec305b445720bd.jpg","link":"/413","face":"https://i1.hdslb.com/bfs/face/19419cf6cbcd182fdfd3802141bdad0bf54d66cb.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/815391/live_6372029_9770289.flv?wsSecret=f2da7ce318a1a14a37d7c2d4764d97cf&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":5269,"uid":1998535,"title":"iPanda我们永远开开心心在一起","uname":"iPanda熊猫频道","online":16212,"user_cover":"https://i0.hdslb.com/bfs/live/2ff40240f317382b8fab8d1d4af44199ac59546a.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5269.jpg?03081510","show_cover":false,"link":"/5269","face":"https://i2.hdslb.com/bfs/face/d26890e2f93ddfab10f2e21f93222ecab5da8e8a.gif","parent_id":1,"parent_name":"娱乐","area_id":28,"area_name":"萌宠","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/837993/live_1998535_9286339.flv?wsSecret=75dcf732c257d3bc7cf2f8e6c644a871&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":353421,"uid":106631,"title":"上舰送自制粘土~不考虑上下贼船嘛~","uname":"西瓜子Suikako","online":1322,"user_cover":"https://i0.hdslb.com/bfs/live/eebb9a8fac7b7403e0b9be392d5c256dd057c7b1.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/353421.jpg?03081507","show_cover":"https://i0.hdslb.com/bfs/vc/b1274fb220d31380b77f9151bcb6c3f710b0d0d4.jpg","link":"/595","face":"https://i0.hdslb.com/bfs/face/be4f9d50deea1c31e873331575531c3a0cea4e1e.jpg","parent_id":1,"parent_name":"娱乐","area_id":139,"area_name":"美少女","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/358194/live_106631_3052291.flv?wsSecret=8784f7b3364b21902795073178f0daa3&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":5419517,"uid":196424914,"title":"直播打包快递233~摸鱼","uname":"小樱桃手工杂货铺c","online":340,"user_cover":"https://i0.hdslb.com/bfs/live/50e584fbc37eb0bff9c4fa38fb34a6c8c5bf6ee0.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/5419517.jpg?03081511","show_cover":false,"link":"/5419517","face":"https://i1.hdslb.com/bfs/face/2d5af4a384b0746f917d4aea00f10c121f39b571.jpg","parent_id":1,"parent_name":"娱乐","area_id":25,"area_name":"手工","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/562263/live_196424914_3845269.flv?wsSecret=15d2a1d49c99570c26f12cb094bec056&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":6335764,"uid":11403277,"title":"女装大佬,啊啊啊","uname":"风小词","online":3151,"user_cover":"https://i0.hdslb.com/bfs/live/26c86b600ac32049a8aac8d4f148c2e0aac4d528.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/6335764.jpg?03081510","show_cover":"https://i0.hdslb.com/bfs/vc/365b7ba5661fd56300d0f3dc892093a13cc21ad9.jpg","link":"/6335764","face":"https://i0.hdslb.com/bfs/face/f5277d66762228d434188ab957aaac96be1ad3d8.jpg","parent_id":1,"parent_name":"娱乐","area_id":145,"area_name":"聊天室","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://qn.live-play.acgvideo.com/live-qn/811990/live_11403277_8254676.flv?wsSecret=0971c89314a5c8dd726dcd77d631d882&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":8503289,"uid":282069177,"title":"农村妇女化妆","uname":"胡屿simple","online":2946,"user_cover":"https://i0.hdslb.com/bfs/live/5a4ddc06ba4e21d95fc4d61046ce90b19b7f0720.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/8503289.jpg?03081510","show_cover":"https://i0.hdslb.com/bfs/vc/654af08b16d3abc3da4fe4015ddf103cc40b2521.jpg","link":"/8503289","face":"https://i0.hdslb.com/bfs/face/caab6ed5aa46f60298a1efb11ea6080a5570da1f.jpg","parent_id":1,"parent_name":"娱乐","area_id":145,"area_name":"聊天室","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/857598/live_282069177_9805841.flv?wsSecret=36f2716b55166540286f88784a8e28b9&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":1,"is_tv":0,"corner":"","pendent":""},{"roomid":1008041,"uid":8003874,"title":"唱鸽鸽老叔叔~","uname":"青山水涧","online":40,"user_cover":"https://i0.hdslb.com/bfs/live/1783a0b133c13968c929fe57d6a5d756bba2674b.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/1008041.jpg?03081511","show_cover":false,"link":"/1008041","face":"https://i0.hdslb.com/bfs/face/cc9c5bd84a98ee999a059b67c4ea4eee574f74dd.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://js.live-play.acgvideo.com/live-js/858958/live_8003874_9826284.flv?wsSecret=2dab5132c0806e7afaa00d4527f3f0b1&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":6733696,"uid":26399685,"title":"不七而遇丶三生有幸","uname":"七七七七次郎","online":2523,"user_cover":"https://i0.hdslb.com/bfs/live/01cfa78ae18d9e209e09a8cfabbb22520842a395.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/6733696.jpg?03081511","show_cover":false,"link":"/6733696","face":"https://i1.hdslb.com/bfs/face/593fa6d58abe3c42e2f3d52567a42dcac189119e.jpg","parent_id":1,"parent_name":"娱乐","area_id":21,"area_name":"唱见","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://dl.live-play.acgvideo.com/live-dl/139521/live_26399685_9201826.flv?wsSecret=fb68eec943b1bc2c54b6839084349748&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""},{"roomid":2256697,"uid":38070613,"title":"一个乖团子","uname":"丢你小心心","online":86,"user_cover":"https://i0.hdslb.com/bfs/live/040331852807a339deabc47d0f66171eccf6049a.jpg","user_cover_flag":1,"system_cover":"https://i0.hdslb.com/bfs/live/2256697.jpg?03081507","show_cover":false,"link":"/2256697","face":"https://i0.hdslb.com/bfs/face/b14a5bcbff95267d16e2520650f0cef5c2e0d4fa.jpg","parent_id":1,"parent_name":"娱乐","area_id":145,"area_name":"聊天室","web_pendent":"","cover_size":{"height":180,"width":320},"play_url":"http://bvc.live-play.acgvideo.com/live-bvc/959275/live_38070613_7623319.flv?wsSecret=803dd746ef1d70b813b4ea08f88c1df7&wsTime=1520494924","accept_quality_v2":[4],"current_quality":0,"accept_quality":"4","broadcast_type":0,"is_tv":0,"corner":"","pendent":""}] + */ + + @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; + } + + public static class Data { + /** + * roomid : 919991 + * uid : 2948981 + * title : 东京上野瞎逛 + * uname : 冷水煮乐器 + * online : 22728 + * user_cover : https://i0.hdslb.com/bfs/live/a704b2150ebdda4afb49a4c153c9116fd04c191e.jpg + * user_cover_flag : 1 + * system_cover : https://i0.hdslb.com/bfs/live/919991.jpg?03081511 + * show_cover : false + * link : /606 + * face : https://i2.hdslb.com/bfs/face/1ffdec7cfef14b79f782f94710bf6c427ae201dd.jpg + * parent_id : 1 + * parent_name : 娱乐 + * area_id : 32 + * area_name : 手机直播 + * web_pendent : + * cover_size : {"height":180,"width":320} + * play_url : http://qn.live-play.acgvideo.com/live-qn/552875/live_2948981_9513554.flv?wsSecret=db4b54fcc5ea0c4089f46067f1c17c36&wsTime=1520494924 + * accept_quality_v2 : [4] + * current_quality : 0 + * accept_quality : 4 + * broadcast_type : 0 + * is_tv : 0 + * corner : + * pendent : + */ + + @SerializedName("roomid") + private int roomid; + @SerializedName("uid") + private int uid; + @SerializedName("title") + private String title; + @SerializedName("uname") + private String uname; + @SerializedName("online") + private int online; + @SerializedName("user_cover") + private String userCover; + @SerializedName("user_cover_flag") + private int userCoverFlag; + @SerializedName("system_cover") + private String systemCover; + @SerializedName("show_cover") + private boolean showCover; + @SerializedName("link") + private String link; + @SerializedName("face") + private String face; + @SerializedName("parent_id") + private int parentId; + @SerializedName("parent_name") + private String parentName; + @SerializedName("area_id") + private int areaId; + @SerializedName("area_name") + private String areaName; + @SerializedName("web_pendent") + private String webPendent; + @SerializedName("cover_size") + private CoverSize coverSize; + @SerializedName("play_url") + private String playUrl; + @SerializedName("current_quality") + private int currentQuality; + @SerializedName("accept_quality") + private String acceptQuality; + @SerializedName("broadcast_type") + private int broadcastType; + @SerializedName("is_tv") + private int isTv; + @SerializedName("corner") + private String corner; + @SerializedName("pendent") + private String pendent; + @SerializedName("accept_quality_v2") + private List acceptQualityV2; + + public int getRoomid() { + return roomid; + } + + public void setRoomid(int roomid) { + this.roomid = roomid; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUname() { + return uname; + } + + public void setUname(String uname) { + this.uname = uname; + } + + public int getOnline() { + return online; + } + + public void setOnline(int online) { + this.online = online; + } + + public String getUserCover() { + return userCover; + } + + public void setUserCover(String userCover) { + this.userCover = userCover; + } + + public int getUserCoverFlag() { + return userCoverFlag; + } + + public void setUserCoverFlag(int userCoverFlag) { + this.userCoverFlag = userCoverFlag; + } + + public String getSystemCover() { + return systemCover; + } + + public void setSystemCover(String systemCover) { + this.systemCover = systemCover; + } + + public boolean isShowCover() { + return showCover; + } + + public void setShowCover(boolean showCover) { + this.showCover = showCover; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getFace() { + return face; + } + + public void setFace(String face) { + this.face = face; + } + + public int getParentId() { + return parentId; + } + + public void setParentId(int parentId) { + this.parentId = parentId; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } + + public int getAreaId() { + return areaId; + } + + public void setAreaId(int areaId) { + this.areaId = areaId; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + public String getWebPendent() { + return webPendent; + } + + public void setWebPendent(String webPendent) { + this.webPendent = webPendent; + } + + public CoverSize getCoverSize() { + return coverSize; + } + + public void setCoverSize(CoverSize coverSize) { + this.coverSize = coverSize; + } + + public String getPlayUrl() { + return playUrl; + } + + public void setPlayUrl(String playUrl) { + this.playUrl = playUrl; + } + + public int getCurrentQuality() { + return currentQuality; + } + + public void setCurrentQuality(int currentQuality) { + this.currentQuality = currentQuality; + } + + public String getAcceptQuality() { + return acceptQuality; + } + + public void setAcceptQuality(String acceptQuality) { + this.acceptQuality = acceptQuality; + } + + public int getBroadcastType() { + return broadcastType; + } + + public void setBroadcastType(int broadcastType) { + this.broadcastType = broadcastType; + } + + public int getIsTv() { + return isTv; + } + + public void setIsTv(int isTv) { + this.isTv = isTv; + } + + public String getCorner() { + return corner; + } + + public void setCorner(String corner) { + this.corner = corner; + } + + public String getPendent() { + return pendent; + } + + public void setPendent(String pendent) { + this.pendent = pendent; + } + + public List getAcceptQualityV2() { + return acceptQualityV2; + } + + public void setAcceptQualityV2(List acceptQualityV2) { + this.acceptQualityV2 = acceptQualityV2; + } + + public static class CoverSize { + /** + * height : 180 + * width : 320 + */ + + @SerializedName("height") + private int height; + @SerializedName("width") + private int width; + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + } +} From 3d190c2df78736634ff43a97ca77bec2eb3c68a5 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 16:26:50 +0800 Subject: [PATCH 38/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E7=9B=B4=E6=92=AD?= =?UTF-8?q?=20=E9=A1=B5=E9=9D=A2=E7=9A=84=20=E6=9F=A5=E7=9C=8B=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A=20=E7=9A=84=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/live/LiveService.java | 18 ++- .../api/live/entity/AreaListEntity.java | 116 ++++++++++++++++++ 2 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/AreaListEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index b7b8151..f14e0c7 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -177,18 +177,30 @@ public interface LiveService { return recommendRefresh("android"); } - //直播页面 下面的 普通分区(复数) 的刷新, 一次会返回 20 个结果, 客户端显示 6 个, 数据用完了之后再次访问该 API + //获取对应分类和状态的直播间 //area_id 和 cate_id 不明确其含义 @GET("room/v1/Area/getRoomList") Call getRoomList( @Query("area_id") int areaId, @Query("cate_id") int categoryId, @Query("parent_area_id") int parentAreaId, - @Query("sort_type") String sortType + @Query("sort_type") String sortType, + @Query("page") Long page ); + //直播页面 下面的 普通分区(复数) 的刷新, 一次会返回 20 个结果, 客户端显示 6 个, 数据用完了之后再次访问该 API default Call getRoomList(int parentAreaId) { - return getRoomList(0, 0, parentAreaId, "dynamic"); + return getRoomList(0, 0, parentAreaId, "dynamic", null); + } + + //直播 -> 某个分区 -> 查看更多 + //获取该页面上方的分类标签 + @GET("room/v1/Area/getList") + Call getAreaList(@Query("parent_id") int parentAreaId); + + //获取该页面下的的直播间(areaId 为 0 表示选择了 "全部"(上方的分类标签), areaId 如果和 parentAreaId 不匹配将返回空的 data 字段) + default Call getRoomList(int areaId, int parentAreaId, long page) { + return getRoomList(areaId, 0, parentAreaId, "online", page); } //直播 -> 全部直播(直播页面的最下面的一个按钮) diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/AreaListEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/AreaListEntity.java new file mode 100644 index 0000000..d1d142b --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/AreaListEntity.java @@ -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":"CS:GO","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; + + 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; + } + + 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; + } + } +} From 49c639effa47e1afb441ffb1013b925db44e5fd7 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 16:29:17 +0800 Subject: [PATCH 39/73] =?UTF-8?q?=E5=A2=9E=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/com/hiczp/bilibili/api/live/LiveService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 560219f..09beb47 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ # 添加依赖 ## Gradle - compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.7' + compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.8' # 名词解释 B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一些常见参数对应的含义 diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index f14e0c7..04332f2 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -178,7 +178,7 @@ public interface LiveService { } //获取对应分类和状态的直播间 - //area_id 和 cate_id 不明确其含义 + //cate_id 不明确其含义 @GET("room/v1/Area/getRoomList") Call getRoomList( @Query("area_id") int areaId, From 9bdaa584ce23f8ea3f7c7de90c9896520af4b962 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 17:00:29 +0800 Subject: [PATCH 40/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=95=B0=E6=8D=AE=E5=8C=85=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=20SPECIAL=5FGIFT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SPECIAL_GIFT.json | 14 ++ .../hiczp/bilibili/api/live/LiveService.java | 1 - .../live/socket/entity/SpecialGiftEntity.java | 132 ++++++++++++++++++ .../socket/event/SpecialGiftPackageEvent.java | 9 ++ .../socket/handler/LiveClientHandler.java | 31 ++-- 5 files changed, 173 insertions(+), 14 deletions(-) create mode 100644 record/bullet_screen_stream_json/SPECIAL_GIFT.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/SpecialGiftEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java diff --git a/record/bullet_screen_stream_json/SPECIAL_GIFT.json b/record/bullet_screen_stream_json/SPECIAL_GIFT.json new file mode 100644 index 0000000..33b401a --- /dev/null +++ b/record/bullet_screen_stream_json/SPECIAL_GIFT.json @@ -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" + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 04332f2..9835741 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -55,7 +55,6 @@ public interface LiveService { Call getTitle(); //TODO 节奏风暴 - //这个 API 不是很明确, 似乎和 节奏风暴 有关系 @GET("SpecialGift/room/{roomId}") Call getSpecialGift(@Path("roomId") long roomId); diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SpecialGiftEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SpecialGiftEntity.java new file mode 100644 index 0000000..1486f45 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SpecialGiftEntity.java @@ -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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java new file mode 100644 index 0000000..69a9c61 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.SpecialGiftEntity; + +public class SpecialGiftPackageEvent extends ReceiveDataPackageEvent { + public SpecialGiftPackageEvent(Object source, SpecialGiftEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index bedbd71..9f37e2d 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -117,21 +117,15 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new WelcomeGuardPackageEvent(this, GSON.fromJson(content, WelcomeGuardEntity.class)); } break; - //开始直播 - case "LIVE": { - eventCreationExpression = () -> new LivePackageEvent(this, GSON.fromJson(content, LiveEntity.class)); - } - break; - //停止直播 - case "PREPARING": { - eventCreationExpression = () -> new PreparingPackageEvent(this, GSON.fromJson(content, PreparingEntity.class)); - } - break; //活动事件 case "ACTIVITY_EVENT": { eventCreationExpression = () -> new ActivityEventPackageEvent(this, GSON.fromJson(content, ActivityEventEntity.class)); } break; + case "SPECIAL_GIFT": { + eventCreationExpression = () -> new SpecialGiftPackageEvent(this, GSON.fromJson(content, SpecialGiftEntity.class)); + } + break; //许愿瓶 case "WISH_BOTTLE": { eventCreationExpression = () -> new WishBottlePackageEvent(this, GSON.fromJson(content, WishBottleEntity.class)); @@ -162,14 +156,25 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(content, GuardMsgEntity.class)); } break; + //TODO TV_START + //小电视抽奖结束(大奖的获得者信息) + case "TV_END": { + eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(content, TVEndEntity.class)); + } + break; //房管变更 case "ROOM_ADMINS": { eventCreationExpression = () -> new RoomAdminsPackageEvent(this, GSON.fromJson(content, RoomAdminsEntity.class)); } break; - //小电视抽奖结束(大奖的获得者信息) - case "TV_END": { - eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(content, TVEndEntity.class)); + //开始直播 + case "LIVE": { + eventCreationExpression = () -> new LivePackageEvent(this, GSON.fromJson(content, LiveEntity.class)); + } + break; + //停止直播 + case "PREPARING": { + eventCreationExpression = () -> new PreparingPackageEvent(this, GSON.fromJson(content, PreparingEntity.class)); } break; default: { From 54530080567270a21a40b4d5c04afdee8f4da215 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 8 Mar 2018 17:24:58 +0800 Subject: [PATCH 41/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 09beb47..42f4ec0 100644 --- a/README.md +++ b/README.md @@ -306,6 +306,7 @@ API 文档 | RoomSilentOnPackageEvent | 收到 ROOM_SILENT_ON 数据包 | | SendGiftPackageEvent | 收到 SEND_GIFT 数据包 | | SendHeartBeatPackageEvent | 每次发送心跳包后触发一次 | +| SpecialGiftPackageEvent | 收到 SPECIAL_GIFT 数据包 | | SysGiftPackageEvent | 收到 SYS_GIFT 数据包 | | SysMsgPackageEvent | 收到 SYS_MSG 数据包 | | TVEndPackageEvent | 收到 TV_END 数据包 | From 5ab15b2e3e55dad4d7898e88e9df6ae126c6ac29 Mon Sep 17 00:00:00 2001 From: czp Date: Sat, 10 Mar 2018 14:55:07 +0800 Subject: [PATCH 42/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20DANMU=5FMSG=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8C=85=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DANMU_MSG(with comment).json | 12 ++++++++---- record/bullet_screen_stream_json/DANMU_MSG.json | 8 ++++++-- .../api/live/socket/entity/DanMuMsgEntity.java | 7 ++++++- .../bilibili/api/test/SendBulletScreenTest.java | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/record/bullet_screen_stream_json/DANMU_MSG(with comment).json b/record/bullet_screen_stream_json/DANMU_MSG(with comment).json index 9046e09..f53c016 100644 --- a/record/bullet_screen_stream_json/DANMU_MSG(with comment).json +++ b/record/bullet_screen_stream_json/DANMU_MSG(with comment).json @@ -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" } diff --git a/record/bullet_screen_stream_json/DANMU_MSG.json b/record/bullet_screen_stream_json/DANMU_MSG.json index 5c3f25c..08f4d88 100644 --- a/record/bullet_screen_stream_json/DANMU_MSG.json +++ b/record/bullet_screen_stream_json/DANMU_MSG.json @@ -19,7 +19,8 @@ 1, 0, 10000, - 1 + 1, + "" ], [ 13, @@ -37,7 +38,10 @@ ], [], 0, - 0 + 0, + { + "uname_color": "" + } ], "cmd": "DANMU_MSG" } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java index 718cd75..ef64ad0 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java @@ -15,7 +15,7 @@ public class DanMuMsgEntity implements DataEntity { }.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 */ @@ -152,4 +152,9 @@ public class DanMuMsgEntity implements DataEntity { public List getUserTitles() { return GSON.fromJson(info.get(5), STRING_LIST_TYPE); } + + //获得用户名颜色 + public String getUsernameColor() { + return info.get(8).getAsJsonObject().get("uname_color").getAsString(); + } } diff --git a/src/test/java/com/hiczp/bilibili/api/test/SendBulletScreenTest.java b/src/test/java/com/hiczp/bilibili/api/test/SendBulletScreenTest.java index 746b14f..eef26d5 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/SendBulletScreenTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/SendBulletScreenTest.java @@ -5,7 +5,7 @@ import com.hiczp.bilibili.api.live.entity.BulletScreenEntity; import org.junit.Test; public class SendBulletScreenTest { - private static final long ROOM_ID = 29434; + private static final long ROOM_ID = 1110317; private static final BilibiliAPI BILIBILI_API = Config.getBilibiliAPI(); @Test From 5d4177b756c2bf3d362328fb6784fa774be24363 Mon Sep 17 00:00:00 2001 From: czp Date: Sun, 11 Mar 2018 00:25:18 +0800 Subject: [PATCH 43/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=95=B0=E6=8D=AE=E5=8C=85=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=20TV=5FSTART?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bullet_screen_stream_json/TV_START.json | 23 ++ .../api/live/socket/entity/TVStartEntity.java | 231 ++++++++++++++++++ .../socket/event/TVStartPackageEvent.java | 9 + .../socket/handler/LiveClientHandler.java | 71 +++--- 4 files changed, 300 insertions(+), 34 deletions(-) create mode 100644 record/bullet_screen_stream_json/TV_START.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVStartEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java diff --git a/record/bullet_screen_stream_json/TV_START.json b/record/bullet_screen_stream_json/TV_START.json new file mode 100644 index 0000000..6abdc17 --- /dev/null +++ b/record/bullet_screen_stream_json/TV_START.json @@ -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 + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVStartEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVStartEntity.java new file mode 100644 index 0000000..23afb2f --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/TVStartEntity.java @@ -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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java new file mode 100644 index 0000000..1352409 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.TVStartEntity; + +public class TVStartPackageEvent extends ReceiveDataPackageEvent { + public TVStartPackageEvent(Object source, TVStartEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 9f37e2d..c69303c 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -62,23 +62,6 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Exception { switch (msg.getPackageType()) { - case VIEWER_COUNT: { - eventBus.post(new ViewerCountPackageEvent(this, ByteBuffer.wrap(msg.getContent()).getInt())); - } - break; - case ENTER_ROOM_SUCCESS: { - eventBus.post(new ConnectSucceedEvent(this)); - ctx.executor().scheduleAtFixedRate( - () -> { - ctx.writeAndFlush(PackageHelper.createHeartBeatPackage()); - eventBus.post(new SendHeartBeatPackageEvent(this)); - }, - 0L, - 30L, - TimeUnit.SECONDS - ); - } - break; case DATA: { String content = new String(msg.getContent()); String cmd = JSON_PARSER.parse(content) @@ -97,9 +80,19 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new SendGiftPackageEvent(this, GSON.fromJson(content, SendGiftEntity.class)); } break; - //系统礼物(丰收庆典, 新春抽奖等) - case "SYS_GIFT": { - eventCreationExpression = () -> new SysGiftPackageEvent(this, GSON.fromJson(content, SysGiftEntity.class)); + //欢迎 + case "WELCOME": { + eventCreationExpression = () -> new WelcomePackageEvent(this, GSON.fromJson(content, WelcomeEntity.class)); + } + break; + //许愿瓶 + case "WISH_BOTTLE": { + eventCreationExpression = () -> new WishBottlePackageEvent(this, GSON.fromJson(content, WishBottleEntity.class)); + } + break; + //欢迎(舰队) + case "WELCOME_GUARD": { + eventCreationExpression = () -> new WelcomeGuardPackageEvent(this, GSON.fromJson(content, WelcomeGuardEntity.class)); } break; //系统消息(小电视等) @@ -107,14 +100,9 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new SysMsgPackageEvent(this, GSON.fromJson(content, SysMsgEntity.class)); } break; - //欢迎 - case "WELCOME": { - eventCreationExpression = () -> new WelcomePackageEvent(this, GSON.fromJson(content, WelcomeEntity.class)); - } - break; - //欢迎(舰队) - case "WELCOME_GUARD": { - eventCreationExpression = () -> new WelcomeGuardPackageEvent(this, GSON.fromJson(content, WelcomeGuardEntity.class)); + //系统礼物(丰收庆典, 新春抽奖等) + case "SYS_GIFT": { + eventCreationExpression = () -> new SysGiftPackageEvent(this, GSON.fromJson(content, SysGiftEntity.class)); } break; //活动事件 @@ -126,11 +114,6 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new SpecialGiftPackageEvent(this, GSON.fromJson(content, SpecialGiftEntity.class)); } break; - //许愿瓶 - case "WISH_BOTTLE": { - eventCreationExpression = () -> new WishBottlePackageEvent(this, GSON.fromJson(content, WishBottleEntity.class)); - } - break; //房间黑名单(添加了一个用户到黑名单) case "ROOM_BLOCK_MSG": { eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(content, RoomBlockMsgEntity.class)); @@ -156,7 +139,10 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(content, GuardMsgEntity.class)); } break; - //TODO TV_START + case "TV_START": { + eventCreationExpression = () -> new TVStartPackageEvent(this, GSON.fromJson(content, TVStartEntity.class)); + } + break; //小电视抽奖结束(大奖的获得者信息) case "TV_END": { eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(content, TVEndEntity.class)); @@ -191,6 +177,23 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { } } break; + case VIEWER_COUNT: { + eventBus.post(new ViewerCountPackageEvent(this, ByteBuffer.wrap(msg.getContent()).getInt())); + } + break; + case ENTER_ROOM_SUCCESS: { + eventBus.post(new ConnectSucceedEvent(this)); + ctx.executor().scheduleAtFixedRate( + () -> { + ctx.writeAndFlush(PackageHelper.createHeartBeatPackage()); + eventBus.post(new SendHeartBeatPackageEvent(this)); + }, + 0L, + 30L, + TimeUnit.SECONDS + ); + } + break; } } From cb2b985d579325befbd17b072d78063b1a2f82b1 Mon Sep 17 00:00:00 2001 From: czp Date: Sun, 11 Mar 2018 00:27:55 +0800 Subject: [PATCH 44/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 42f4ec0..6f4a9a4 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,7 @@ IOException 在网络错误时抛出(获取 cookie 时需要进行网络请求) ### API 调用示例 打印一个直播间的历史弹幕 - int roomId = 3; + long roomId = 3; new BilibiliAPI() .getLiveService() .getHistoryBulletScreens(roomId) @@ -223,7 +223,7 @@ IOException 在网络错误时抛出(获取 cookie 时需要进行网络请求) String username = "yourUsername"; String password = "yourPassword"; - int roomId = 3; + long roomId = 3; BilibiliAPI bilibiliAPI = new BilibiliAPI() .login(username, password); @@ -246,7 +246,7 @@ API 文档 ## Socket ### 获取直播间实时弹幕 - int roomId = 3; + long roomId = 3; LiveClient liveClient = new BilibiliAPI() .getLiveClient(roomId) .registerListener(new MyListener()) @@ -310,6 +310,7 @@ API 文档 | SysGiftPackageEvent | 收到 SYS_GIFT 数据包 | | SysMsgPackageEvent | 收到 SYS_MSG 数据包 | | TVEndPackageEvent | 收到 TV_END 数据包 | +| TVStartPackageEvent | 收到 TV_START 数据包 | | UnknownPackageEvent | B站新增了新种类的数据包, 出现此情况请提交 issue | | ViewerCountPackageEvent | 收到 房间人数 数据包(不是 Json) | | WelcomeGuardPackageEvent | 收到 WELCOME_GUARD 数据包 | @@ -353,8 +354,8 @@ room_id 的获取要通过 在代码中我们这样做 - int showRoomId = 3; - int roomId = bilibiliAPI.getLiveService() + long showRoomId = 3; + long roomId = bilibiliAPI.getLiveService() .getRoomInfo(showRoomId) .execute() .body() From 62072210f5a0a033845473ea4e038a445924ac47 Mon Sep 17 00:00:00 2001 From: czp Date: Sun, 11 Mar 2018 00:49:55 +0800 Subject: [PATCH 45/73] =?UTF-8?q?=E8=8A=82=E5=A5=8F=E9=A3=8E=E6=9A=B4?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85=E4=B8=AD=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=20real=5Froomid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- .../{SYS_GIFT.json => SYS_GIFT(丰收庆典).json} | 0 .../bullet_screen_stream_json/SYS_GIFT(新春抽奖).json | 11 +++++++++++ .../SYS_GIFT(普通礼物,不可抽奖).json | 9 +++++++++ .../bullet_screen_stream_json/SYS_GIFT(节奏风暴).json | 10 ++++++++++ 5 files changed, 31 insertions(+), 1 deletion(-) rename record/bullet_screen_stream_json/{SYS_GIFT.json => SYS_GIFT(丰收庆典).json} (100%) create mode 100644 record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json create mode 100644 record/bullet_screen_stream_json/SYS_GIFT(普通礼物,不可抽奖).json create mode 100644 record/bullet_screen_stream_json/SYS_GIFT(节奏风暴).json diff --git a/build.gradle b/build.gradle index c6c37e4..65ba32e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group = 'com.hiczp' -version = '0.0.8' +version = '0.0.9' description = 'Bilibili android client API library written in Java' apply plugin: 'idea' diff --git a/record/bullet_screen_stream_json/SYS_GIFT.json b/record/bullet_screen_stream_json/SYS_GIFT(丰收庆典).json similarity index 100% rename from record/bullet_screen_stream_json/SYS_GIFT.json rename to record/bullet_screen_stream_json/SYS_GIFT(丰收庆典).json diff --git a/record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json b/record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json new file mode 100644 index 0000000..d7536ae --- /dev/null +++ b/record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json @@ -0,0 +1,11 @@ +{ + "cmd": "SYS_GIFT", + "msg": "小螃海白翼OuO在直播间5540554开启了新春抽奖,红包大派送啦!一起来沾沾喜气吧!", + "msg_text": "小螃海白翼OuO在直播间5540554开启了新春抽奖,红包大派送啦!一起来沾沾喜气吧!", + "tips": "小螃海白翼OuO在直播间5540554开启了新春抽奖,红包大派送啦!一起来沾沾喜气吧!", + "url": "http://live.bilibili.com/5540554 ", + "roomid": 5540554, + "real_roomid": 5540554, + "giftId": 113, + "msgTips": 0 +} diff --git a/record/bullet_screen_stream_json/SYS_GIFT(普通礼物,不可抽奖).json b/record/bullet_screen_stream_json/SYS_GIFT(普通礼物,不可抽奖).json new file mode 100644 index 0000000..cf55e8d --- /dev/null +++ b/record/bullet_screen_stream_json/SYS_GIFT(普通礼物,不可抽奖).json @@ -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 +} diff --git a/record/bullet_screen_stream_json/SYS_GIFT(节奏风暴).json b/record/bullet_screen_stream_json/SYS_GIFT(节奏风暴).json new file mode 100644 index 0000000..c56d79e --- /dev/null +++ b/record/bullet_screen_stream_json/SYS_GIFT(节奏风暴).json @@ -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 +} From b53d92087782bd6d76bd3b92829daf268ed838e4 Mon Sep 17 00:00:00 2001 From: czp Date: Sun, 11 Mar 2018 13:45:16 +0800 Subject: [PATCH 46/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8F=82=E4=B8=8E?= =?UTF-8?q?=E5=B0=8F=E7=94=B5=E8=A7=86=E6=8A=BD=E5=A5=96=20=E7=9A=84=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/live/LiveService.java | 12 ++- .../entity/JoinAppSmallTVResponseEntity.java | 92 +++++++++++++++++++ 2 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 9835741..24bbd08 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -41,13 +41,18 @@ public interface LiveService { @GET("AppIndex/getAllItem") Call getAllItem(); - //TODO 小电视 //查看可用的小电视抽奖 //当目标房间没有可用的小电视抽奖时返回 -400 @GET("AppSmallTV/index") Call getAppSmallTV(@Query("roomid") long roomId); - //TODO 参与抽奖 - //TODO 查看抽奖结果 + + //参与小电视抽奖 + //房间号必须与小电视号对应 + //目标小电视不存在时(房间号与小电视号不匹配时也视为不存在)返回 -400 "不存在小电视信息" + @POST("AppSmallTV/join") + Call joinAppSmallTV(@Query("roomid") long roomId, @Query("id") long tvId); + + //TODO 查看小电视抽奖结果 //获得所有头衔的列表 //这里的 Title 是头衔的意思 @@ -57,6 +62,7 @@ public interface LiveService { //TODO 节奏风暴 @GET("SpecialGift/room/{roomId}") Call getSpecialGift(@Path("roomId") long roomId); + //TODO 参与节奏风暴抽奖 //获取自己的用户信息(live 站的个人信息, 非总站) //未登录时返回 3 diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java new file mode 100644 index 0000000..fd7bd3e --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java @@ -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 int id; + @SerializedName("dtime") + private int dtime; + @SerializedName("status") + private int status; + + public int getId() { + return id; + } + + public void setId(int 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; + } + } +} From 3fe58e743d39626593ccdf1837cd99160ad5d85c Mon Sep 17 00:00:00 2001 From: czp Date: Sun, 11 Mar 2018 19:17:59 +0800 Subject: [PATCH 47/73] =?UTF-8?q?LiveClient=20=E4=BD=BF=E7=94=A8=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E6=8F=90=E4=BE=9B=E7=9A=84=20EventLoopGroup,=20?= =?UTF-8?q?=E5=B9=B6=E5=A2=9E=E5=8A=A0=E5=BC=82=E6=AD=A5=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 ++-- .../com/hiczp/bilibili/api/BilibiliAPI.java | 7 +- .../bilibili/api/live/socket/LiveClient.java | 115 +++++++----------- .../socket/handler/LiveClientHandler.java | 31 ++++- .../api/provider/LiveClientProvider.java | 3 +- .../bilibili/api/test/LiveClientTest.java | 18 ++- 6 files changed, 109 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 6f4a9a4..6727ce4 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ # 添加依赖 ## Gradle - compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.8' + compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.9' # 名词解释 B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一些常见参数对应的含义 @@ -99,7 +99,7 @@ LoginException 在 accessToken 错误或过期时抛出 try { bilibiliAPI.login(username, password); } catch (CaptchaMismatchException e) { //如果该账号现在需要验证码来进行登录, 就会抛出异常 - final cookie = "sid=123456"; //自己造一个 cookie 或者从服务器取得 + cookie = "sid=123456"; //自己造一个 cookie 或者从服务器取得 Response response = bilibiliAPI.getPassportService() .getCaptcha(cookie) .execute(); @@ -159,7 +159,7 @@ B站客户端内置的 WebView 就是通过这种方式来工作的(WebView 访 如果只想得到用于进行 SSO 操作的那条 URL, 可以这么做 - final String goUrl = "https://account.bilibili.com/account/home"; + String goUrl = "https://account.bilibili.com/account/home"; bilibiliAPI.getSsoUrl(goUrl); 返回值是一个 HttpUrl, 里面 url 的值差不多是这样的 @@ -247,17 +247,24 @@ API 文档 ### 获取直播间实时弹幕 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. + + eventLoopGroup.shutdownGracefully(); + +将异步关闭所有使用这个 EventLoopGroup 的 LiveClient. + (connect 方法运行结束只代表 socket 确实是连上了, 但是服务器还没有响应进房请求数据包) (当服务器响应进房请求数据包时才代表真的连上了, 此时会有一个连接成功的事件, 见下文) @@ -284,9 +291,13 @@ API 文档 如果持续 40 秒(心跳包为 30 秒)没有收到任何消息, 将视为掉线, 会跟服务器主动断开连接一样(这通常是发送了服务器无法读取的数据包)触发一次 ConnectionCloseEvent. - liveClient.close(); + liveClient.closeChannel(); -即可关闭连接. +即可阻塞关闭连接. + + liveClient.closeChannelAsync(); + +即可异步关闭连接. 所有的事件(有些数据包我也不知道它里面的一些值是什么含义, /record 目录下面有抓取到的 Json, 可以用来查看): diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 2e79c35..7b59074 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -15,6 +15,7 @@ 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; @@ -380,10 +381,10 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv } @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() { diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java b/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java index 6a5cbeb..c8bd48d 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java @@ -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.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 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(), showRoomId, 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 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; + } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index c69303c..360c6ac 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -5,6 +5,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; +import com.hiczp.bilibili.api.live.socket.LiveClient; import com.hiczp.bilibili.api.live.socket.Package; import com.hiczp.bilibili.api.live.socket.PackageHelper; import com.hiczp.bilibili.api.live.socket.entity.*; @@ -25,14 +26,18 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { private static final Gson GSON = new Gson(); private static final JsonParser JSON_PARSER = new JsonParser(); - private long roomId; - private long userId; - private EventBus eventBus; + private final LiveClient liveClient; + private final EventBus eventBus; + private final long showRoomId; + private final long roomId; + private final long userId; - public LiveClientHandler(long roomId, long userId, EventBus eventBus) { + public LiveClientHandler(LiveClient liveClient, long showRoomId, long roomId, long userId) { + this.liveClient = liveClient; + this.eventBus = liveClient.getEventBus(); + this.showRoomId = showRoomId; this.roomId = roomId; this.userId = userId; - this.eventBus = eventBus; } @Override @@ -203,4 +208,20 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { .create() .toJson(JSON_PARSER.parse(json)); } + + public LiveClient getLiveClient() { + return liveClient; + } + + public long getShowRoomId() { + return showRoomId; + } + + public long getRoomId() { + return roomId; + } + + public long getUserId() { + return userId; + } } diff --git a/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java b/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java index b1935a0..4404484 100644 --- a/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java +++ b/src/main/java/com/hiczp/bilibili/api/provider/LiveClientProvider.java @@ -1,7 +1,8 @@ package com.hiczp.bilibili.api.provider; import com.hiczp.bilibili.api.live.socket.LiveClient; +import io.netty.channel.EventLoopGroup; public interface LiveClientProvider { - LiveClient getLiveClient(long showRoomId); + LiveClient getLiveClient(EventLoopGroup eventLoopGroup, long showRoomId); } diff --git a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java index 370a285..e7f8767 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java @@ -5,6 +5,8 @@ import com.hiczp.bilibili.api.BilibiliAPI; import com.hiczp.bilibili.api.live.socket.LiveClient; import com.hiczp.bilibili.api.live.socket.entity.*; import com.hiczp.bilibili.api.live.socket.event.*; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; import org.junit.FixMethodOrder; import org.junit.Ignore; import org.junit.Test; @@ -24,8 +26,9 @@ public class LiveClientTest { @Ignore @Test public void _0_duplicateConnectAndCloseTest() throws Exception { + EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); LiveClient liveClient = BILIBILI_API - .getLiveClient(ROOM_ID); + .getLiveClient(eventLoopGroup, ROOM_ID); LOGGER.debug("Connecting!"); liveClient.connect(); Thread.sleep(5000); @@ -33,31 +36,34 @@ public class LiveClientTest { liveClient.connect(); Thread.sleep(5000); LOGGER.debug("Disconnecting!"); - liveClient.close(); + liveClient.closeChannel(); Thread.sleep(5000); LOGGER.debug("Disconnecting!"); - liveClient.close(); + liveClient.closeChannel(); Thread.sleep(5000); LOGGER.debug("Connecting!"); liveClient.connect(); Thread.sleep(5000); LOGGER.debug("Disconnecting!"); - liveClient.close(); + liveClient.closeChannel(); Thread.sleep(5000); + eventLoopGroup.shutdownGracefully(); } @Ignore @Test public void _1_longTimeTest() throws Exception { + EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); LiveClient liveClient = BILIBILI_API - .getLiveClient(ROOM_ID) + .getLiveClient(eventLoopGroup, ROOM_ID) .registerListener(new Listener()); LOGGER.debug("Start long-time test"); LOGGER.debug("Connecting!"); liveClient.connect(); Thread.sleep(TEST_TIME); LOGGER.debug("Disconnecting!"); - liveClient.close(); + liveClient.closeChannel(); + eventLoopGroup.shutdownGracefully(); Thread.sleep(5000); } From f97ec15242b6082723a40007d0715b4db2671d3c Mon Sep 17 00:00:00 2001 From: czp Date: Sun, 11 Mar 2018 19:31:13 +0800 Subject: [PATCH 48/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6727ce4..aedab6b 100644 --- a/README.md +++ b/README.md @@ -261,10 +261,6 @@ API 文档 多个 LiveClient 可以复用同一个 EventLoopGroup. - eventLoopGroup.shutdownGracefully(); - -将异步关闭所有使用这个 EventLoopGroup 的 LiveClient. - (connect 方法运行结束只代表 socket 确实是连上了, 但是服务器还没有响应进房请求数据包) (当服务器响应进房请求数据包时才代表真的连上了, 此时会有一个连接成功的事件, 见下文) @@ -299,6 +295,10 @@ API 文档 即可异步关闭连接. + eventLoopGroup.shutdownGracefully(); + +即可关闭事件循环, 结束 Nio 工作线程(所有使用这个 EventLoopGroup 的 LiveClient 也将在此时被关闭). + 所有的事件(有些数据包我也不知道它里面的一些值是什么含义, /record 目录下面有抓取到的 Json, 可以用来查看): | 事件 | 抛出条件 | From c8a7dc03c7118087e3bd679c66a32a38adec9844 Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 12 Mar 2018 22:34:25 +0800 Subject: [PATCH 49/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index aedab6b..ab09de6 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ LoginException 在 accessToken 错误或过期时抛出 bilibiliAPI.login(username, password); } catch (CaptchaMismatchException e) { //如果该账号现在需要验证码来进行登录, 就会抛出异常 cookie = "sid=123456"; //自己造一个 cookie 或者从服务器取得 - Response response = bilibiliAPI.getPassportService() + Response response = bilibiliAPI.getCaptchaService() .getCaptcha(cookie) .execute(); InputStream inputStream = response.body().byteStream(); @@ -219,14 +219,23 @@ IOException 在网络错误时抛出(获取 cookie 时需要进行网络请求) liveHistoryBulletScreenEntity.getText()) ); -发送一条弹幕到指定直播间 +签到 String username = "yourUsername"; String password = "yourPassword"; + BilibiliAPI bilibiliAPI = new BilibiliAPI(); + bilibiliAPI.login(username, password); + bilibiliAPI.getLiveService() + .getSignInfo() + .execute(); + +发送一条弹幕到指定直播间 + long roomId = 3; - - BilibiliAPI bilibiliAPI = new BilibiliAPI() - .login(username, password); + String username = "yourUsername"; + String password = "yourPassword"; + BilibiliAPI bilibiliAPI = new BilibiliAPI(); + bilibiliAPI.login(username, password); bilibiliAPI.getLiveService() .sendBulletScreen( @@ -235,7 +244,8 @@ IOException 在网络错误时抛出(获取 cookie 时需要进行网络请求) bilibiliAPI.getBilibiliAccount().getUserId(), //实际上并不需要包含 mid 就可以正常发送弹幕, 但是真实的 Android 客户端确实发送了 mid "这是自动发送的弹幕" ) - ).execute(); + ) + .execute(); (如果要调用需要鉴权的 API, 需要先登录) @@ -299,6 +309,11 @@ API 文档 即可关闭事件循环, 结束 Nio 工作线程(所有使用这个 EventLoopGroup 的 LiveClient 也将在此时被关闭). +如果需要在直播间发送弹幕可以直接使用如下代码(需要先登录) + + String message = "这是一条弹幕"; + liveClient.sendBulletScreen(message); + 所有的事件(有些数据包我也不知道它里面的一些值是什么含义, /record 目录下面有抓取到的 Json, 可以用来查看): | 事件 | 抛出条件 | From dc39fb07d6299fb3a7e82460b5e8448046e34fbf Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 10:52:46 +0800 Subject: [PATCH 50/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=B0=8F=E7=94=B5=E8=A7=86=E6=8A=BD=E5=A5=96=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=20=E7=9A=84=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- .../hiczp/bilibili/api/live/LiveService.java | 13 +- .../api/live/entity/AppSmallTVEntity.java | 18 +- .../GetAppSmallTVRewardResponseEntity.java | 164 ++++++++++++++++++ .../entity/JoinAppSmallTVResponseEntity.java | 6 +- 5 files changed, 188 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/GetAppSmallTVRewardResponseEntity.java diff --git a/build.gradle b/build.gradle index 65ba32e..fa69522 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group = 'com.hiczp' -version = '0.0.9' +version = '0.0.10' description = 'Bilibili android client API library written in Java' apply plugin: 'idea' diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 24bbd08..4909b14 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -49,10 +49,19 @@ public interface LiveService { //参与小电视抽奖 //房间号必须与小电视号对应 //目标小电视不存在时(房间号与小电视号不匹配时也视为不存在)返回 -400 "不存在小电视信息" + //SYS_MSG 里面取得的小电视编号是一个字符串, 实际上它肯定是一个数字 @POST("AppSmallTV/join") - Call joinAppSmallTV(@Query("roomid") long roomId, @Query("id") long tvId); + Call joinAppSmallTV(@Query("roomid") long roomId, @Query("id") String tvId); - //TODO 查看小电视抽奖结果 + //通过 getAppSmallTV 取得的小电视编号是一个数字 + default Call joinAppSmallTV(long roomId, long tvId) { + return joinAppSmallTV(roomId, String.valueOf(tvId)); + } + + //获得小电视抽奖结果(不访问这个 API, 奖励也会自动进入背包) + //其中的 status 为 0 时, 表示返回正常开奖结果, 1 为没有参与抽奖或小电视已过期, 2 为正在开奖过程中. + @GET("AppSmallTV/getReward") + Call getAppSmallTVReward(@Query("id") long tvId); //获得所有头衔的列表 //这里的 Title 是头衔的意思 diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java index dad6391..af32dac 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/AppSmallTVEntity.java @@ -61,17 +61,17 @@ public class AppSmallTVEntity { */ @SerializedName("lastid") - private int lastid; + private long lastid; @SerializedName("join") private List join; @SerializedName("unjoin") private List unjoin; - public int getLastid() { + public long getLastid() { return lastid; } - public void setLastid(int lastid) { + public void setLastid(long lastid) { this.lastid = lastid; } @@ -98,15 +98,15 @@ public class AppSmallTVEntity { */ @SerializedName("id") - private int id; + private long id; @SerializedName("dtime") private int dtime; - public int getId() { + public long getId() { return id; } - public void setId(int id) { + public void setId(long id) { this.id = id; } @@ -126,15 +126,15 @@ public class AppSmallTVEntity { */ @SerializedName("id") - private int id; + private long id; @SerializedName("dtime") private int dtime; - public int getId() { + public long getId() { return id; } - public void setId(int id) { + public void setId(long id) { this.id = id; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/GetAppSmallTVRewardResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/GetAppSmallTVRewardResponseEntity.java new file mode 100644 index 0000000..d275fb7 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/GetAppSmallTVRewardResponseEntity.java @@ -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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java index fd7bd3e..9cef298 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/JoinAppSmallTVResponseEntity.java @@ -59,17 +59,17 @@ public class JoinAppSmallTVResponseEntity { */ @SerializedName("id") - private int id; + private long id; @SerializedName("dtime") private int dtime; @SerializedName("status") private int status; - public int getId() { + public long getId() { return id; } - public void setId(int id) { + public void setId(long id) { this.id = id; } From 26fe4e397c2c2a15a0da3bd26b151c307477293d Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 18:21:33 +0800 Subject: [PATCH 51/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E8=B0=83=E8=AF=95=E7=9A=84=20ReceiveDataPack?= =?UTF-8?q?ageDebugEvent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../event/ReceiveDataPackageDebugEvent.java | 19 +++++ .../socket/event/UnknownPackageEvent.java | 12 ++-- .../socket/handler/LiveClientHandler.java | 71 ++++++++++--------- .../bilibili/api/test/LiveClientTest.java | 2 +- 5 files changed, 66 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java diff --git a/README.md b/README.md index ab09de6..a00d012 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,7 @@ API 文档 | GuardMsgPackageEvent | 收到 GUARD_MSG 数据包 | | LivePackageEvent | 收到 LIVE 数据包 | | PreparingPackageEvent | 收到 PREPARING 数据包 | +| ReceiveDataPackageDebugEvent | 该事件用于调试, 收到任何 Data 数据包时都会触发 | | RoomAdminsPackageEvent | 收到 ROOM_ADMINS 数据包 | | RoomBlockMsgPackageEvent | 收到 ROOM_BLOCK_MSG 数据包 | | RoomSilentOffPackageEvent | 收到 ROOM_SILENT_OFF 数据包 | diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java new file mode 100644 index 0000000..1389cfd --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java @@ -0,0 +1,19 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.google.gson.JsonObject; + +import java.util.EventObject; + +//这个事件用于调试, 任何 Data 数据包都会触发一次这个事件 +public class ReceiveDataPackageDebugEvent extends EventObject { + private JsonObject jsonObject; + + public ReceiveDataPackageDebugEvent(Object source, JsonObject jsonObject) { + super(source); + this.jsonObject = jsonObject; + } + + public JsonObject getJsonObject() { + return jsonObject; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java index c13ba13..da4e285 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java @@ -1,16 +1,18 @@ package com.hiczp.bilibili.api.live.socket.event; +import com.google.gson.JsonObject; + import java.util.EventObject; public class UnknownPackageEvent extends EventObject { - private String json; + private JsonObject jsonObject; - public UnknownPackageEvent(Object source, String json) { + public UnknownPackageEvent(Object source, JsonObject jsonObject) { super(source); - this.json = json; + this.jsonObject = jsonObject; } - public String getJson() { - return json; + public JsonObject getJsonObject() { + return jsonObject; } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 360c6ac..193f8cd 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -1,10 +1,7 @@ package com.hiczp.bilibili.api.live.socket.handler; import com.google.common.eventbus.EventBus; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; +import com.google.gson.*; import com.hiczp.bilibili.api.live.socket.LiveClient; import com.hiczp.bilibili.api.live.socket.Package; import com.hiczp.bilibili.api.live.socket.PackageHelper; @@ -17,6 +14,8 @@ import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @@ -68,109 +67,115 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Exception { switch (msg.getPackageType()) { case DATA: { - String content = new String(msg.getContent()); - String cmd = JSON_PARSER.parse(content) - .getAsJsonObject() - .get("cmd") - .getAsString(); + JsonObject jsonObject; + try { + jsonObject = JSON_PARSER.parse(new InputStreamReader(new ByteArrayInputStream(msg.getContent()))) + .getAsJsonObject(); + } catch (JsonSyntaxException | IllegalStateException e) { + LOGGER.error("Receive invalid json: \n{}", msg.getContent()); + e.printStackTrace(); + break; + } + eventBus.post(new ReceiveDataPackageDebugEvent(this, jsonObject)); + String cmd = jsonObject.get("cmd").getAsString(); Supplier eventCreationExpression; //try 不能写在 switch 外面, 用 lambda 来延迟执行 switch (cmd) { //弹幕消息 case "DANMU_MSG": { - eventCreationExpression = () -> new DanMuMsgPackageEvent(this, GSON.fromJson(content, DanMuMsgEntity.class)); + eventCreationExpression = () -> new DanMuMsgPackageEvent(this, GSON.fromJson(jsonObject, DanMuMsgEntity.class)); } break; //送礼 case "SEND_GIFT": { - eventCreationExpression = () -> new SendGiftPackageEvent(this, GSON.fromJson(content, SendGiftEntity.class)); + eventCreationExpression = () -> new SendGiftPackageEvent(this, GSON.fromJson(jsonObject, SendGiftEntity.class)); } break; //欢迎 case "WELCOME": { - eventCreationExpression = () -> new WelcomePackageEvent(this, GSON.fromJson(content, WelcomeEntity.class)); + eventCreationExpression = () -> new WelcomePackageEvent(this, GSON.fromJson(jsonObject, WelcomeEntity.class)); } break; //许愿瓶 case "WISH_BOTTLE": { - eventCreationExpression = () -> new WishBottlePackageEvent(this, GSON.fromJson(content, WishBottleEntity.class)); + eventCreationExpression = () -> new WishBottlePackageEvent(this, GSON.fromJson(jsonObject, WishBottleEntity.class)); } break; //欢迎(舰队) case "WELCOME_GUARD": { - eventCreationExpression = () -> new WelcomeGuardPackageEvent(this, GSON.fromJson(content, WelcomeGuardEntity.class)); + eventCreationExpression = () -> new WelcomeGuardPackageEvent(this, GSON.fromJson(jsonObject, WelcomeGuardEntity.class)); } break; //系统消息(小电视等) case "SYS_MSG": { - eventCreationExpression = () -> new SysMsgPackageEvent(this, GSON.fromJson(content, SysMsgEntity.class)); + eventCreationExpression = () -> new SysMsgPackageEvent(this, GSON.fromJson(jsonObject, SysMsgEntity.class)); } break; //系统礼物(丰收庆典, 新春抽奖等) case "SYS_GIFT": { - eventCreationExpression = () -> new SysGiftPackageEvent(this, GSON.fromJson(content, SysGiftEntity.class)); + eventCreationExpression = () -> new SysGiftPackageEvent(this, GSON.fromJson(jsonObject, SysGiftEntity.class)); } break; //活动事件 case "ACTIVITY_EVENT": { - eventCreationExpression = () -> new ActivityEventPackageEvent(this, GSON.fromJson(content, ActivityEventEntity.class)); + eventCreationExpression = () -> new ActivityEventPackageEvent(this, GSON.fromJson(jsonObject, ActivityEventEntity.class)); } break; case "SPECIAL_GIFT": { - eventCreationExpression = () -> new SpecialGiftPackageEvent(this, GSON.fromJson(content, SpecialGiftEntity.class)); + eventCreationExpression = () -> new SpecialGiftPackageEvent(this, GSON.fromJson(jsonObject, SpecialGiftEntity.class)); } break; //房间黑名单(添加了一个用户到黑名单) case "ROOM_BLOCK_MSG": { - eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(content, RoomBlockMsgEntity.class)); + eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(jsonObject, RoomBlockMsgEntity.class)); } break; //房间开启了禁言(禁止某一等级以下的用户发言) case "ROOM_SILENT_ON": { - eventCreationExpression = () -> new RoomSilentOnPackageEvent(this, GSON.fromJson(content, RoomSilentOnEntity.class)); + eventCreationExpression = () -> new RoomSilentOnPackageEvent(this, GSON.fromJson(jsonObject, RoomSilentOnEntity.class)); } break; //房间结束禁言 case "ROOM_SILENT_OFF": { - eventCreationExpression = () -> new RoomSilentOffPackageEvent(this, GSON.fromJson(content, RoomSilentOffEntity.class)); + eventCreationExpression = () -> new RoomSilentOffPackageEvent(this, GSON.fromJson(jsonObject, RoomSilentOffEntity.class)); } break; //船票购买 case "GUARD_BUY": { - eventCreationExpression = () -> new GuardBuyPackageEvent(this, GSON.fromJson(content, GuardBuyEntity.class)); + eventCreationExpression = () -> new GuardBuyPackageEvent(this, GSON.fromJson(jsonObject, GuardBuyEntity.class)); } break; //舰队消息(登船) case "GUARD_MSG": { - eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(content, GuardMsgEntity.class)); + eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(jsonObject, GuardMsgEntity.class)); } break; case "TV_START": { - eventCreationExpression = () -> new TVStartPackageEvent(this, GSON.fromJson(content, TVStartEntity.class)); + eventCreationExpression = () -> new TVStartPackageEvent(this, GSON.fromJson(jsonObject, TVStartEntity.class)); } break; //小电视抽奖结束(大奖的获得者信息) case "TV_END": { - eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(content, TVEndEntity.class)); + eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(jsonObject, TVEndEntity.class)); } break; //房管变更 case "ROOM_ADMINS": { - eventCreationExpression = () -> new RoomAdminsPackageEvent(this, GSON.fromJson(content, RoomAdminsEntity.class)); + eventCreationExpression = () -> new RoomAdminsPackageEvent(this, GSON.fromJson(jsonObject, RoomAdminsEntity.class)); } break; //开始直播 case "LIVE": { - eventCreationExpression = () -> new LivePackageEvent(this, GSON.fromJson(content, LiveEntity.class)); + eventCreationExpression = () -> new LivePackageEvent(this, GSON.fromJson(jsonObject, LiveEntity.class)); } break; //停止直播 case "PREPARING": { - eventCreationExpression = () -> new PreparingPackageEvent(this, GSON.fromJson(content, PreparingEntity.class)); + eventCreationExpression = () -> new PreparingPackageEvent(this, GSON.fromJson(jsonObject, PreparingEntity.class)); } break; default: { - LOGGER.error("Received unknown json below: \n{}", formatJson(content)); - eventCreationExpression = () -> new UnknownPackageEvent(this, content); + LOGGER.error("Received unknown json below: \n{}", formatJson(jsonObject)); + eventCreationExpression = () -> new UnknownPackageEvent(this, jsonObject); } break; } @@ -178,7 +183,7 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { try { eventBus.post(eventCreationExpression.get()); } catch (JsonParseException e) { - LOGGER.error("Json parse error: {}, json below: \n{}", e.getMessage(), formatJson(content)); + LOGGER.error("Json parse error: {}, json below: \n{}", e.getMessage(), formatJson(jsonObject)); } } break; @@ -202,11 +207,11 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { } } - private String formatJson(String json) { + private String formatJson(JsonElement jsonElement) { return new GsonBuilder() .setPrettyPrinting() .create() - .toJson(JSON_PARSER.parse(json)); + .toJson(jsonElement); } public LiveClient getLiveClient() { diff --git a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java index e7f8767..e655bdc 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java @@ -20,7 +20,7 @@ import java.util.List; public class LiveClientTest { private static final Logger LOGGER = LoggerFactory.getLogger(LiveClientTest.class); private static final BilibiliAPI BILIBILI_API = Config.getBilibiliAPI(); - private static final long ROOM_ID = 3; + private static final long ROOM_ID = 102; private static final long TEST_TIME = 70 * 1000; @Ignore From 5cc07cfcea8ed07563c5d23b53b4a3170ba45c51 Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 22:30:20 +0800 Subject: [PATCH 52/73] =?UTF-8?q?=E5=BD=93=E5=9C=A8=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E4=B8=AD=E6=8E=A5=E6=94=B6=E5=88=B0?= =?UTF-8?q?=E4=B8=8D=E5=8F=AF=E8=A7=A3=E6=9E=90=E7=9A=84=20JSON=20?= =?UTF-8?q?=E6=97=B6,=20=E8=BE=93=E5=87=BA=E4=B8=80=E4=B8=AA=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E8=80=8C=E4=B8=8D=E6=98=AF=E6=AF=94=E7=89=B9?= =?UTF-8?q?=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bilibili/api/live/socket/handler/LiveClientHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 193f8cd..a088a7c 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -72,7 +72,7 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { jsonObject = JSON_PARSER.parse(new InputStreamReader(new ByteArrayInputStream(msg.getContent()))) .getAsJsonObject(); } catch (JsonSyntaxException | IllegalStateException e) { - LOGGER.error("Receive invalid json: \n{}", msg.getContent()); + LOGGER.error("Receive invalid json: \n{}", new String(msg.getContent())); e.printStackTrace(); break; } From 084f0e0863c225e15aacc55c9b85aaf6d1648374 Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 22:58:15 +0800 Subject: [PATCH 53/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20RAFFLE=5FEND?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bullet_screen_stream_json/RAFFLE_END.json | 17 ++ .../live/socket/entity/RaffleEndEntity.java | 164 ++++++++++++++++++ .../socket/event/RaffleEndPackageEvent.java | 9 + .../socket/handler/LiveClientHandler.java | 6 + 4 files changed, 196 insertions(+) create mode 100644 record/bullet_screen_stream_json/RAFFLE_END.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java diff --git a/record/bullet_screen_stream_json/RAFFLE_END.json b/record/bullet_screen_stream_json/RAFFLE_END.json new file mode 100644 index 0000000..c132aa3 --- /dev/null +++ b/record/bullet_screen_stream_json/RAFFLE_END.json @@ -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 + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java new file mode 100644 index 0000000..e46b210 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java @@ -0,0 +1,164 @@ +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; + + 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 int giftId; + @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 int getGiftId() { + return giftId; + } + + public void setGiftId(int 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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java new file mode 100644 index 0000000..533098f --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.RaffleEndEntity; + +public class RaffleEndPackageEvent extends ReceiveDataPackageEvent { + public RaffleEndPackageEvent(Object source, RaffleEndEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index a088a7c..8157e3a 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -124,6 +124,12 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new SpecialGiftPackageEvent(this, GSON.fromJson(jsonObject, SpecialGiftEntity.class)); } break; + //TODO RAFFLE_START + //抽奖结束(小奖, 通常是不定期活动) + case "RAFFLE_END": { + eventCreationExpression = () -> new RaffleEndPackageEvent(this, GSON.fromJson(jsonObject, RaffleEndEntity.class)); + } + break; //房间黑名单(添加了一个用户到黑名单) case "ROOM_BLOCK_MSG": { eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(jsonObject, RoomBlockMsgEntity.class)); From cde9cee03d02a3ffa996ee48817f0e02adc63d73 Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 23:16:39 +0800 Subject: [PATCH 54/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20RAFFLE=5FSTART?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../RAFFLE_START.json | 10 ++ .../live/socket/entity/RaffleEndEntity.java | 1 + .../live/socket/entity/RaffleStartEntity.java | 93 +++++++++++++++++++ .../socket/event/RaffleStartPackageEvent.java | 9 ++ .../socket/handler/LiveClientHandler.java | 8 +- 6 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 record/bullet_screen_stream_json/RAFFLE_START.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleStartEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java diff --git a/README.md b/README.md index a00d012..2ee8959 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,8 @@ API 文档 | GuardMsgPackageEvent | 收到 GUARD_MSG 数据包 | | LivePackageEvent | 收到 LIVE 数据包 | | PreparingPackageEvent | 收到 PREPARING 数据包 | +| RaffleEndPackageEvent | 收到 RAFFLE_END 数据包 | +| RaffleStartPackageEvent | 收到 RAFFLE_START 数据包 | | ReceiveDataPackageDebugEvent | 该事件用于调试, 收到任何 Data 数据包时都会触发 | | RoomAdminsPackageEvent | 收到 ROOM_ADMINS 数据包 | | RoomBlockMsgPackageEvent | 收到 ROOM_BLOCK_MSG 数据包 | diff --git a/record/bullet_screen_stream_json/RAFFLE_START.json b/record/bullet_screen_stream_json/RAFFLE_START.json new file mode 100644 index 0000000..340117b --- /dev/null +++ b/record/bullet_screen_stream_json/RAFFLE_START.json @@ -0,0 +1,10 @@ +{ + "cmd": "RAFFLE_START", + "roomid": 234024, + "data": { + "raffleId": 16915, + "type": "flower_rain", + "from": "爱吃喵姐的鱼", + "time": 60 + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java index e46b210..25febaa 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java @@ -16,6 +16,7 @@ public class RaffleEndEntity implements DataEntity { @SerializedName("data") private Data data; + @Override public String getCmd() { return cmd; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleStartEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleStartEntity.java new file mode 100644 index 0000000..7ab1581 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleStartEntity.java @@ -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; + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java new file mode 100644 index 0000000..1c29863 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.RaffleStartEntity; + +public class RaffleStartPackageEvent extends ReceiveDataPackageEvent { + public RaffleStartPackageEvent(Object source, RaffleStartEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 8157e3a..bf8f1d3 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -124,8 +124,12 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new SpecialGiftPackageEvent(this, GSON.fromJson(jsonObject, SpecialGiftEntity.class)); } break; - //TODO RAFFLE_START - //抽奖结束(小奖, 通常是不定期活动) + //抽奖开始(小奖, 通常是不定期活动) + case "RAFFLE_START": { + eventCreationExpression = () -> new RaffleStartPackageEvent(this, GSON.fromJson(jsonObject, RaffleStartEntity.class)); + } + break; + //抽奖 case "RAFFLE_END": { eventCreationExpression = () -> new RaffleEndPackageEvent(this, GSON.fromJson(jsonObject, RaffleEndEntity.class)); } From 4b4ee68cfc515b6d4546b3fa6eb5280463163c29 Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 23:23:31 +0800 Subject: [PATCH 55/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20EVENT=5FCMD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../bullet_screen_stream_json/EVENT_CMD.json | 8 +++ .../live/socket/entity/EventCmdEntity.java | 71 +++++++++++++++++++ .../socket/event/EventCmdPackageEvent.java | 9 +++ .../socket/handler/LiveClientHandler.java | 4 ++ 5 files changed, 93 insertions(+) create mode 100644 record/bullet_screen_stream_json/EVENT_CMD.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/EventCmdEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java diff --git a/README.md b/README.md index 2ee8959..598c44d 100644 --- a/README.md +++ b/README.md @@ -322,6 +322,7 @@ API 文档 | ConnectionCloseEvent | 连接断开(主动或被动) | | ConnectSucceedEvent | 进房成功 | | DanMuMsgPackageEvent | 收到 DANMU_MSG 数据包 | +| EventCmdPackageEvent | 收到 EVENT_CMD 数据包 | | GuardBuyPackageEvent | 收到 GUARD_BUY 数据包 | | GuardMsgPackageEvent | 收到 GUARD_MSG 数据包 | | LivePackageEvent | 收到 LIVE 数据包 | diff --git a/record/bullet_screen_stream_json/EVENT_CMD.json b/record/bullet_screen_stream_json/EVENT_CMD.json new file mode 100644 index 0000000..fb1bed7 --- /dev/null +++ b/record/bullet_screen_stream_json/EVENT_CMD.json @@ -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" + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/EventCmdEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/EventCmdEntity.java new file mode 100644 index 0000000..9a25dec --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/EventCmdEntity.java @@ -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; + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java new file mode 100644 index 0000000..4dae4ee --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.EventCmdEntity; + +public class EventCmdPackageEvent extends ReceiveDataPackageEvent { + public EventCmdPackageEvent(Object source, EventCmdEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index bf8f1d3..6c2aba7 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -134,6 +134,10 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new RaffleEndPackageEvent(this, GSON.fromJson(jsonObject, RaffleEndEntity.class)); } break; + case "EVENT_CMD": { + eventCreationExpression = () -> new EventCmdPackageEvent(this, GSON.fromJson(jsonObject, EventCmdEntity.class)); + } + break; //房间黑名单(添加了一个用户到黑名单) case "ROOM_BLOCK_MSG": { eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(jsonObject, RoomBlockMsgEntity.class)); From 44fc73108ff46878e9ca392698eec4e88cb3ac0f Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 23:43:59 +0800 Subject: [PATCH 56/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20ROOM=5FSHIELD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../ROOM_SHIELD.json | 11 +++ .../live/socket/entity/RoomShieldEntity.java | 67 +++++++++++++++++++ .../socket/event/RoomShieldPackageEvent.java | 9 +++ .../socket/handler/LiveClientHandler.java | 5 ++ 5 files changed, 93 insertions(+) create mode 100644 record/bullet_screen_stream_json/ROOM_SHIELD.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomShieldEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java diff --git a/README.md b/README.md index 598c44d..26057ec 100644 --- a/README.md +++ b/README.md @@ -332,6 +332,7 @@ API 文档 | ReceiveDataPackageDebugEvent | 该事件用于调试, 收到任何 Data 数据包时都会触发 | | RoomAdminsPackageEvent | 收到 ROOM_ADMINS 数据包 | | RoomBlockMsgPackageEvent | 收到 ROOM_BLOCK_MSG 数据包 | +| RoomShieldPackageEvent | 收到 ROOM_SHIELD 数据包 | | RoomSilentOffPackageEvent | 收到 ROOM_SILENT_OFF 数据包 | | RoomSilentOnPackageEvent | 收到 ROOM_SILENT_ON 数据包 | | SendGiftPackageEvent | 收到 SEND_GIFT 数据包 | diff --git a/record/bullet_screen_stream_json/ROOM_SHIELD.json b/record/bullet_screen_stream_json/ROOM_SHIELD.json new file mode 100644 index 0000000..5df5508 --- /dev/null +++ b/record/bullet_screen_stream_json/ROOM_SHIELD.json @@ -0,0 +1,11 @@ +{ + "cmd": "ROOM_SHIELD", + "type": 1, + "user": [], + "keyword": [ + "暗号", + "摄像头", + "色相头" + ], + "roomid": 505447 +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomShieldEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomShieldEntity.java new file mode 100644 index 0000000..cb0c28d --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomShieldEntity.java @@ -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 user; + @SerializedName("keyword") + private List 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 getUser() { + return user; + } + + public void setUser(List user) { + this.user = user; + } + + public List getKeyword() { + return keyword; + } + + public void setKeyword(List keyword) { + this.keyword = keyword; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java new file mode 100644 index 0000000..5763cc0 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.RoomShieldEntity; + +public class RoomShieldPackageEvent extends ReceiveDataPackageEvent { + public RoomShieldPackageEvent(Object source, RoomShieldEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 6c2aba7..046dee4 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -187,6 +187,11 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new PreparingPackageEvent(this, GSON.fromJson(jsonObject, PreparingEntity.class)); } break; + //房间屏蔽 + case "ROOM_SHIELD": { + eventCreationExpression = () -> new RoomShieldPackageEvent(this, GSON.fromJson(jsonObject, RoomShieldEntity.class)); + } + break; default: { LOGGER.error("Received unknown json below: \n{}", formatJson(jsonObject)); eventCreationExpression = () -> new UnknownPackageEvent(this, jsonObject); From f585e2be75b2a91d56fe74efbbef0d437b8628e4 Mon Sep 17 00:00:00 2001 From: czp Date: Tue, 13 Mar 2018 23:48:00 +0800 Subject: [PATCH 57/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20CUT=5FOFF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + record/bullet_screen_stream_json/CUT_OFF.json | 5 +++ .../api/live/socket/entity/CutOffEntity.java | 43 +++++++++++++++++++ .../live/socket/event/CutOffPackageEvent.java | 9 ++++ .../socket/handler/LiveClientHandler.java | 5 +++ 5 files changed, 63 insertions(+) create mode 100644 record/bullet_screen_stream_json/CUT_OFF.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/CutOffEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java diff --git a/README.md b/README.md index 26057ec..e0d9c57 100644 --- a/README.md +++ b/README.md @@ -321,6 +321,7 @@ API 文档 | ActivityEventPackageEvent | 收到 ACTIVITY_EVENT 数据包 | | ConnectionCloseEvent | 连接断开(主动或被动) | | ConnectSucceedEvent | 进房成功 | +| CutOffPackageEvent | 收到 CUT_OFF 数据包 | | DanMuMsgPackageEvent | 收到 DANMU_MSG 数据包 | | EventCmdPackageEvent | 收到 EVENT_CMD 数据包 | | GuardBuyPackageEvent | 收到 GUARD_BUY 数据包 | diff --git a/record/bullet_screen_stream_json/CUT_OFF.json b/record/bullet_screen_stream_json/CUT_OFF.json new file mode 100644 index 0000000..a0118f3 --- /dev/null +++ b/record/bullet_screen_stream_json/CUT_OFF.json @@ -0,0 +1,5 @@ +{ + "cmd": "CUT_OFF", + "msg": "禁播游戏", + "roomid": 8446134 +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/CutOffEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/CutOffEntity.java new file mode 100644 index 0000000..67d0d98 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/CutOffEntity.java @@ -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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java new file mode 100644 index 0000000..6dca74b --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.CutOffEntity; + +public class CutOffPackageEvent extends ReceiveDataPackageEvent { + public CutOffPackageEvent(Object source, CutOffEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 046dee4..4f1b107 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -192,6 +192,11 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new RoomShieldPackageEvent(this, GSON.fromJson(jsonObject, RoomShieldEntity.class)); } break; + //被 B站 管理员强制中断 + case "CUT_OFF": { + eventCreationExpression = () -> new CutOffPackageEvent(this, GSON.fromJson(jsonObject, CutOffEntity.class)); + } + break; default: { LOGGER.error("Received unknown json below: \n{}", formatJson(jsonObject)); eventCreationExpression = () -> new UnknownPackageEvent(this, jsonObject); From 6bfc1bd8ebdebceaceb9e2f01a5ef0d5cdc7be71 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 00:11:20 +0800 Subject: [PATCH 58/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E7=9A=84=E6=95=B0=E6=8D=AE=E5=8C=85?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20WELCOME=5FACTIVITY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../WELCOME_ACTIVITY.json | 9 ++ .../socket/entity/WelcomeActivityEntity.java | 82 +++++++++++++++++++ .../event/WelcomeActivityPackageEvent.java | 9 ++ .../socket/handler/LiveClientHandler.java | 5 ++ 5 files changed, 106 insertions(+) create mode 100644 record/bullet_screen_stream_json/WELCOME_ACTIVITY.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeActivityEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java diff --git a/README.md b/README.md index e0d9c57..aa596bf 100644 --- a/README.md +++ b/README.md @@ -345,6 +345,7 @@ API 文档 | TVStartPackageEvent | 收到 TV_START 数据包 | | UnknownPackageEvent | B站新增了新种类的数据包, 出现此情况请提交 issue | | ViewerCountPackageEvent | 收到 房间人数 数据包(不是 Json) | +| WelcomeActivityPackageEvent | 收到 WELCOME_ACTIVITY 数据包 | | WelcomeGuardPackageEvent | 收到 WELCOME_GUARD 数据包 | | WelcomePackageEvent | 收到 WELCOME 数据包 | | WishBottlePackageEvent | 收到 WISH_BOTTLE 数据包 | diff --git a/record/bullet_screen_stream_json/WELCOME_ACTIVITY.json b/record/bullet_screen_stream_json/WELCOME_ACTIVITY.json new file mode 100644 index 0000000..38ebeee --- /dev/null +++ b/record/bullet_screen_stream_json/WELCOME_ACTIVITY.json @@ -0,0 +1,9 @@ +{ + "cmd": "WELCOME_ACTIVITY", + "data": { + "uid": 49427998, + "uname": "起个名真tm费事", + "type": "forever_love", + "display_mode": 1 + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeActivityEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeActivityEntity.java new file mode 100644 index 0000000..eb510f3 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/WelcomeActivityEntity.java @@ -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; + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java new file mode 100644 index 0000000..7e44126 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.WelcomeActivityEntity; + +public class WelcomeActivityPackageEvent extends ReceiveDataPackageEvent { + public WelcomeActivityPackageEvent(Object source, WelcomeActivityEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 4f1b107..589a06c 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -172,6 +172,11 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(jsonObject, TVEndEntity.class)); } break; + //欢迎(活动) + case "WELCOME_ACTIVITY": { + eventCreationExpression = () -> new WelcomeActivityPackageEvent(this, GSON.fromJson(jsonObject, WelcomeActivityEntity.class)); + } + break; //房管变更 case "ROOM_ADMINS": { eventCreationExpression = () -> new RoomAdminsPackageEvent(this, GSON.fromJson(jsonObject, RoomAdminsEntity.class)); From dc7c76343393368432f8de74e715c56524977854 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 00:13:44 +0800 Subject: [PATCH 59/73] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bilibili/api/live/socket/entity/RaffleEndEntity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java index 25febaa..cb2b65f 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RaffleEndEntity.java @@ -115,7 +115,7 @@ public class RaffleEndEntity implements DataEntity { @SerializedName("face") private String face; @SerializedName("giftId") - private int giftId; + private String giftId; //礼物如果是 经验原石 一类的东西, 它的 id 是个字符串, 例如 "stuff-1" @SerializedName("giftName") private String giftName; @SerializedName("giftNum") @@ -137,11 +137,11 @@ public class RaffleEndEntity implements DataEntity { this.face = face; } - public int getGiftId() { + public String getGiftId() { return giftId; } - public void setGiftId(int giftId) { + public void setGiftId(String giftId) { this.giftId = giftId; } From 79af856db9172d87bf2bd88ed44355a795accde8 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 00:35:14 +0800 Subject: [PATCH 60/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=B5=81=E4=B8=AD=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=8C=85=E7=B1=BB=E5=9E=8B=20CHANGE=5FROOM=5FINFO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../CHANGE_ROOM_INFO.json | 4 +++ .../PrintResponseBodyInterceptor.java | 26 --------------- .../socket/entity/ChangeRoomInfoEntity.java | 32 +++++++++++++++++++ .../event/ChangeRoomInfoPackageEvent.java | 9 ++++++ .../socket/handler/LiveClientHandler.java | 5 +++ .../bilibili/api/test/GetAwardsTest.java | 3 +- 7 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 record/bullet_screen_stream_json/CHANGE_ROOM_INFO.json delete mode 100644 src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/ChangeRoomInfoEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java diff --git a/README.md b/README.md index aa596bf..6ef0554 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,7 @@ API 文档 | 事件 | 抛出条件 | | :--- | :--- | | ActivityEventPackageEvent | 收到 ACTIVITY_EVENT 数据包 | +| ChangeRoomInfoPackageEvent | 收到 CHANGE_ROOM_INFO 数据包 | | ConnectionCloseEvent | 连接断开(主动或被动) | | ConnectSucceedEvent | 进房成功 | | CutOffPackageEvent | 收到 CUT_OFF 数据包 | diff --git a/record/bullet_screen_stream_json/CHANGE_ROOM_INFO.json b/record/bullet_screen_stream_json/CHANGE_ROOM_INFO.json new file mode 100644 index 0000000..99f0ac9 --- /dev/null +++ b/record/bullet_screen_stream_json/CHANGE_ROOM_INFO.json @@ -0,0 +1,4 @@ +{ + "cmd": "CHANGE_ROOM_INFO", + "background": "http://static.hdslb.com/live-static/images/bg/4.jpg" +} diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java deleted file mode 100644 index 648e2cb..0000000 --- a/src/main/java/com/hiczp/bilibili/api/interceptor/PrintResponseBodyInterceptor.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.hiczp.bilibili.api.interceptor; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import okhttp3.Interceptor; -import okhttp3.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -public class PrintResponseBodyInterceptor implements Interceptor { - private static final Logger LOGGER = LoggerFactory.getLogger(PrintResponseBodyInterceptor.class); - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - - @Override - public Response intercept(Chain chain) throws IOException { - Response response = chain.proceed(chain.request()); - - JsonObject jsonObject = InterceptorHelper.getJsonInBody(response); - LOGGER.info(GSON.toJson(jsonObject)); - - return response; - } -} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/ChangeRoomInfoEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/ChangeRoomInfoEntity.java new file mode 100644 index 0000000..41e3078 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/ChangeRoomInfoEntity.java @@ -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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java new file mode 100644 index 0000000..6fa5a27 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java @@ -0,0 +1,9 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.entity.ChangeRoomInfoEntity; + +public class ChangeRoomInfoPackageEvent extends ReceiveDataPackageEvent { + public ChangeRoomInfoPackageEvent(Object source, ChangeRoomInfoEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 589a06c..373420b 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -197,6 +197,11 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new RoomShieldPackageEvent(this, GSON.fromJson(jsonObject, RoomShieldEntity.class)); } break; + //更换房间背景图片 + case "CHANGE_ROOM_INFO": { + eventCreationExpression = () -> new ChangeRoomInfoPackageEvent(this, GSON.fromJson(jsonObject, ChangeRoomInfoEntity.class)); + } + break; //被 B站 管理员强制中断 case "CUT_OFF": { eventCreationExpression = () -> new CutOffPackageEvent(this, GSON.fromJson(jsonObject, CutOffEntity.class)); diff --git a/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java b/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java index ba09358..e481975 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java @@ -1,7 +1,6 @@ package com.hiczp.bilibili.api.test; import com.hiczp.bilibili.api.BilibiliAPI; -import com.hiczp.bilibili.api.interceptor.PrintResponseBodyInterceptor; import okhttp3.logging.HttpLoggingInterceptor; import org.junit.Test; @@ -13,7 +12,7 @@ public class GetAwardsTest { @Test public void getAwards() throws Exception { BILIBILI_API - .getLiveService(Collections.singletonList(new PrintResponseBodyInterceptor()), HttpLoggingInterceptor.Level.BODY) + .getLiveService(Collections.emptyList(), HttpLoggingInterceptor.Level.BODY) .getAwards() .execute() .body(); From 2250f7003b64731ac92690e5f36b1913c798959a Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 09:49:53 +0800 Subject: [PATCH 61/73] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E7=BB=A7=E6=89=BF=E5=85=B3=E7=B3=BB,=20=E7=8E=B0?= =?UTF-8?q?=E5=9C=A8=E5=8F=AF=E4=BB=A5=E4=BB=8E=E4=BA=8B=E4=BB=B6=E4=BB=8E?= =?UTF-8?q?=E5=8F=96=E5=88=B0=20LiveClient=20=E5=AE=9E=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bilibili/api/live/socket/LiveClient.java | 2 +- .../event/ActivityEventPackageEvent.java | 3 +- .../event/ChangeRoomInfoPackageEvent.java | 3 +- .../socket/event/ConnectSucceedEvent.java | 6 +- .../socket/event/ConnectionCloseEvent.java | 6 +- .../live/socket/event/CutOffPackageEvent.java | 3 +- .../socket/event/DanMuMsgPackageEvent.java | 3 +- .../bilibili/api/live/socket/event/Event.java | 20 +++++ .../socket/event/EventCmdPackageEvent.java | 3 +- .../socket/event/GuardBuyPackageEvent.java | 3 +- .../socket/event/GuardMsgPackageEvent.java | 3 +- .../live/socket/event/LivePackageEvent.java | 3 +- .../socket/event/PreparingPackageEvent.java | 3 +- .../socket/event/RaffleEndPackageEvent.java | 3 +- .../socket/event/RaffleStartPackageEvent.java | 3 +- .../event/ReceiveDataPackageDebugEvent.java | 13 ++- .../socket/event/ReceiveDataPackageEvent.java | 3 +- .../socket/event/ReceivePackageEvent.java | 6 +- .../event/ReceiveRoomStatusPackageEvent.java | 4 +- .../socket/event/RoomAdminsPackageEvent.java | 3 +- .../event/RoomBlockMsgPackageEvent.java | 3 +- .../socket/event/RoomShieldPackageEvent.java | 3 +- .../event/RoomSilentOffPackageEvent.java | 3 +- .../event/RoomSilentOnPackageEvent.java | 3 +- .../socket/event/SendGiftPackageEvent.java | 3 +- .../event/SendHeartBeatPackageEvent.java | 6 +- .../socket/event/SpecialGiftPackageEvent.java | 3 +- .../socket/event/SysGiftPackageEvent.java | 3 +- .../live/socket/event/SysMsgPackageEvent.java | 3 +- .../live/socket/event/TVEndPackageEvent.java | 3 +- .../socket/event/TVStartPackageEvent.java | 3 +- .../socket/event/UnknownPackageEvent.java | 7 +- .../socket/event/ViewerCountPackageEvent.java | 6 +- .../event/WelcomeActivityPackageEvent.java | 3 +- .../event/WelcomeGuardPackageEvent.java | 3 +- .../socket/event/WelcomePackageEvent.java | 3 +- .../socket/event/WishBottlePackageEvent.java | 3 +- .../socket/handler/LiveClientHandler.java | 89 ++++++++----------- 38 files changed, 141 insertions(+), 105 deletions(-) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/Event.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java b/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java index c8bd48d..130b2a2 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/LiveClient.java @@ -97,7 +97,7 @@ public class LiveClient { .addLast(new IdleStateHandler(40, 0, 0)) .addLast(new PackageEncoder()) .addLast(new PackageDecoder()) - .addLast(new LiveClientHandler(self(), showRoomId, roomId, userId)); + .addLast(new LiveClientHandler(self(), roomId, userId)); } }); diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java index 759d4ee..7c62c60 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ActivityEventPackageEvent.java @@ -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 ReceiveDataPackageEvent { - public ActivityEventPackageEvent(Object source, ActivityEventEntity entity) { + public ActivityEventPackageEvent(LiveClient source, ActivityEventEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java index 6fa5a27..f95b2ea 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ChangeRoomInfoPackageEvent.java @@ -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.ChangeRoomInfoEntity; public class ChangeRoomInfoPackageEvent extends ReceiveDataPackageEvent { - public ChangeRoomInfoPackageEvent(Object source, ChangeRoomInfoEntity entity) { + public ChangeRoomInfoPackageEvent(LiveClient source, ChangeRoomInfoEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectSucceedEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectSucceedEvent.java index 2622d15..70229e8 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectSucceedEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectSucceedEvent.java @@ -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); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectionCloseEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectionCloseEvent.java index 1315d68..1b02561 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectionCloseEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ConnectionCloseEvent.java @@ -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); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java index 6dca74b..8b4094d 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/CutOffPackageEvent.java @@ -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.CutOffEntity; public class CutOffPackageEvent extends ReceiveDataPackageEvent { - public CutOffPackageEvent(Object source, CutOffEntity entity) { + public CutOffPackageEvent(LiveClient source, CutOffEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java index c3672a9..8943671 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/DanMuMsgPackageEvent.java @@ -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.DanMuMsgEntity; public class DanMuMsgPackageEvent extends ReceiveDataPackageEvent { - public DanMuMsgPackageEvent(Object source, DanMuMsgEntity entity) { + public DanMuMsgPackageEvent(LiveClient source, DanMuMsgEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/Event.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/Event.java new file mode 100644 index 0000000..090da65 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/Event.java @@ -0,0 +1,20 @@ +package com.hiczp.bilibili.api.live.socket.event; + +import com.hiczp.bilibili.api.live.socket.LiveClient; + +import java.util.EventObject; + +public abstract class Event extends EventObject { + Event(LiveClient source) { + super(source); + } + + @Override + public Object getSource() { + return source; + } + + public LiveClient getSource0() { + return (LiveClient) source; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java index 4dae4ee..29e152a 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/EventCmdPackageEvent.java @@ -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.EventCmdEntity; public class EventCmdPackageEvent extends ReceiveDataPackageEvent { - public EventCmdPackageEvent(Object source, EventCmdEntity entity) { + public EventCmdPackageEvent(LiveClient source, EventCmdEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java index 9f84401..ed37c79 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardBuyPackageEvent.java @@ -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.GuardBuyEntity; public class GuardBuyPackageEvent extends ReceiveDataPackageEvent { - public GuardBuyPackageEvent(Object source, GuardBuyEntity entity) { + public GuardBuyPackageEvent(LiveClient source, GuardBuyEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java index 7094e9c..2388eb4 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/GuardMsgPackageEvent.java @@ -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.GuardMsgEntity; public class GuardMsgPackageEvent extends ReceiveDataPackageEvent { - public GuardMsgPackageEvent(Object source, GuardMsgEntity entity) { + public GuardMsgPackageEvent(LiveClient source, GuardMsgEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java index 76c1f0b..c45ece1 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/LivePackageEvent.java @@ -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.LiveEntity; public class LivePackageEvent extends ReceiveRoomStatusPackageEvent { - public LivePackageEvent(Object source, LiveEntity entity) { + public LivePackageEvent(LiveClient source, LiveEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java index f960ff9..7df9177 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/PreparingPackageEvent.java @@ -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.PreparingEntity; public class PreparingPackageEvent extends ReceiveRoomStatusPackageEvent { - public PreparingPackageEvent(Object source, PreparingEntity entity) { + public PreparingPackageEvent(LiveClient source, PreparingEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java index 533098f..80a23f0 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleEndPackageEvent.java @@ -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.RaffleEndEntity; public class RaffleEndPackageEvent extends ReceiveDataPackageEvent { - public RaffleEndPackageEvent(Object source, RaffleEndEntity entity) { + public RaffleEndPackageEvent(LiveClient source, RaffleEndEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java index 1c29863..ac80f4f 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RaffleStartPackageEvent.java @@ -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.RaffleStartEntity; public class RaffleStartPackageEvent extends ReceiveDataPackageEvent { - public RaffleStartPackageEvent(Object source, RaffleStartEntity entity) { + public RaffleStartPackageEvent(LiveClient source, RaffleStartEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java index 1389cfd..b410b8e 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java @@ -1,19 +1,24 @@ package com.hiczp.bilibili.api.live.socket.event; import com.google.gson.JsonObject; - -import java.util.EventObject; +import com.hiczp.bilibili.api.live.socket.LiveClient; //这个事件用于调试, 任何 Data 数据包都会触发一次这个事件 -public class ReceiveDataPackageDebugEvent extends EventObject { +public class ReceiveDataPackageDebugEvent extends Event { private JsonObject jsonObject; + private String cmd; - public ReceiveDataPackageDebugEvent(Object source, JsonObject jsonObject) { + public ReceiveDataPackageDebugEvent(LiveClient source, JsonObject jsonObject, String cmd) { super(source); this.jsonObject = jsonObject; + this.cmd = cmd; } public JsonObject getJsonObject() { return jsonObject; } + + public String getCmd() { + return cmd; + } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java index 757e83a..c6d2876 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageEvent.java @@ -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.DataEntity; public abstract class ReceiveDataPackageEvent extends ReceivePackageEvent { - ReceiveDataPackageEvent(Object source, T entity) { + ReceiveDataPackageEvent(LiveClient source, T entity) { super(source, entity); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java index 25f1285..ceb049c 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceivePackageEvent.java @@ -1,11 +1,11 @@ package com.hiczp.bilibili.api.live.socket.event; -import java.util.EventObject; +import com.hiczp.bilibili.api.live.socket.LiveClient; -public abstract class ReceivePackageEvent extends EventObject { +public abstract class ReceivePackageEvent extends Event { protected T entity; - ReceivePackageEvent(Object source, T entity) { + ReceivePackageEvent(LiveClient source, T entity) { super(source); this.entity = entity; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java index b97370a..4463e77 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveRoomStatusPackageEvent.java @@ -1,12 +1,14 @@ package com.hiczp.bilibili.api.live.socket.event; +import com.hiczp.bilibili.api.live.socket.LiveClient; import com.hiczp.bilibili.api.live.socket.entity.RoomStatusEntity; public abstract class ReceiveRoomStatusPackageEvent extends ReceiveDataPackageEvent { - ReceiveRoomStatusPackageEvent(Object source, T entity) { + ReceiveRoomStatusPackageEvent(LiveClient source, T entity) { super(source, entity); } + @Override public RoomStatusEntity getEntity0() { return entity; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java index 88dd723..1700091 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomAdminsPackageEvent.java @@ -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.RoomAdminsEntity; public class RoomAdminsPackageEvent extends ReceiveDataPackageEvent { - public RoomAdminsPackageEvent(Object source, RoomAdminsEntity entity) { + public RoomAdminsPackageEvent(LiveClient source, RoomAdminsEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java index 8618f80..6bbd443 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomBlockMsgPackageEvent.java @@ -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.RoomBlockMsgEntity; public class RoomBlockMsgPackageEvent extends ReceiveDataPackageEvent { - public RoomBlockMsgPackageEvent(Object source, RoomBlockMsgEntity entity) { + public RoomBlockMsgPackageEvent(LiveClient source, RoomBlockMsgEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java index 5763cc0..bb6bd9b 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomShieldPackageEvent.java @@ -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.RoomShieldEntity; public class RoomShieldPackageEvent extends ReceiveDataPackageEvent { - public RoomShieldPackageEvent(Object source, RoomShieldEntity entity) { + public RoomShieldPackageEvent(LiveClient source, RoomShieldEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java index f7e5167..3751f3b 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOffPackageEvent.java @@ -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.RoomSilentOffEntity; public class RoomSilentOffPackageEvent extends ReceiveDataPackageEvent { - public RoomSilentOffPackageEvent(Object source, RoomSilentOffEntity entity) { + public RoomSilentOffPackageEvent(LiveClient source, RoomSilentOffEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java index d0681d5..e6691bf 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomSilentOnPackageEvent.java @@ -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.RoomSilentOnEntity; public class RoomSilentOnPackageEvent extends ReceiveDataPackageEvent { - public RoomSilentOnPackageEvent(Object source, RoomSilentOnEntity entity) { + public RoomSilentOnPackageEvent(LiveClient source, RoomSilentOnEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java index d5f1950..5a19aac 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendGiftPackageEvent.java @@ -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.SendGiftEntity; public class SendGiftPackageEvent extends ReceiveDataPackageEvent { - public SendGiftPackageEvent(Object source, SendGiftEntity entity) { + public SendGiftPackageEvent(LiveClient source, SendGiftEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendHeartBeatPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendHeartBeatPackageEvent.java index f902cc2..6b53fff 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendHeartBeatPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SendHeartBeatPackageEvent.java @@ -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 SendHeartBeatPackageEvent extends EventObject { - public SendHeartBeatPackageEvent(Object source) { +public class SendHeartBeatPackageEvent extends Event { + public SendHeartBeatPackageEvent(LiveClient source) { super(source); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java index 69a9c61..7a953ec 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SpecialGiftPackageEvent.java @@ -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.SpecialGiftEntity; public class SpecialGiftPackageEvent extends ReceiveDataPackageEvent { - public SpecialGiftPackageEvent(Object source, SpecialGiftEntity entity) { + public SpecialGiftPackageEvent(LiveClient source, SpecialGiftEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java index e1af383..99c13e1 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysGiftPackageEvent.java @@ -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.SysGiftEntity; public class SysGiftPackageEvent extends ReceiveDataPackageEvent { - public SysGiftPackageEvent(Object source, SysGiftEntity entity) { + public SysGiftPackageEvent(LiveClient source, SysGiftEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java index 78b80ee..2c75899 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/SysMsgPackageEvent.java @@ -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.SysMsgEntity; public class SysMsgPackageEvent extends ReceiveDataPackageEvent { - public SysMsgPackageEvent(Object source, SysMsgEntity entity) { + public SysMsgPackageEvent(LiveClient source, SysMsgEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java index df656f5..95e4a64 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVEndPackageEvent.java @@ -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.TVEndEntity; public class TVEndPackageEvent extends ReceiveDataPackageEvent { - public TVEndPackageEvent(Object source, TVEndEntity entity) { + public TVEndPackageEvent(LiveClient source, TVEndEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java index 1352409..ae73738 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/TVStartPackageEvent.java @@ -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.TVStartEntity; public class TVStartPackageEvent extends ReceiveDataPackageEvent { - public TVStartPackageEvent(Object source, TVStartEntity entity) { + public TVStartPackageEvent(LiveClient source, TVStartEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java index da4e285..32d2c4e 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/UnknownPackageEvent.java @@ -1,13 +1,12 @@ package com.hiczp.bilibili.api.live.socket.event; import com.google.gson.JsonObject; +import com.hiczp.bilibili.api.live.socket.LiveClient; -import java.util.EventObject; - -public class UnknownPackageEvent extends EventObject { +public class UnknownPackageEvent extends Event { private JsonObject jsonObject; - public UnknownPackageEvent(Object source, JsonObject jsonObject) { + public UnknownPackageEvent(LiveClient source, JsonObject jsonObject) { super(source); this.jsonObject = jsonObject; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ViewerCountPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ViewerCountPackageEvent.java index 44e960f..20b2233 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ViewerCountPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ViewerCountPackageEvent.java @@ -1,11 +1,11 @@ package com.hiczp.bilibili.api.live.socket.event; -import java.util.EventObject; +import com.hiczp.bilibili.api.live.socket.LiveClient; -public class ViewerCountPackageEvent extends EventObject { +public class ViewerCountPackageEvent extends Event { private int viewerCount; - public ViewerCountPackageEvent(Object source, int viewerCount) { + public ViewerCountPackageEvent(LiveClient source, int viewerCount) { super(source); this.viewerCount = viewerCount; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java index 7e44126..2391772 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeActivityPackageEvent.java @@ -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.WelcomeActivityEntity; public class WelcomeActivityPackageEvent extends ReceiveDataPackageEvent { - public WelcomeActivityPackageEvent(Object source, WelcomeActivityEntity entity) { + public WelcomeActivityPackageEvent(LiveClient source, WelcomeActivityEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java index 3415885..72ea8a3 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomeGuardPackageEvent.java @@ -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.WelcomeGuardEntity; public class WelcomeGuardPackageEvent extends ReceiveDataPackageEvent { - public WelcomeGuardPackageEvent(Object source, WelcomeGuardEntity entity) { + public WelcomeGuardPackageEvent(LiveClient source, WelcomeGuardEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java index e16c911..4610f52 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WelcomePackageEvent.java @@ -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.WelcomeEntity; public class WelcomePackageEvent extends ReceiveDataPackageEvent { - public WelcomePackageEvent(Object source, WelcomeEntity entity) { + public WelcomePackageEvent(LiveClient source, WelcomeEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java index 25363dd..975bebe 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/WishBottlePackageEvent.java @@ -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.WishBottleEntity; public class WishBottlePackageEvent extends ReceiveDataPackageEvent { - public WishBottlePackageEvent(Object source, WishBottleEntity entity) { + public WishBottlePackageEvent(LiveClient source, WishBottleEntity entity) { super(source, entity); } } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index 373420b..b1a0fa2 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -27,14 +27,12 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { private final LiveClient liveClient; private final EventBus eventBus; - private final long showRoomId; private final long roomId; private final long userId; - public LiveClientHandler(LiveClient liveClient, long showRoomId, long roomId, long userId) { + public LiveClientHandler(LiveClient liveClient, long roomId, long userId) { this.liveClient = liveClient; this.eventBus = liveClient.getEventBus(); - this.showRoomId = showRoomId; this.roomId = roomId; this.userId = userId; } @@ -49,7 +47,7 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); - eventBus.post(new ConnectionCloseEvent(this)); + eventBus.post(new ConnectionCloseEvent(liveClient)); } @Override @@ -68,148 +66,149 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { switch (msg.getPackageType()) { case DATA: { JsonObject jsonObject; + String cmd; try { jsonObject = JSON_PARSER.parse(new InputStreamReader(new ByteArrayInputStream(msg.getContent()))) .getAsJsonObject(); - } catch (JsonSyntaxException | IllegalStateException e) { + cmd = jsonObject.get("cmd").getAsString(); + } catch (JsonSyntaxException | IllegalStateException | NullPointerException e) { LOGGER.error("Receive invalid json: \n{}", new String(msg.getContent())); e.printStackTrace(); break; } - eventBus.post(new ReceiveDataPackageDebugEvent(this, jsonObject)); - String cmd = jsonObject.get("cmd").getAsString(); + eventBus.post(new ReceiveDataPackageDebugEvent(liveClient, jsonObject, cmd)); Supplier eventCreationExpression; //try 不能写在 switch 外面, 用 lambda 来延迟执行 switch (cmd) { //弹幕消息 case "DANMU_MSG": { - eventCreationExpression = () -> new DanMuMsgPackageEvent(this, GSON.fromJson(jsonObject, DanMuMsgEntity.class)); + eventCreationExpression = () -> new DanMuMsgPackageEvent(liveClient, GSON.fromJson(jsonObject, DanMuMsgEntity.class)); } break; //送礼 case "SEND_GIFT": { - eventCreationExpression = () -> new SendGiftPackageEvent(this, GSON.fromJson(jsonObject, SendGiftEntity.class)); + eventCreationExpression = () -> new SendGiftPackageEvent(liveClient, GSON.fromJson(jsonObject, SendGiftEntity.class)); } break; //欢迎 case "WELCOME": { - eventCreationExpression = () -> new WelcomePackageEvent(this, GSON.fromJson(jsonObject, WelcomeEntity.class)); + eventCreationExpression = () -> new WelcomePackageEvent(liveClient, GSON.fromJson(jsonObject, WelcomeEntity.class)); } break; //许愿瓶 case "WISH_BOTTLE": { - eventCreationExpression = () -> new WishBottlePackageEvent(this, GSON.fromJson(jsonObject, WishBottleEntity.class)); + eventCreationExpression = () -> new WishBottlePackageEvent(liveClient, GSON.fromJson(jsonObject, WishBottleEntity.class)); } break; //欢迎(舰队) case "WELCOME_GUARD": { - eventCreationExpression = () -> new WelcomeGuardPackageEvent(this, GSON.fromJson(jsonObject, WelcomeGuardEntity.class)); + eventCreationExpression = () -> new WelcomeGuardPackageEvent(liveClient, GSON.fromJson(jsonObject, WelcomeGuardEntity.class)); } break; //系统消息(小电视等) case "SYS_MSG": { - eventCreationExpression = () -> new SysMsgPackageEvent(this, GSON.fromJson(jsonObject, SysMsgEntity.class)); + eventCreationExpression = () -> new SysMsgPackageEvent(liveClient, GSON.fromJson(jsonObject, SysMsgEntity.class)); } break; //系统礼物(丰收庆典, 新春抽奖等) case "SYS_GIFT": { - eventCreationExpression = () -> new SysGiftPackageEvent(this, GSON.fromJson(jsonObject, SysGiftEntity.class)); + eventCreationExpression = () -> new SysGiftPackageEvent(liveClient, GSON.fromJson(jsonObject, SysGiftEntity.class)); } break; //活动事件 case "ACTIVITY_EVENT": { - eventCreationExpression = () -> new ActivityEventPackageEvent(this, GSON.fromJson(jsonObject, ActivityEventEntity.class)); + eventCreationExpression = () -> new ActivityEventPackageEvent(liveClient, GSON.fromJson(jsonObject, ActivityEventEntity.class)); } break; case "SPECIAL_GIFT": { - eventCreationExpression = () -> new SpecialGiftPackageEvent(this, GSON.fromJson(jsonObject, SpecialGiftEntity.class)); + eventCreationExpression = () -> new SpecialGiftPackageEvent(liveClient, GSON.fromJson(jsonObject, SpecialGiftEntity.class)); } break; //抽奖开始(小奖, 通常是不定期活动) case "RAFFLE_START": { - eventCreationExpression = () -> new RaffleStartPackageEvent(this, GSON.fromJson(jsonObject, RaffleStartEntity.class)); + eventCreationExpression = () -> new RaffleStartPackageEvent(liveClient, GSON.fromJson(jsonObject, RaffleStartEntity.class)); } break; //抽奖 case "RAFFLE_END": { - eventCreationExpression = () -> new RaffleEndPackageEvent(this, GSON.fromJson(jsonObject, RaffleEndEntity.class)); + eventCreationExpression = () -> new RaffleEndPackageEvent(liveClient, GSON.fromJson(jsonObject, RaffleEndEntity.class)); } break; case "EVENT_CMD": { - eventCreationExpression = () -> new EventCmdPackageEvent(this, GSON.fromJson(jsonObject, EventCmdEntity.class)); + eventCreationExpression = () -> new EventCmdPackageEvent(liveClient, GSON.fromJson(jsonObject, EventCmdEntity.class)); } break; //房间黑名单(添加了一个用户到黑名单) case "ROOM_BLOCK_MSG": { - eventCreationExpression = () -> new RoomBlockMsgPackageEvent(this, GSON.fromJson(jsonObject, RoomBlockMsgEntity.class)); + eventCreationExpression = () -> new RoomBlockMsgPackageEvent(liveClient, GSON.fromJson(jsonObject, RoomBlockMsgEntity.class)); } break; //房间开启了禁言(禁止某一等级以下的用户发言) case "ROOM_SILENT_ON": { - eventCreationExpression = () -> new RoomSilentOnPackageEvent(this, GSON.fromJson(jsonObject, RoomSilentOnEntity.class)); + eventCreationExpression = () -> new RoomSilentOnPackageEvent(liveClient, GSON.fromJson(jsonObject, RoomSilentOnEntity.class)); } break; //房间结束禁言 case "ROOM_SILENT_OFF": { - eventCreationExpression = () -> new RoomSilentOffPackageEvent(this, GSON.fromJson(jsonObject, RoomSilentOffEntity.class)); + eventCreationExpression = () -> new RoomSilentOffPackageEvent(liveClient, GSON.fromJson(jsonObject, RoomSilentOffEntity.class)); } break; //船票购买 case "GUARD_BUY": { - eventCreationExpression = () -> new GuardBuyPackageEvent(this, GSON.fromJson(jsonObject, GuardBuyEntity.class)); + eventCreationExpression = () -> new GuardBuyPackageEvent(liveClient, GSON.fromJson(jsonObject, GuardBuyEntity.class)); } break; //舰队消息(登船) case "GUARD_MSG": { - eventCreationExpression = () -> new GuardMsgPackageEvent(this, GSON.fromJson(jsonObject, GuardMsgEntity.class)); + eventCreationExpression = () -> new GuardMsgPackageEvent(liveClient, GSON.fromJson(jsonObject, GuardMsgEntity.class)); } break; case "TV_START": { - eventCreationExpression = () -> new TVStartPackageEvent(this, GSON.fromJson(jsonObject, TVStartEntity.class)); + eventCreationExpression = () -> new TVStartPackageEvent(liveClient, GSON.fromJson(jsonObject, TVStartEntity.class)); } break; //小电视抽奖结束(大奖的获得者信息) case "TV_END": { - eventCreationExpression = () -> new TVEndPackageEvent(this, GSON.fromJson(jsonObject, TVEndEntity.class)); + eventCreationExpression = () -> new TVEndPackageEvent(liveClient, GSON.fromJson(jsonObject, TVEndEntity.class)); } break; //欢迎(活动) case "WELCOME_ACTIVITY": { - eventCreationExpression = () -> new WelcomeActivityPackageEvent(this, GSON.fromJson(jsonObject, WelcomeActivityEntity.class)); + eventCreationExpression = () -> new WelcomeActivityPackageEvent(liveClient, GSON.fromJson(jsonObject, WelcomeActivityEntity.class)); } break; //房管变更 case "ROOM_ADMINS": { - eventCreationExpression = () -> new RoomAdminsPackageEvent(this, GSON.fromJson(jsonObject, RoomAdminsEntity.class)); + eventCreationExpression = () -> new RoomAdminsPackageEvent(liveClient, GSON.fromJson(jsonObject, RoomAdminsEntity.class)); } break; //开始直播 case "LIVE": { - eventCreationExpression = () -> new LivePackageEvent(this, GSON.fromJson(jsonObject, LiveEntity.class)); + eventCreationExpression = () -> new LivePackageEvent(liveClient, GSON.fromJson(jsonObject, LiveEntity.class)); } break; //停止直播 case "PREPARING": { - eventCreationExpression = () -> new PreparingPackageEvent(this, GSON.fromJson(jsonObject, PreparingEntity.class)); + eventCreationExpression = () -> new PreparingPackageEvent(liveClient, GSON.fromJson(jsonObject, PreparingEntity.class)); } break; //房间屏蔽 case "ROOM_SHIELD": { - eventCreationExpression = () -> new RoomShieldPackageEvent(this, GSON.fromJson(jsonObject, RoomShieldEntity.class)); + eventCreationExpression = () -> new RoomShieldPackageEvent(liveClient, GSON.fromJson(jsonObject, RoomShieldEntity.class)); } break; //更换房间背景图片 case "CHANGE_ROOM_INFO": { - eventCreationExpression = () -> new ChangeRoomInfoPackageEvent(this, GSON.fromJson(jsonObject, ChangeRoomInfoEntity.class)); + eventCreationExpression = () -> new ChangeRoomInfoPackageEvent(liveClient, GSON.fromJson(jsonObject, ChangeRoomInfoEntity.class)); } break; //被 B站 管理员强制中断 case "CUT_OFF": { - eventCreationExpression = () -> new CutOffPackageEvent(this, GSON.fromJson(jsonObject, CutOffEntity.class)); + eventCreationExpression = () -> new CutOffPackageEvent(liveClient, GSON.fromJson(jsonObject, CutOffEntity.class)); } break; default: { LOGGER.error("Received unknown json below: \n{}", formatJson(jsonObject)); - eventCreationExpression = () -> new UnknownPackageEvent(this, jsonObject); + eventCreationExpression = () -> new UnknownPackageEvent(liveClient, jsonObject); } break; } @@ -222,15 +221,15 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { } break; case VIEWER_COUNT: { - eventBus.post(new ViewerCountPackageEvent(this, ByteBuffer.wrap(msg.getContent()).getInt())); + eventBus.post(new ViewerCountPackageEvent(liveClient, ByteBuffer.wrap(msg.getContent()).getInt())); } break; case ENTER_ROOM_SUCCESS: { - eventBus.post(new ConnectSucceedEvent(this)); + eventBus.post(new ConnectSucceedEvent(liveClient)); ctx.executor().scheduleAtFixedRate( () -> { ctx.writeAndFlush(PackageHelper.createHeartBeatPackage()); - eventBus.post(new SendHeartBeatPackageEvent(this)); + eventBus.post(new SendHeartBeatPackageEvent(liveClient)); }, 0L, 30L, @@ -247,20 +246,4 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { .create() .toJson(jsonElement); } - - public LiveClient getLiveClient() { - return liveClient; - } - - public long getShowRoomId() { - return showRoomId; - } - - public long getRoomId() { - return roomId; - } - - public long getUserId() { - return userId; - } } From 6109d5f33ee27c3a0bfb5543c3ee4a807e3643a2 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 11:23:08 +0800 Subject: [PATCH 62/73] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20SEND=5FGIFT=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8C=85=E7=9A=84=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bullet_screen_stream_json/SEND_GIFT.json | 99 ++-- .../SYS_GIFT(丰收庆典).json | 11 - .../SYS_GIFT(新春抽奖).json | 11 - .../SYS_GIFT(活动礼物).json | 11 + record/bullet_screen_stream_json/SYS_MSG.json | 14 +- .../hiczp/bilibili/api/live/LiveService.java | 423 ++++++++++++++---- .../api/live/entity/BulletScreenEntity.java | 37 +- .../live/socket/entity/DanMuMsgEntity.java | 82 +++- .../live/socket/entity/SendGiftEntity.java | 393 +++++++++++----- .../api/passport/PassportService.java | 31 +- .../bilibili/api/passport/SsoService.java | 8 +- .../bilibili/api/test/LiveClientTest.java | 2 +- 12 files changed, 806 insertions(+), 316 deletions(-) delete mode 100644 record/bullet_screen_stream_json/SYS_GIFT(丰收庆典).json delete mode 100644 record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json create mode 100644 record/bullet_screen_stream_json/SYS_GIFT(活动礼物).json diff --git a/record/bullet_screen_stream_json/SEND_GIFT.json b/record/bullet_screen_stream_json/SEND_GIFT.json index 7330bc1..d6fc7a0 100644 --- a/record/bullet_screen_stream_json/SEND_GIFT.json +++ b/record/bullet_screen_stream_json/SEND_GIFT.json @@ -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 } } diff --git a/record/bullet_screen_stream_json/SYS_GIFT(丰收庆典).json b/record/bullet_screen_stream_json/SYS_GIFT(丰收庆典).json deleted file mode 100644 index ee2e9ac..0000000 --- a/record/bullet_screen_stream_json/SYS_GIFT(丰收庆典).json +++ /dev/null @@ -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 -} diff --git a/record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json b/record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json deleted file mode 100644 index d7536ae..0000000 --- a/record/bullet_screen_stream_json/SYS_GIFT(新春抽奖).json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "cmd": "SYS_GIFT", - "msg": "小螃海白翼OuO在直播间5540554开启了新春抽奖,红包大派送啦!一起来沾沾喜气吧!", - "msg_text": "小螃海白翼OuO在直播间5540554开启了新春抽奖,红包大派送啦!一起来沾沾喜气吧!", - "tips": "小螃海白翼OuO在直播间5540554开启了新春抽奖,红包大派送啦!一起来沾沾喜气吧!", - "url": "http://live.bilibili.com/5540554 ", - "roomid": 5540554, - "real_roomid": 5540554, - "giftId": 113, - "msgTips": 0 -} diff --git a/record/bullet_screen_stream_json/SYS_GIFT(活动礼物).json b/record/bullet_screen_stream_json/SYS_GIFT(活动礼物).json new file mode 100644 index 0000000..8ba9948 --- /dev/null +++ b/record/bullet_screen_stream_json/SYS_GIFT(活动礼物).json @@ -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 +} diff --git a/record/bullet_screen_stream_json/SYS_MSG.json b/record/bullet_screen_stream_json/SYS_MSG.json index 9bde5ee..f3e5c02 100644 --- a/record/bullet_screen_stream_json/SYS_MSG.json +++ b/record/bullet_screen_stream_json/SYS_MSG.json @@ -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" } diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 4909b14..e99e9a1 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -5,30 +5,50 @@ 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 getBulletScreenConfig(@Query("type") String type); + /** + * 获取弹幕设置的快捷调用 + */ default Call getBulletScreenConfig() { return getBulletScreenConfig("all"); } - //获得房间的历史弹幕(十条) + /** + * 获得房间的历史弹幕(十条) + * + * @param roomId 房间号 + */ @GET("AppRoom/msg") Call getHistoryBulletScreens(@Query("room_id") long roomId); - //获取直播间信息 - //登录后访问该 API 将在服务器新增一条直播间观看历史 + /** + * 获取直播间信息 + * 登录后访问该 API 将在服务器新增一条直播间观看历史 + * + * @param roomId 房间号 + */ @GET("AppRoom/index") Call getRoomInfo(@Query("room_id") long roomId); - //获得是否关注了一个主播 - //未登录时返回 401 + /** + * 获得是否关注了一个主播 + * 未登录时返回 401 + * + * @param hostUserId 主播的用户 ID + */ @POST("feed/v1/feed/isFollowed") Call isFollowed(@Query("follow") long hostUserId); @@ -37,34 +57,56 @@ public interface LiveService { @GET("AppBag/sendDaily") Call sendDaily(); - //获得所有礼物的列表 + /** + * 获得所有礼物的列表 + */ @GET("AppIndex/getAllItem") Call getAllItem(); - //查看可用的小电视抽奖 - //当目标房间没有可用的小电视抽奖时返回 -400 + /** + * 查看可用的小电视抽奖 + * 当目标房间没有可用的小电视抽奖时返回 -400 + * + * @param roomId 房间号 + */ @GET("AppSmallTV/index") Call getAppSmallTV(@Query("roomid") long roomId); - //参与小电视抽奖 - //房间号必须与小电视号对应 - //目标小电视不存在时(房间号与小电视号不匹配时也视为不存在)返回 -400 "不存在小电视信息" - //SYS_MSG 里面取得的小电视编号是一个字符串, 实际上它肯定是一个数字 + /** + * 参与小电视抽奖 + * 房间号必须与小电视号对应 + * 目标小电视不存在时(房间号与小电视号不匹配时也视为不存在)返回 -400 "不存在小电视信息" + * SYS_MSG 里面取得的小电视编号是一个字符串, 实际上它肯定是一个数字 + * + * @param roomId 房间号 + * @param tvId 小电视号 + */ @POST("AppSmallTV/join") Call joinAppSmallTV(@Query("roomid") long roomId, @Query("id") String tvId); - //通过 getAppSmallTV 取得的小电视编号是一个数字 + /** + * 通过 getAppSmallTV 取得的小电视编号是一个数字 + * + * @param roomId 房间号 + * @param tvId 小电视号 + */ default Call joinAppSmallTV(long roomId, long tvId) { return joinAppSmallTV(roomId, String.valueOf(tvId)); } - //获得小电视抽奖结果(不访问这个 API, 奖励也会自动进入背包) - //其中的 status 为 0 时, 表示返回正常开奖结果, 1 为没有参与抽奖或小电视已过期, 2 为正在开奖过程中. + /** + * 获得小电视抽奖结果(不访问这个 API, 奖励也会自动进入背包) + * + * @param tvId 小电视号 + * @return 返回内容中的 status 为 0 时, 表示返回正常开奖结果, 1 为没有参与抽奖或小电视已过期, 2 为正在开奖过程中 + */ @GET("AppSmallTV/getReward") Call getAppSmallTVReward(@Query("id") long tvId); - //获得所有头衔的列表 - //这里的 Title 是头衔的意思 + /** + * 获得所有头衔的列表 + * 这里的 Title 是头衔的意思 + */ @GET("appUser/getTitle") Call getTitle(); @@ -73,33 +115,67 @@ public interface LiveService { Call getSpecialGift(@Path("roomId") long roomId); //TODO 参与节奏风暴抽奖 - //获取自己的用户信息(live 站的个人信息, 非总站) - //未登录时返回 3 + /** + * 获取自己的用户信息(live 站的个人信息, 非总站) + * 未登录时返回 3 + */ @GET("mobile/getUser") Call 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 getPlayUrl(@Query("cid") long cid, @Query("otype") String outputType); + /** + * 获取直播间推流地址的快捷调用 + * + * @param cid 房间号 + */ default Call getPlayUrl(long cid) { return getPlayUrl(cid, "json"); } - //发送一个 Restful 心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级 - //2018-03-06 开始, 只有老爷才能通过观看直播获得经验 - //未登录时返回 3 + /** + * 发送一个 Restful 心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级 + * 2018-03-06 开始, 只有老爷才能通过观看直播获得经验 + * 未登录时返回 3 + * + * @param roomId 房间号 + * @param scale 屏幕大小 + */ @POST("mobile/userOnlineHeart") @FormUrlEncoded Call sendOnlineHeart(@Field("room_id") long roomId, @Field("scale") String scale); + /** + * 发送心跳包的快捷调用 + * + * @param roomId 房间号 + */ default Call 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 sendBulletScreen(@Field("cid") long cid, @@ -113,6 +189,11 @@ public interface LiveService { @Field("fontsize") int fontSize, @Field("playTime") String playTime); + /** + * 发送弹幕的快捷调用 + * + * @param bulletScreenEntity 弹幕实体类 + */ default Call sendBulletScreen(BulletScreenEntity bulletScreenEntity) { return sendBulletScreen( bulletScreenEntity.getCid(), @@ -128,23 +209,43 @@ public interface LiveService { ); } - //获取下一个宝箱任务的信息 + /** + * 获取下一个宝箱任务的信息 + */ @GET("mobile/freeSilverCurrentTask") Call getFreeSilverCurrentTask(); - //领取宝箱 + /** + * 领取宝箱 + */ @GET("mobile/freeSilverAward") Call getFreeSilverAward(); - //查看自己的背包(礼物) + /** + * 查看自己的背包(礼物) + */ @GET("AppBag/playerBag") Call getPlayerBag(); - //查看哪些礼物是活动礼物, 在客户端上, 活动礼物会有一个右上角标记 "活动" + /** + * 查看哪些礼物是活动礼物, 在客户端上, 活动礼物会有一个右上角标记 "活动" + * + * @param roomId 房间号 + */ @GET("AppRoom/activityGift") Call getActivityGifts(@Query("room_id") long roomId); - //送礼物 + /** + * 送礼物 + * + * @param giftId 礼物 ID + * @param number 数量 + * @param roomUserId 主播的用户 ID + * @param roomId 房间号 + * @param timeStamp 时间戳 + * @param bagId 礼物在自己背包里的 ID + * @param random 随机数 + */ @POST("AppBag/send") @FormUrlEncoded Call sendGift(@Field("giftId") long giftId, @@ -155,6 +256,11 @@ public interface LiveService { @Field("bag_id") long bagId, @Field("rnd") long random); + /** + * 送礼物的快捷调用 + * + * @param giftEntity 礼物实体类 + */ default Call sendGift(GiftEntity giftEntity) { return sendGift( giftEntity.getGiftId(), @@ -167,32 +273,56 @@ public interface LiveService { ); } - //获得礼物榜(七日榜) + /** + * 获得礼物榜(七日榜) + * + * @param roomId 房间号 + */ @GET("AppRoom/getGiftTop") Call getGiftTop(@Query("room_id") int roomId); - //"直播" 页面(这个页面对应的后台数据, 包括 banner, 推荐主播, 各种分区的推荐等) - //这个 API 会读取 "_device"(固定参数) 或者 "device" 来判断平台, 只需要有一个就能正常工作, 客户端上是两个都有, 且值都为 "android" + /** + * "直播" 页面(这个页面对应的后台数据, 包括 banner, 推荐主播, 各种分区的推荐等) + * + * @param device 这个 API 会读取 "_device"(固定参数) 或者 "device" 来判断平台, 只需要有一个就能正常工作, 客户端上是两个都有, 且值都为 "android" + */ @GET("room/v1/AppIndex/getAllList") Call getAllList(@Query("device") String device); + /** + * 获取 "直播" 页面数据的快捷调用 + */ default Call getAllList() { return getAllList("android"); } - //刷新 "推荐主播" 区域, 必须有 device, platform, scala - //scala 为 xxhdpi 时返回 12 个, 客户端显示六个, 刷新两次后再次访问该 API - //该 API 返回的内容结构与 getAllList 返回的内容中的 recommend_data 字段是一样的 - //该 API 返回的 banner_data 是在普通分区的推荐的上面的那个 banner, 在新版 APP 中, 点击这个 banner 会固定的跳转到 bilibili 相簿的 画友 标签页 + /** + * 刷新 "推荐主播" 区域, 必须有 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 recommendRefresh(@Query("device") String device); + /** + * 刷新 "推荐主播" 区域 的快捷调用 + */ default Call recommendRefresh() { return recommendRefresh("android"); } - //获取对应分类和状态的直播间 - //cate_id 不明确其含义 + /** + * 获取对应分类和状态的直播间 + * + * @param areaId 分区 ID + * @param categoryId 不明确其含义 + * @param parentAreaId 父分区 ID + * @param sortType 排序方式 + * @param page 页码, 可以为 null(第一页) + */ @GET("room/v1/Area/getRoomList") Call getRoomList( @Query("area_id") int areaId, @@ -202,102 +332,179 @@ public interface LiveService { @Query("page") Long page ); - //直播页面 下面的 普通分区(复数) 的刷新, 一次会返回 20 个结果, 客户端显示 6 个, 数据用完了之后再次访问该 API + /** + * 直播页面 下面的 普通分区(复数) 的刷新, 一次会返回 20 个结果, 客户端显示 6 个, 数据用完了之后再次访问该 API + * + * @param parentAreaId 父分区 ID + */ default Call getRoomList(int parentAreaId) { return getRoomList(0, 0, parentAreaId, "dynamic", null); } - //直播 -> 某个分区 -> 查看更多 - //获取该页面上方的分类标签 + /** + * 直播 -> 某个分区 -> 查看更多 + * 获取该页面上方的分类标签 + * + * @param parentAreaId 父分区 ID + */ @GET("room/v1/Area/getList") Call getAreaList(@Query("parent_id") int parentAreaId); - //获取该页面下的的直播间(areaId 为 0 表示选择了 "全部"(上方的分类标签), areaId 如果和 parentAreaId 不匹配将返回空的 data 字段) + /** + * 获取该页面下的的直播间(areaId 为 0 表示选择了 "全部"(上方的分类标签), areaId 如果和 parentAreaId 不匹配将返回空的 data 字段) + * + * @param areaId 分区 ID + * @param parentAreaId 父分区 ID + * @param page 页码 + */ default Call 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 getRooms(@Query("area_id") int areaId, @Query("page") int page, @Query("sort") String sort); - //推荐直播 + /** + * 推荐直播 + * + * @param page 页码 + */ default Call getSuggestionRooms(int page) { return getRooms(0, page, "suggestion"); } - //最热直播 + /** + * 最热直播 + * + * @param page 页码 + */ default Call getHottestRooms(int page) { return getRooms(0, page, "hottest"); } - //最新直播 + /** + * 最新直播 + * + * @param page 页码 + */ default Call getLatestRooms(int page) { return getRooms(0, page, "latest"); } - //视频轮播 + /** + * 视频轮播 + * + * @param page 页码 + */ default Call getRoundRooms(int page) { return getRooms(0, page, "roundroom"); } - //live 站的搜索("直播" 页面) - //type 为 room 时只返回 房间 的搜索结果 - //type 为 user 时只返回 用户 的搜索结果 - //type 为 all 时 房间 与 用户 的搜索结果都有 + /** + * live 站的搜索("直播" 页面) + * + * @param keyword 关键字 + * @param page 页码 + * @param pageSize 页容量 + * @param type 为 room 时只返回 房间 的搜索结果, 为 user 时只返回 用户 的搜索结果, all 时 房间 与 用户 的搜索结果都有 + */ @GET("AppSearch/index") Call 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 search(String keyword, long page, long pageSize) { return search(keyword, page, pageSize, "all"); } - //侧拉抽屉 -> 直播中心 -> 右上角日历图标 - //签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能)) - //无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign() + /** + * 侧拉抽屉 -> 直播中心 -> 右上角日历图标 + * 签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能)) + * 无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign() + */ @GET("AppUser/getSignInfo") Call getSignInfo(); - //侧拉抽屉 -> 直播中心 -> 我的关注 - //获得关注列表 - //未登录时返回 32205 + /** + * 侧拉抽屉 -> 直播中心 -> 我的关注 + * 获得关注列表 + * 未登录时返回 32205 + * + * @param page 页码 + * @param pageSize 页容量 + */ @GET("AppFeed/index") Call getFollowedHosts(@Query("page") long page, @Query("pagesize") long pageSize); - //侧拉抽屉 -> 直播中心 -> 观看历史 + /** + * 侧拉抽屉 -> 直播中心 -> 观看历史 + * + * @param page 页码 + * @param pageSize 页容量 + */ @GET("AppUser/history") Call getHistory(@Query("page") long page, @Query("pagesize") long pageSize); - //佩戴中心 - //侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 粉丝勋章 - //获得用户拥有的粉丝勋章 + /** + * 佩戴中心 + * 侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 粉丝勋章 + * 获得用户拥有的粉丝勋章 + */ @GET("AppUser/medal") Call getMyMedalList(); - //佩戴粉丝勋章 + /** + * 佩戴粉丝勋章 + * + * @param medalId 勋章 ID + */ @POST("AppUser/wearMedal") Call wearMedal(@Query("medal_id") int medalId); - //取消佩戴粉丝勋章(取消佩戴当前佩戴着的粉丝勋章) - //URL 上的 canel 不是拼写错误, 它原本就是这样的 + /** + * 取消佩戴粉丝勋章(取消佩戴当前佩戴着的粉丝勋章) + * URL 上的 canel 不是拼写错误, 它原本就是这样的 + */ @GET("AppUser/canelMedal") Call cancelMedal(); - //侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 我的头衔 - //获得用户拥有的头衔 + /** + * 侧拉抽屉 -> 直播中心 -> 佩戴中心 -> 我的头衔 + * 获得用户拥有的头衔 + */ @GET("appUser/myTitleList") Call getMyTitleList(); - //获得当前佩戴着的头衔的详情 - //当前未佩戴任何东西时, 返回的 code 为 -1, message 为 "nodata" + /** + * 获得当前佩戴着的头衔的详情 + * 当前未佩戴任何东西时, 返回的 code 为 -1, message 为 "nodata" + */ @GET("appUser/getWearTitle") Call getWearTitle(); - //佩戴头衔 + /** + * 佩戴头衔 + * + * @param title 头衔名 + */ @POST("AppUser/wearTitle") Call wearTitle(@Query("title") String title); - //取消佩戴头衔(取消佩戴当前佩戴着的头衔) + /** + * 取消佩戴头衔(取消佩戴当前佩戴着的头衔) + */ @GET("appUser/cancelTitle") Call cancelTitle(); @@ -308,46 +515,70 @@ public interface LiveService { @GET("AppUser/awards") Call getAwards(); - //瓜子商店 - //侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币 - //将 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次 - //已经兑换过时返回 403 + /** + * 瓜子商店 + * 侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币 + * 将 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次 + * 已经兑换过时返回 403 + */ @POST("AppExchange/silver2coin") Call silver2Coin(); - //扭蛋机 - //侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 - //获得 扭蛋机(普通扭蛋) 这个页面对应的后台数据 + /** + * 扭蛋机 + * 侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 + * 获得 扭蛋机(普通扭蛋) 这个页面对应的后台数据 + */ @GET("AppUser/capsuleInfo") Call getCapsuleInfo(); - //抽扭蛋 - //count 只能为 1, 10, 100 + /** + * 抽扭蛋 + * + * @param count 数量, 只能为 1, 10, 100 + * @param type 扭蛋类型, 只能为 "normal" 或 "colorful" + */ @POST("AppUser/capsuleInfoOpen") @FormUrlEncoded Call openCapsule(@Field("count") int count, @Field("type") String type); - //抽普通扭蛋 - //侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 -> 扭 - //普通扭蛋的 type 为 "normal" + /** + * 抽普通扭蛋 + * 侧拉抽屉 -> 直播中心 -> 扭蛋机 -> 普通扭蛋 -> 扭 + * 普通扭蛋的 type 为 "normal" + * + * @param count 数量, 只能为 1, 10, 100 + */ default Call openNormalCapsule(int count) { return openCapsule(count, "normal"); } - //梦幻扭蛋 + /** + * 抽梦幻扭蛋 + * + * @param count 数量, 只能为 1, 10, 100 + */ default Call openColorfulCapsule(int count) { return openCapsule(count, "colorful"); } - //房间设置 - //侧拉抽屉 -> 直播中心 -> 房间设置 -> (上面的个人信息, 包括 房间号, 粉丝数, UP 经验) - //根据用户 ID 来获取房间信息, 通常用于获取自己的直播间信息(可以用来获取他人的房间信息) - //该 API 不会增加直播间观看历史 + /** + * 房间设置 + * 侧拉抽屉 -> 直播中心 -> 房间设置 -> (上面的个人信息, 包括 房间号, 粉丝数, UP 经验) + * 根据用户 ID 来获取房间信息, 通常用于获取自己的直播间信息(可以用来获取他人的房间信息) + * 该 API 不会增加直播间观看历史 + * + * @param userId 用户 ID + */ @GET("assistant/getRoomInfo") Call getAssistantRoomInfo(@Query("uId") long userId); - //侧拉抽屉 -> 直播中心 -> 房间设置 -> 我的封面 - //获取自己的直播间的封面(获取其他人的封面会 -403) + /** + * 侧拉抽屉 -> 直播中心 -> 房间设置 -> 我的封面 + * 获取自己的直播间的封面(获取其他人的封面会 -403) + * + * @param roomId 房间号 + */ @GET("mhand/assistant/getCover") Call getCover(@Query("roomId") long roomId); diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java index 636441f..3685eb3 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/BulletScreenEntity.java @@ -7,26 +7,35 @@ public class BulletScreenEntity { private long mid; - //弹幕长度限制为 LiveRoomInfoEntity.getData().getMsgLength(), 对于每个用户而言, 每个房间都一样 - //通过完成 B站 有关任务, 获得成就, 可以加大这个限制(舰长, 老爷等可以直接加大限制), 最长好像是 40 个字 + /** + * 弹幕长度限制为 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"; @@ -38,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; diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java index ef64ad0..374fced 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/DanMuMsgEntity.java @@ -41,68 +41,94 @@ public class DanMuMsgEntity implements DataEntity { 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 getFansMedalLevel() { if (info.get(3).getAsJsonArray().size() > 0) { return Optional.of(info.get(3).getAsJsonArray().get(0).getAsInt()); @@ -111,7 +137,9 @@ public class DanMuMsgEntity implements DataEntity { } } - //获取粉丝勋章名称 + /** + * 获取粉丝勋章名称 + */ public Optional getFansMedalName() { if (info.get(3).getAsJsonArray().size() > 0) { return Optional.of(info.get(3).getAsJsonArray().get(1).getAsString()); @@ -120,7 +148,9 @@ public class DanMuMsgEntity implements DataEntity { } } - //获取粉丝勋章对应的主播的名字 + /** + * 粉丝勋章对应的主播的名字 + */ public Optional getFansMedalOwnerName() { if (info.get(3).getAsJsonArray().size() > 0) { return Optional.of(info.get(3).getAsJsonArray().get(2).getAsString()); @@ -129,7 +159,9 @@ public class DanMuMsgEntity implements DataEntity { } } - //获取粉丝勋章对应的主播的直播间 ID + /** + * 粉丝勋章对应的主播的直播间 ID + */ public Optional getFansMedalOwnerRoomId() { if (info.get(3).getAsJsonArray().size() > 0) { return Optional.of(info.get(3).getAsJsonArray().get(3).getAsString()); @@ -138,22 +170,30 @@ public class DanMuMsgEntity implements DataEntity { } } - //获得用户的观众等级 + /** + * 用户的观众等级 + */ public int getUserLevel() { return info.get(4).getAsJsonArray().get(0).getAsInt(); } - //获得用户的观众等级排名 + /** + * 用户的观众等级排名 + */ public String getUserRank() { return info.get(4).getAsJsonArray().get(3).getAsString(); } - //获得用户头衔 + /** + * 用户头衔 + */ public List getUserTitles() { return GSON.fromJson(info.get(5), STRING_LIST_TYPE); } - //获得用户名颜色 + /** + * 用户名颜色 + */ public String getUsernameColor() { return info.get(8).getAsJsonObject().get("uname_color").getAsString(); } diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java index cf16259..8d848a5 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/SendGiftEntity.java @@ -1,7 +1,6 @@ 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; @@ -9,7 +8,7 @@ import java.util.List; 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") @@ -17,7 +16,6 @@ public class SendGiftEntity implements DataEntity { @SerializedName("data") private DataEntity data; - @Override public String getCmd() { return cmd; } @@ -36,35 +34,39 @@ public class SendGiftEntity implements DataEntity { 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") @@ -72,9 +74,9 @@ public class SendGiftEntity implements DataEntity { @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") @@ -95,6 +97,17 @@ public class SendGiftEntity implements DataEntity { 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") @@ -113,18 +126,24 @@ public class SendGiftEntity implements DataEntity { 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 topList; - @SerializedName("medal") - private JsonElement medal; + private List topList; @SerializedName("smalltv_msg") - private JsonElement smallTVMsg; + private JsonElement smalltvMsg; @SerializedName("notice_msg") - private List noticeMsg; + private JsonElement noticeMsg; public String getGiftName() { return giftName; @@ -142,20 +161,20 @@ public class SendGiftEntity implements DataEntity { 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() { @@ -238,6 +257,14 @@ public class SendGiftEntity implements DataEntity { this.newTitle = newTitle; } + public JsonElement getMedal() { + return medal; + } + + public void setMedal(JsonElement medal) { + this.medal = medal; + } + public String getTitle() { return title; } @@ -310,11 +337,19 @@ public class SendGiftEntity implements DataEntity { 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; } @@ -326,70 +361,208 @@ public class SendGiftEntity implements DataEntity { this.addFollow = addFollow; } - public List 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 getTopList() { return topList; } - public void setTopList(List topList) { + public void setTopList(List 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") @@ -397,7 +570,7 @@ public class SendGiftEntity implements DataEntity { @SerializedName("change") private int change; @SerializedName("progress") - private ProgressEntity progress; + private Progress progress; public int getCoin() { return coin; @@ -415,17 +588,17 @@ public class SendGiftEntity implements DataEntity { 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 */ @@ -452,9 +625,9 @@ public class SendGiftEntity implements DataEntity { } } - public static class ColorfulEntity { + public static class Colorful { /** - * coin : 0 + * coin : 2 * change : 0 * progress : {"now":0,"max":5000} */ @@ -464,7 +637,7 @@ public class SendGiftEntity implements DataEntity { @SerializedName("change") private int change; @SerializedName("progress") - private ProgressEntityX progress; + private ProgressX progress; public int getCoin() { return coin; @@ -482,15 +655,15 @@ public class SendGiftEntity implements DataEntity { 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 @@ -520,31 +693,31 @@ public class SendGiftEntity implements DataEntity { } } - 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; @@ -554,20 +727,12 @@ public class SendGiftEntity implements DataEntity { 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() { @@ -578,14 +743,6 @@ public class SendGiftEntity implements DataEntity { this.face = face; } - public String getGuardLevel() { - return guardLevel; - } - - public void setGuardLevel(String guardLevel) { - this.guardLevel = guardLevel; - } - public int getRank() { return rank; } @@ -601,6 +758,22 @@ public class SendGiftEntity implements DataEntity { 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; + } } } } diff --git a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java index 98f1549..3b0f915 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java @@ -8,22 +8,51 @@ import retrofit2.http.POST; import retrofit2.http.Query; public interface PassportService { + /** + * 获得公钥 + */ @POST("api/oauth2/getKey") Call getKey(); + /** + * 登录 + * + * @param username 用户名 + * @param password 密码 + */ @POST("api/oauth2/login") Call login(@Query("username") String username, @Query("password") String password); - //在一段时间内进行多次错误的登录, 将被要求输入验证码 + /** + * 带验证码的登录 + * 在一段时间内进行多次错误的登录, 将被要求输入验证码 + * @param username 用户名 + * @param password 密码 + * @param captcha 验证码 + * @param cookies cookies + */ @POST("api/oauth2/login") Call login(@Query("username") String username, @Query("password") String password, @Query("captcha") String captcha, @Header("Cookie") String cookies); + /** + * 获得账户信息 + * @param accessToken token + */ @GET("api/oauth2/info") Call getInfo(@Query("access_token") String accessToken); + /** + * 刷新 token + * @param accessToken token + * @param refreshToken refreshToken + */ @POST("api/oauth2/refreshToken") Call refreshToken(@Query("access_token") String accessToken, @Query("refresh_token") String refreshToken); + /** + * 注销 + * @param accessToken token + */ @POST("api/oauth2/revoke") Call logout(@Query("access_token") String accessToken); } diff --git a/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java index 0b46ff7..90bc831 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java @@ -7,9 +7,11 @@ import retrofit2.http.Query; import javax.annotation.Nullable; -//sso 很特别, 它可能返回的是一个 HTML 页面, 所以单独分出来 -//sso 会经过两次 302 跳转, 需要保存其中的 cookie, 然后才能抵达最终页面并且进入 cookie 登录状态 -//如果 gourl 为 null, 则会跳转到 B站 首页 +/** + * sso 很特别, 它可能返回的是一个 HTML 页面, 所以单独分出来 + * sso 会经过两次 302 跳转, 需要保存其中的 cookie, 然后才能抵达最终页面并且进入 cookie 登录状态 + * 如果 gourl 为 null, 则会跳转到 B站 首页 + */ public interface SsoService { @GET("api/login/sso") Call sso(@Nullable @Query("gourl") String goUrl); diff --git a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java index e655bdc..df814ab 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/LiveClientTest.java @@ -128,7 +128,7 @@ public class LiveClientTest { public void sendGift(SendGiftPackageEvent sendGiftPackageEvent) { SendGiftEntity.DataEntity dataEntity = sendGiftPackageEvent.getEntity().getData(); LOGGER.info("[SendGift] {} give {}*{}", - dataEntity.getUserName(), + dataEntity.getUsername(), dataEntity.getGiftName(), dataEntity.getNum() ); From 29d6460f62b2eade40d305f225aa6846506da600 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 11:27:10 +0800 Subject: [PATCH 63/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E6=95=B0=E6=8D=AE=E5=8C=85=E7=A7=8D=E7=B1=BB?= =?UTF-8?q?=20ROOM=5FLOCK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../bullet_screen_stream_json/ROOM_LOCK.json | 5 +++ .../live/socket/entity/RoomLockEntity.java | 43 +++++++++++++++++++ .../socket/event/RoomLockPackageEvent.java | 10 +++++ .../socket/handler/LiveClientHandler.java | 5 +++ 5 files changed, 64 insertions(+) create mode 100644 record/bullet_screen_stream_json/ROOM_LOCK.json create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomLockEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomLockPackageEvent.java diff --git a/README.md b/README.md index 6ef0554..52f7ed6 100644 --- a/README.md +++ b/README.md @@ -334,6 +334,7 @@ API 文档 | ReceiveDataPackageDebugEvent | 该事件用于调试, 收到任何 Data 数据包时都会触发 | | RoomAdminsPackageEvent | 收到 ROOM_ADMINS 数据包 | | RoomBlockMsgPackageEvent | 收到 ROOM_BLOCK_MSG 数据包 | +| RoomLockPackageEvent | 收到 ROOM_LOCK 数据包 | | RoomShieldPackageEvent | 收到 ROOM_SHIELD 数据包 | | RoomSilentOffPackageEvent | 收到 ROOM_SILENT_OFF 数据包 | | RoomSilentOnPackageEvent | 收到 ROOM_SILENT_ON 数据包 | diff --git a/record/bullet_screen_stream_json/ROOM_LOCK.json b/record/bullet_screen_stream_json/ROOM_LOCK.json new file mode 100644 index 0000000..2e2a152 --- /dev/null +++ b/record/bullet_screen_stream_json/ROOM_LOCK.json @@ -0,0 +1,5 @@ +{ + "cmd": "ROOM_LOCK", + "expire": "2018-03-15 10:24:18", + "roomid": 6477301 +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomLockEntity.java b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomLockEntity.java new file mode 100644 index 0000000..58158f7 --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/entity/RoomLockEntity.java @@ -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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomLockPackageEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomLockPackageEvent.java new file mode 100644 index 0000000..2e80aac --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/RoomLockPackageEvent.java @@ -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.RoomLockEntity; + +public class RoomLockPackageEvent extends ReceiveDataPackageEvent { + public RoomLockPackageEvent(LiveClient source, RoomLockEntity entity) { + super(source, entity); + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java index b1a0fa2..8bfb2b8 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/handler/LiveClientHandler.java @@ -206,6 +206,11 @@ public class LiveClientHandler extends SimpleChannelInboundHandler { eventCreationExpression = () -> new CutOffPackageEvent(liveClient, GSON.fromJson(jsonObject, CutOffEntity.class)); } break; + //房间被封 + case "ROOM_LOCK": { + eventCreationExpression = () -> new RoomLockPackageEvent(liveClient, GSON.fromJson(jsonObject, RoomLockEntity.class)); + } + break; default: { LOGGER.error("Received unknown json below: \n{}", formatJson(jsonObject)); eventCreationExpression = () -> new UnknownPackageEvent(liveClient, jsonObject); From 3f413b6bd13ff7558480a417cb826406e4d26fdb Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 22:54:54 +0800 Subject: [PATCH 64/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=A4=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bilibili/api/BilibiliSecurityHelper.java | 83 ++++++++++++++++-- .../hiczp/bilibili/api/ServerErrorCode.java | 86 ++++++++++++++----- .../AutoRefreshTokenInterceptor.java | 6 +- .../interceptor/CancelRequestInterceptor.java | 6 ++ .../ErrorResponseConverterInterceptor.java | 7 +- .../hiczp/bilibili/api/live/LiveService.java | 23 +++-- .../bilibili/api/live/socket/Package.java | 18 ++-- .../api/live/socket/PackageHelper.java | 11 +++ .../api/live/socket/codec/PackageDecoder.java | 3 + .../api/live/socket/codec/PackageEncoder.java | 3 + .../event/ReceiveDataPackageDebugEvent.java | 4 +- .../bilibili/api/passport/CaptchaService.java | 13 +++ .../api/passport/PassportService.java | 11 ++- .../bilibili/api/passport/SsoService.java | 7 +- .../bilibili/api/web/live/LiveService.java | 18 ++-- 15 files changed, 240 insertions(+), 59 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java b/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java index ca89c96..0df7cc9 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliSecurityHelper.java @@ -23,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(); @@ -62,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 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"); @@ -82,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 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, @@ -115,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 { @@ -123,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) diff --git a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java index be89649..47980c2 100644 --- a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java +++ b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java @@ -1,54 +1,100 @@ 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 { - //"invalid params" + /** + * "invalid params" + */ public static final int INVALID_PARAMS = 1; - //"user no login" + /** + * "user no login" + */ public static final int USER_NO_LOGIN = 3; - //"请登录" + /** + * "请登录" + */ public static final int PLEASE_LOGIN = 401; - //"每天最多能兑换 1 个" + /** + * "每天最多能兑换 1 个" + */ public static final int FORBIDDEN = 403; - //"请登录" + /** + * "请登录" + */ public static final int PLEASE_LOGIN0 = 32205; - //"请先登录" + /** + * "请先登录" + */ 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; } } diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java index 87df1d3..f08e0a5 100644 --- a/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java @@ -12,7 +12,11 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.stream.IntStream; -//自动刷新 token +/** + * 自动刷新 token + * 如果一次请求的返回值表示鉴权失败, 会尝试刷新一次 token 然后自动重放请求 + * 刷新 token 的行为将只发生一次, 如果刷新 token 失败, 下次请求的时候不会再次执行刷新 token 操作而会直接返回原本的返回内容 + */ public class AutoRefreshTokenInterceptor implements Interceptor { private static final Logger LOGGER = LoggerFactory.getLogger(AutoRefreshTokenInterceptor.class); diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java index 1ed1bd5..fbf7693 100644 --- a/src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/CancelRequestInterceptor.java @@ -7,6 +7,12 @@ import okhttp3.Response; import java.io.IOException; +/** + * 这个拦截器用于取消请求 + * 如果需要让数据经过其他拦截器处理, 但是不想发生真实的网络请求, 就可以使用这个 + * + * @see UserCancelRequestException + */ public class CancelRequestInterceptor implements Interceptor { private Request request; diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java index c0cf386..f276d2c 100644 --- a/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/ErrorResponseConverterInterceptor.java @@ -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(); diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index e99e9a1..f3293f2 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -45,9 +45,9 @@ public interface LiveService { /** * 获得是否关注了一个主播 - * 未登录时返回 401 * * @param hostUserId 主播的用户 ID + * @return 未登录时返回 401 */ @POST("feed/v1/feed/isFollowed") Call isFollowed(@Query("follow") long hostUserId); @@ -65,9 +65,9 @@ public interface LiveService { /** * 查看可用的小电视抽奖 - * 当目标房间没有可用的小电视抽奖时返回 -400 * * @param roomId 房间号 + * @return 当目标房间没有可用的小电视抽奖时返回 -400 */ @GET("AppSmallTV/index") Call getAppSmallTV(@Query("roomid") long roomId); @@ -75,11 +75,11 @@ public interface LiveService { /** * 参与小电视抽奖 * 房间号必须与小电视号对应 - * 目标小电视不存在时(房间号与小电视号不匹配时也视为不存在)返回 -400 "不存在小电视信息" * SYS_MSG 里面取得的小电视编号是一个字符串, 实际上它肯定是一个数字 * * @param roomId 房间号 * @param tvId 小电视号 + * @return 目标小电视不存在时(房间号与小电视号不匹配时也视为不存在)返回 -400 "不存在小电视信息" */ @POST("AppSmallTV/join") Call joinAppSmallTV(@Query("roomid") long roomId, @Query("id") String tvId); @@ -117,7 +117,8 @@ public interface LiveService { /** * 获取自己的用户信息(live 站的个人信息, 非总站) - * 未登录时返回 3 + * + * @return 未登录时返回 3 */ @GET("mobile/getUser") Call getUserInfo(); @@ -143,10 +144,10 @@ public interface LiveService { /** * 发送一个 Restful 心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级 * 2018-03-06 开始, 只有老爷才能通过观看直播获得经验 - * 未登录时返回 3 * * @param roomId 房间号 * @param scale 屏幕大小 + * @return 未登录时返回 3 */ @POST("mobile/userOnlineHeart") @FormUrlEncoded @@ -432,7 +433,8 @@ public interface LiveService { /** * 侧拉抽屉 -> 直播中心 -> 右上角日历图标 * 签到(live 站签到, 非总站(虽然我也不知道总站有没有签到功能)) - * 无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign() + * + * @return 无论是否已经签到, 返回的 code 都是 0. 除了字符串比对, 要想知道是否已经签到要通过 getUserInfo().getIsSign() */ @GET("AppUser/getSignInfo") Call getSignInfo(); @@ -489,7 +491,8 @@ public interface LiveService { /** * 获得当前佩戴着的头衔的详情 - * 当前未佩戴任何东西时, 返回的 code 为 -1, message 为 "nodata" + * + * @return 当前未佩戴任何东西时, 返回的 code 为 -1, message 为 "nodata" */ @GET("appUser/getWearTitle") Call getWearTitle(); @@ -519,7 +522,8 @@ public interface LiveService { * 瓜子商店 * 侧拉抽屉 -> 直播中心 -> 瓜子商店 -> 银瓜子兑换 -> 硬币银瓜子互换 -> 兑换硬币 * 将 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次 - * 已经兑换过时返回 403 + * + * @return 已经兑换过时返回 403 */ @POST("AppExchange/silver2coin") Call silver2Coin(); @@ -575,9 +579,10 @@ public interface LiveService { /** * 侧拉抽屉 -> 直播中心 -> 房间设置 -> 我的封面 - * 获取自己的直播间的封面(获取其他人的封面会 -403) + * 获取自己的直播间的封面 * * @param roomId 房间号 + * @return 获取其他人的封面会 -403 */ @GET("mhand/assistant/getCover") Call getCover(@Query("roomId") long roomId); diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/Package.java b/src/main/java/com/hiczp/bilibili/api/live/socket/Package.java index 89f8843..a91ed4d 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/Package.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/Package.java @@ -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; diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/PackageHelper.java b/src/main/java/com/hiczp/bilibili/api/live/socket/PackageHelper.java index 9cd841b..04903e6 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/PackageHelper.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/PackageHelper.java @@ -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, diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageDecoder.java b/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageDecoder.java index ec4a061..3bef2b5 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageDecoder.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageDecoder.java @@ -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 out) throws Exception { diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageEncoder.java b/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageEncoder.java index d789f13..31ac924 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageEncoder.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/codec/PackageEncoder.java @@ -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 { @Override protected void encode(ChannelHandlerContext ctx, Package msg, ByteBuf out) throws Exception { diff --git a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java index b410b8e..b2eae06 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java +++ b/src/main/java/com/hiczp/bilibili/api/live/socket/event/ReceiveDataPackageDebugEvent.java @@ -3,7 +3,9 @@ package com.hiczp.bilibili.api.live.socket.event; import com.google.gson.JsonObject; import com.hiczp.bilibili.api.live.socket.LiveClient; -//这个事件用于调试, 任何 Data 数据包都会触发一次这个事件 +/** + * 这个事件用于调试, 任何 Data 数据包都会触发一次这个事件 + */ public class ReceiveDataPackageDebugEvent extends Event { private JsonObject jsonObject; private String cmd; diff --git a/src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java b/src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java index e180740..2578a95 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/CaptchaService.java @@ -9,9 +9,22 @@ import java.io.IOException; import java.io.InputStream; public interface CaptchaService { + /** + * 获得验证码(图形) + * + * @param cookies 请求时使用的 cookies 与返回的验证码是配对的 + * @return 返回一张 PNG + */ @GET("captcha") Call getCaptcha(@Header("Cookie") String cookies); + /** + * 以流的形式获得验证码 + * + * @param cookies 请求时使用的 cookies 与返回的验证码是配对的 + * @return 一张 PNG 图片的输入流 + * @throws IOException 网络错误 + */ default InputStream getCaptchaAsStream(String cookies) throws IOException { return getCaptcha(cookies) .execute() diff --git a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java index 3b0f915..3a9fd04 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/PassportService.java @@ -26,16 +26,19 @@ public interface PassportService { /** * 带验证码的登录 * 在一段时间内进行多次错误的登录, 将被要求输入验证码 + * * @param username 用户名 * @param password 密码 - * @param captcha 验证码 - * @param cookies cookies + * @param captcha 验证码 + * @param cookies cookies + * @see CaptchaService */ @POST("api/oauth2/login") Call login(@Query("username") String username, @Query("password") String password, @Query("captcha") String captcha, @Header("Cookie") String cookies); /** * 获得账户信息 + * * @param accessToken token */ @GET("api/oauth2/info") @@ -43,7 +46,8 @@ public interface PassportService { /** * 刷新 token - * @param accessToken token + * + * @param accessToken token * @param refreshToken refreshToken */ @POST("api/oauth2/refreshToken") @@ -51,6 +55,7 @@ public interface PassportService { /** * 注销 + * * @param accessToken token */ @POST("api/oauth2/revoke") diff --git a/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java index 90bc831..3ce6e39 100644 --- a/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java +++ b/src/main/java/com/hiczp/bilibili/api/passport/SsoService.java @@ -10,9 +10,14 @@ import javax.annotation.Nullable; /** * sso 很特别, 它可能返回的是一个 HTML 页面, 所以单独分出来 * sso 会经过两次 302 跳转, 需要保存其中的 cookie, 然后才能抵达最终页面并且进入 cookie 登录状态 - * 如果 gourl 为 null, 则会跳转到 B站 首页 */ public interface SsoService { + /** + * 通过 token 得到 cookie + * + * @param goUrl 全部的跳转完成后, 会进入指定的 URL, 如果 goUrl 为 null, 则跳转到 B站 首页 + * @return 最终跳转完成后的页面 + */ @GET("api/login/sso") Call sso(@Nullable @Query("gourl") String goUrl); } diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java index 23b620e..cc69805 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java @@ -7,9 +7,12 @@ import retrofit2.http.GET; import retrofit2.http.Query; public interface LiveService { - //直播间心跳包 - //参数为时间戳(不是 unix 时间戳) - //未登录时返回 401 + /** + * 直播间心跳包 + * + * @param timestamp 时间戳(不是 unix 时间戳) + * @return 未登录时返回 401 + */ @GET("feed/v1/feed/heartBeat") Call sendHeartBeat(@Query("_") long timestamp); @@ -17,9 +20,12 @@ public interface LiveService { return sendHeartBeat(System.currentTimeMillis()); } - //获取用户信息 - //成功时, code 为 "REPONSE_OK" - //未登录时返回 500 + /** + * 获取用户信息 + * + * @param timestamp 成功时, code 为 "REPONSE_OK" + * @return 未登录时返回 500 + */ @GET("User/getUserInfo") Call getUserInfo(@Query("ts") long timestamp); From ed7a4ae737091e55310233e7e024a33ce2b9c5f5 Mon Sep 17 00:00:00 2001 From: czp Date: Wed, 14 Mar 2018 23:29:48 +0800 Subject: [PATCH 65/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=A4=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/hiczp/bilibili/api/web/live/LiveService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java index cc69805..04f31fc 100644 --- a/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/web/live/LiveService.java @@ -23,8 +23,8 @@ public interface LiveService { /** * 获取用户信息 * - * @param timestamp 成功时, code 为 "REPONSE_OK" - * @return 未登录时返回 500 + * @param timestamp 时间戳(不是 unix 时间戳) + * @return 成功时, code 为 "REPONSE_OK", 未登录时返回 500 */ @GET("User/getUserInfo") Call getUserInfo(@Query("ts") long timestamp); From b666086ccd01003f1c08242571ea936782558738 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 15 Mar 2018 09:58:27 +0800 Subject: [PATCH 66/73] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/ServerErrorCode.java | 11 +++++ .../hiczp/bilibili/api/live/LiveService.java | 2 + .../live/entity/SendGiftResponseEntity.java | 40 +++++++++++++------ 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java index 47980c2..7e0a944 100644 --- a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java +++ b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java @@ -76,6 +76,16 @@ public class ServerErrorCode { * "每天最多能兑换 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; /** * "请登录" */ @@ -85,6 +95,7 @@ public class ServerErrorCode { */ public static final int NO_LOGIN = -101; /** + * 搜索时, 关键字字数过少或过多 * "关键字不能小于2个字节或大于50字节" */ public static final int KEYWORD_CAN_NOT_LESS_THAN_2_BYTES_OR_GREATER_THAN_50_BYTES = -609; diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index f3293f2..216e525 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -246,6 +246,8 @@ public interface LiveService { * @param timeStamp 时间戳 * @param bagId 礼物在自己背包里的 ID * @param random 随机数 + * @return roomUserId 与 roomId 不匹配时返回 200012 + * @return bagId 错误时(背包里没有这个礼物)返回 200019 */ @POST("AppBag/send") @FormUrlEncoded diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/SendGiftResponseEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/SendGiftResponseEntity.java index 37a6617..8175875 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/SendGiftResponseEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/SendGiftResponseEntity.java @@ -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 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; } From b1dd916ff3a421c4549699f40de3b4f1d83b4ad8 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 15 Mar 2018 22:04:43 +0800 Subject: [PATCH 67/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=A0=81=E4=B8=8E=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java | 5 +++++ src/main/java/com/hiczp/bilibili/api/live/LiveService.java | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java index 7e0a944..632ee55 100644 --- a/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java +++ b/src/main/java/com/hiczp/bilibili/api/ServerErrorCode.java @@ -90,6 +90,11 @@ public class ServerErrorCode { * "请登录" */ public static final int PLEASE_LOGIN0 = 32205; + /** + * "message": "invalid request" + * "data": "bad token" + */ + public static final int INVALID_REQUEST = 65530; /** * "请先登录" */ diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 216e525..4e6eb30 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -247,7 +247,7 @@ public interface LiveService { * @param bagId 礼物在自己背包里的 ID * @param random 随机数 * @return roomUserId 与 roomId 不匹配时返回 200012 - * @return bagId 错误时(背包里没有这个礼物)返回 200019 + * bagId 错误时(背包里没有这个礼物)返回 200019 */ @POST("AppBag/send") @FormUrlEncoded @@ -526,6 +526,7 @@ public interface LiveService { * 将 700 银瓜子兑换为 1 硬币, 每个用户每天只能换一次 * * @return 已经兑换过时返回 403 + * 2018-03-15 访问此 API 必须有一个合法的 UA, 否则返回 65530 */ @POST("AppExchange/silver2coin") Call silver2Coin(); From 8b4d016b00f222a9711fbe106208e1c4c481bff6 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 15 Mar 2018 23:19:43 +0800 Subject: [PATCH 68/73] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E9=A2=86=E5=8F=96?= =?UTF-8?q?=E4=BF=A1=E4=BB=B0=E4=BB=BB=E5=8A=A1=20=E7=9A=84=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/live/LiveService.java | 32 ++ .../api/live/entity/MobileActivityEntity.java | 225 +++++++++ .../api/live/entity/ReceiveUserTaskAward.java | 55 ++ .../api/live/entity/UserTasksEntity.java | 478 ++++++++++++++++++ 4 files changed, 790 insertions(+) create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/MobileActivityEntity.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/ReceiveUserTaskAward.java create mode 100644 src/main/java/com/hiczp/bilibili/api/live/entity/UserTasksEntity.java diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 4e6eb30..fe8cb14 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -141,6 +141,38 @@ public interface LiveService { return getPlayUrl(cid, "json"); } + /** + * 获取当前这段时间的活动(不定期活动, 每次持续几周)和信仰任务 + * + * @param roomId 房间号 + */ + @GET("activity/v1/Common/mobileActivity") + Call getMobileActivity(@Query("roomid") long roomId); + + /** + * 获取用户的信仰任务列表 + * + * @return 2018-02 现在只有 double_watch_task 这个任务是有效的 + */ + @GET("activity/v1/task/user_tasks") + Call getUserTasks(); + + /** + * 领取一个信仰任务 + * + * @param taskId 任务名 + * @return 任务未完成或者已领取返回 -400 + */ + @POST("activity/v1/task/receive_award") + Call receiveUserTaskAward(@Query("task_id") String taskId); + + /** + * 领取 double_watch_task 任务的奖励 + */ + default Call receiveDoubleWatchTaskAward() { + return receiveUserTaskAward("double_watch_task"); + } + /** * 发送一个 Restful 心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级 * 2018-03-06 开始, 只有老爷才能通过观看直播获得经验 diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/MobileActivityEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/MobileActivityEntity.java new file mode 100644 index 0000000..b2c722f --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/MobileActivityEntity.java @@ -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; + } + } + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/ReceiveUserTaskAward.java b/src/main/java/com/hiczp/bilibili/api/live/entity/ReceiveUserTaskAward.java new file mode 100644 index 0000000..a80352e --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/ReceiveUserTaskAward.java @@ -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; + } +} diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/UserTasksEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/UserTasksEntity.java new file mode 100644 index 0000000..f03cc4f --- /dev/null +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/UserTasksEntity.java @@ -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; + + 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 getAwards() { + return awards; + } + + public void setAwards(List 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 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 getAwards() { + return awards; + } + + public void setAwards(List 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 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 getAwards() { + return awards; + } + + public void setAwards(List 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; + } + } + } + } +} From 29affaa4381d175db541510249a52cb7a5683ca7 Mon Sep 17 00:00:00 2001 From: czp Date: Thu, 15 Mar 2018 23:50:12 +0800 Subject: [PATCH 69/73] =?UTF-8?q?=E4=B8=BA=20BilibiliWebAPI=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hiczp/bilibili/api/BilibiliAPI.java | 21 +++++++++++++++---- .../AutoRefreshTokenInterceptor.java | 6 ++---- .../hiczp/bilibili/api/live/LiveService.java | 11 +++++++--- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 7b59074..0289deb 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -51,6 +51,8 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv private CaptchaService captchaService; private LiveService liveService; + private BilibiliWebAPI bilibiliWebAPI; + public BilibiliAPI() { this.bilibiliClientProperties = BilibiliClientProperties.defaultSetting(); this.bilibiliAccount = BilibiliAccount.emptyInstance(); @@ -71,7 +73,6 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv this.bilibiliAccount = new BilibiliAccount(bilibiliAccount); } - //TODO 不明确客户端访问 passport.bilibili.com 时使用的 UA @Override public PassportService getPassportService() { if (passportService == null) { @@ -83,7 +84,15 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv public PassportService getPassportService(@Nonnull List interceptors, @Nonnull HttpLoggingInterceptor.Level logLevel) { OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); + //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", @@ -148,7 +157,6 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv .addInterceptor(new AddAppKeyInterceptor(bilibiliClientProperties)) .addInterceptor(new AutoRefreshTokenInterceptor( this, - autoRefreshToken, ServerErrorCode.Common.UNAUTHORIZED, ServerErrorCode.Live.USER_NO_LOGIN, ServerErrorCode.Live.PLEASE_LOGIN, @@ -258,11 +266,14 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv @Override public BilibiliWebAPI getBilibiliWebAPI() throws IOException { - return new BilibiliWebAPI(toCookies()); + return getBilibiliWebAPI(BrowserProperties.defaultSetting()); } public BilibiliWebAPI getBilibiliWebAPI(BrowserProperties browserProperties) throws IOException { - return new BilibiliWebAPI(browserProperties, toCookies()); + if (bilibiliWebAPI == null) { + bilibiliWebAPI = new BilibiliWebAPI(browserProperties, toCookies()); + } + return bilibiliWebAPI; } public LoginResponseEntity login(@Nonnull String username, @Nonnull String password) throws IOException, LoginException, CaptchaMismatchException { @@ -301,6 +312,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv } } bilibiliAccount.copyFrom(loginResponseEntity.toBilibiliAccount()); + bilibiliWebAPI = null; LOGGER.info("Login succeed with username: {}", username); return loginResponseEntity; } @@ -334,6 +346,7 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv } } bilibiliAccount.copyFrom(refreshTokenResponseEntity.toBilibiliAccount()); + bilibiliWebAPI = null; LOGGER.info("RefreshToken succeed with userId: {}", bilibiliAccount.getUserId()); return refreshTokenResponseEntity; } diff --git a/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java b/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java index f08e0a5..ff6279d 100644 --- a/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java +++ b/src/main/java/com/hiczp/bilibili/api/interceptor/AutoRefreshTokenInterceptor.java @@ -21,12 +21,10 @@ public class AutoRefreshTokenInterceptor implements Interceptor { private static final Logger LOGGER = LoggerFactory.getLogger(AutoRefreshTokenInterceptor.class); private BilibiliAPI bilibiliAPI; - private Boolean autoRefreshToken; private int[] codes; - public AutoRefreshTokenInterceptor(BilibiliAPI bilibiliAPI, Boolean autoRefreshToken, int... codes) { + public AutoRefreshTokenInterceptor(BilibiliAPI bilibiliAPI, int... codes) { this.bilibiliAPI = bilibiliAPI; - this.autoRefreshToken = autoRefreshToken; this.codes = codes; } @@ -34,7 +32,7 @@ public class AutoRefreshTokenInterceptor implements Interceptor { public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); - if (!autoRefreshToken) { + if (!bilibiliAPI.isAutoRefreshToken()) { return response; } diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index fe8cb14..1c9741d 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -52,8 +52,8 @@ public interface LiveService { @POST("feed/v1/feed/isFollowed") Call isFollowed(@Query("follow") long hostUserId); - //TODO 每日背包任务 - //该 API 意义不明(似乎跟什么 每日背包任务 有关) + //TODO sendDaily + //该 API 意义不明 @GET("AppBag/sendDaily") Call sendDaily(); @@ -110,10 +110,11 @@ public interface LiveService { @GET("appUser/getTitle") Call getTitle(); - //TODO 节奏风暴 + //TODO 查看房间里是否有节奏风暴 @GET("SpecialGift/room/{roomId}") Call getSpecialGift(@Path("roomId") long roomId); //TODO 参与节奏风暴抽奖 + //TODO 查看节奏风暴奖励 /** * 获取自己的用户信息(live 站的个人信息, 非总站) @@ -173,6 +174,10 @@ public interface LiveService { return receiveUserTaskAward("double_watch_task"); } + //TODO 查看一个房间是否有活动抽奖 + //TODO 参与活动抽奖 + //TODO 查看活动抽奖奖励 + /** * 发送一个 Restful 心跳包, 五分钟一次. 这被用于统计观看直播的时间, 可以提升观众等级 * 2018-03-06 开始, 只有老爷才能通过观看直播获得经验 From 7e31fb4900e326993b85f9946a3fe8d7e45b2b34 Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 16 Mar 2018 09:34:44 +0800 Subject: [PATCH 70/73] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20LiveRoomInfoEntity?= =?UTF-8?q?=20=E7=9A=84=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/live/entity/LiveRoomInfoEntity.java | 332 +++++++++++++----- 1 file changed, 250 insertions(+), 82 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/LiveRoomInfoEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/LiveRoomInfoEntity.java index 763e6c9..988f2ae 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/LiveRoomInfoEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/LiveRoomInfoEntity.java @@ -1,5 +1,6 @@ package com.hiczp.bilibili.api.live.entity; +import com.google.gson.JsonElement; import com.google.gson.annotations.SerializedName; import java.util.List; @@ -8,7 +9,7 @@ import java.util.Map; public class LiveRoomInfoEntity { /** * code : 0 - * data : {"room_id":29434,"title":"继续玩游戏~","cover":"http://i0.hdslb.com/bfs/live/744637d38c9f0a994bf7164a3b73493f537c3876.jpg","mid":2866663,"uname":"hyx5020","face":"http://i2.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg","m_face":"http://i2.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg","background_id":1,"attention":310,"is_attention":0,"online":261,"create":1438266869,"create_at":"2015-07-30 22:34:29","sch_id":0,"status":"PREPARING","area":"单机联机","area_id":1,"area_v2_id":107,"area_v2_parent_id":2,"schedule":{"cid":10029434,"sch_id":0,"title":"继续玩游戏~","mid":2866663,"manager":[],"start":1438266869,"start_at":"2015-07-30 22:34:29","aid":0,"stream_id":20393,"online":261,"status":"PREPARING","meta_id":0,"pending_meta_id":0},"meta":{"tag":["坎巴拉太空计划"],"description":"


<\/p>


<\/h1>


<\/p>","typeid":1,"tag_ids":{"0":24},"cover":"http://i0.hdslb.com/bfs/live/744637d38c9f0a994bf7164a3b73493f537c3876.jpg","check_status":"VERIFY","aid":0},"cmt":"livecmt-2.bilibili.com","cmt_port":88,"cmt_port_goim":2243,"recommend":[{"owner":{"face":"http://i1.hdslb.com/bfs/face/cdb0ddf5087248eb30c05ac9257f3f87c3f9f42d.jpg","mid":13661517,"name":"萌萌哒少女深海酱"},"cover":{"src":"http://i0.hdslb.com/bfs/live/1081638.jpg?11020048"},"title":"ASMR~鸽子王主播居然......","room_id":1081638,"online":7708},{"owner":{"face":"http://i0.hdslb.com/bfs/face/b60b42e1a570589cac62e4e3c6f5d0e8a4c994a7.jpg","mid":4186467,"name":"鹿島ちゃんは可愛い"},"cover":{"src":"http://i0.hdslb.com/bfs/live/1266586.jpg?11020045"},"title":"想找个萌妹连麦","room_id":1266586,"online":5520}],"toplist":[],"isvip":0,"opentime":0,"prepare":"主播正在摔♂跤中...","isadmin":0,"hot_word":[{"id":45,"words":"当然是选择原谅她啊!"},{"id":44,"words":"还有这种操作!"},{"id":42,"words":"怕是要修仙哦"},{"id":41,"words":"gay里gay气"},{"id":39,"words":"请大家注意弹幕礼仪哦!"},{"id":37,"words":"那你很棒哦!"},{"id":36,"words":"向大佬低头"},{"id":30,"words":"bilibili-(゜-゜)つロ乾杯~"},{"id":25,"words":"prprpr"},{"id":22,"words":"excuse me?"},{"id":21,"words":"gg"},{"id":20,"words":"你为什么这么熟练啊"},{"id":19,"words":"老司机带带我"},{"id":13,"words":"666666666"},{"id":12,"words":"啪啪啪啪啪"},{"id":11,"words":"Yooooooo"},{"id":10,"words":"FFFFFFFFFF"},{"id":9,"words":"色情主播"},{"id":7,"words":"红红火火恍恍惚惚"},{"id":5,"words":"喂,妖妖零吗"},{"id":3,"words":"_(:з」∠)_"},{"id":2,"words":"2333333"}],"roomgifts":[{"id":7,"name":"666","price":666,"type":1,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-7.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/7.gif?20171010161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":8,"name":"233","price":233,"type":1,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-8.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/8.gif?20171010161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":25,"name":"小电视","price":1245000,"type":0,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-25.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/25.gif?20171010161652","count_set":"1,2,3,4,5","combo_num":1,"super_num":1,"count_map":{"1":"高能","2":"高能","3":"高能","4":"高能","5":"高能"}},{"id":3,"name":"B坷垃","price":9900,"type":0,"coin_type":{"gold":"gold","silver":"silver"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-3.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/3.gif?20171010161652","count_set":"1,10,46,520,1314","combo_num":1,"super_num":46,"count_map":{"1":"连击","10":"连击","46":"高能","520":"高能","1314":"高能"}},{"id":4,"name":"喵娘","price":5200,"type":0,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-4.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/4.gif?20171010161652","count_set":"1,2,10,87,520","combo_num":2,"super_num":87,"count_map":{"1":"","2":"连击","10":"连击","87":"高能","520":"高能"}},{"id":6,"name":"亿圆","price":1000,"type":0,"coin_type":{"gold":"gold","silver":"silver"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-6.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/6.gif?20171010161652","count_set":"1,10,99,450,1314","combo_num":10,"super_num":450,"count_map":{"1":"","10":"连击","99":"连击","450":"高能","1314":"高能"}},{"id":1,"name":"辣条","price":100,"type":0,"coin_type":{"gold":"gold","silver":"silver"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-1.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/1.gif?20171010161652","count_set":"1,10,99,520,4500","combo_num":99,"super_num":4500,"count_map":{"1":"","10":"","99":"连击","520":"连击","4500":"高能"}}],"ignore_gift":[{"id":1,"num":10},{"id":21,"num":10}],"msg_mode":1,"msg_color":16777215,"msg_length":20,"master_level":11,"master_level_color":5805790,"broadcast_type":0,"activity_gift":[],"check_version":0,"activity_id":0,"event_corner":[],"guard_level":0,"guard_info":{"heart_status":0,"heart_time":300},"guard_notice":0,"guard_tip_flag":0,"new_year_ceremony":0,"special_gift_gif":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901","show_room_id":29434} + * data : {"room_id":23058,"title":"哔哩哔哩音悦台","cover":"http://i0.hdslb.com/bfs/live/6029764557e3cbe91475faae26e6e244de8c1d3c.jpg","mid":11153765,"uname":"3号直播间","face":"http://i0.hdslb.com/bfs/face/5d35da6e93fbfb1a77ad6d1f1004b08413913f9a.jpg","m_face":"http://i0.hdslb.com/bfs/face/5d35da6e93fbfb1a77ad6d1f1004b08413913f9a.jpg","background_id":1,"attention":313994,"is_attention":1,"online":25101,"create":1434695375,"create_at":"2015-06-19 14:29:35","sch_id":0,"status":"LIVE","area":"放映厅","area_id":7,"area_v2_id":34,"area_v2_parent_id":1,"area_v2_name":"音乐台","area_v2_parent_name":"娱乐","schedule":{"cid":10023058,"sch_id":0,"title":"哔哩哔哩音悦台","mid":11153765,"manager":[],"start":1434695375,"start_at":"2015-06-19 14:29:35","aid":0,"stream_id":13998,"online":25101,"status":"LIVE","meta_id":0,"pending_meta_id":0},"meta":{"tag":["ACG音乐"],"description":"

这里是哔哩哔哩官方音乐台喔!<\/p>

一起来听音乐吧ε=ε=(ノ≧∇≦)ノ<\/p>

没想到蒸汽配圣诞下装,意外的很暴露呢=3=<\/p>\n","typeid":1,"tag_ids":{"0":24},"cover":"http://i0.hdslb.com/bfs/live/6029764557e3cbe91475faae26e6e244de8c1d3c.jpg","check_status":"VERIFY","aid":0},"cmt":"livecmt-2.bilibili.com","cmt_port":88,"cmt_port_goim":2243,"recommend":[{"owner":{"face":"http://i2.hdslb.com/bfs/face/941f199204fd885cca123cbe8be6eedb6639d0e0.jpg","mid":14117221,"name":"就决定是你了长生"},"cover":{"src":"http://i0.hdslb.com/bfs/live/1170236.jpg?03160920"},"title":"【长生】唱的不好听算我输!","room_id":1170236,"online":3649},{"owner":{"face":"http://i2.hdslb.com/bfs/face/2af1a482007bee57d176559defc861cd39481dcf.jpg","mid":2756858,"name":"咿呀哥哥"},"cover":{"src":"http://i0.hdslb.com/bfs/live/2532274.jpg?03160920"},"title":"暖音哥哥 数羊哄睡","room_id":2532274,"online":92}],"toplist":[{"name":"桃花榜","type":"lover_2018"}],"isvip":0,"opentime":33690,"prepare":"主播正在嘿嘿嘿中...","isadmin":0,"hot_word":[{"id":48,"words":"打call"},{"id":47,"words":"囍"},{"id":44,"words":"还有这种操作!"},{"id":41,"words":"gay里gay气"},{"id":39,"words":"请大家注意弹幕礼仪哦!"},{"id":36,"words":"向大佬低头"},{"id":25,"words":"prprpr"},{"id":21,"words":"gg"},{"id":20,"words":"你为什么这么熟练啊"},{"id":19,"words":"老司机带带我"},{"id":13,"words":"666666666"},{"id":12,"words":"啪啪啪啪啪"},{"id":11,"words":"Yooooooo"},{"id":10,"words":"FFFFFFFFFF"},{"id":9,"words":"色情主播"},{"id":7,"words":"红红火火恍恍惚惚"},{"id":5,"words":"喂,妖妖零吗"},{"id":2,"words":"2333333"}],"roomgifts":[{"id":116,"name":"情书","price":2000,"type":2,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-116.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/116.gif?20180314161652","count_set":"1,5,10,99,225","combo_num":5,"super_num":225,"count_map":{"1":"","5":"","10":"","99":"","225":"高能"}},{"id":25,"name":"小电视","price":1245000,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-25.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/25.gif?20180314161652","count_set":"1,2,3,4,5","combo_num":1,"super_num":1,"count_map":{"1":"高能","2":"高能","3":"高能","4":"高能","5":"高能"}},{"id":3,"name":"B坷垃","price":9900,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-3.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/3.gif?20180314161652","count_set":"1,10,46,520,1314","combo_num":1,"super_num":46,"count_map":{"1":"","10":"","46":"高能","520":"高能","1314":"高能"}},{"id":4,"name":"喵娘","price":5200,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-4.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/4.gif?20180314161652","count_set":"1,2,10,87,520","combo_num":2,"super_num":87,"count_map":{"1":"","2":"","10":"","87":"高能","520":"高能"}},{"id":6,"name":"亿圆","price":1000,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-6.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/6.gif?20180314161652","count_set":"1,10,99,450,1314","combo_num":10,"super_num":450,"count_map":{"1":"","10":"","99":"","450":"高能","1314":"高能"}},{"id":7,"name":"666","price":666,"type":1,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-7.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/7.gif?20180314161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":8,"name":"233","price":233,"type":1,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-8.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/8.gif?20180314161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":1,"name":"辣条","price":100,"type":0,"coin_type":{"silver":"silver"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-1.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/1.gif?20180314161652","count_set":"1,10,99,520,4500","combo_num":0,"super_num":0,"count_map":{"1":"","10":"","99":"","520":"","4500":""}}],"ignore_gift":[{"id":1,"num":10},{"id":21,"num":10}],"msg_mode":1,"msg_color":16777215,"msg_length":30,"master_level":36,"master_level_color":16746162,"broadcast_type":0,"activity_gift":[{"id":115,"bag_id":67456406,"name":"桃花","num":1,"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-115.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/115.gif?20180314161652","combo_num":0,"super_num":0,"count_set":"1,1","count_map":{"1":"全部"}}],"check_version":0,"activity_id":0,"event_corner":[],"guard_level":0,"guard_info":{"heart_status":0,"heart_time":300},"guard_notice":0,"guard_tip_flag":1,"new_year_ceremony":0,"special_gift_gif":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901","show_room_id":3} */ @SerializedName("code") @@ -44,56 +45,58 @@ public class LiveRoomInfoEntity { public static class LiveRoomEntity { /** - * room_id : 29434 - * title : 继续玩游戏~ - * cover : http://i0.hdslb.com/bfs/live/744637d38c9f0a994bf7164a3b73493f537c3876.jpg - * mid : 2866663 - * uname : hyx5020 - * face : http://i2.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg - * m_face : http://i2.hdslb.com/bfs/face/0434dccc0ec4de223e8ca374dea06a6e1e8eb471.jpg + * room_id : 23058 + * title : 哔哩哔哩音悦台 + * cover : http://i0.hdslb.com/bfs/live/6029764557e3cbe91475faae26e6e244de8c1d3c.jpg + * mid : 11153765 + * uname : 3号直播间 + * face : http://i0.hdslb.com/bfs/face/5d35da6e93fbfb1a77ad6d1f1004b08413913f9a.jpg + * m_face : http://i0.hdslb.com/bfs/face/5d35da6e93fbfb1a77ad6d1f1004b08413913f9a.jpg * background_id : 1 - * attention : 310 - * is_attention : 0 - * online : 261 - * create : 1438266869 - * create_at : 2015-07-30 22:34:29 + * attention : 313994 + * is_attention : 1 + * online : 25101 + * create : 1434695375 + * create_at : 2015-06-19 14:29:35 * sch_id : 0 - * status : PREPARING - * area : 单机联机 - * area_id : 1 - * area_v2_id : 107 - * area_v2_parent_id : 2 - * schedule : {"cid":10029434,"sch_id":0,"title":"继续玩游戏~","mid":2866663,"manager":[],"start":1438266869,"start_at":"2015-07-30 22:34:29","aid":0,"stream_id":20393,"online":261,"status":"PREPARING","meta_id":0,"pending_meta_id":0} - * meta : {"tag":["坎巴拉太空计划"],"description":"


<\/p>


<\/h1>


<\/p>","typeid":1,"tag_ids":{"0":24},"cover":"http://i0.hdslb.com/bfs/live/744637d38c9f0a994bf7164a3b73493f537c3876.jpg","check_status":"VERIFY","aid":0} + * status : LIVE + * area : 放映厅 + * area_id : 7 + * area_v2_id : 34 + * area_v2_parent_id : 1 + * area_v2_name : 音乐台 + * area_v2_parent_name : 娱乐 + * schedule : {"cid":10023058,"sch_id":0,"title":"哔哩哔哩音悦台","mid":11153765,"manager":[],"start":1434695375,"start_at":"2015-06-19 14:29:35","aid":0,"stream_id":13998,"online":25101,"status":"LIVE","meta_id":0,"pending_meta_id":0} + * meta : {"tag":["ACG音乐"],"description":"

这里是哔哩哔哩官方音乐台喔!<\/p>

一起来听音乐吧ε=ε=(ノ≧∇≦)ノ<\/p>

没想到蒸汽配圣诞下装,意外的很暴露呢=3=<\/p>\n","typeid":1,"tag_ids":{"0":24},"cover":"http://i0.hdslb.com/bfs/live/6029764557e3cbe91475faae26e6e244de8c1d3c.jpg","check_status":"VERIFY","aid":0} * cmt : livecmt-2.bilibili.com * cmt_port : 88 * cmt_port_goim : 2243 - * recommend : [{"owner":{"face":"http://i1.hdslb.com/bfs/face/cdb0ddf5087248eb30c05ac9257f3f87c3f9f42d.jpg","mid":13661517,"name":"萌萌哒少女深海酱"},"cover":{"src":"http://i0.hdslb.com/bfs/live/1081638.jpg?11020048"},"title":"ASMR~鸽子王主播居然......","room_id":1081638,"online":7708},{"owner":{"face":"http://i0.hdslb.com/bfs/face/b60b42e1a570589cac62e4e3c6f5d0e8a4c994a7.jpg","mid":4186467,"name":"鹿島ちゃんは可愛い"},"cover":{"src":"http://i0.hdslb.com/bfs/live/1266586.jpg?11020045"},"title":"想找个萌妹连麦","room_id":1266586,"online":5520}] - * toplist : [] + * recommend : [{"owner":{"face":"http://i2.hdslb.com/bfs/face/941f199204fd885cca123cbe8be6eedb6639d0e0.jpg","mid":14117221,"name":"就决定是你了长生"},"cover":{"src":"http://i0.hdslb.com/bfs/live/1170236.jpg?03160920"},"title":"【长生】唱的不好听算我输!","room_id":1170236,"online":3649},{"owner":{"face":"http://i2.hdslb.com/bfs/face/2af1a482007bee57d176559defc861cd39481dcf.jpg","mid":2756858,"name":"咿呀哥哥"},"cover":{"src":"http://i0.hdslb.com/bfs/live/2532274.jpg?03160920"},"title":"暖音哥哥 数羊哄睡","room_id":2532274,"online":92}] + * toplist : [{"name":"桃花榜","type":"lover_2018"}] * isvip : 0 - * opentime : 0 - * prepare : 主播正在摔♂跤中... + * opentime : 33690 + * prepare : 主播正在嘿嘿嘿中... * isadmin : 0 - * hot_word : [{"id":45,"words":"当然是选择原谅她啊!"},{"id":44,"words":"还有这种操作!"},{"id":42,"words":"怕是要修仙哦"},{"id":41,"words":"gay里gay气"},{"id":39,"words":"请大家注意弹幕礼仪哦!"},{"id":37,"words":"那你很棒哦!"},{"id":36,"words":"向大佬低头"},{"id":30,"words":"bilibili-(゜-゜)つロ乾杯~"},{"id":25,"words":"prprpr"},{"id":22,"words":"excuse me?"},{"id":21,"words":"gg"},{"id":20,"words":"你为什么这么熟练啊"},{"id":19,"words":"老司机带带我"},{"id":13,"words":"666666666"},{"id":12,"words":"啪啪啪啪啪"},{"id":11,"words":"Yooooooo"},{"id":10,"words":"FFFFFFFFFF"},{"id":9,"words":"色情主播"},{"id":7,"words":"红红火火恍恍惚惚"},{"id":5,"words":"喂,妖妖零吗"},{"id":3,"words":"_(:з」∠)_"},{"id":2,"words":"2333333"}] - * roomgifts : [{"id":7,"name":"666","price":666,"type":1,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-7.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/7.gif?20171010161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":8,"name":"233","price":233,"type":1,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-8.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/8.gif?20171010161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":25,"name":"小电视","price":1245000,"type":0,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-25.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/25.gif?20171010161652","count_set":"1,2,3,4,5","combo_num":1,"super_num":1,"count_map":{"1":"高能","2":"高能","3":"高能","4":"高能","5":"高能"}},{"id":3,"name":"B坷垃","price":9900,"type":0,"coin_type":{"gold":"gold","silver":"silver"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-3.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/3.gif?20171010161652","count_set":"1,10,46,520,1314","combo_num":1,"super_num":46,"count_map":{"1":"连击","10":"连击","46":"高能","520":"高能","1314":"高能"}},{"id":4,"name":"喵娘","price":5200,"type":0,"coin_type":{"gold":"gold"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-4.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/4.gif?20171010161652","count_set":"1,2,10,87,520","combo_num":2,"super_num":87,"count_map":{"1":"","2":"连击","10":"连击","87":"高能","520":"高能"}},{"id":6,"name":"亿圆","price":1000,"type":0,"coin_type":{"gold":"gold","silver":"silver"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-6.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/6.gif?20171010161652","count_set":"1,10,99,450,1314","combo_num":10,"super_num":450,"count_map":{"1":"","10":"连击","99":"连击","450":"高能","1314":"高能"}},{"id":1,"name":"辣条","price":100,"type":0,"coin_type":{"gold":"gold","silver":"silver"},"img":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-1.png?20171010161652","gift_url":"http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/1.gif?20171010161652","count_set":"1,10,99,520,4500","combo_num":99,"super_num":4500,"count_map":{"1":"","10":"","99":"连击","520":"连击","4500":"高能"}}] + * hot_word : [{"id":48,"words":"打call"},{"id":47,"words":"囍"},{"id":44,"words":"还有这种操作!"},{"id":41,"words":"gay里gay气"},{"id":39,"words":"请大家注意弹幕礼仪哦!"},{"id":36,"words":"向大佬低头"},{"id":25,"words":"prprpr"},{"id":21,"words":"gg"},{"id":20,"words":"你为什么这么熟练啊"},{"id":19,"words":"老司机带带我"},{"id":13,"words":"666666666"},{"id":12,"words":"啪啪啪啪啪"},{"id":11,"words":"Yooooooo"},{"id":10,"words":"FFFFFFFFFF"},{"id":9,"words":"色情主播"},{"id":7,"words":"红红火火恍恍惚惚"},{"id":5,"words":"喂,妖妖零吗"},{"id":2,"words":"2333333"}] + * roomgifts : [{"id":116,"name":"情书","price":2000,"type":2,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-116.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/116.gif?20180314161652","count_set":"1,5,10,99,225","combo_num":5,"super_num":225,"count_map":{"1":"","5":"","10":"","99":"","225":"高能"}},{"id":25,"name":"小电视","price":1245000,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-25.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/25.gif?20180314161652","count_set":"1,2,3,4,5","combo_num":1,"super_num":1,"count_map":{"1":"高能","2":"高能","3":"高能","4":"高能","5":"高能"}},{"id":3,"name":"B坷垃","price":9900,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-3.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/3.gif?20180314161652","count_set":"1,10,46,520,1314","combo_num":1,"super_num":46,"count_map":{"1":"","10":"","46":"高能","520":"高能","1314":"高能"}},{"id":4,"name":"喵娘","price":5200,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-4.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/4.gif?20180314161652","count_set":"1,2,10,87,520","combo_num":2,"super_num":87,"count_map":{"1":"","2":"","10":"","87":"高能","520":"高能"}},{"id":6,"name":"亿圆","price":1000,"type":0,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-6.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/6.gif?20180314161652","count_set":"1,10,99,450,1314","combo_num":10,"super_num":450,"count_map":{"1":"","10":"","99":"","450":"高能","1314":"高能"}},{"id":7,"name":"666","price":666,"type":1,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-7.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/7.gif?20180314161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":8,"name":"233","price":233,"type":1,"coin_type":{"gold":"gold"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-8.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/8.gif?20180314161652","count_set":"1,2,3,4,5","combo_num":0,"super_num":0,"count_map":{"1":"","2":"","3":"","4":"","5":""}},{"id":1,"name":"辣条","price":100,"type":0,"coin_type":{"silver":"silver"},"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-1.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/1.gif?20180314161652","count_set":"1,10,99,520,4500","combo_num":0,"super_num":0,"count_map":{"1":"","10":"","99":"","520":"","4500":""}}] * ignore_gift : [{"id":1,"num":10},{"id":21,"num":10}] * msg_mode : 1 * msg_color : 16777215 - * msg_length : 20 - * master_level : 11 - * master_level_color : 5805790 + * msg_length : 30 + * master_level : 36 + * master_level_color : 16746162 * broadcast_type : 0 - * activity_gift : [] + * activity_gift : [{"id":115,"bag_id":67456406,"name":"桃花","num":1,"img":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-115.png?20180314161652","gift_url":"http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/115.gif?20180314161652","combo_num":0,"super_num":0,"count_set":"1,1","count_map":{"1":"全部"}}] * check_version : 0 * activity_id : 0 * event_corner : [] * guard_level : 0 * guard_info : {"heart_status":0,"heart_time":300} * guard_notice : 0 - * guard_tip_flag : 0 + * guard_tip_flag : 1 * new_year_ceremony : 0 * special_gift_gif : http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/2/jiezou.gif?2017011901 - * show_room_id : 29434 + * show_room_id : 3 */ @SerializedName("room_id") @@ -134,6 +137,10 @@ public class LiveRoomInfoEntity { private int areaV2Id; @SerializedName("area_v2_parent_id") private int areaV2ParentId; + @SerializedName("area_v2_name") + private String areaV2Name; + @SerializedName("area_v2_parent_name") + private String areaV2ParentName; @SerializedName("schedule") private ScheduleEntity schedule; @SerializedName("meta") @@ -185,7 +192,7 @@ public class LiveRoomInfoEntity { @SerializedName("recommend") private List recommend; @SerializedName("toplist") - private List toplist; + private List toplist; @SerializedName("hot_word") private List hotWord; @SerializedName("roomgifts") @@ -193,9 +200,9 @@ public class LiveRoomInfoEntity { @SerializedName("ignore_gift") private List ignoreGift; @SerializedName("activity_gift") - private List activityGift; + private List activityGift; @SerializedName("event_corner") - private List eventCorner; + private JsonElement eventCorner; public long getRoomId() { return roomId; @@ -349,6 +356,22 @@ public class LiveRoomInfoEntity { this.areaV2ParentId = areaV2ParentId; } + public String getAreaV2Name() { + return areaV2Name; + } + + public void setAreaV2Name(String areaV2Name) { + this.areaV2Name = areaV2Name; + } + + public String getAreaV2ParentName() { + return areaV2ParentName; + } + + public void setAreaV2ParentName(String areaV2ParentName) { + this.areaV2ParentName = areaV2ParentName; + } + public ScheduleEntity getSchedule() { return schedule; } @@ -549,11 +572,11 @@ public class LiveRoomInfoEntity { this.recommend = recommend; } - public List getToplist() { + public List getToplist() { return toplist; } - public void setToplist(List toplist) { + public void setToplist(List toplist) { this.toplist = toplist; } @@ -581,35 +604,35 @@ public class LiveRoomInfoEntity { this.ignoreGift = ignoreGift; } - public List getActivityGift() { + public List getActivityGift() { return activityGift; } - public void setActivityGift(List activityGift) { + public void setActivityGift(List activityGift) { this.activityGift = activityGift; } - public List getEventCorner() { + public JsonElement getEventCorner() { return eventCorner; } - public void setEventCorner(List eventCorner) { + public void setEventCorner(JsonElement eventCorner) { this.eventCorner = eventCorner; } public static class ScheduleEntity { /** - * cid : 10029434 + * cid : 10023058 * sch_id : 0 - * title : 继续玩游戏~ - * mid : 2866663 + * title : 哔哩哔哩音悦台 + * mid : 11153765 * manager : [] - * start : 1438266869 - * start_at : 2015-07-30 22:34:29 + * start : 1434695375 + * start_at : 2015-06-19 14:29:35 * aid : 0 - * stream_id : 20393 - * online : 261 - * status : PREPARING + * stream_id : 13998 + * online : 25101 + * status : LIVE * meta_id : 0 * pending_meta_id : 0 */ @@ -748,11 +771,12 @@ public class LiveRoomInfoEntity { public static class MetaEntity { /** - * tag : ["坎巴拉太空计划"] - * description :




+ * tag : ["ACG音乐"] + * description :

这里是哔哩哔哩官方音乐台喔!

一起来听音乐吧ε=ε=(ノ≧∇≦)ノ

没想到蒸汽配圣诞下装,意外的很暴露呢=3=

+ * typeid : 1 * tag_ids : {"0":24} - * cover : http://i0.hdslb.com/bfs/live/744637d38c9f0a994bf7164a3b73493f537c3876.jpg + * cover : http://i0.hdslb.com/bfs/live/6029764557e3cbe91475faae26e6e244de8c1d3c.jpg * check_status : VERIFY * aid : 0 */ @@ -876,11 +900,11 @@ public class LiveRoomInfoEntity { public static class RecommendEntity { /** - * owner : {"face":"http://i1.hdslb.com/bfs/face/cdb0ddf5087248eb30c05ac9257f3f87c3f9f42d.jpg","mid":13661517,"name":"萌萌哒少女深海酱"} - * cover : {"src":"http://i0.hdslb.com/bfs/live/1081638.jpg?11020048"} - * title : ASMR~鸽子王主播居然...... - * room_id : 1081638 - * online : 7708 + * owner : {"face":"http://i2.hdslb.com/bfs/face/941f199204fd885cca123cbe8be6eedb6639d0e0.jpg","mid":14117221,"name":"就决定是你了长生"} + * cover : {"src":"http://i0.hdslb.com/bfs/live/1170236.jpg?03160920"} + * title : 【长生】唱的不好听算我输! + * room_id : 1170236 + * online : 3649 */ @SerializedName("owner") @@ -936,9 +960,9 @@ public class LiveRoomInfoEntity { public static class OwnerEntity { /** - * face : http://i1.hdslb.com/bfs/face/cdb0ddf5087248eb30c05ac9257f3f87c3f9f42d.jpg - * mid : 13661517 - * name : 萌萌哒少女深海酱 + * face : http://i2.hdslb.com/bfs/face/941f199204fd885cca123cbe8be6eedb6639d0e0.jpg + * mid : 14117221 + * name : 就决定是你了长生 */ @SerializedName("face") @@ -975,7 +999,7 @@ public class LiveRoomInfoEntity { public static class CoverEntity { /** - * src : http://i0.hdslb.com/bfs/live/1081638.jpg?11020048 + * src : http://i0.hdslb.com/bfs/live/1170236.jpg?03160920 */ @SerializedName("src") @@ -991,10 +1015,38 @@ public class LiveRoomInfoEntity { } } + public static class ToplistEntity { + /** + * name : 桃花榜 + * type : lover_2018 + */ + + @SerializedName("name") + private String name; + @SerializedName("type") + private String type; + + 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 static class HotWordEntity { /** - * id : 45 - * words : 当然是选择原谅她啊! + * id : 48 + * words : 打call */ @SerializedName("id") @@ -1021,21 +1073,21 @@ public class LiveRoomInfoEntity { public static class RoomgiftsEntity { /** - * id : 7 - * name : 666 - * price : 666 - * type : 1 + * id : 116 + * name : 情书 + * price : 2000 + * type : 2 * coin_type : {"gold":"gold"} - * img : http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift-static-icon/gift-7.png?20171010161652 - * gift_url : http://static.hdslb.com/live-static/live-room/images/gift-section/mobilegift/3/7.gif?20171010161652 - * count_set : 1,2,3,4,5 - * combo_num : 0 - * super_num : 0 - * count_map : {"1":"","2":"","3":"","4":"","5":""} + * img : http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-116.png?20180314161652 + * gift_url : http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/116.gif?20180314161652 + * count_set : 1,5,10,99,225 + * combo_num : 5 + * super_num : 225 + * count_map : {"1":"","5":"","10":"","99":"","225":"高能"} */ @SerializedName("id") - private long id; + private int id; @SerializedName("name") private String name; @SerializedName("price") @@ -1057,11 +1109,11 @@ public class LiveRoomInfoEntity { @SerializedName("count_map") private Map countMap; - public long getId() { + public int getId() { return id; } - public void setId(long id) { + public void setId(int id) { this.id = id; } @@ -1170,25 +1222,141 @@ public class LiveRoomInfoEntity { */ @SerializedName("id") - private long id; + private int id; @SerializedName("num") - private long num; + private int num; - public long getId() { + public int getId() { return id; } - public void setId(long id) { + public void setId(int id) { this.id = id; } - public long getNum() { + public int getNum() { return num; } - public void setNum(long num) { + public void setNum(int num) { this.num = num; } } + + public static class ActivityGiftEntity { + /** + * id : 115 + * bag_id : 67456406 + * name : 桃花 + * num : 1 + * img : http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift-static-icon/gift-115.png?20180314161652 + * gift_url : http://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/115.gif?20180314161652 + * combo_num : 0 + * super_num : 0 + * count_set : 1,1 + * count_map : {"1":"全部"} + */ + + @SerializedName("id") + private int id; + @SerializedName("bag_id") + private int bagId; + @SerializedName("name") + private String name; + @SerializedName("num") + private int num; + @SerializedName("img") + private String img; + @SerializedName("gift_url") + private String giftUrl; + @SerializedName("combo_num") + private int comboNum; + @SerializedName("super_num") + private int superNum; + @SerializedName("count_set") + private String countSet; + @SerializedName("count_map") + private Map countMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getBagId() { + return bagId; + } + + public void setBagId(int bagId) { + this.bagId = bagId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } + + public String getImg() { + return img; + } + + public void setImg(String img) { + this.img = img; + } + + public String getGiftUrl() { + return giftUrl; + } + + public void setGiftUrl(String giftUrl) { + this.giftUrl = giftUrl; + } + + public int getComboNum() { + return comboNum; + } + + public void setComboNum(int comboNum) { + this.comboNum = comboNum; + } + + public int getSuperNum() { + return superNum; + } + + public void setSuperNum(int superNum) { + this.superNum = superNum; + } + + public String getCountSet() { + return countSet; + } + + public void setCountSet(String countSet) { + this.countSet = countSet; + } + + public Map getCountMap() { + return countMap; + } + + public void setCountMap(Map countMap) { + this.countMap = countMap; + } + } } } From 693f96f1803ca83479c1d86197eeb0d1cdfe81a6 Mon Sep 17 00:00:00 2001 From: czp Date: Fri, 16 Mar 2018 09:38:14 +0800 Subject: [PATCH 71/73] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=9D=A5=E5=88=9B=E5=BB=BA=20BilibiliAPI=20=E5=AE=9E=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 52f7ed6..cd2f91b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ # 添加依赖 ## Gradle - compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.9' + compile group: 'com.hiczp', name: 'bilibili-api', version: '0.0.10' # 名词解释 B站不少参数都是瞎取的, 并且不统一, 经常混用, 以下给出一些常见参数对应的含义 diff --git a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java index 0289deb..febcb21 100644 --- a/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java +++ b/src/main/java/com/hiczp/bilibili/api/BilibiliAPI.java @@ -63,14 +63,14 @@ public class BilibiliAPI implements BilibiliServiceProvider, BilibiliCaptchaProv 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); } @Override From 8cc01b311b942272873fa286de7f64e4e1636392 Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 2 Apr 2018 10:14:06 +0800 Subject: [PATCH 72/73] =?UTF-8?q?=E5=AE=8C=E6=88=90=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=8E=B7=E5=A5=96=E8=AE=B0=E5=BD=95=20=E7=9A=84=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hiczp/bilibili/api/live/LiveService.java | 3 +- .../api/live/entity/AwardsEntity.java | 229 +++++++++++++++++- .../bilibili/api/test/GetAwardsTest.java | 2 +- 3 files changed, 218 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index 1c9741d..cdebec8 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -552,10 +552,9 @@ public interface LiveService { //TODO 头衔工坊(没有可升级头衔, 暂不明确此 API) - //TODO 获奖记录(没有获奖记录, 暂不明确返回值) //侧拉抽屉 -> 直播中心 -> 获奖记录 @GET("AppUser/awards") - Call getAwards(); + Call getAwardRecords(); /** * 瓜子商店 diff --git a/src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java b/src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java index 7e81926..34b051b 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java +++ b/src/main/java/com/hiczp/bilibili/api/live/entity/AwardsEntity.java @@ -1,6 +1,5 @@ package com.hiczp.bilibili.api.live.entity; -import com.google.gson.JsonObject; import com.google.gson.annotations.SerializedName; import java.util.List; @@ -9,7 +8,7 @@ public class AwardsEntity { /** * code : 0 * message : OK - * data : {"list":[],"use_count":0,"count":0} + * 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") @@ -17,7 +16,7 @@ public class AwardsEntity { @SerializedName("message") private String message; @SerializedName("data") - private Data data; + private DataEntity data; public int getCode() { return code; @@ -35,19 +34,19 @@ public class AwardsEntity { this.message = message; } - public Data getData() { + public DataEntity getData() { return data; } - public void setData(Data data) { + public void setData(DataEntity data) { this.data = data; } - public static class Data { + public static class DataEntity { /** - * list : [] + * 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 : 0 + * count : 2 */ @SerializedName("use_count") @@ -55,7 +54,7 @@ public class AwardsEntity { @SerializedName("count") private int count; @SerializedName("list") - private List list; + private List awardList; public int getUseCount() { return useCount; @@ -73,12 +72,216 @@ public class AwardsEntity { this.count = count; } - public List getList() { - return list; + public List getAwardList() { + return awardList; } - public void setList(List list) { - this.list = list; + public void setAwardList(List 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; + } } } } diff --git a/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java b/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java index e481975..f3af578 100644 --- a/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java +++ b/src/test/java/com/hiczp/bilibili/api/test/GetAwardsTest.java @@ -13,7 +13,7 @@ public class GetAwardsTest { public void getAwards() throws Exception { BILIBILI_API .getLiveService(Collections.emptyList(), HttpLoggingInterceptor.Level.BODY) - .getAwards() + .getAwardRecords() .execute() .body(); } From ac03bd30741fd5e46991eb82cbcd8825439ceae7 Mon Sep 17 00:00:00 2001 From: czp Date: Mon, 2 Apr 2018 10:20:26 +0800 Subject: [PATCH 73/73] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=A4=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/hiczp/bilibili/api/live/LiveService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java index cdebec8..66696b8 100644 --- a/src/main/java/com/hiczp/bilibili/api/live/LiveService.java +++ b/src/main/java/com/hiczp/bilibili/api/live/LiveService.java @@ -552,7 +552,10 @@ public interface LiveService { //TODO 头衔工坊(没有可升级头衔, 暂不明确此 API) - //侧拉抽屉 -> 直播中心 -> 获奖记录 + /** + * 侧拉抽屉 -> 直播中心 -> 获奖记录 + * 获得用户的获奖记录 + */ @GET("AppUser/awards") Call getAwardRecords();