diff --git a/pom.xml b/pom.xml
index c5fa807..dc05015 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,7 +56,6 @@
-
com.alibaba
@@ -96,6 +95,11 @@
1.15
+
+ com.google.zxing
+ core
+ 3.4.1
+
@@ -115,7 +119,9 @@
复制正式文件
-
+
diff --git a/src/main/java/com/yutou/qqbot/QQBotApplication.java b/src/main/java/com/yutou/qqbot/QQBotApplication.java
index 8bc2643..dd22940 100644
--- a/src/main/java/com/yutou/qqbot/QQBotApplication.java
+++ b/src/main/java/com/yutou/qqbot/QQBotApplication.java
@@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class QQBotApplication {
- public static final String version="QQBot v.1.2.10.1";
+ public static final String version="QQBot v.1.2.11";
public static void main(String[] args) {
System.out.println("version = " + version);
SpringApplication.run(QQBotApplication.class, args);
diff --git a/src/main/java/com/yutou/qqbot/QQBotManager.java b/src/main/java/com/yutou/qqbot/QQBotManager.java
index 2e87c7f..a4df99f 100644
--- a/src/main/java/com/yutou/qqbot/QQBotManager.java
+++ b/src/main/java/com/yutou/qqbot/QQBotManager.java
@@ -7,6 +7,7 @@ import com.yutou.qqbot.models.Commands.Bangumi;
import com.yutou.qqbot.models.Commands.BTDownload;
import com.yutou.qqbot.models.Commands.System.*;
import com.yutou.qqbot.models.Model;
+import com.yutou.qqbot.models.WebSign.BiliBiliMangeSign;
import com.yutou.qqbot.models.WebSign.Tsdm;
import com.yutou.qqbot.models.XiaoMi.MiRouter;
import com.yutou.qqbot.models.setu.GetSeTu;
@@ -49,6 +50,7 @@ public class QQBotManager {
Model.classList.add(MiRouter.class);
Model.classList.add(GetSeTu.class);
Model.classList.add(BTDownload.class);
+ Model.classList.add(BiliBiliMangeSign.class);
}
private static QQBotManager botManager = null;
private Bot bot;
diff --git a/src/main/java/com/yutou/qqbot/bilibili/BiliBiliManga.java b/src/main/java/com/yutou/qqbot/bilibili/BiliBiliManga.java
new file mode 100644
index 0000000..a86767a
--- /dev/null
+++ b/src/main/java/com/yutou/qqbot/bilibili/BiliBiliManga.java
@@ -0,0 +1,16 @@
+package com.yutou.qqbot.bilibili;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yutou.qqbot.utlis.HttpTools;
+
+public class BiliBiliManga {
+ public static JSONObject sign(){
+ JSONObject body=new JSONObject();
+ body.put("platform","android");
+ return BiliBiliUtils.http_post("https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn", HttpTools.toUrlParams(body));
+ }
+
+ public static void main(String[] args) {
+ BiliBiliManga.sign();
+ }
+}
diff --git a/src/main/java/com/yutou/qqbot/bilibili/BiliBiliUtils.java b/src/main/java/com/yutou/qqbot/bilibili/BiliBiliUtils.java
new file mode 100644
index 0000000..b1061ef
--- /dev/null
+++ b/src/main/java/com/yutou/qqbot/bilibili/BiliBiliUtils.java
@@ -0,0 +1,173 @@
+package com.yutou.qqbot.bilibili;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.yutou.qqbot.utlis.ConfigTools;
+import org.springframework.util.StringUtils;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
+public class BiliBiliUtils {
+ 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 = outputStream.toString(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);
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static JSONObject http_post(String url, String body) {
+ JSONObject json = null;
+ try {
+ if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ oldBiliBiliHttpTime = System.currentTimeMillis();
+ }
+ HttpURLConnection connection = getBiliHttpPost(url, getCookie());
+ connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
+ OutputStream connectionOutputStream = null;
+ if (!StringUtils.isEmpty(body)) {
+ connectionOutputStream = connection.getOutputStream();
+ connectionOutputStream.write(body.getBytes(StandardCharsets.UTF_8));
+ connectionOutputStream.flush();
+ }
+ connection.connect();
+ if(connection.getResponseCode()==400){
+ return null;
+ }
+ 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 = outputStream.toString(StandardCharsets.UTF_8);
+ outputStream.close();
+ try {
+ json = JSON.parseObject(str);
+ json.put("cookie", connection.getHeaderField("Set-Cookie"));
+ return json;
+ } catch (Exception e) {
+ 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) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ public static String getCookie() {
+ if (StringUtils.isEmpty(ConfigTools.readFile(new File("bilibili.cookie")))) {
+
+ return "";
+ }
+ JSONObject json = JSONObject.parseObject(ConfigTools.readFile(new File("bilibili.cookie")));
+ StringBuilder builder = new StringBuilder();
+ for (String s : json.keySet()) {
+ builder.append(s).append("=").append(json.getString(s)).append(";");
+
+ }
+ return builder.toString();
+ }
+
+ public static HttpURLConnection getBiliHttpPost(String url, String cookie) throws Exception {
+ if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ oldBiliBiliHttpTime = System.currentTimeMillis();
+ }
+ HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
+ connection.setRequestMethod("POST");
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ setConnection(cookie, connection);
+ return connection;
+ }
+
+ public static HttpURLConnection getBiliHttpGet(String url, String cookie) throws IOException {
+ if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ignored) {
+ }
+ oldBiliBiliHttpTime = System.currentTimeMillis();
+ }
+ HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+ setConnection(cookie, connection);
+ connection.setReadTimeout(5000);
+ connection.setConnectTimeout(5000);
+ return connection;
+ }
+
+ private static void setConnection(String cookie, HttpURLConnection connection) {
+ 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", ".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");
+ }
+
+ public static JSONObject getLoginInfo() {
+ JSONObject jsonObject = BiliBiliUtils.http_get("https://api.bilibili.com/x/web-interface/nav");
+ if (jsonObject == null) {
+ jsonObject = new JSONObject();
+ jsonObject.put("code", "-1");
+ jsonObject.put("data", new JSONObject());
+ }
+ return jsonObject;
+ }
+}
diff --git a/src/main/java/com/yutou/qqbot/bilibili/BiliLogin.java b/src/main/java/com/yutou/qqbot/bilibili/BiliLogin.java
new file mode 100644
index 0000000..9c09583
--- /dev/null
+++ b/src/main/java/com/yutou/qqbot/bilibili/BiliLogin.java
@@ -0,0 +1,73 @@
+package com.yutou.qqbot.bilibili;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.yutou.qqbot.utlis.ConfigTools;
+import com.yutou.qqbot.utlis.HttpTools;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class BiliLogin {
+
+
+ public JSONObject login(){
+ JSONObject login= JSONObject.parseObject(HttpTools.get("https://passport.bilibili.com/qrcode/getLoginUrl"));
+ JSONObject json=new JSONObject();
+ json.put("code",login.getInteger("code"));
+ json.put("url",login.getJSONObject("data").getString("url"));
+ new Thread(() -> waitLogin(login.getJSONObject("data").getString("oauthKey"))).start();
+ return json;
+ }
+
+ public void waitLogin(String oauthKey){
+ long time=System.currentTimeMillis();
+ String bd="gourl=https%3A%2F%2Fpassport.bilibili.com%2Fajax%2FminiLogin%2Fredirect&oauthKey="+oauthKey;
+ new Timer().schedule(new TimerTask() {
+ @Override
+ public void run() {
+ if((System.currentTimeMillis()-time)>5*60*1000){
+ cancel();
+ return;
+ }
+ JSONObject json=JSONObject.parseObject(HttpTools.post("https://passport.bilibili.com/qrcode/getLoginInfo",bd.getBytes(StandardCharsets.UTF_8)));
+ if(json.containsKey("code")&&json.getInteger("code")==0){
+ System.out.println("json = " + json);
+ String _url=json.getJSONObject("data").getString("url");
+ Map map=HttpTools.getUrlParams(_url);
+
+ JSONObject cookie=new JSONObject();
+ JSONArray array=new JSONArray();
+ for (String key : map.keySet()) {
+ cookie.put(key,map.get(key));
+ }
+ System.out.println(array);
+
+ JSONObject tmp=BiliBiliUtils.http_post(_url,"");
+ System.out.println("tmp = " + tmp);
+ String sid=tmp.getString("cookie");
+ sid=sid.split("sid=")[1];
+ sid=sid.split(";")[0];
+ cookie.put("sid",sid);
+ cookie.put("Domain",".bilibili.com");
+ ConfigTools.saveFile(new File("bilibili.cookie"),cookie.toJSONString());
+ cancel();
+ }
+ }
+ },0,3000);
+
+ }
+ public boolean testLogin(){
+ JSONObject jsonObject = BiliBiliUtils.getLoginInfo();
+ return jsonObject.getInteger("code")==0;
+ }
+
+
+ public static void main(String[] args) {
+ BiliLogin login = new BiliLogin();
+ login.testLogin();
+ }
+}
diff --git a/src/main/java/com/yutou/qqbot/models/Model.java b/src/main/java/com/yutou/qqbot/models/Model.java
index 576b825..03c8206 100644
--- a/src/main/java/com/yutou/qqbot/models/Model.java
+++ b/src/main/java/com/yutou/qqbot/models/Model.java
@@ -44,6 +44,7 @@ public abstract class Model implements ModelInterface {
public static final String ROUTER_ADD = "!添加设备";
public static final String ROUTER_DEL = "!删除设备";
public static final String BT_DOWNLOAD = "下载bt";
+ public static final String BILI_MANGA_SIGN="!B站漫画签到";
}
diff --git a/src/main/java/com/yutou/qqbot/models/WebSign/BiliBiliMangeSign.java b/src/main/java/com/yutou/qqbot/models/WebSign/BiliBiliMangeSign.java
new file mode 100644
index 0000000..e728728
--- /dev/null
+++ b/src/main/java/com/yutou/qqbot/models/WebSign/BiliBiliMangeSign.java
@@ -0,0 +1,60 @@
+package com.yutou.qqbot.models.WebSign;
+
+import com.yutou.qqbot.QQBotManager;
+import com.yutou.qqbot.bilibili.BiliBiliManga;
+import com.yutou.qqbot.bilibili.BiliLogin;
+import com.yutou.qqbot.models.Model;
+import com.yutou.qqbot.utlis.QRCodeUtils;
+import net.mamoe.mirai.event.events.MessageEvent;
+
+import java.io.File;
+
+public class BiliBiliMangeSign extends Model {
+ @Override
+ public boolean isUserPublic() {
+ return false;
+ }
+
+ @Override
+ public String[] getUsePowers() {
+ return new String[]{
+ QQFromCommands.BILI_MANGA_SIGN
+ };
+ }
+
+ @Override
+ public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
+ super.onMessage(qq, event, isGroup);
+ if(event.getMessage().contentToString().equals(QQFromCommands.BILI_MANGA_SIGN)){
+ String msg;
+ if(new BiliLogin().testLogin()){
+ if(BiliBiliManga.sign()==null){
+ msg="B站漫画已经签到过了";
+ }else{
+ msg="B站漫画签到完成";
+ }
+ QQBotManager.getInstance().sendMessage(qq,msg);
+ }else{
+ String url = new BiliLogin().login().getString("url");
+ File code = QRCodeUtils.createQRCode("bili_login",url);
+ QQBotManager.getInstance().sendMessage(code,qq,"B站未登录,请扫码登陆后再试");
+ }
+ }
+ }
+
+ @Override
+ public void onTime(String time) {
+ super.onTime(time);
+ if("00:01:00".equals(time)){
+ if(new BiliLogin().testLogin()){
+ String msg;
+ if(BiliBiliManga.sign()==null){
+ msg="B站漫画已经签到过了";
+ }else{
+ msg="B站漫画签到完成";
+ }
+ QQBotManager.getInstance().sendMessage(msg);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java b/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java
index d916c49..567ccd0 100644
--- a/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java
+++ b/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java
@@ -11,6 +11,7 @@ public class ConfigTools {
public static final String CONFIG = "config.json";
public static final String DATA = "data.json";
public static final String SQLITE = "sqlite.json";
+ public static final String BiliBili = "bilibili.cookie";
static {
try {
@@ -104,7 +105,7 @@ public class ConfigTools {
String tmp;
StringBuilder str = new StringBuilder();
while ((tmp = reader.readLine()) != null) {
- str.append(tmp);
+ str.append(tmp).append("\n");
}
reader.close();
return str.toString();
diff --git a/src/main/java/com/yutou/qqbot/utlis/HttpTools.java b/src/main/java/com/yutou/qqbot/utlis/HttpTools.java
index acab6be..ec63cf0 100644
--- a/src/main/java/com/yutou/qqbot/utlis/HttpTools.java
+++ b/src/main/java/com/yutou/qqbot/utlis/HttpTools.java
@@ -7,6 +7,8 @@ import org.jetbrains.annotations.NotNull;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.*;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -89,11 +91,13 @@ public class HttpTools {
//connection.addRequestProperty("User-Agent", getExtUa());
//connection.addRequestProperty("content-type", "application/json");
connection.addRequestProperty("charset", "UTF-8");
- OutputStream outputStream = connection.getOutputStream();
- //System.out.println(new String(body));
- outputStream.write(body);
- outputStream.flush();
- outputStream.close();
+ if(body!=null) {
+ OutputStream outputStream = connection.getOutputStream();
+ //System.out.println(new String(body));
+ outputStream.write(body);
+ outputStream.flush();
+ outputStream.close();
+ }
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((tmp = reader.readLine()) != null) {
@@ -124,11 +128,11 @@ public class HttpTools {
Set keys = json.keySet();
for (String key : keys) {
try {
- string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8"));
+ string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
try {
- string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("=");
+ string.append("&").append(URLEncoder.encode(key, StandardCharsets.UTF_8)).append("=");
// string += "&" + key + "=";
} catch (Exception e1) {
string.append("&").append(key).append("=");
@@ -139,6 +143,17 @@ public class HttpTools {
string = new StringBuilder(string.substring(1, string.length()).replaceAll(" ", ""));
return string.toString();
}
+ public static Map getUrlParams(String url){
+ Map map=new HashMap<>();
+ if(url.contains("?")){
+ String param=url.split("\\?")[1];
+ String[] params=param.split("&");
+ for (String par : params) {
+ map.put(par.split("=")[0],par.split("=")[1]);
+ }
+ }
+ return map;
+ }
public static void main(String[] args) {
JSONObject json = new JSONObject();
diff --git a/src/main/java/com/yutou/qqbot/utlis/QRCodeUtils.java b/src/main/java/com/yutou/qqbot/utlis/QRCodeUtils.java
new file mode 100644
index 0000000..3b9050e
--- /dev/null
+++ b/src/main/java/com/yutou/qqbot/utlis/QRCodeUtils.java
@@ -0,0 +1,58 @@
+package com.yutou.qqbot.utlis;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class QRCodeUtils {
+ private static final int BLACK = 0xFF000000;
+ private static final int WHITE = 0xFFFFFFFF;
+
+
+ public static File createQRCode(String codeName,String value){
+ try {
+ String imageType = "jpg";// 图片类型
+ MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+ Map hints = new HashMap();
+ hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+ BitMatrix bitMatrix = multiFormatWriter.encode(value, BarcodeFormat.QR_CODE, 400, 400, hints);
+ if(!new File("QRCode").exists()){
+ boolean mkdirs = new File(("QRCode")).mkdirs();
+ System.out.println("create QRCode dir is = "+mkdirs);
+ }
+ File file1 = new File("QRCode"+File.separator+ codeName + "." + imageType);
+ writeToFile(bitMatrix, imageType, file1);
+ return file1;
+ } catch (WriterException | IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ private static BufferedImage toBufferedImage(BitMatrix matrix) {
+ int width = matrix.getWidth();
+ int height = matrix.getHeight();
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ for (int x = 0; x < width; x++) {
+ for (int y = 0; y < height; y++) {
+ image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
+ }
+ }
+ return image;
+ }
+
+ private static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
+ BufferedImage image = toBufferedImage(matrix);
+ if (!ImageIO.write(image, format, file)) {
+ throw new IOException("Could not write an image of format " + format + " to " + file);
+ }
+ }
+}
diff --git a/src/main/java/com/yutou/qqbot/utlis/WebClient.java b/src/main/java/com/yutou/qqbot/utlis/WebClient.java
index baa871c..b6d3f7a 100644
--- a/src/main/java/com/yutou/qqbot/utlis/WebClient.java
+++ b/src/main/java/com/yutou/qqbot/utlis/WebClient.java
@@ -49,21 +49,24 @@ public class WebClient {
json.getString("domain"),
json.getString("path"),
containsDate ? new Date(t) : new Date(),
- json.getBoolean("secure"),
- json.getBoolean("httpOnly")
+ json.containsKey("secure")?json.getBoolean("secure"):false,
+ json.containsKey("httpOnly")?json.getBoolean("httpOnly"):false
);
list.add(cookie);
}
return list;
}
-
+ static boolean headless=false;
+ public static void setHeadless(boolean headless){
+ WebClient.headless=headless;
+ }
public static ChromeOptions getOptions() {
ChromeOptions options = new ChromeOptions();
// options.addArguments("--disable-gpu");
// options.addArguments("blink-settings=imagesEnabled=false");
String headless = RedisTools.get("headless");
- if("true".equals(headless)) {
+ if("true".equals(headless)||WebClient.headless) {
options.addArguments("--headless");
}
options.addArguments("--no-sandbox");