diff --git a/pom.xml b/pom.xml
index 35fc14e..b688616 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,6 +114,12 @@
kotlin-stdlib
${kotlin.version}
+
+
+ redis.clients
+ jedis
+ 3.6.0-RC1
+
diff --git a/src/main/java/com/yutou/bilibili/BiliBili/Live.java b/src/main/java/com/yutou/bilibili/BiliBili/Live.java
index baa41c9..a8f8c50 100644
--- a/src/main/java/com/yutou/bilibili/BiliBili/Live.java
+++ b/src/main/java/com/yutou/bilibili/BiliBili/Live.java
@@ -112,7 +112,7 @@ public class Live implements ApplicationContextAware {
}
}
- private int reloadLike = 0;
+ private Date startTime;
/**
* 开始监听
@@ -133,6 +133,7 @@ public class Live implements ApplicationContextAware {
stop();
return;
}
+ startTime=new Date();
HashMap header = new HashMap();
header.put("Sec-WebSocket-Extensions", "permessage-deflate; client_max_window_bits");
header.put("Sec-WebSocket-Key", "tORCZd8AI6xIyvqvgvI1Vw==");
@@ -180,11 +181,12 @@ public class Live implements ApplicationContextAware {
public void onClose(int i, String s, boolean b) {
com.yutou.bilibili.Tools.Log.i("连接时间:" + (System.currentTimeMillis() - time));
if (upData.getOfflinelistening() == 1) {
- System.err.println(roomId + " 断开连接,重连...");
+ Log.i(roomId + " 断开连接,重连...");
try {
init = true;
heartBeattimer.cancel();
client.close();
+ liveOfRoomId.remove(roomId + "");
start();
} catch (Exception e) {
Log.e(e);
@@ -221,9 +223,7 @@ public class Live implements ApplicationContextAware {
if (danmuManager != null) {
danmuManager.close();
}
- if(liveOfRoomId.contains(roomId+"")){
- liveOfRoomId.remove(roomId+"");
- }
+ liveOfRoomId.remove(roomId+"");
if (SaveLive.getInstance().checkLive(roomId)) {
SaveLive.getInstance().stop(roomId);
}
@@ -339,7 +339,7 @@ public class Live implements ApplicationContextAware {
switch (json.getString("cmd")) {
case "INTERACT_WORD"://普通用户进直播间
danmu = json.getJSONObject("data").getString("uname") + " 进入到直播间";
- //com.yutou.bilibili.Tools.Log.i(danmu);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
liveData.setUid(json.getJSONObject("data").getInteger("uid"));
liveData.setType(LiveData.INTERACT_WORD);
liveData.setMsg(danmu);
@@ -361,11 +361,10 @@ public class Live implements ApplicationContextAware {
danmuData.setUname(infoData.getJSONArray(2).getString(1));
if (upData != null && upData.getSavedanmu() == 1) {
- Log.i(danmuData.toString());
if (danmuManager != null)
danmuManager.addDanmu(danmuData);
}
- // com.yutou.bilibili.Tools.Log.i(json.toJSONString());
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
break;
case "SEND_GIFT"://送礼
data = json.getJSONObject("data");
@@ -392,6 +391,7 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
break;
case "COMBO_SEND"://礼物连击
data = json.getJSONObject("data");
@@ -422,9 +422,9 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
break;
case "ENTRY_EFFECT"://舰长进直播间
- // com.yutou.bilibili.Tools.Log.i("[舰长]" + json.getJSONObject("data").getString("uid") + " 进入到直播间");
info.setVipuserindex(info.getVipuserindex() + 1);
danmu = "[舰长]" + json.getJSONObject("data").getString("uid") + " 进入到直播间";
liveData.setUid(json.getJSONObject("data").getInteger("uid"));
@@ -433,6 +433,7 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
liveData.setSubtime(new Date());
service.addLiveData(liveData);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
break;
case "LIVE_INTERACTIVE_GAME"://彩色弹幕?通过游戏弹幕
break;
@@ -452,6 +453,7 @@ public class Live implements ApplicationContextAware {
liveData.setSubtime(new Date());
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,danmu);
break;
case "USER_TOAST_MSG":
break;
@@ -469,6 +471,7 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
info.setGiftuser(info.getGiftuser() + 1);
service.addLiveData(liveData);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,liveData.toString());
break;
case "LIVE"://开始直播,不过有在心跳包上做检测了,所以也无所谓?
if (upData.getLive() == 1) {
@@ -490,6 +493,7 @@ public class Live implements ApplicationContextAware {
QQBotManager.getInstance().sendMessage(file, builder.toString());
}
});
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,upData.getName()+"开播了!");
break;
case "PREPARING"://
case "SUPER_CHAT_MESSAGE_JPN":
@@ -519,9 +523,11 @@ public class Live implements ApplicationContextAware {
liveData.setRoomid(roomId);
liveData.setSubtime(new Date());
service.addLiveData(liveData);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,liveData.toString());
}
} catch (Exception e) {
Log.e(e);
+ Log.i(AppTools.getToDayTimeToString(startTime),roomId,e.getLocalizedMessage());
try {
JSONObject.parseObject(new String(bytes, StandardCharsets.UTF_8));
processData(new String(bytes, StandardCharsets.UTF_8), null);
diff --git a/src/main/java/com/yutou/bilibili/BiliBili/Tools/SaveLive.java b/src/main/java/com/yutou/bilibili/BiliBili/Tools/SaveLive.java
index cc4a3d5..c85b2ad 100644
--- a/src/main/java/com/yutou/bilibili/BiliBili/Tools/SaveLive.java
+++ b/src/main/java/com/yutou/bilibili/BiliBili/Tools/SaveLive.java
@@ -157,7 +157,8 @@ public class SaveLive {
} catch (Exception e) {
com.yutou.bilibili.Tools.Log.e(e);
Log.i("录制发生意外:" + e.getMessage());
- QQBotManager.getInstance().sendMessage("录制发生意外:" + e.getMessage());
+ QQBotManager.getInstance().sendMessage("录制发生意外:" + e.getLocalizedMessage());
+ LiveUtils.LiveInfoManager.getInstance().check(roomId);
}
SaveLive.this.stop(roomId);
diff --git a/src/main/java/com/yutou/bilibili/QQBot/QQBotManager.java b/src/main/java/com/yutou/bilibili/QQBot/QQBotManager.java
index babe217..7ee5b86 100644
--- a/src/main/java/com/yutou/bilibili/QQBot/QQBotManager.java
+++ b/src/main/java/com/yutou/bilibili/QQBot/QQBotManager.java
@@ -24,7 +24,6 @@ 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;
@@ -49,6 +48,8 @@ public class QQBotManager implements ApplicationContextAware {
private static class QQCommands {
private final static String QQ_HELP = "!help";
+ private final static String QQ_SYSTEM_LOG = "!log";
+ private final static String QQ_SYSTEM_STOP = "!stopliveservice";
private final static String QQ_GET_IP = "!ip";
private final static String QQ_GET_VERSION = "!version";
private final static String QQ_LIVE_LIST = "!列表";
@@ -60,7 +61,7 @@ public class QQBotManager implements ApplicationContextAware {
private static QQBotManager botManager = null;
private Bot bot;
- private static long qqGroup ;
+ private static long qqGroup;
private boolean isLogin = false;
private static boolean isInit = false;
@@ -73,7 +74,7 @@ public class QQBotManager implements ApplicationContextAware {
}
public void init() {
- if(!((boolean) ConfigTools.load(ConfigTools.CONFIG,"qq_bot"))){
+ if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "qq_bot"))) {
return;
}
new Thread(new Runnable() {
@@ -230,6 +231,7 @@ public class QQBotManager implements ApplicationContextAware {
private void myGroup(String msg) {
msg = msg.replace("!", "!").toLowerCase();
+ msg=msg.trim();
StringBuilder builder = new StringBuilder();
JSONObject json;
String[] cmd = new String[0];
@@ -243,12 +245,17 @@ public class QQBotManager implements ApplicationContextAware {
case QQCommands.QQ_GET_VERSION:
sendVersion();
break;
+ case QQCommands.QQ_SYSTEM_STOP:
+ getInstance().sendMessage("正在停止服务");
+ System.out.println("结束进程");
+ System.exit(0);
+ break;
case QQCommands.QQ_LIVE_LIST:
builder.append("当前正在记录数据的直播间:");
builder.append("\n");
for (Live live : Live.lives) {
JSONObject liveJson = LiveUtils.LiveInfoManager.getInstance().getInfo(live.getInfo().getRoomid());
- if(LiveUtils.isLivePlayer(live.getInfo().getRoomid())){
+ if (LiveUtils.isLivePlayer(live.getInfo().getRoomid())) {
builder.append("【直播中】");
}
builder
@@ -327,6 +334,26 @@ public class QQBotManager implements ApplicationContextAware {
} catch (Exception e) {
getInstance().sendMessage("参数错误。\n使用方式: " + QQCommands.QQ_LIVE_USE_SAVE + "+空格+roomId");
}
+ } else if (msg.startsWith(QQCommands.QQ_SYSTEM_LOG)) {
+ try {
+ cmd = msg.split(" ");
+ switch (cmd[1]){
+ case "true":
+ RedisTools.set(1,"live-log","true");
+ getInstance().sendMessage("日志设为 true");
+ break;
+ case "false":
+ RedisTools.set(1,"live-log","false");
+ getInstance().sendMessage("日志设为 false");
+ break;
+ default:
+ getInstance().sendMessage("设置错误,"+QQCommands.QQ_SYSTEM_LOG +" true|false");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }else {
+ System.out.println("未知指令:"+msg);
}
}
}
diff --git a/src/main/java/com/yutou/bilibili/Tools/AppTools.java b/src/main/java/com/yutou/bilibili/Tools/AppTools.java
index 9e731c8..d967959 100644
--- a/src/main/java/com/yutou/bilibili/Tools/AppTools.java
+++ b/src/main/java/com/yutou/bilibili/Tools/AppTools.java
@@ -55,6 +55,8 @@ public class AppTools {
}
public static String getToDayTime() {
return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+ } public static String getToDayTime(Date date) {
+ return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
public static Date getToDayStartTime(){
return new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(AppTools.getToDayTime() + " " + "00:00",new ParsePosition(0));
diff --git a/src/main/java/com/yutou/bilibili/Tools/Log.java b/src/main/java/com/yutou/bilibili/Tools/Log.java
index e76ffe7..a1e4e7c 100644
--- a/src/main/java/com/yutou/bilibili/Tools/Log.java
+++ b/src/main/java/com/yutou/bilibili/Tools/Log.java
@@ -1,6 +1,14 @@
package com.yutou.bilibili.Tools;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.FileHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
public class Log {
+ private static Logger logger;
public static void i(Object log) {
if (!((boolean) ConfigTools.load(ConfigTools.CONFIG, "logout")))
return;
@@ -17,4 +25,26 @@ public class Log {
i(e.getMessage());
e.printStackTrace();
}
+ public static void i(String timer,int roomId,Object log){
+ String logFlag=RedisTools.get("live-log",1);
+ if(logFlag!=null&&logFlag.equals("true")) {
+ getLogger("[" + timer.replace(":", "_") + "]" + roomId).log(Level.INFO, log.toString());
+ }
+ }
+
+ public static Logger getLogger(String fileName){
+ if(logger==null){
+ try {
+ if(!new File("logs").exists()){
+ new File("logs").mkdirs();
+ }
+ logger=Logger.getLogger("Live-Log");
+ FileHandler handler=new FileHandler("logs"+ File.separator+fileName+".log");
+ logger.addHandler(handler);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return logger;
+ }
}
diff --git a/src/main/java/com/yutou/bilibili/Tools/RedisTools.java b/src/main/java/com/yutou/bilibili/Tools/RedisTools.java
new file mode 100644
index 0000000..00d21dd
--- /dev/null
+++ b/src/main/java/com/yutou/bilibili/Tools/RedisTools.java
@@ -0,0 +1,237 @@
+package com.yutou.bilibili.Tools;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yutou.bilibili.QQBot.QQBotManager;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+import redis.clients.jedis.JedisPubSub;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Properties;
+import java.util.Set;
+
+
+public class RedisTools {
+ private static boolean isNotInstallRedis = false;
+ private static String host;
+ private static int port;
+ public static int TOKEN_TIMEOUT_DEFAULT = 360;
+
+ private RedisTools() {
+
+ }
+
+ // 写成静态代码块形式,只加载一次,节省资源
+ static {
+ //Properties properties = PropertyUtil.loadProperties("jedis.properties");
+ //host = properties.getProperty("redis.host");
+ //port = Integer.valueOf(properties.getProperty("redis.port"));
+ host = "127.0.0.1";
+ port = 6379;
+ }
+
+ public static boolean set(int dbIndex, String key, String value) {
+ try {
+ if (isNotInstallRedis) {
+ return false;
+ }
+ Jedis jedis = getRedis();
+ jedis.select(dbIndex);
+ String ret = jedis.set(key, value);
+ Log.i("Redis set =" + ret);
+ jedis.close();
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean set(String key, String value) {
+ return set(0, key, value);
+ }
+
+ public static boolean set(String key, String value, int timeout) {
+ try {
+ if (isNotInstallRedis) {
+ return false;
+ }
+ Jedis jedis = getRedis();
+ if (timeout == -1) {
+ jedis.set(key, value);
+ } else {
+ jedis.setex(key, timeout, value);
+ }
+ jedis.close();
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public static String get(String key, int dbIndex) {
+ String value = "-999";
+ if (isNotInstallRedis) {
+ return value;
+ }
+ try (Jedis jedis = getRedis()) {
+ jedis.select(dbIndex);
+ value = jedis.get(key);
+ jedis.close();
+ } catch (Exception e) {
+ // TODO: handle exception
+ // e.printStackTrace();
+ }
+ return value;
+ }
+
+ public static String get(String key) {
+ return get(key, 0);
+ }
+
+ public static boolean remove(String key) {
+ return remove(key,0);
+ }
+
+ public static void removeLoginState(String uid) {
+ Jedis jedis = getRedis();
+ Set keys = jedis.keys("*");
+ for (String string : keys) {
+ if (string.equals(uid)) {
+ jedis.del(string);
+ }
+ }
+
+ }
+
+ public static String ping() {
+ Jedis jedis = getRedis();
+ String tmp = jedis.ping();
+ jedis.close();
+ return tmp;
+ }
+
+ public static boolean exists(String key, String value) {
+ if (isNotInstallRedis) {
+ return false;
+ }
+ Jedis jedis = getRedis();
+ boolean flag = value.equals(jedis.get(key));
+ jedis.close();
+ return flag;
+ }
+
+ public static Jedis getRedis() {
+ return new Jedis(host, port);
+ }
+
+ public static boolean remove(String key, int index) {
+ if (isNotInstallRedis) {
+ return false;
+ }
+ Jedis jedis = getRedis();
+ jedis.select(index);
+ Long i = jedis.del(key);
+ jedis.close();
+ if (i > 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private static class PropertyUtil {
+
+ // 加载property文件到io流里面
+ public static Properties loadProperties(String propertyFile) {
+ Properties properties = new Properties();
+ try {
+ InputStream is = PropertyUtil.class.getClassLoader().getResourceAsStream(propertyFile);
+ if (is == null) {
+ is = PropertyUtil.class.getClassLoader().getResourceAsStream(propertyFile);
+ }
+ properties.load(is);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return properties;
+ }
+ }
+
+ private static Jedis getPoolRedis() {
+ if (isNotInstallRedis) {
+ return null;
+ }
+ JedisPoolConfig poolConfig = new JedisPoolConfig();
+ poolConfig.setMaxIdle(0);
+ poolConfig.setMaxWaitMillis(1000);
+ JedisPool pool = new JedisPool(poolConfig, host);
+ return pool.getResource();
+ }
+
+ public static void pullMsg(String channel, String msg) {
+ Jedis jedis = getPoolRedis();
+ jedis.publish(channel, msg);
+ jedis.close();
+ }
+
+ private static boolean init = false;
+
+ public static void initRedisPoolSub() {
+ if (init)
+ return;
+ init = true;
+ Log.i("初始化订阅");
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Jedis jedis = getPoolRedis();
+ if (jedis != null)
+ jedis.psubscribe(new Consumer(), "*");
+ }
+ }).start();
+
+ }
+
+ protected static class Consumer extends JedisPubSub {
+ @Override
+ public void onPMessage(String pattern, String channel, String message) {
+ super.onPMessage(pattern, channel, message);
+ Log.i("onPMessage: channel=" + channel + " msg=" + message + " pattern=" + pattern);
+ switch (channel) {
+ case "bot":
+ bot(message);
+ break;
+ }
+ }
+
+ @Override
+ public void onMessage(String channel, String message) {
+ super.onMessage(channel, message);
+ Log.i("onMessage: channel=" + channel + " msg=" + message);
+ }
+
+
+
+
+ public static void bot(String value) {
+ switch (value) {
+ case "getip":
+ JSONObject json = JSONObject.parseObject(HttpTools.get("https://api.asilu.com/ip/"));
+ String ip = json.getString("ip");
+ QQBotManager.getInstance().sendMessage("服务器IP:\n" + ip);
+ break;
+ }
+ }
+ }
+ public static void main(String[] args) {
+ RedisTools.pullMsg("msg", "abc");
+ }
+}
diff --git a/src/main/java/com/yutou/bilibili/sqlite/BiliBiliLiveDatabasesManager.java b/src/main/java/com/yutou/bilibili/sqlite/BiliBiliLiveDatabasesManager.java
index 6aa0e1f..c16c08a 100644
--- a/src/main/java/com/yutou/bilibili/sqlite/BiliBiliLiveDatabasesManager.java
+++ b/src/main/java/com/yutou/bilibili/sqlite/BiliBiliLiveDatabasesManager.java
@@ -47,7 +47,6 @@ public class BiliBiliLiveDatabasesManager extends SQLiteManager {
,data.getUid()
,data.getUname()
);
- Log.i(sql);
statement.execute(sql);
statement.closeOnCompletion();
}catch (Exception e){