2021-04-30 17:49:25 +08:00

472 lines
18 KiB
Java

package com.yutou.bilibili.BiliBili;
import com.yutou.bilibili.BiliBili.Datas.BiliBiliUpData;
import com.yutou.bilibili.BiliBili.Datas.GiftData;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService;
import com.yutou.bilibili.BiliBili.Tools.SaveLive;
import com.yutou.bilibili.Tools.AppTools;
import com.yutou.bilibili.Tools.Log;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.Inflater;
public class LiveUtils {
private static String cookie = null;
public LiveUtils() {
}
public static String getLiveUrl(int roomId) {
JSONObject json = http_get("https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo?id=" + roomId + "&type=0");
if (json != null)
return "wss://" + json.getJSONObject("data").getJSONArray("host_list").getJSONObject(0).getString("host") + "/sub";
return null;
}
public static void printHex(byte[] bytes) {
String str = DatatypeConverter.printHexBinary(bytes);
for (int i = 0; i < str.length(); i = i + 4) {
if (i % 32 == 0 && i != 0) {
com.yutou.bilibili.Tools.Log.i("\n");
}
if (str.length() - i > 4) {
com.yutou.bilibili.Tools.Log.i(str.substring(i, i + 4));
} else {
com.yutou.bilibili.Tools.Log.i(str.substring(i));
}
}
}
public static byte[] dec(byte[] data) {
byte[] output = new byte[0];
Inflater decompresser = new Inflater();
decompresser.reset();
decompresser.setInput(data);
ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!decompresser.finished()) {
int i = decompresser.inflate(buf);
o.write(buf, 0, i);
}
output = o.toByteArray();
} catch (Exception e) {
// com.yutou.bilibili.Tools.Log.e(e);
try {
JSONObject json = JSONObject.parseObject(new String(data, StandardCharsets.UTF_8));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// outputStream.write(toLH(json.toJSONString().length() + 16));
//outputStream.write(new byte[]{0, 16, 0, 1, 0, 0, 0, 5, 0, 0, 0, 1});
outputStream.write(json.toJSONString().getBytes(StandardCharsets.UTF_8));
output = outputStream.toByteArray();
} catch (Exception e1) {
output = data;
}
} finally {
try {
o.close();
} catch (IOException e) {
com.yutou.bilibili.Tools.Log.e(e);
}
}
decompresser.end();
return output;
}
public static List<String> getMsgList(byte[] bytes, List<String> list, boolean isOne) {
int len = 16;
ByteBuffer datas = ByteBuffer.allocate(bytes.length - len);
byte[] heads = new byte[4];
//获取到头信息
System.arraycopy(bytes, 0, heads, 0, 4);
int size = bytesToInt2(heads, 0) - 16;
//datas=MainApp.dec(datas);
if (size == datas.array().length) {
System.arraycopy(bytes, len, datas.array(), 0, bytes.length - len);
list.add(new String(datas.array(), StandardCharsets.UTF_8));
} else {
try {
// com.yutou.bilibili.Tools.Log.i("datas size = " + size);
if (size > 1000000000) {
try {
JSONObject.parseObject(new String(bytes));
list.add(new String(bytes, StandardCharsets.UTF_8));
return list;
} catch (Exception e) {
com.yutou.bilibili.Tools.Log.e(e);
}
}
datas.clear();
datas = ByteBuffer.allocate(size);
System.arraycopy(bytes, len, datas.array(), 0, size);
list.add(new String(datas.array(), StandardCharsets.UTF_8));
byte[] tmps = new byte[bytes.length - size - 16];
int length = bytes.length - (size + len);
System.arraycopy(bytes, size + (len), tmps, 0, length);
getMsgList(tmps, list, false);
} catch (Exception e) {
list.add(new String(bytes, StandardCharsets.UTF_8));
}
}
return list;
}
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;
}
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 String getCookie() {
if (StringUtils.isEmpty(getFile("cookies.json"))) {
return "";
}
JSONObject json = JSONObject.parseObject(getFile("cookies.json"));
StringBuilder builder = new StringBuilder();
for (String s : json.keySet()) {
builder.append(s).append("=").append(json.getString(s)).append(";");
}
return builder.toString();
}
/* public static String createCookie(){
String bid="AUTO"+AppTools.randomString(16,new String[]{AppTools.numbers});
bid="AUTO6616152607312876";
return String.format("LIVE_BUVID=%s; _uuid=%sinfoc; buvid3=%sinfoc; sid=%s; fingerprint=%s; buvid_fp=%sinfoc; buvid_fp_plain=%sinfoc; PVID=%d;"
,bid
,UUID.randomUUID().toString()
,UUID.randomUUID().toString()
,"bm3byv4p"
,"074eae35a01a56c40558a54ab33179e5"
,UUID.randomUUID().toString()
,UUID.randomUUID().toString()
,AppTools.randomCommon(0,9,1)[0]);
}*/
private static long oldBiliBiliHttpTime = 0;
public synchronized static JSONObject http_get(String url) {
try {
Log.i("调用url = "+url);
HttpURLConnection connection = getBiliHttpGet(url, getCookie());
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = 0, size;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
String str = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
outputStream.close();
try {
JSONObject json = JSON.parseObject(str);
return json;
} catch (Exception e) {
JSONObject json = new JSONObject();
json.put("html", str);
return json;
} finally {
stream.close();
connection.disconnect();
}
} catch (IOException e) {
//com.yutou.bilibili.Tools.Log.e(e);
Log.e(e);
Log.i("412 in " + url);
}
return null;
}
public static JSONObject http_post(String url, String body) {
try {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
com.yutou.bilibili.Tools.Log.e(e);
}
oldBiliBiliHttpTime = System.currentTimeMillis();
}
HttpURLConnection connection = getBiliHttpPost(url, getCookie());
OutputStream connectionOutputStream = null;
if (!StringUtils.isEmpty(body)) {
connectionOutputStream = connection.getOutputStream();
connectionOutputStream.write(body.getBytes(StandardCharsets.UTF_8));
connectionOutputStream.flush();
}
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = 0, size;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
String str = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
outputStream.close();
try {
JSONObject json = JSON.parseObject(str);
json.put("cookie", connection.getHeaderField("Set-Cookie"));
return json;
} catch (Exception e) {
JSONObject json = new JSONObject();
json.put("html", str);
json.put("cookie", connection.getHeaderField("Set-Cookie"));
return json;
} finally {
stream.close();
if (connectionOutputStream != null)
connectionOutputStream.close();
connection.disconnect();
}
} catch (Exception e) {
com.yutou.bilibili.Tools.Log.e(e);
}
return new JSONObject();
}
public static HttpURLConnection getBiliHttpPost(String url, String cookie) throws Exception {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
com.yutou.bilibili.Tools.Log.e(e);
}
oldBiliBiliHttpTime = System.currentTimeMillis();
}
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
connection.setRequestProperty("Cache-Control", "max-age=0");
connection.setRequestProperty("Referer", "https://live.bilibili.com");
connection.setRequestProperty("Connection", "keep-alive");
connection.setRequestProperty("Upgrade-Insecure-Requests", "1");
connection.setRequestProperty("Cookie", cookie);
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36");
return connection;
}
public static HttpURLConnection getBiliHttpGet(String url, String cookie) throws IOException {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
com.yutou.bilibili.Tools.Log.e(e);
}
oldBiliBiliHttpTime = System.currentTimeMillis();
}
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
connection.setRequestProperty("Cache-Control", "max-age=0");
connection.setRequestProperty("Referer", "https://live.bilibili.com");
connection.setRequestProperty("Connection", "keep-alive");
connection.setRequestProperty("Upgrade-Insecure-Requests", "1");
connection.setRequestProperty("Cookie", cookie);
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36");
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
return connection;
}
public static String getFile(String filePath) {
File file = new File(filePath);
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String str = "", tmp;
while ((tmp = reader.readLine()) != null) {
str += tmp;
}
reader.close();
return str;
} catch (Exception e) {
}
return null;
}
public static JSONObject getUserLoginInfo() {
return LiveUtils.http_get("https://api.bilibili.com/x/web-interface/nav");
}
public static Live liveContains(BilibiliUpInfo data) {
for (Live live : Live.lives) {
if (live.getInfo().getRoomid().equals(data.getRoomid())) {
return live;
}
}
return null;
}
private static JSONObject getLiveInfo(int roomId) {
return http_get("https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=" + roomId);
}
public static String getLiveTitle(int roomId) {
JSONObject json = LiveInfoManager.getInstance().getInfo(roomId);
if (json != null) {
return json.getJSONObject("data").getJSONObject("room_info").getString("title");
}
return null;
}
public static boolean isLivePlayer(int roomId) {
JSONObject json = LiveInfoManager.getInstance().getInfo(roomId);
if (json == null) {
return false;
}
BilibiliUpInfo upData = new BilibiliUpInfo();
upData.setRoomid(roomId);
//Log.i("直播检测:" + roomId + " > " + (json.getJSONObject("data").getJSONObject("room_info").getInteger("live_status") == 1) + " 录播器:" + liveContains(upData));
return json.getJSONObject("data").getJSONObject("room_info").getInteger("live_status") == 1;
}
private static void checkLiveSave(int roomId) {
BilibiliUpInfo upData = new BilibiliUpInfo();
upData.setRoomid(roomId);
Live live = liveContains(upData);
if (live == null) {
live = new Live();
live.add(roomId, !StringUtils.isEmpty(AppTools.readFile(new File("cookies.json"))));
try {
live.start();
} catch (Exception e) {
com.yutou.bilibili.Tools.Log.e(e);
}
}
if (!SaveLive.getInstance().checkLive(roomId)) {
SaveLive.getInstance().addLive(roomId);
}
}
public static class LiveGiftConfig {
@Resource
IBiliBiliLiveService service;
private static LiveGiftConfig config;
public static List<GiftData> giftDataList = new ArrayList<>();
public static LiveGiftConfig getInstance() {
if (config == null) {
config = new LiveGiftConfig();
}
return config;
}
private LiveGiftConfig() {
init();
}
public void init() {
giftDataList = new ArrayList<>();
JSONObject json = http_get("https://api.live.bilibili.com/xlive/web-room/v1/giftPanel/giftConfig?platform=pc");
JSONArray list = json.getJSONObject("data").getJSONArray("list");
for (Object o : list) {
JSONObject item = (JSONObject) o;
GiftData data = new GiftData();
data.setPrice(item.getInteger("price"));
data.setName(item.getString("name"));
data.setId(item.getInteger("id"));
data.setRights(item.getString("rights"));
data.setIcon(item.getString("img_basic"));
data.setDesc(item.getString("desc"));
giftDataList.add(data);
}
}
}
public static class LiveInfoManager {
private static LiveInfoManager manager;
private Map<Integer, JSONObject> infoMap;
public static LiveInfoManager getInstance() {
if (manager == null) {
manager = new LiveInfoManager();
}
return manager;
}
private LiveInfoManager() {
infoMap = new HashMap<>();
}
public synchronized void check(List<BilibiliUpInfo> list) {
for (BilibiliUpInfo upInfo : list) {
JSONObject json = getLiveInfo(upInfo.getRoomid());
if (json != null) {
infoMap.put(upInfo.getRoomid(), json);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i("信息map数量:"+infoMap.size());
}
public synchronized void check(int roomId) {
JSONObject json = getLiveInfo(roomId);
if (json != null) {
Log.i("登记直播:"+roomId);
infoMap.put(roomId, json);
}else{
infoMap.remove(roomId);
}
}
public synchronized JSONObject getInfo(int roomId) {
if (!infoMap.containsKey(roomId)) {
//check(roomId);
return null;
}
return infoMap.get(roomId);
}
}
}