新增机器人指令控制

This commit is contained in:
yutou 2021-04-08 18:33:34 +08:00
parent ef0d7e5850
commit ab6bfbfd42
11 changed files with 746 additions and 49 deletions

33
pom.xml
View File

@ -15,6 +15,7 @@
<description>Demo project for Spring Boot</description> <description>Demo project for Spring Boot</description>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<kotlin.version>1.4.10</kotlin.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
@ -102,10 +103,42 @@
<artifactId>poi-ooxml-schemas</artifactId> <artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version> <version>3.17</version>
</dependency> </dependency>
<dependency>
<groupId>net.mamoe</groupId>
<artifactId>mirai-core-jvm</artifactId>
<version>2.5.0</version> <!-- 替换版本为你需要的版本 -->
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>

View File

@ -30,7 +30,8 @@ public class RealTimeDataController {
@RequestMapping("get/query.do") @RequestMapping("get/query.do")
public JSONObject queryToDayLiveData(int roomid,Date startTime,Date endTime) throws ParseException { public JSONObject queryToDayLiveData(int roomid,Date startTime,Date endTime) throws ParseException {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
BilibiliUpInfo info = service.queryUpToRoomId(roomid); BilibiliUpInfo info = new BilibiliUpInfo();
info.setRoomid(roomid);
Live live = LiveUtils.liveContains(info); Live live = LiveUtils.liveContains(info);
if(startTime==null){ if(startTime==null){
startTime=AppTools.getToDayStartTime(); startTime=AppTools.getToDayStartTime();

View File

@ -10,7 +10,6 @@ import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService;
import com.yutou.bilibili.BiliBili.Tools.BiliTools; import com.yutou.bilibili.BiliBili.Tools.BiliTools;
import com.yutou.bilibili.Services.IUserService; import com.yutou.bilibili.Services.IUserService;
import com.yutou.bilibili.Tools.AppTools; import com.yutou.bilibili.Tools.AppTools;
import com.yutou.bilibili.Tools.Log;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo; import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
import com.yutou.bilibili.mybatis.model.UUser; import com.yutou.bilibili.mybatis.model.UUser;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -19,7 +18,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
@Controller @Controller

View File

@ -7,8 +7,11 @@ import com.yutou.bilibili.BiliBili.Datas.LiveData;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService; import com.yutou.bilibili.BiliBili.Services.IBiliBiliLiveService;
import com.yutou.bilibili.BiliBili.Tools.SaveLive; import com.yutou.bilibili.BiliBili.Tools.SaveLive;
import com.yutou.bilibili.QQBot.QQBotManager;
import com.yutou.bilibili.Tools.AppTools; import com.yutou.bilibili.Tools.AppTools;
import com.yutou.bilibili.Tools.Log; import com.yutou.bilibili.Tools.Log;
import com.yutou.bilibili.Tools.Tools;
import com.yutou.bilibili.interfaces.DownloadInterface;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveData; import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveData;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveInfo; import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliLiveInfo;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo; import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
@ -104,7 +107,7 @@ public class Live implements ApplicationContextAware {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
} }
} }
@ -147,7 +150,7 @@ public class Live implements ApplicationContextAware {
try { try {
likeLive(); likeLive();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
} }
} }
@ -179,7 +182,7 @@ public class Live implements ApplicationContextAware {
client.close(); client.close();
start(); start();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
} }
return; return;
} }
@ -197,7 +200,7 @@ public class Live implements ApplicationContextAware {
@Override @Override
public void onError(Exception e) { public void onError(Exception e) {
e.printStackTrace(); Log.e(e);
run = false; run = false;
client.close(); client.close();
} }
@ -281,13 +284,13 @@ public class Live implements ApplicationContextAware {
JSONObject json = JSONObject.parseObject(new String(bytes, StandardCharsets.UTF_8)); JSONObject json = JSONObject.parseObject(new String(bytes, StandardCharsets.UTF_8));
com.yutou.bilibili.Tools.Log.i(json.toJSONString()); com.yutou.bilibili.Tools.Log.i(json.toJSONString());
} catch (Exception e) { } catch (Exception e) {
checkLive();
int popular = LiveUtils.bytesToInt2(bytes, 0); int popular = LiveUtils.bytesToInt2(bytes, 0);
info.setPopular(popular); info.setPopular(popular);
checkLive();
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
com.yutou.bilibili.Tools.Log.i("----------ERROR----------"); com.yutou.bilibili.Tools.Log.i("----------ERROR----------");
com.yutou.bilibili.Tools.Log.i(new String(data, StandardCharsets.UTF_8)); com.yutou.bilibili.Tools.Log.i(new String(data, StandardCharsets.UTF_8));
LiveUtils.printHex(LiveUtils.dec(data)); LiveUtils.printHex(LiveUtils.dec(data));
@ -467,6 +470,18 @@ public class Live implements ApplicationContextAware {
case "WIDGET_BANNER"://鬼知道是啥 case "WIDGET_BANNER"://鬼知道是啥
case "HOT_RANK_SETTLEMENT": case "HOT_RANK_SETTLEMENT":
case "LIVE"://开始直播,不过有在心跳包上做检测了所以也无所谓 case "LIVE"://开始直播,不过有在心跳包上做检测了所以也无所谓
JSONObject liveInfo = LiveUtils.getLiveInfo(roomId);
StringBuilder builder = new StringBuilder();
builder.append(upData.getName()).append("开播了!").append("\n");
builder.append(liveInfo.getJSONObject("data").getJSONObject("room_info").getString("title"));
Tools.download(liveInfo.getJSONObject("data").getJSONObject("room_info").getString("keyframe"), new DownloadInterface() {
@Override
public void onDownload(File file) {
super.onDownload(file);
QQBotManager.getInstance().sendMessage(file, builder.toString());
}
});
break;
case "PK_BATTLE_SETTLE_V2": case "PK_BATTLE_SETTLE_V2":
case "PK_BATTLE_END": case "PK_BATTLE_END":
case "PK_BATTLE_SETTLE": case "PK_BATTLE_SETTLE":
@ -487,12 +502,12 @@ public class Live implements ApplicationContextAware {
service.addLiveData(liveData); service.addLiveData(liveData);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
try { try {
JSONObject.parseObject(new String(bytes, StandardCharsets.UTF_8)); JSONObject.parseObject(new String(bytes, StandardCharsets.UTF_8));
processData(new String(bytes, StandardCharsets.UTF_8), null); processData(new String(bytes, StandardCharsets.UTF_8), null);
} catch (Exception e2) { } catch (Exception e2) {
e2.printStackTrace(); Log.e(e2);
com.yutou.bilibili.Tools.Log.i(msg); com.yutou.bilibili.Tools.Log.i(msg);
com.yutou.bilibili.Tools.Log.i("---------ERROR -----"); com.yutou.bilibili.Tools.Log.i("---------ERROR -----");
LiveUtils.printHex(bytes); LiveUtils.printHex(bytes);
@ -558,7 +573,7 @@ public class Live implements ApplicationContextAware {
outputStream.flush(); outputStream.flush();
client.send(outputStream.toByteArray()); client.send(outputStream.toByteArray());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Log.e(e);
com.yutou.bilibili.Tools.Log.i(client.isClosed()); com.yutou.bilibili.Tools.Log.i(client.isClosed());
com.yutou.bilibili.Tools.Log.i(client.isOpen()); com.yutou.bilibili.Tools.Log.i(client.isOpen());

View File

@ -43,11 +43,10 @@ public class LiveUtils {
com.yutou.bilibili.Tools.Log.i("\n"); com.yutou.bilibili.Tools.Log.i("\n");
} }
if (str.length() - i > 4) { if (str.length() - i > 4) {
System.out.print(str.substring(i, i + 4)); com.yutou.bilibili.Tools.Log.i(str.substring(i, i + 4));
} else { } else {
com.yutou.bilibili.Tools.Log.i(str.substring(i)); com.yutou.bilibili.Tools.Log.i(str.substring(i));
} }
System.out.print(" ");
} }
} }
@ -211,7 +210,8 @@ public class LiveUtils {
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); //e.printStackTrace();
Log.i("412 in "+url);
} }
return null; return null;
} }
@ -340,9 +340,19 @@ public class LiveUtils {
} }
return null; return null;
} }
public 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=getLiveInfo(roomId);
if(json!=null){
return json.getJSONObject("data").getJSONObject("room_info").getString("title");
}
return null;
}
public static boolean isLivePlayer(int roomId) { public static boolean isLivePlayer(int roomId) {
JSONObject json = http_get("https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=" + roomId); JSONObject json =getLiveInfo(roomId);
if (json == null) if (json == null)
return false; return false;
BilibiliUpInfo upData = new BilibiliUpInfo(); BilibiliUpInfo upData = new BilibiliUpInfo();

View File

@ -3,6 +3,7 @@ package com.yutou.bilibili.BiliBili.Tools;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.yutou.bilibili.BiliBili.Live; import com.yutou.bilibili.BiliBili.Live;
import com.yutou.bilibili.BiliBili.LiveUtils; import com.yutou.bilibili.BiliBili.LiveUtils;
import com.yutou.bilibili.QQBot.QQBotManager;
import com.yutou.bilibili.Tools.AppTools; import com.yutou.bilibili.Tools.AppTools;
import com.yutou.bilibili.Tools.HttpTools; import com.yutou.bilibili.Tools.HttpTools;
@ -14,9 +15,9 @@ import java.util.*;
public class SaveLive { public class SaveLive {
private static SaveLive live; private static SaveLive live;
private List<String> saveList = new ArrayList<>(); private final List<String> saveList = new ArrayList<>();
private Map<Integer,DownloadThread> downloads = new HashMap<>(); private final Map<Integer, DownloadThread> downloads = new HashMap<>();
private Map<Integer,Timer> heartbeats=new HashMap<>(); private final Map<Integer, Timer> heartbeats = new HashMap<>();
public static void main(String[] args) { public static void main(String[] args) {
SaveLive.getInstance().addLive(3715397); SaveLive.getInstance().addLive(3715397);
@ -35,7 +36,11 @@ public class SaveLive {
public void addLive(Live live) { public void addLive(Live live) {
addLive(live.geData().getRoomid()); addLive(live.geData().getRoomid());
} }
public void startLive(int roomId){
saveList.add(roomId + "");
start(roomId);
QQBotManager.getInstance().sendMessage(roomId+" 已启动录制");
}
public void addLive(int roomId) { public void addLive(int roomId) {
if (saveList.contains(roomId + "")) { if (saveList.contains(roomId + "")) {
return; return;
@ -45,11 +50,15 @@ public class SaveLive {
} }
saveList.add(roomId + ""); saveList.add(roomId + "");
start(roomId); start(roomId);
QQBotManager.getInstance().sendMessage(roomId+" 已启动录制");
} }
public boolean checkLive(int roomId) { public boolean checkLive(int roomId) {
return saveList.contains(roomId + ""); return saveList.contains(roomId + "");
} }
public File getLiveFile(int roomId){
return downloads.get(roomId).liveFile;
}
private long timer = 0; private long timer = 0;
@ -84,6 +93,7 @@ public class SaveLive {
int roomId = 0; int roomId = 0;
boolean isSave = true; boolean isSave = true;
Timer heartbeat; Timer heartbeat;
File liveFile;
public DownloadThread(int roomId) { public DownloadThread(int roomId) {
this.roomId = roomId; this.roomId = roomId;
@ -115,17 +125,17 @@ public class SaveLive {
heartbeats.put(roomId, heartbeat); heartbeats.put(roomId, heartbeat);
//heartbeats.add(beat); //heartbeats.add(beat);
InputStream inputStream = connection.getInputStream(); InputStream inputStream = connection.getInputStream();
File file = new File(String.format("live%s%s%s[%s]%d.mp4", liveFile = new File(String.format("live%s%s%s[%s]%d.mp4",
File.separator, File.separator,
AppTools.getToDayTime(), AppTools.getToDayTime(),
File.separator, File.separator,
AppTools.getToDayNowTimeToString().replace(":", ""), AppTools.getToDayNowTimeToString().replace(":", ""),
roomId)); roomId));
if (!file.exists()) { if (!liveFile.exists()) {
file.mkdirs(); liveFile.mkdirs();
file.delete(); liveFile.delete();
} }
FileOutputStream outputStream = new FileOutputStream(file); FileOutputStream outputStream = new FileOutputStream(liveFile);
int len; int len;
byte[] bytes = new byte[1024]; byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) != -1 && isSave) { while ((len = inputStream.read(bytes)) != -1 && isSave) {
@ -137,13 +147,14 @@ public class SaveLive {
com.yutou.bilibili.Tools.Log.i("录制完成:" + roomId + " save = " + isSave + " len = " + len); com.yutou.bilibili.Tools.Log.i("录制完成:" + roomId + " save = " + isSave + " len = " + len);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally {
SaveLive.this.stop(roomId);
} }
SaveLive.this.stop(roomId);
} }
private class Heartbeat extends TimerTask { private class Heartbeat extends TimerTask {
int nextInterval = 1; int nextInterval = 1;
@Override @Override
public void run() { public void run() {
try { try {

View File

@ -2,18 +2,22 @@ package com.yutou.bilibili;
import com.yutou.bilibili.BiliBili.Live; import com.yutou.bilibili.BiliBili.Live;
import com.yutou.bilibili.BiliBili.Tools.LiveT; import com.yutou.bilibili.BiliBili.Tools.LiveT;
import com.yutou.bilibili.QQBot.QQBotManager;
import com.yutou.bilibili.Tools.ExcelUtils; import com.yutou.bilibili.Tools.ExcelUtils;
import com.yutou.bilibili.Tools.ServiceTools; import com.yutou.bilibili.Tools.ServiceTools;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@Import({Live.class,ServiceTools.class, ExcelUtils.class}) @Import({Live.class,ServiceTools.class, ExcelUtils.class, QQBotManager.class})
@SpringBootApplication @SpringBootApplication
public class BilibiliApplication { public class BilibiliApplication {
public static String version="0.6";
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(BilibiliApplication.class, args); SpringApplication.run(BilibiliApplication.class, args);
QQBotManager.getInstance().init();
} }
} }

View File

@ -0,0 +1,404 @@
package com.yutou.bilibili.QQBot;
import com.alibaba.fastjson.JSONObject;
import com.yutou.bilibili.BiliBili.Controllers.RealTimeDataController;
import com.yutou.bilibili.BiliBili.Live;
import com.yutou.bilibili.BiliBili.LiveUtils;
import com.yutou.bilibili.BiliBili.Tools.SaveLive;
import com.yutou.bilibili.BilibiliApplication;
import com.yutou.bilibili.Tools.AppTools;
import com.yutou.bilibili.Tools.HttpTools;
import com.yutou.bilibili.Tools.Log;
import com.yutou.bilibili.Tools.Tools;
import com.yutou.bilibili.interfaces.DownloadInterface;
import com.yutou.bilibili.mybatis.Bili.mybatis.model.BilibiliUpInfo;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.BotFactory;
import net.mamoe.mirai.event.GlobalEventChannel;
import net.mamoe.mirai.event.events.GroupMessageEvent;
import net.mamoe.mirai.message.data.Image;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.utils.BotConfiguration;
import net.mamoe.mirai.utils.ExternalResource;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.Resource;
import java.io.File;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class QQBotManager implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (QQBotManager.applicationContext == null)
QQBotManager.applicationContext = applicationContext;
}
private <T> T getBean(Class<T> tClass) {
return applicationContext.getBean(tClass);
}
private static class QQCommands {
private final static String QQ_HELP = "!help";
private final static String QQ_GET_IP = "!ip";
private final static String QQ_GET_VERSION = "!version";
private final static String QQ_LIVE_LIST = "!直播列表";
private final static String QQ_LIVE_SAVE = "!录播列表";
private final static String QQ_LIVE_TO_DAY_DATE = "!今日数据";
private final static String QQ_LIVE_DATE = "!数据";
private final static String QQ_LIVE_USE_SAVE = "!启动录播";
}
private static QQBotManager botManager = null;
private Bot bot;
private static final long qqGroup = 891655174L;
private boolean isLogin = false;
private static boolean isInit = false;
private static final boolean debug = true;
@Resource
RealTimeDataController realTimeDataController;
private QQBotManager() {
}
public void init() {
new Thread(new Runnable() {
@Override
public void run() {
long qq = 3620756944L;
String password = "UAs6YBYMyxJU";
System.out.println("调用机器人");
bot = BotFactory.INSTANCE.newBot(qq, password, new BotConfiguration() {
{
setProtocol(MiraiProtocol.ANDROID_PAD);
fileBasedDeviceInfo("qq_bot_devices_info.json");
if (debug) {
noBotLog();
noNetworkLog();
}
}
});
//Events.registerEvents(bot, new MessageListener());
GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, new MessageListener());
System.out.println("准备登陆");
bot.login();
System.out.println("登陆成功");
isLogin = true;
isInit = true;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String str = sendMessage("姬妻酱上线拉~");
Log.i(str);
}
}).start();
bot.join();
}
}).start();
}
public static QQBotManager getInstance() {
if (botManager == null && !isInit) {
botManager = new QQBotManager();
}
return botManager;
}
public boolean isLogin() {
return isLogin;
}
private Image getImage(File file) {
if (bot != null) {
return Objects.requireNonNull(bot.getGroup(qqGroup)).uploadImage(ExternalResource.create(file));
}
return null;
}
private String getNotLoginQQ() {
return "没有登录QQ";
}
public String sendMessage(String text) {
if (bot != null) {
try {
return Objects.requireNonNull(bot.getGroup(qqGroup)).sendMessage(text).toString();
} catch (Exception e) {
e.printStackTrace();
}
}
return getNotLoginQQ();
}
public String sendMessage(Long group, String text) {
if (bot != null) {
try {
return Objects.requireNonNull(bot.getGroup(group)).sendMessage(text).toString();
} catch (Exception e) {
e.printStackTrace();
}
}
return getNotLoginQQ();
}
public void sendMessage(Long group, MessageChainBuilder builder) {
if (bot != null) {
Objects.requireNonNull(bot.getGroup(group)).sendMessage(builder.asMessageChain());
}
}
public String sendMessage(File imageFile, String text) {
try {
if (bot != null) {
Image image = getImage(imageFile);
MessageChainBuilder builder = new MessageChainBuilder();
if (image != null) {
builder.append(image);
}
builder.append(text);
return Objects.requireNonNull(bot.getGroup(qqGroup)).sendMessage(builder.asMessageChain()).toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return getNotLoginQQ();
}
public String sendMessage(List<File> imgs, String text) {
if (bot != null) {
MessageChainBuilder builder = new MessageChainBuilder();
for (File img : imgs) {
builder.append(Objects.requireNonNull(getImage(img)));
}
builder.append(text);
return Objects.requireNonNull(bot.getGroup(qqGroup)).sendMessage(builder.asMessageChain()).toString();
}
return getNotLoginQQ();
}
private static List<String> getImages(String str) {
List<String> list = new ArrayList<>();
String regex = "<img(.*?)/img>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
list.add(matcher.group().replace("<img", "")
.replace("/img>", "")
.trim());
}
return list;
}
public static void main(String[] args) {
getInstance();
}
private static class MessageListener implements Consumer<GroupMessageEvent> {
@Override
public void accept(GroupMessageEvent event) {
String msg = event.getMessage().contentToString();
switch (event.getGroup().getId() + "") {
case qqGroup + "":
myGroup(msg);
}
}
private void myGroup(String msg) {
msg = msg.replace("", "!").toLowerCase();
StringBuilder builder = new StringBuilder();
JSONObject json;
String[] cmd = new String[0];
int _roomId = 0;
switch (msg) {
case QQCommands.QQ_GET_IP:
json = JSONObject.parseObject(HttpTools.get("https://api.asilu.com/ip/"));
String ip = json.getString("ip");
getInstance().sendMessage("服务器IP:" + ip);
break;
case QQCommands.QQ_GET_VERSION:
sendVersion();
break;
case QQCommands.QQ_LIVE_LIST:
builder.append("当前正在记录数据的直播间:");
builder.append("\n");
for (Live live : Live.lives) {
JSONObject liveJson = LiveUtils.getLiveInfo(live.getInfo().getRoomid());
builder
.append("名字:").append(live.geData().getName()).append(" ")
.append(" roomId:").append(live.geData().getRoomid()).append(" ");
if (liveJson != null) {
builder.append("标题:").append(liveJson.getJSONObject("data").getJSONObject("room_info").getString("title")).append("\n");
} else {
builder.append("\n");
}
}
getInstance().sendMessage(builder.toString());
break;
case QQCommands.QQ_LIVE_SAVE:
builder.append("当前正在录制的直播间:");
builder.append("\n");
for (String roomId : SaveLive.getInstance().getLiveList()) {
BilibiliUpInfo data = new BilibiliUpInfo();
data.setRoomid(Integer.parseInt(roomId));
Live live = LiveUtils.liveContains(data);
if (live != null) {
File file = SaveLive.getInstance().getLiveFile(_roomId);
builder
.append("名字:").append(live.geData().getName()).append(" ")
.append("文件大小(字节):").append(file.length()).append(" ")
.append("roomId:").append(live.geData().getRoomid()).append("\n");
}
}
getInstance().sendMessage(builder.toString());
break;
case QQCommands.QQ_HELP:
for (Field field : QQCommands.class.getDeclaredFields()) {
try {
field.setAccessible(true);
builder.append(field.get(null)).append("\n");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
getInstance().sendMessage(builder.toString());
break;
default:
if(msg.startsWith(QQCommands.QQ_LIVE_TO_DAY_DATE)){
try {
cmd = msg.split(" ");
_roomId = Integer.parseInt(cmd[1]);
QQBotManager.getInstance().sendMessage("请稍等,正在查询...");
sendGiftData(_roomId, null, null);
} catch (Exception e) {
getInstance().sendMessage("参数错误。\n使用方式: " + QQCommands.QQ_LIVE_TO_DAY_DATE + "+空格+roomId");
}
}else if(msg.startsWith(QQCommands.QQ_LIVE_DATE)){
try {
cmd = msg.split(" ");
_roomId = Integer.parseInt(cmd[1]);
Date startTime = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").parse(cmd[2]);
Date endTime = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").parse(cmd[3]);
QQBotManager.getInstance().sendMessage("请稍等,正在查询...");
sendGiftData(_roomId, startTime, endTime);
} catch (Exception e) {
getInstance().sendMessage("参数错误。" +
"\n使用方式: " + QQCommands.QQ_LIVE_DATE + "+空格+roomId+起始时间+空格+结束时间" +
"\n时间格式年-月-日_时:分:秒 例:2021-4-1_12:00:00" +
"\n时分秒不可省略");
}
}else if(msg.startsWith(QQCommands.QQ_LIVE_USE_SAVE)){
try {
cmd = msg.split(" ");
_roomId = Integer.parseInt(cmd[1]);
if (SaveLive.getInstance().checkLive(_roomId)) {
SaveLive.getInstance().stop(_roomId);
}
SaveLive.getInstance().startLive(_roomId);
getInstance().sendMessage("已启动" + _roomId + "的录播");
} catch (Exception e) {
getInstance().sendMessage("参数错误。\n使用方式: " + QQCommands.QQ_LIVE_USE_SAVE + "+空格+roomId");
}
}
}
}
public void sendGiftData(int roomId, Date startTime, Date endTime) throws ParseException {
StringBuilder builder = new StringBuilder();
if (startTime == null) {
startTime = AppTools.getToDayStartTime();
}
if (endTime == null) {
endTime = AppTools.getToDayNowTime();
}
if (getInstance().realTimeDataController == null)
getInstance().realTimeDataController = getInstance().getBean(RealTimeDataController.class);
JSONObject json = getInstance().realTimeDataController.queryToDayLiveData(roomId, startTime, endTime);
System.out.println(json);
builder.append("当前人气:").append(json.getJSONObject("data").getInteger("popular")).append("\n");
builder.append("普通观众入场:").append(json.getJSONObject("data").getInteger("userLength")).append("\n");
builder.append("舰长入场:").append(json.getJSONObject("data").getInteger("vipLength")).append("\n");
int price = 0;
for (Object o : json.getJSONObject("data").getJSONArray("price")) {
price += ((JSONObject) o).getInteger("price");
}
builder.append("金瓜子:").append(price).append(" 抽成后:").append((price / 2) / 1000).append("").append("\n");
builder.append("礼物收益情况:").append("\n");
for (Object o : json.getJSONObject("data").getJSONArray("gift")) {
builder.append(((JSONObject) o).getString("giftName")).append(":").append(((JSONObject) o).getInteger("size")).append("\n");
}
getInstance().sendMessage(builder.toString());
}
private List<File> files;
private int index = 0;
private void sendImagesMsg(List<String> imgs, String text) {
files = new ArrayList<>();
index = 0;
if (imgs.size() == 0) {
getInstance().sendMessage(text);
return;
}
for (String img : imgs) {
Tools.download(img, new DownloadInterface() {
@Override
public void onDownload(File file) {
super.onDownload(file);
files.add(file);
send(imgs.size(), text);
}
@Override
public void onError(Exception e) {
super.onError(e);
index++;
send(imgs.size(), text);
}
});
}
}
private void send(int size, String text) {
if ((files.size() + index) == size) {
String str = getInstance().sendMessage(files, text);
Log.i("str = " + str);
}
}
private void sendVersion() {
String msg = "软件版本:" + BilibiliApplication.version;
QQBotManager.getInstance().sendMessage(msg);
}
}
}

View File

@ -2,10 +2,17 @@ package com.yutou.bilibili.Tools;
public class Log { public class Log {
public static void i(Object log){ public static void i(Object log){
if(true)
return;
System.out.printf("[%s]%s%n", System.out.printf("[%s]%s%n",
AppTools.getToDayNowTimeToString(), AppTools.getToDayNowTimeToString(),
log log
); );
} }
public static void e(Exception e){
if(true)
return;
e.printStackTrace();
}
} }

View File

@ -0,0 +1,211 @@
package com.yutou.bilibili.Tools;
import com.alibaba.fastjson.JSONArray;
import com.yutou.bilibili.interfaces.DownloadInterface;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Random;
public class Tools {
/**
* 获取项目路径
*
* @param request
* @return
*/
public static String getPath(HttpServletRequest request) {
return request.getServletContext().getRealPath("/") + "/";
}
/**
* 获取客户端IP
*
* @param request
* @return
*/
public static String getRemoteAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
ip = request.getRemoteAddr();
}
return ip;
}
/**
* N以内的不重复随机数
*
* @param min 最小值
* @param max 最大值
* @param n
* @return
*/
public static int[] randomCommon(int min, int max, int n) {
int len = max - min + 1;
if (max < min || n > len) {
return new int[0];
}
// 初始化给定范围的待选数组
int[] source = new int[len];
for (int i = min; i < min + len; i++) {
source[i - min] = i;
}
int[] result = new int[n];
Random rd = new Random();
int index = 0;
for (int i = 0; i < result.length; i++) {
// 待选数组0到(len-2)随机一个下标
index = Math.abs(rd.nextInt() % len--);
// 将随机到的数放入结果集
result[i] = source[index];
// 将待选数组中被随机到的数用待选数组(len-1)下标对应的数替换
source[index] = source[len];
}
return result;
}
public static void download(String url, DownloadInterface downloadInterface) {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36");
connection.disconnect();
new File("tmp").mkdirs();
File file = new File("tmp" + File.separator + url.trim().split("/")[url.trim().split("/").length - 1]);
if (file.exists()) {
file.delete();
}
FileOutputStream outputStream = new FileOutputStream(file);
InputStream inputStream = connection.getInputStream();
byte[] bytes = new byte[4096];
int len;
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
outputStream.close();
inputStream.close();
downloadInterface.onDownload(file);
} catch (IOException e) {
e.printStackTrace();
downloadInterface.onError(e);
}
}
/**
* 构造给前端的文件
*
* @param file 文件路径
* @return 前端获取的文件
*/
public static ResponseEntity<FileSystemResource> getFile(File file) {
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
try {
headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
headers.add("Content-Disposition", "attachment; filename=" + file.getName());
}
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
headers.add("Last-Modified", new Date().toString());
headers.add("ETag", String.valueOf(System.currentTimeMillis()));
return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
}
public static String getFileMD5(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte buffer[] = new byte[1024];
int len;
try {
digest = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer, 0, 1024)) != -1) {
digest.update(buffer, 0, len);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bytesToHexString(digest.digest());
}
private static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (byte aSrc : src) {
int v = aSrc & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
public static String base64ToString(String base) {
base = base.replace(" ", "+");
try {
base = new String(Base64.getDecoder().decode(base.replace("\r\n", "").getBytes()));
} catch (Exception e) {
try {
base = URLDecoder.decode(base, "UTF-8");
base = base.replace(" ", "+");
base = new String(Base64.getDecoder().decode(base.replace("\r\n", "").getBytes()));
} catch (Exception e1) {
e1.printStackTrace();
}
}
return base;
}
/**
* 异常输出
*
* @param e 异常
* @return
*/
public static String getExceptionString(Exception e) {
StringWriter writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
e.printStackTrace(printWriter);
printWriter.close();
return writer.toString();
}
public static String getToDayTime() {
return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
}
}

View File

@ -1,6 +1,9 @@
package com.yutou.bilibili.interfaces; package com.yutou.bilibili.interfaces;
import java.io.File;
public abstract class DownloadInterface { public abstract class DownloadInterface {
public void onDownload(String file){}; public void onDownloading(double soFarBytes, double totalBytes){};
public void onDownload(File file){};
public void onError(Exception e){}; public void onError(Exception e){};
} }