diff --git a/biliapi/pom.xml b/biliapi/pom.xml
index 6c77166..f2bc687 100644
--- a/biliapi/pom.xml
+++ b/biliapi/pom.xml
@@ -22,5 +22,11 @@
rxjava
3.1.8
+
+ com.aayushatharva.brotli4j
+ brotli4j
+ 1.16.0
+
+
\ No newline at end of file
diff --git a/biliapi/src/main/java/com/yutou/Main.java b/biliapi/src/main/java/com/yutou/Main.java
index 452021b..90107b7 100644
--- a/biliapi/src/main/java/com/yutou/Main.java
+++ b/biliapi/src/main/java/com/yutou/Main.java
@@ -5,6 +5,7 @@ import com.yutou.bili.api.LiveApi;
import com.yutou.bili.api.UserApi;
import com.yutou.bili.bean.live.LiveRoomConfig;
import com.yutou.bili.bean.live.LiveRoomPlayInfo;
+import com.yutou.bili.bean.live.SpiBean;
import com.yutou.bili.bean.login.LoginCookie;
import com.yutou.bili.bean.login.UserInfoBean;
import com.yutou.bili.enums.LiveProtocol;
@@ -17,35 +18,42 @@ import com.yutou.bili.databases.BiliBiliLoginDatabase;
import com.yutou.bili.net.BiliUserNetApiManager;
import com.yutou.bili.net.WebSocketManager;
import com.yutou.inter.IHttpApiCheckCallback;
-import com.yutou.okhttp.BaseBean;
-import com.yutou.okhttp.FileCallback;
import com.yutou.okhttp.HttpCallback;
import com.yutou.okhttp.HttpLoggingInterceptor;
+import com.yutou.utils.Log;
import jakarta.xml.bind.DatatypeConverter;
import okhttp3.Headers;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HttpLoggingInterceptor.setLog(false);
HttpLoggingInterceptor.setLog(true);
- getPlayUrl();
- //testSocket();
-
+ // getPlayUrl();
+ LiveRoomConfig config=new LiveRoomConfig();
+ LoginCookie cookie = BiliBiliLoginDatabase.getInstance().get();
+ config.setLogin(true);
+ config.setUid(cookie.getDedeUserID());
+ config.setRoomId(String.valueOf(855204));
+ config.setRoomId(String.valueOf(22642754));
+ config.setRoomId(String.valueOf(81004));
+ WebSocketManager.getInstance().addRoom(config);
}
- public static void testSocket() {
+ public static void testSocket(SpiBean spi) {
try {
JSONObject json = new JSONObject();
- json.put("roomid", "13246789");
+ // json.put("roomid", "32805602");
+ json.put("roomid", "855204");
json.put("protover", "3");
json.put("platform", "web");
json.put("type", 2);
+ json.put("buvid",spi.getB_3());
json.put("key", "aaaabbb");
+ Log.i(json);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// outputStream.write(toLH(json.toString().length() + 16));
outputStream.write(new byte[]{0, 0, 1, 68, 0, 16, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1});
@@ -76,7 +84,7 @@ public class Main {
.getApi(new IHttpApiCheckCallback() {
@Override
public void onSuccess(LiveApi api) {
- String roomId = "22689676";
+ String roomId = "32805602";
String mid = "68057278";
// roomId="42062";
diff --git a/biliapi/src/main/java/com/yutou/bili/api/LiveApi.java b/biliapi/src/main/java/com/yutou/bili/api/LiveApi.java
index 565d2b4..f39356b 100644
--- a/biliapi/src/main/java/com/yutou/bili/api/LiveApi.java
+++ b/biliapi/src/main/java/com/yutou/bili/api/LiveApi.java
@@ -5,10 +5,7 @@ import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.FileBody;
import com.yutou.okhttp.HttpBody;
import retrofit2.Call;
-import retrofit2.http.GET;
-import retrofit2.http.Query;
-import retrofit2.http.Streaming;
-import retrofit2.http.Url;
+import retrofit2.http.*;
/**
* 直播间相关API
diff --git a/biliapi/src/main/java/com/yutou/bili/api/UserApi.java b/biliapi/src/main/java/com/yutou/bili/api/UserApi.java
index 20440e4..6af1ba5 100644
--- a/biliapi/src/main/java/com/yutou/bili/api/UserApi.java
+++ b/biliapi/src/main/java/com/yutou/bili/api/UserApi.java
@@ -1,5 +1,6 @@
package com.yutou.bili.api;
+import com.yutou.bili.bean.live.SpiBean;
import com.yutou.bili.bean.login.UserInfoBean;
import com.yutou.okhttp.HttpBody;
import retrofit2.Call;
@@ -8,4 +9,8 @@ import retrofit2.http.GET;
public interface UserApi {
@GET("/x/web-interface/nav")
Call> getUserInfo();
+
+
+ @GET("/x/frontend/finger/spi")
+ Call> getFingerSpi();
}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/live/SpiBean.java b/biliapi/src/main/java/com/yutou/bili/bean/live/SpiBean.java
new file mode 100644
index 0000000..5daee56
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/live/SpiBean.java
@@ -0,0 +1,12 @@
+package com.yutou.bili.bean.live;
+
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SpiBean extends BaseBean {
+ private String b_3;
+ private String b_4;
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/WebSocketBody.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/WebSocketBody.java
new file mode 100644
index 0000000..2956644
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/WebSocketBody.java
@@ -0,0 +1,34 @@
+package com.yutou.bili.bean.websocket;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class WebSocketBody {
+ List bodyList;
+
+ public WebSocketBody(byte[] bytes) {
+ bodyList = new ArrayList<>();
+ addBody(bytes, 0);
+ }
+
+ private void addBody(byte[] bytes, int offset) {
+ if (offset >= bytes.length) {
+ return;
+ }
+ byte[] headerByte = new byte[16];
+ System.arraycopy(bytes, offset, headerByte, 0, headerByte.length);
+ WebSocketHeader header = new WebSocketHeader(headerByte);
+ byte[] data = new byte[header.getDataSize() - header.getHeaderSize()];
+ System.arraycopy(bytes, offset + header.getHeaderSize(), data, 0, data.length);
+ try {
+ bodyList.add(JSONObject.parseObject(new String(data)));
+ } catch (Exception e) {
+ System.out.println(header + "|" + new String(data));
+ }
+ addBody(bytes, offset + header.dataSize);
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/WebSocketHeader.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/WebSocketHeader.java
new file mode 100644
index 0000000..12bd2da
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/WebSocketHeader.java
@@ -0,0 +1,27 @@
+package com.yutou.bili.bean.websocket;
+
+import com.yutou.bili.utils.BytesUtils;
+import lombok.Data;
+
+@Data
+public class WebSocketHeader {
+ int dataSize;
+ int agree;
+ int headerSize;
+ int cmdData;
+
+ public WebSocketHeader(byte[] bytes) {
+ byte[] size = new byte[4];
+ byte[] header = new byte[4];
+ byte[] cmd = new byte[4];
+ byte[] agreement = new byte[4];
+ System.arraycopy(bytes, 0, size, 0, 4);
+ System.arraycopy(bytes, 8, cmd, 0, 4);
+ System.arraycopy(bytes, 6, agreement, 2, 2);
+ System.arraycopy(bytes, 4, header, 2, 2);
+ dataSize = BytesUtils.bytesToInt2(size, 0);
+ agree = BytesUtils.bytesToInt2(agreement, 0);
+ headerSize = BytesUtils.bytesToInt2(header, 0);
+ cmdData = BytesUtils.bytesToInt2(cmd, 0);
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSDanmuData.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSDanmuData.java
new file mode 100644
index 0000000..f418e0f
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSDanmuData.java
@@ -0,0 +1,50 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.yutou.utils.Log;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 弹幕信息
+ * 弹幕
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class WSDanmuData extends WSData {
+ private String dm_v2;
+ private int id;
+ private int model;// 1~3 滚动弹幕 4 底端弹幕 5 顶端弹幕 6 逆向弹幕 7 精准定位 8 高级弹幕
+ private int fontSize;
+ private String fontColor;
+ private long time;
+ private String uCode;
+ private String danmu;
+ private long uid;
+ private String uname;
+ private WSUserMedal medal;
+
+ public WSDanmuData(JSONObject json) {
+ super(json);
+ JSONArray infoData = json.getJSONArray("info");
+ setModel(infoData.getJSONArray(0).getInteger(1));
+ setFontSize(infoData.getJSONArray(0).getInteger(2));
+ setFontColor(Integer.toHexString(infoData.getJSONArray(0).getInteger(3)));
+ setTime(infoData.getJSONArray(0).getLong(4));
+ setUCode(infoData.getJSONArray(0).getString(7));
+ setDanmu(infoData.getString(1));
+ setUid(infoData.getJSONArray(2).getInteger(0));
+ setUname(infoData.getJSONArray(2).getString(1));
+ try {
+ medal = WSUserMedal.create(infoData.getJSONArray(3));
+ } catch (Exception e) {
+ Log.i("弹幕信息解析失败:" + json);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "弹幕 = " + "用户:" + getUname() + " 发送了: " + getDanmu() +" | json = "+jsonSrc;
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSData.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSData.java
new file mode 100644
index 0000000..e331efd
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSData.java
@@ -0,0 +1,42 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONObject;
+
+import java.io.Serializable;
+
+public class WSData implements Serializable {
+ public String cmd;
+ public String jsonSrc;
+ public long ws_timer;
+
+ @Deprecated
+ public WSData() {
+ throw new NullPointerException("需要传入json");
+ }
+
+ @Override
+ public String toString() {
+ return "WSData{" +
+ "cmd='" + cmd + '\'' +
+ ", jsonSrc='" + jsonSrc + '\'' +
+ '}';
+ }
+
+ public WSData(JSONObject json) {
+ this.cmd = json.getString("cmd");
+ ws_timer = System.currentTimeMillis();
+ this.jsonSrc = json.toString();
+ }
+
+ public static WSData parse(JSONObject json) {
+ String cmd = json.getString("cmd");
+ return switch (cmd) {
+ case "DANMU_MSG" -> new WSDanmuData(json);
+ case "DM_INTERACTION" -> new WSDmInteraction(json);
+ case "SEND_GIFT" -> new WSSendGift(json);
+ case "INTERACT_WORD" -> new WSInteractWord(json);
+ case "GUARD_BUY" -> new WSGuardBuy(json);
+ default -> new WSData(json);
+ };
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSDmInteraction.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSDmInteraction.java
new file mode 100644
index 0000000..d73e5c3
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSDmInteraction.java
@@ -0,0 +1,54 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 连续弹幕消息
+ * 连续弹幕消息
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class WSDmInteraction extends WSData{
+ public final static int TYPE_ZAN=106;//点赞
+ public final static int TYPE_SHARE=105;//分享
+ public final static int TYPE_DANMU=102;//弹幕
+ private ComboData combo;
+ private int type;
+
+ public static void main(String[] args) {
+ JSONObject json=JSONObject.parseObject("{\"cmd\":\"DM_INTERACTION\",\"data\":{\"data\":\"{\\\"fade_duration\\\":10000,\\\"cnt\\\":5,\\\"card_appear_interval\\\":0,\\\"suffix_text\\\":\\\"人正在点赞\\\",\\\"reset_cnt\\\":1,\\\"display_flag\\\":1}\",\"dmscore\":36,\"id\":53793047788032,\"status\":4,\"type\":106}}");
+ WSDmInteraction wsDmInteraction=new WSDmInteraction(json);
+ System.out.println(wsDmInteraction);
+ }
+ public WSDmInteraction(JSONObject json) {
+ super(json);
+ JSONObject data=json.getJSONObject("data");
+ JSONObject comboJson=JSONObject.parseObject(data.getString("data"));
+ combo=JSONObject.parseObject(data.getString("data"), ComboData.class);
+ type=data.getIntValue("type");
+ if(type==106){
+ combo.setContent(comboJson.getString("suffix_text"));
+ }
+ }
+
+ @Data
+ public static class ComboData implements Serializable {
+ String content;
+ String guide;
+ int cnt;
+ }
+
+ @Override
+ public String toString() {
+ return "WSDmInteraction{" +
+ "combo=" + combo +
+ ", cmd='" + cmd + '\'' +
+ ", jsonSrc='" + jsonSrc + '\'' +
+ ", ws_timer=" + ws_timer +
+ '}';
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSGuardBuy.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSGuardBuy.java
new file mode 100644
index 0000000..06b10fa
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSGuardBuy.java
@@ -0,0 +1,42 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 大航海购买
+ * 上舰通知
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class WSGuardBuy extends WSData{
+ private long uid;
+ private String username;
+ private long guardLevel;
+ private long num;
+ private long price;
+ private long giftID;
+ private String giftName;
+ private long startTime;
+ private long endTime;
+
+ public static void main(String[] args) {
+ JSONObject json=JSONObject.parseObject("{\"cmd\":\"GUARD_BUY\",\"data\":{\"uid\":5427372,\"username\":\"李湜渰\",\"guard_level\":3,\"num\":1,\"price\":198000,\"gift_id\":10003,\"gift_name\":\"舰长\",\"start_time\":1724985039,\"end_time\":1724985039}}");
+ WSGuardBuy wsguardBuy = new WSGuardBuy(json);
+ System.out.println(wsguardBuy);
+ }
+ public WSGuardBuy(JSONObject json) {
+ super(json);
+ JSONObject data = json.getJSONObject("data");
+ uid = data.getLong("uid");
+ username = data.getString("username");
+ guardLevel = data.getLong("guard_level");
+ num = data.getLong("num");
+ price = data.getLong("price");
+ giftID = data.getLong("gift_id");
+ giftName = data.getString("gift_name");
+ startTime = data.getLong("start_time");
+ endTime = data.getLong("end_time");
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSInteractWord.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSInteractWord.java
new file mode 100644
index 0000000..f9635cb
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSInteractWord.java
@@ -0,0 +1,70 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.util.StringUtils;
+
+/**
+ * 进场信息
+ * 进场
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class WSInteractWord extends WSData {
+ public final static int TYPE_ENTER = 1;
+ public final static int TYPE_FOLLOW = 2;
+ private int type; //1为进场,2为关注
+ private long roomId;
+ private long timer;
+ private WSUserMedal medal;
+ private long uid;
+ private String uname;
+ private String uname_color;
+ private String face;
+
+
+ public WSInteractWord(JSONObject json) {
+ super(json);
+ JSONObject data = json.getJSONObject("data");
+ JSONObject medalJson = data.containsKey("fans_medal") ? data.getJSONObject("fans_medal"):null;
+ type = data.getIntValue("msg_type");
+ roomId = data.getLong("roomid");
+ timer = data.getLong("score");
+ uid = data.getLong("uid");
+ uname = data.getString("uname");
+ uname_color = data.getString("uname_color");
+ face = data.getJSONObject("uinfo").getJSONObject("base").getString("face");
+ if (medalJson != null) {
+ medal = new WSUserMedal();
+ medal.setUid(medalJson.getLong("anchor_roomid"));
+ medal.setMedal_name(medalJson.getString("medal_name"));
+ medal.setMedal_color(Integer.toHexString(medalJson.getIntValue("medal_color")));
+ medal.setMedal_level(medalJson.getIntValue("medal_level"));
+ }
+ }
+
+ public String getUname_color() {
+ if (StringUtils.hasLength(uname_color)) {
+ uname_color = "FFFFFF";
+ }
+ return uname_color;
+ }
+
+ @Override
+ public String toString() {
+ return "WSInteractWord{" +
+ "type=" + type +
+ ", roomId=" + roomId +
+ ", timer=" + timer +
+ ", medal=" + medal +
+ ", uid=" + uid +
+ ", uname='" + uname + '\'' +
+ ", uname_color='" + uname_color + '\'' +
+ ", face='" + face + '\'' +
+ ", cmd='" + cmd + '\'' +
+ ", jsonSrc='" + jsonSrc + '\'' +
+ ", ws_timer=" + ws_timer +
+ '}';
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSMedalInfo.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSMedalInfo.java
new file mode 100644
index 0000000..d93cc5c
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSMedalInfo.java
@@ -0,0 +1,37 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.yutou.okhttp.BaseBean;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class WSMedalInfo extends BaseBean {
+ @JSONField(name = "anchor_roomid")
+ private long anchorRoomid;
+ @JSONField(name = "anchor_uname")
+ private String anchorUname;
+ @JSONField(name = "guard_level")
+ private long guardLevel;
+ @JSONField(name = "icon_id")
+ private long iconID;
+ @JSONField(name = "is_lighted")
+ private long isLighted;
+ @JSONField(name = "medal_color")
+ private long medalColor;
+ @JSONField(name = "medal_color_border")
+ private long medalColorBorder;
+ @JSONField(name = "medal_color_end")
+ private long medalColorEnd;
+ @JSONField(name = "medal_color_start")
+ private long medalColorStart;
+ @JSONField(name = "medal_level")
+ private long medalLevel;
+ @JSONField(name = "medal_name")
+ private String medalName;
+ @JSONField(name = "special")
+ private String special;
+ @JSONField(name = "target_id")
+ private long targetID;
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSSendGift.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSSendGift.java
new file mode 100644
index 0000000..13d2c44
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSSendGift.java
@@ -0,0 +1,246 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@lombok.Data
+public class WSSendGift extends WSData {
+ private Data data;
+
+ public WSSendGift(JSONObject json) {
+ super(json);
+ data = JSONObject.parseObject(json.getJSONObject("data").toString(), Data.class);
+ }
+
+ @Override
+ public String toString() {
+ return "WSSendGift{" +
+ "data=" + data +
+ ", cmd='" + cmd + '\'' +
+ ", jsonSrc='" + jsonSrc + '\'' +
+ ", ws_timer=" + ws_timer +
+ '}';
+ }
+
+ @lombok.Data
+ public static class Data implements Serializable {
+ @JSONField(name = "action")
+ private String action;
+ @JSONField(name = "batch_combo_id")
+ private String batchComboID;
+ @JSONField(name = "batch_combo_send")
+ private ComboSend batchComboSend;
+ @JSONField(name = "combo_send")
+ private ComboSend comboSend;
+ @JSONField(name = "beatId")
+ private String beatID;
+ @JSONField(name = "biz_source")
+ private String bizSource;
+ @JSONField(name = "broadcast_id")
+ private long broadcastID;
+ @JSONField(name = "coin_type")
+ private String coinType;
+ @JSONField(name = "combo_resources_id")
+ private long comboResourcesID;
+ @JSONField(name = "combo_stay_time")
+ private long comboStayTime;
+ @JSONField(name = "combo_total_coin")
+ private long comboTotalCoin;
+ @JSONField(name = "crit_prob")
+ private long critProb;
+ @JSONField(name = "demarcation")
+ private long demarcation;
+ @JSONField(name = "discount_price")
+ private long discountPrice;
+ @JSONField(name = "dmscore")
+ private long dmscore;
+ @JSONField(name = "draw")
+ private long draw;
+ @JSONField(name = "effect")
+ private long effect;
+ @JSONField(name = "effect_block")
+ private long effectBlock;
+ @JSONField(name = "face")
+ private String face;
+ @JSONField(name = "face_effect_id")
+ private long faceEffectID;
+ @JSONField(name = "face_effect_type")
+ private long faceEffectType;
+ @JSONField(name = "face_effect_v2")
+ private FaceEffectV2 faceEffectV2;
+ @JSONField(name = "float_sc_resource_id")
+ private long floatScResourceID;
+ @JSONField(name = "giftId")
+ private long giftID;
+ @JSONField(name = "giftName")
+ private String giftName;
+ @JSONField(name = "giftType")
+ private long giftType;
+ @JSONField(name = "gift_info")
+ private GiftInfo giftInfo;
+ @JSONField(name = "gift_tag")
+ private List giftTag;
+ @JSONField(name = "gold")
+ private long gold;
+ @JSONField(name = "guard_level")
+ private long guardLevel;
+ @JSONField(name = "is_first")
+ private boolean isFirst;
+ @JSONField(name = "is_join_receiver")
+ private boolean isJoinReceiver;
+ @JSONField(name = "is_naming")
+ private boolean isNaming;
+ @JSONField(name = "is_special_batch")
+ private long isSpecialBatch;
+ @JSONField(name = "magnification")
+ private long magnification;
+ @JSONField(name = "medal_info")
+ private WSMedalInfo medalInfo;
+ @JSONField(name = "name_color")
+ private String nameColor;
+ @JSONField(name = "num")
+ private long num;
+ @JSONField(name = "original_gift_name")
+ private String originalGiftName;
+ @JSONField(name = "price")
+ private long price;
+ @JSONField(name = "rcost")
+ private long rcost;
+ @JSONField(name = "receive_user_info")
+ private ReceiveUserInfo receiveUserInfo;
+ @JSONField(name = "receiver_uinfo")
+ private ErUinfo receiverUinfo;
+ @JSONField(name = "remain")
+ private long remain;
+ @JSONField(name = "rnd")
+ private String rnd;
+ @JSONField(name = "sender_uinfo")
+ private ErUinfo senderUinfo;
+ @JSONField(name = "silver")
+ private long silver;
+ @JSONField(name = "super")
+ private long dataSuper;
+ @JSONField(name = "super_batch_gift_num")
+ private long superBatchGiftNum;
+ @JSONField(name = "super_gift_num")
+ private long superGiftNum;
+ @JSONField(name = "svga_block")
+ private long svgaBlock;
+ @JSONField(name = "switch")
+ private boolean dataSwitch;
+ @JSONField(name = "tag_image")
+ private String tagImage;
+ @JSONField(name = "tid")
+ private String tid;
+ @JSONField(name = "timestamp")
+ private long timestamp;
+ @JSONField(name = "total_coin")
+ private long totalCoin;
+ @JSONField(name = "uid")
+ private long uid;
+ @JSONField(name = "uname")
+ private String uname;
+ @JSONField(name = "wealth_level")
+ private long wealthLevel;
+ }
+
+ @lombok.Data
+ public static class FaceEffectV2 implements Serializable{
+ @JSONField(name = "id")
+ private long id;
+ @JSONField(name = "type")
+ private long type;
+ }
+
+ @lombok.Data
+ public static class GiftInfo implements Serializable{
+ @JSONField(name = "effect_id")
+ private long effectID;
+ @JSONField(name = "has_imaged_gift")
+ private long hasImagedGift;
+ @JSONField(name = "img_basic")
+ private String imgBasic;
+ @JSONField(name = "webp")
+ private String webp;
+ }
+
+ @lombok.Data
+ public static class ReceiveUserInfo implements Serializable {
+ @JSONField(name = "uid")
+ private long uid;
+ @JSONField(name = "uname")
+ private String uname;
+ }
+
+ @lombok.Data
+ public static class ErUinfo implements Serializable {
+ @JSONField(name = "base")
+ private Base base;
+ @JSONField(name = "uid")
+ private long uid;
+ }
+
+ @lombok.Data
+ public static class Base implements Serializable {
+ @JSONField(name = "face")
+ private String face;
+ @JSONField(name = "is_mystery")
+ private boolean isMystery;
+ @JSONField(name = "name")
+ private String name;
+ @JSONField(name = "name_color")
+ private long nameColor;
+ @JSONField(name = "name_color_str")
+ private String nameColorStr;
+ @JSONField(name = "official_info")
+ private OfficialInfo officialInfo;
+ @JSONField(name = "origin_info")
+ private Info originInfo;
+ @JSONField(name = "risk_ctrl_info")
+ private Info riskCtrlInfo;
+ }
+
+ @lombok.Data
+ public static class OfficialInfo implements Serializable {
+ @JSONField(name = "desc")
+ private String desc;
+ @JSONField(name = "role")
+ private long role;
+ @JSONField(name = "title")
+ private String title;
+ @JSONField(name = "type")
+ private long type;
+ }
+
+ @lombok.Data
+ public static class Info implements Serializable {
+ @JSONField(name = "face")
+ private String face;
+ @JSONField(name = "name")
+ private String name;
+ }
+ @lombok.Data
+ public static class ComboSend implements Serializable {
+ @JSONField(name = "action")
+ private String action;
+ @JSONField(name = "combo_id")
+ private String comboID;
+ @JSONField(name = "combo_num")
+ private long comboNum;
+ @JSONField(name = "gift_id")
+ private long giftID;
+ @JSONField(name = "gift_name")
+ private String giftName;
+ @JSONField(name = "gift_num")
+ private long giftNum;
+ @JSONField(name = "uid")
+ private long uid;
+ @JSONField(name = "uname")
+ private String uname;
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSSuperChatMessage.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSSuperChatMessage.java
new file mode 100644
index 0000000..9344686
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSSuperChatMessage.java
@@ -0,0 +1,33 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 超级留言
+ * 醒目留言
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class WSSuperChatMessage extends WSData{
+ private long price;
+ private long rate;
+ private long uid;
+ private long start_time;
+ private long end_time;
+ private String message;
+ private String message_trans;
+ private String message_font_color;
+ private WSMedalInfo medal_info;
+
+
+ public static void main(String[] args) {
+ JSONObject json=JSONObject.parseObject("{\"cmd\":\"SUPER_CHAT_MESSAGE\",\"data\":{\"background_bottom_color\":\"#2A60B2\",\"background_color\":\"#EDF5FF\",\"background_color_end\":\"#405D85\",\"background_color_start\":\"#3171D2\",\"background_icon\":\"\",\"background_image\":\"\",\"background_price_color\":\"#7497CD\",\"color_point\":0.7,\"dmscore\":616,\"end_time\":1724997230,\"gift\":{\"gift_id\":12000,\"gift_name\":\"醒目留言\",\"num\":1},\"group_medal\":{\"is_lighted\":0,\"medal_id\":0,\"name\":\"\"},\"id\":10427329,\"is_mystery\":false,\"is_ranked\":0,\"is_send_audit\":1,\"medal_info\":{\"anchor_roomid\":81004,\"anchor_uname\":\"艾尔莎_Channel\",\"guard_level\":0,\"icon_id\":0,\"is_lighted\":1,\"medal_color\":\"#1a544b\",\"medal_color_border\":1725515,\"medal_color_end\":5414290,\"medal_color_start\":1725515,\"medal_level\":21,\"medal_name\":\"艾薯条\",\"special\":\"\",\"target_id\":1521415},\"message\":\"莎莎,想安利你个植物大战僵尸的改版叫植物大战僵尸:肉鸽,具体情况私信你了,辛苦了\",\"message_font_color\":\"#A3F6FF\",\"message_trans\":\"サーシャ、あなたのPlantsvs.Zombiesの改版をPlantsvs.Zombiesと言いたい:肉鳩、具体的な状況は私的にあなたを信じて、お疲れ様でした\",\"price\":30,\"rate\":1000,\"start_time\":1724997170,\"time\":60,\"token\":\"9925C118\",\"trans_mark\":0,\"ts\":1724997170,\"uid\":100002175,\"uinfo\":{\"base\":{\"face\":\"https://i1.hdslb.com/bfs/face/b5ec3b1f7025b5546225ae0f36941d55ddef405b.jpg\",\"is_mystery\":false,\"name\":\"中吴同学\",\"name_color\":0,\"name_color_str\":\"#666666\",\"official_info\":{\"desc\":\"\",\"role\":0,\"title\":\"\",\"type\":-1},\"origin_info\":{\"face\":\"https://i1.hdslb.com/bfs/face/b5ec3b1f7025b5546225ae0f36941d55ddef405b.jpg\",\"name\":\"中吴同学\"}},\"guard\":{\"expired_str\":\"\",\"level\":0},\"medal\":{\"color\":1725515,\"color_border\":1725515,\"color_end\":5414290,\"color_start\":1725515,\"guard_icon\":\"\",\"guard_level\":0,\"honor_icon\":\"\",\"id\":0,\"is_light\":1,\"level\":21,\"name\":\"艾薯条\",\"ruid\":1521415,\"score\":50001980,\"typ\":0,\"user_receive_count\":0,\"v2_medal_color_border\":\"#5FC7F4FF\",\"v2_medal_color_end\":\"#43B3E3CC\",\"v2_medal_color_level\":\"#00308C99\",\"v2_medal_color_start\":\"#43B3E3CC\",\"v2_medal_color_text\":\"#FFFFFFFF\"},\"title\":{\"old_title_css_id\":\"\",\"title_css_id\":\"\"},\"uid\":100002175},\"user_info\":{\"face\":\"https://i1.hdslb.com/bfs/face/b5ec3b1f7025b5546225ae0f36941d55ddef405b.jpg\",\"face_frame\":\"\",\"guard_level\":0,\"is_main_vip\":1,\"is_svip\":0,\"is_vip\":0,\"level_color\":\"#5896de\",\"manager\":0,\"name_color\":\"#666666\",\"title\":\"\",\"uname\":\"中吴同学\",\"user_level\":25}},\"is_report\":true,\"msg_id\":\"19106780029655552:1000:1000\",\"p_is_ack\":true,\"p_msg_type\":1,\"send_time\":1724997170767}");
+ WSSuperChatMessage message=new WSSuperChatMessage(json);
+ System.out.println(message);
+ }
+ public WSSuperChatMessage(JSONObject json) {
+ super(json);
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSUserMedal.java b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSUserMedal.java
new file mode 100644
index 0000000..3114046
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/bean/websocket/live/WSUserMedal.java
@@ -0,0 +1,25 @@
+package com.yutou.bili.bean.websocket.live;
+
+import com.alibaba.fastjson2.JSONArray;
+import lombok.Data;
+
+@Data
+public class WSUserMedal {
+ private long uid;
+ private String medal_name;
+ private String medal_color = "FFFFFF";
+ private String medal_anchor;
+ private int medal_level;
+
+ public static WSUserMedal create(JSONArray array) {
+ if (array.isEmpty()) {
+ return null;
+ }
+ WSUserMedal medal = new WSUserMedal();
+ medal.setUid(array.getIntValue(3));
+ medal.setMedal_name(array.getString(1));
+ medal.setMedal_anchor(array.getString(2));
+ medal.setMedal_level(array.getIntValue(0));
+ return medal;
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/net/BiliLiveNetApiManager.java b/biliapi/src/main/java/com/yutou/bili/net/BiliLiveNetApiManager.java
index 851c275..3a7707d 100644
--- a/biliapi/src/main/java/com/yutou/bili/net/BiliLiveNetApiManager.java
+++ b/biliapi/src/main/java/com/yutou/bili/net/BiliLiveNetApiManager.java
@@ -33,7 +33,7 @@ public class BiliLiveNetApiManager extends BaseApi {
header.put("Referer", "https://live.bilibili.com");
header.put("Connection", "keep-alive");
header.put("Upgrade-Insecure-Requests", "1");
- setHeaders(header);
+ addHeader(header);
callback.onSuccess(createApi(LiveApi.class));
}
}
diff --git a/biliapi/src/main/java/com/yutou/bili/net/WebSocketManager.java b/biliapi/src/main/java/com/yutou/bili/net/WebSocketManager.java
index 5073c15..203ca57 100644
--- a/biliapi/src/main/java/com/yutou/bili/net/WebSocketManager.java
+++ b/biliapi/src/main/java/com/yutou/bili/net/WebSocketManager.java
@@ -1,18 +1,27 @@
package com.yutou.bili.net;
+import com.aayushatharva.brotli4j.Brotli4jLoader;
+import com.aayushatharva.brotli4j.decoder.Decoder;
+import com.aayushatharva.brotli4j.decoder.DecoderJNI;
+import com.aayushatharva.brotli4j.decoder.DirectDecompress;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bili.api.LiveApi;
import com.yutou.bili.bean.live.LiveDanmuInfo;
import com.yutou.bili.bean.live.LiveRoomConfig;
+import com.yutou.bili.bean.websocket.WebSocketBody;
+import com.yutou.bili.bean.websocket.WebSocketHeader;
+import com.yutou.bili.bean.websocket.live.WSData;
+import com.yutou.bili.databases.BiliBiliLoginDatabase;
+import com.yutou.bili.utils.BiliUserUtils;
+import com.yutou.bili.utils.BytesUtils;
import com.yutou.inter.IHttpApiCheckCallback;
import com.yutou.okhttp.HttpCallback;
-import jakarta.xml.bind.DatatypeConverter;
+import com.yutou.utils.Log;
import okhttp3.Headers;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import java.io.ByteArrayOutputStream;
-import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
@@ -21,7 +30,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
-import java.util.zip.Inflater;
public class WebSocketManager {
private static WebSocketManager instance;
@@ -81,25 +89,6 @@ public class WebSocketManager {
super(serverUri);
this.roomConfig = roomId;
heartbeatTask = new HeartbeatTask();
- HashMap header = new HashMap<>();
- header.put("Sec-WebSocket-Extensions", "permessage-deflate; client_max_window_bits");
- header.put("Sec-WebSocket-Key", "f1kFoce72Pn+wbjdPyONLw==");
- // header.put("Sec-WebSocket-Key", roomId.getLiveInfo().getToken());
- header.put("Sec-WebSocket-Version", "13");
- header.put("Cache-Control", "no-cache");
- header.put("Connection", "Upgrade");
- header.put("Accept-Encoding:", "gzip, deflate, br, zstd");
- header.put("Host", roomId.getLiveInfo().getHostList().get(0).getHost() + ":" + roomId.getLiveInfo().getHostList().get(0).getWssPort());
- header.put("Origin", "https://live.bilibili.com");
- header.put("Pragma", "no-cache");
- header.put("Upgrade", "websocket");
- header.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36");
- for (String key : header.keySet()) {
- addHeader(key, header.get(key));
- }
- System.out.println();
- System.out.println();
- System.out.println("header = " + header);
connect();
}
@@ -108,7 +97,7 @@ public class WebSocketManager {
WebSocketManager.getInstance().roomMap.put(roomConfig, this);
heartbeatTask.setSocket(this);
heartbeatTask.sendInitAuthData();
- new Timer().schedule(heartbeatTask, 0, 30000);
+ new Timer().schedule(heartbeatTask, 1000, 30000);
System.out.println("WebSocketClientTh.onOpen");
}
@@ -146,17 +135,40 @@ public class WebSocketManager {
* @param data 待压缩的数据
*/
public void decompress(byte[] data) {
+ byte[] bytes = new byte[data.length - 16];
+ WebSocketHeader header = new WebSocketHeader(data);
+ System.arraycopy(data, header.getHeaderSize(), bytes, 0, data.length - header.getHeaderSize());
+ System.out.println("数据大小:" + header.getDataSize() + " 协议:" + header.getAgree() + " 头部大小:" + header.getHeaderSize() + " 命令:" + header.getCmdData());
+ switch (header.getAgree()) {
+ case 0:
+ case 1:
+ danmu(bytes);
+ break;
+ default:
+ unzipDanmu(bytes, header.getAgree() == 3);
+ }
+
+ }
+
+ private void danmu(byte[] bytes) {
+ Log.i("未压缩:" + new String(bytes));
+ }
+
+ private void unzipDanmu(byte[] bytes, boolean useHeader) {
try {
- Inflater inflater = new Inflater();
- inflater.reset();
- inflater.setInput(data);
- ByteArrayOutputStream out = new ByteArrayOutputStream(data.length);
- byte[] buf = new byte[8192];
- while (!inflater.finished()) {
- int i = inflater.inflate(buf);
- out.write(buf, 0, i);
+ Brotli4jLoader.ensureAvailability();
+ DirectDecompress directDecompress = Decoder.decompress(bytes);
+ if (directDecompress.getResultStatus() == DecoderJNI.Status.DONE) {
+ WebSocketBody body = new WebSocketBody(directDecompress.getDecompressedData());
+ Log.i("3协议:" + useHeader + " 命令数:" + body.getBodyList().size());
+ for (JSONObject json : body.getBodyList()) {
+ Log.i("解压:" + WSData.parse(json));
+ }
+ System.out.println();
+ System.out.println();
+ } else {
+ Log.e(new RuntimeException("解压失败"));
}
- System.out.println("接收值:" + new String(out.toByteArray()));
} catch (Exception e) {
e.printStackTrace();
}
@@ -171,60 +183,66 @@ public class WebSocketManager {
@Override
public void run() {
-
+ try {
+ // com.yutou.bilibili.Tools.Log.i("-------发送心跳--------");
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ outputStream.write(BytesUtils.toLH("[object Object]".length() + 16));
+ outputStream.write(new byte[]{0, 16, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1});
+ outputStream.write("[object Object]".getBytes(StandardCharsets.UTF_8));
+ outputStream.flush();
+ socket.send(outputStream.toByteArray());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
public void sendInitAuthData() {
JSONObject json = new JSONObject();
if (roomConfig.isLogin()) {
- json.put("uid", roomConfig.getUid());
+ json.put("uid", Long.parseLong(roomConfig.getUid()));
+
} else {
- json.put("uid", "0");
+ json.put("uid", 0);
}
- try {
- json.put("roomid", roomConfig.getRoomId());
- json.put("protover", "3");
- json.put("platform", "web");
- json.put("buvid", "F56FA00C-B043-DDB7-B7D2-D1A2AEC3034E24804infoc");
- json.put("type", 2);
- json.put("key", roomConfig.getLiveInfo().getToken());
- byte[] bytes = {0, 16, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1};
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- outputStream.write(toLH(json.toString().length() + bytes.length));
- outputStream.write(bytes);
- outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
- outputStream.flush();
- System.out.println("\n\n\n");
- String str = DatatypeConverter.printHexBinary(outputStream.toByteArray());
- for (int i = 0; i < str.length(); i = i + 4) {
- if (i % 32 == 0 && i != 0) {
- System.out.println();
- }
- if (str.length() - i > 4) {
- System.out.print(str.substring(i, i + 4) + " ");
- } else {
- System.out.println(str.substring(i));
+ BiliUserUtils.getBuvid(new IHttpApiCheckCallback() {
+ @Override
+ public void onSuccess(String api) {
+ try {
+ json.put("roomid", Long.parseLong(roomConfig.getRoomId()));
+ json.put("protover", 3);
+ json.put("buvid", api);
+ json.put("platform", "web");
+ json.put("type", 2);
+ json.put("key", roomConfig.getLiveInfo().getToken());
+ byte[] bytes = {0, 16, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1};
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ System.out.println("bytes.length = " + bytes.length);
+ Log.i(json);
+ outputStream.write(BytesUtils.toLH(json.toString().length() + 16));
+ outputStream.write(bytes);
+ outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
+ outputStream.flush();
+ BytesUtils.printHex(outputStream.toByteArray());
+ System.out.println(socket.isOpen());
+ socket.send(outputStream.toByteArray());
+
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
- System.out.println("\n\n\n");
- System.out.println(socket.isOpen());
- socket.send(outputStream.toByteArray());
- } catch (Exception e) {
- e.printStackTrace();
- }
+ @Override
+ public void onError(int code, String error) {
+
+ }
+ });
+
}
- public byte[] toLH(int n) {
- byte[] b = new byte[4];
- b[3] = (byte) (n & 0xff);
- b[2] = (byte) (n >> 8 & 0xff);
- b[1] = (byte) (n >> 16 & 0xff);
- b[0] = (byte) (n >> 24 & 0xff);
- return b;
- }
}
+
}
+
}
diff --git a/biliapi/src/main/java/com/yutou/bili/utils/BiliUserUtils.java b/biliapi/src/main/java/com/yutou/bili/utils/BiliUserUtils.java
new file mode 100644
index 0000000..4e63b2c
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/utils/BiliUserUtils.java
@@ -0,0 +1,41 @@
+package com.yutou.bili.utils;
+
+import com.yutou.bili.api.UserApi;
+import com.yutou.bili.bean.live.SpiBean;
+import com.yutou.bili.net.BiliUserNetApiManager;
+import com.yutou.inter.IHttpApiCheckCallback;
+import com.yutou.okhttp.HttpCallback;
+import com.yutou.utils.RedisTools;
+import okhttp3.Headers;
+
+public class BiliUserUtils {
+ public static void getBuvid(IHttpApiCheckCallback callback) {
+ String buvid= RedisTools.get(RedisTools.BILI_USER_BUVID);
+ if(buvid!=null){
+ callback.onSuccess(buvid);
+ return;
+ }
+ BiliUserNetApiManager.getInstance().getUserApi(new IHttpApiCheckCallback() {
+ @Override
+ public void onSuccess(UserApi api) {
+ api.getFingerSpi().enqueue(new HttpCallback() {
+ @Override
+ public void onResponse(Headers headers, int code, String status, SpiBean response, String rawResponse) {
+ RedisTools.set(RedisTools.BILI_USER_BUVID,response.getB_3());
+ callback.onSuccess(response.getB_3());
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+
+ }
+ });
+ }
+
+ @Override
+ public void onError(int code, String error) {
+
+ }
+ });
+ }
+}
diff --git a/biliapi/src/main/java/com/yutou/bili/utils/BytesUtils.java b/biliapi/src/main/java/com/yutou/bili/utils/BytesUtils.java
new file mode 100644
index 0000000..6b27cd2
--- /dev/null
+++ b/biliapi/src/main/java/com/yutou/bili/utils/BytesUtils.java
@@ -0,0 +1,41 @@
+package com.yutou.bili.utils;
+
+import com.yutou.utils.Log;
+import jakarta.xml.bind.DatatypeConverter;
+
+public class BytesUtils {
+
+ public static int bytesToInt2(byte[] src, int offset) {
+ int value;
+ value = (int) (((src[offset] & 0xFF) << 24)
+ | ((src[offset + 1] & 0xFF) << 16)
+ | ((src[offset + 2] & 0xFF) << 8)
+ | (src[offset + 3] & 0xFF));
+ return value;
+ }
+
+ public static void printHex(byte[] byteArray) {
+ System.out.println("\n\n\n");
+ String str = DatatypeConverter.printHexBinary(byteArray);
+ Log.i(str);
+ for (int i = 0; i < str.length(); i = i + 4) {
+ if (i % 32 == 0 && i != 0) {
+ System.out.println();
+ }
+ if (str.length() - i > 4) {
+ System.out.print(str.substring(i, i + 4) + " ");
+ } else {
+ System.out.println(str.substring(i));
+ }
+ }
+ System.out.println("\n\n\n");
+ }
+ public static byte[] toLH(int n) {
+ byte[] b = new byte[4];
+ b[3] = (byte) (n & 0xff);
+ b[2] = (byte) (n >> 8 & 0xff);
+ b[1] = (byte) (n >> 16 & 0xff);
+ b[0] = (byte) (n >> 24 & 0xff);
+ return b;
+ }
+}
diff --git a/common/src/main/java/com/yutou/okhttp/api/BaseApi.java b/common/src/main/java/com/yutou/okhttp/api/BaseApi.java
index f606f8c..a52f0ba 100644
--- a/common/src/main/java/com/yutou/okhttp/api/BaseApi.java
+++ b/common/src/main/java/com/yutou/okhttp/api/BaseApi.java
@@ -35,6 +35,10 @@ public class BaseApi {
this.headers = headers;
return this;
}
+ public void addHeader(HashMap headers){
+ this.headers.putAll(headers);
+ }
+
public BaseApi setParams(HashMap params) {
this.params = params;
diff --git a/common/src/main/java/com/yutou/utils/Log.java b/common/src/main/java/com/yutou/utils/Log.java
index 6fe4ce1..f0becbf 100644
--- a/common/src/main/java/com/yutou/utils/Log.java
+++ b/common/src/main/java/com/yutou/utils/Log.java
@@ -8,7 +8,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
public class Log {
- private static Logger logger;
+ private static Logger logger=Logger.getLogger("Biliob");
public static void i(String tag, Object log) {
i('[' + tag + ']' + log);
@@ -18,6 +18,7 @@ public class Log {
if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "logcat"))) {
return;
}
+ // logger.log(Level.INFO, log.toString());
System.out.printf("[%s]%s%n",
AppTools.getToDayNowTimeToString(),
log
diff --git a/common/src/main/java/com/yutou/utils/RedisTools.java b/common/src/main/java/com/yutou/utils/RedisTools.java
index 1ff6853..16eeb9f 100644
--- a/common/src/main/java/com/yutou/utils/RedisTools.java
+++ b/common/src/main/java/com/yutou/utils/RedisTools.java
@@ -14,6 +14,7 @@ import java.util.Set;
public class RedisTools {
public static final int QQBOT_USER = 3;
+ public static final String BILI_USER_BUVID = "bili_user_buvid";
private static boolean isNotInstallRedis = false;
private static String host;
private static int port;
@@ -28,7 +29,7 @@ public class RedisTools {
//Properties properties = PropertyUtil.loadProperties("jedis.properties");
//host = properties.getProperty("redis.host");
//port = Integer.valueOf(properties.getProperty("redis.port"));
- host = "127.0.0.1";
+ host = "172.22.81.254";
port = 6379;
}
@@ -74,7 +75,7 @@ public class RedisTools {
}
public static String get(String key, int dbIndex) {
- String value = "-999";
+ String value = null;
if (isNotInstallRedis) {
return value;
}