Merge pull request 'dev_该合并了' (#8) from dev_ into master

Reviewed-on: #8
This commit is contained in:
yutou 2024-01-17 17:23:44 +08:00
commit 3b52742ac1
59 changed files with 2015 additions and 268 deletions

17
KFCFactory.json Normal file
View File

@ -0,0 +1,17 @@
{
"8.9.63": {
"base_url": "http://192.168.31.88:7400",
"type": "fuqiuluo/unidbg-fetch-qsign",
"key": "114514"
},
"0.1.0": {
"base_url": "http://127.0.0.1:8888",
"type": "kiliokuara/magic-signer-guide",
"server_identity_key": "vivo50",
"authorization_key": "kfc"
},
"8.8.88": {
"base_url": "http://127.0.0.1:80",
"type": "TLV544Provider"
}
}

Binary file not shown.

0
mvnw vendored Normal file → Executable file
View File

44
pom.xml
View File

@ -35,7 +35,7 @@
<dependency>
<groupId>net.mamoe</groupId>
<artifactId>mirai-core-jvm</artifactId>
<version>2.12.0</version>
<version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
@ -52,7 +52,7 @@
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.2.3</version>
<version>4.3.1</version>
</dependency>
@ -60,7 +60,7 @@
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.7</version>
<version>2.0.22</version>
</dependency>
<dependency>
@ -77,28 +77,46 @@
<scope>system</scope>
<systemPath>${project.basedir}/libs/json-jena-1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>com.fix-protocol-version.mirai2</groupId>
<artifactId>mirai2</artifactId>
<version>1.9.9</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/fix-protocol-version-1.9.9.mirai2.jar</systemPath>
</dependency>
<!-- QQ协议修复的依赖 -->
<dependency>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client</artifactId>
<version>2.12.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.2.1</version>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>4.2.1</version>
<version>4.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-api -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>4.2.1</version>
<version>4.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-remote-driver -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>4.2.1</version>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-http-jdk-client</artifactId>
<version>4.8.1</version>
</dependency>
@ -117,13 +135,13 @@
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.21.1</version>
<version>3.21.12</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
@ -138,6 +156,13 @@
<version>0.10.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.brotli/dec -->
<dependency>
<groupId>org.brotli</groupId>
<artifactId>dec</artifactId>
<version>0.1.2</version>
</dependency>
</dependencies>
<build>
@ -193,6 +218,7 @@
<!--使用-Dloader.path需要在打包的时候增加<layout>ZIP</layou
t>,不指定的话-Dloader.path不生效-->
<layout>ZIP</layout>
<includeSystemScope>true</includeSystemScope>
<!-- 指定该jar包启动时的主类[建议] -->
<mainClass>com.yutou.qqbot.QQBotApplication</mainClass>
</configuration>

View File

@ -0,0 +1,8 @@
package com.yutou.bilibili;
public class BaseAPI {
public static final String BASE_URL = "https://api.bilibili.com/";
public static final String MCBBS_PNG = "https://www.mcbbs.net/template/mcbbs/image/special_photo_bg.png";
public static final String ACCESS_TOKEN = "https://passport.bilibili.com/login/app/third";
}

View File

@ -0,0 +1,9 @@
package com.yutou.bilibili.api;
public class LiveAPI {
public static final String LIVE_SEND_DANMU="https://api.live.bilibili.com/msg/send";
public static final String LIVE_ROOM_INFO = "https://api.live.bilibili.com/room/v1/Room/get_info";
public static final String LIVE_TASK_PROGRESS = "https://api.live.bilibili.com/xlive/app-ucenter/v1/userTask/GetUserTaskProgress";
public static final String LIVE_SET_TASK_PROGRESS = "https://api.live.bilibili.com/xlive/app-ucenter/v1/userTask/UserTaskReceiveRewards";
}

View File

@ -0,0 +1,7 @@
package com.yutou.bilibili.api;
public class LoginAPI {
public static final String LOGIN_QRCODE = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate";
public static final String LOGIN_QRCODE_POLL="https://passport.bilibili.com/x/passport-login/web/qrcode/poll";
}

View File

@ -0,0 +1,9 @@
package com.yutou.bilibili.api;
public class MangaApi {
public static final String SIGN = "https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn";
public static final String LIST_PRODUCT_DATE = "https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/ListProduct";
public static final String USER_POINT = "https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/GetUserPoint";
public static final String PAY_MISSION = "https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/Exchange";
}

View File

@ -0,0 +1,7 @@
package com.yutou.bilibili.api;
public class SignApi {
public static final String LIVE_SIGN_COIN = "https://api.live.bilibili.com/xlive/revenue/v1/wallet/silver2coin";
public static final String LIVE_SIGN = "https://api.live.bilibili.com/xlive/web-ucenter/v1/sign/DoSign";
public static final String VIP_SIGN = "https://api.bilibili.com/pgc/activity/score/task/sign";
}

View File

@ -0,0 +1,10 @@
package com.yutou.bilibili.api;
public class UserApi {
@Deprecated
public static final String USER_INFO = "https://api.bilibili.com/x/space/acc/info";
public static final String USER_INFO_V2="https://api.bilibili.com/x/space/wbi/acc/info";
public static final String NAV = "https://api.bilibili.com/x/web-interface/nav";
}

View File

@ -0,0 +1,6 @@
package com.yutou.bilibili.api;
public class VideoApi {
public static final String VIDEO_AI = "https://api.bilibili.com/x/web-interface/view/conclusion/get";
}

View File

@ -69,14 +69,9 @@ public class AppController {
return "not message";
}
if (json.containsKey("image")) {
image = HttpTools.syncDownload(json.getString("image"), System.currentTimeMillis() + ".png");
image = HttpTools.syncDownload(json.getString("image"), System.currentTimeMillis() + ".png",true);
}
if (image != null) {
ret = QQBotManager.getInstance().sendMessage(image, json.getLong("qq"), json.getString("message"));
} else {
ret = QQBotManager.getInstance().sendMessage(json.getLong("qq"), json.getString("message"));
}
return ret==null?"message send fail":"message send success";
}

View File

@ -1,6 +1,7 @@
package com.yutou.qqbot.Controllers;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.BiliBili.BiliVideo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@ -17,7 +18,7 @@ public class BiliBiliController {
String url = json.getString("url");
boolean downDanmu = json.containsKey("danmu") && "on".equals(json.getString("danmu"));
boolean merge = json.containsKey("merge") && "on".equals(json.getString("merge"));
BiliVideo video = new BiliVideo();
BiliVideo video = new BiliVideo(QQBotManager.defQQ);
video.downVideo(url, downDanmu, merge);
}
).start();

View File

@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class QQBotApplication {
public static final String version="QQBot v.1.3.5.1";
public static final String version="QQBot v.1.6.2";
public static void main(String[] args) {
System.out.println("version = " + version);
SpringApplication.run(QQBotApplication.class, args);

View File

@ -6,15 +6,13 @@ import com.yutou.qqbot.Listeners.QQMessageListener;
import com.yutou.qqbot.utlis.*;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.BotFactory;
import net.mamoe.mirai.contact.Group;
import net.mamoe.mirai.auth.BotAuthorization;
import net.mamoe.mirai.event.GlobalEventChannel;
import net.mamoe.mirai.message.MessageReceipt;
import net.mamoe.mirai.message.data.Image;
import net.mamoe.mirai.message.data.MessageChain;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import net.mamoe.mirai.message.data.*;
import net.mamoe.mirai.utils.BotConfiguration;
import net.mamoe.mirai.utils.ExternalResource;
import xyz.cssxsh.mirai.tool.FixProtocolVersion;
import java.io.File;
import java.io.IOException;
@ -24,6 +22,7 @@ import java.util.Objects;
public class QQBotManager {
public static Long defGroup = 891655174L;
public static Long defQQ = 583819556L;
private static QQBotManager botManager = null;
@ -43,14 +42,39 @@ public class QQBotManager {
private void init() {
new Thread(new Runnable() {
private void reset() {
try {
Log.i("QQBot", "签名加密服务未启动,1分钟后重试");
Thread.sleep(60 * 1000);
init();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String test = HttpTools.get("http://192.168.31.88:7400/");
try {
JSONObject json = JSONObject.parseObject(test);
if (json.getInteger("code") != 0) {
reset();
return;
}
} catch (Exception e) {
reset();
return;
}
long qq = ConfigTools.load(ConfigTools.CONFIG, "qq_number", Long.class);
String password = ConfigTools.load(ConfigTools.CONFIG, "qq_password", String.class);
System.out.println("qq = " + qq);
System.out.println("password = " + password);
FixProtocolVersion.load(BotConfiguration.MiraiProtocol.ANDROID_PAD);
bot = BotFactory.INSTANCE.newBot(qq, password, new BotConfiguration() {
{
setProtocol(MiraiProtocol.ANDROID_PAD);
fileBasedDeviceInfo("qq_bot_devices_info.json");
if ("nas".equals(ConfigTools.load(ConfigTools.CONFIG, "model"))) {
@ -95,6 +119,9 @@ public class QQBotManager {
}
private Image getImage(File file, Long qq) {
if (file == null) {
return null;
}
if (bot != null) {
ExternalResource resource = ExternalResource.create(file);
Image image;
@ -147,8 +174,10 @@ public class QQBotManager {
public MessageReceipt<?> sendMessage(Long group, MessageChainBuilder builder) {
if (bot != null) {
if (QQNumberManager.getManager().isGroup(group)) {
System.out.println("发群");
return Objects.requireNonNull(bot.getGroup(group)).sendMessage(builder.asMessageChain());
} else {
System.out.println("发个人");
return Objects.requireNonNull(bot.getFriend(group)).sendMessage(builder.asMessageChain());
}
}
@ -170,6 +199,15 @@ public class QQBotManager {
if (image != null) {
builder.append(image);
}
List<String> list = PatternTools.getQQ(text);
if (!list.isEmpty()) {
for (String _qq : list) {
String[] tmp = text.split(_qq);
builder.append(tmp[0]);
builder.append(new At(Long.parseLong(_qq.replace("@", ""))));
text = text.replace(tmp[0] + _qq, "");
}
}
builder.append(text);
if (QQNumberManager.getManager().isGroup(qq)) {
return Objects.requireNonNull(bot.getGroup(qq)).sendMessage(builder.asMessageChain());

View File

@ -113,6 +113,7 @@ public class QQNumberManager {
return false;
}
public boolean isExistsPower(Long qq, String... power){
//1
if(RedisTools.exists(qq,null)){
JSONObject json=JSON.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("power");

View File

@ -0,0 +1,98 @@
package com.yutou.qqbot.bilibili;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class AppUserTask {
private long isSurplus;
private long status;
private long progress;
private long target;
private Wallet wallet;
private List<WeekTask> weekTask = new ArrayList<>();
private long weekTotal;
private long weekGroup;
private DayTask dayTask;
public List<WeekTask> getWeekTask() {
if (weekTask == null) {
weekTask = new ArrayList<>();
}
return weekTask;
}
public static String toMessageFormat(AppUserTask oldTask, AppUserTask newTask) {
StringBuilder sb = new StringBuilder();
sb.append("当前电池数量:").append(String.format("%.2f → %.2f",
(double) oldTask.wallet.gold / 100,
(double) newTask.wallet.gold / 100)
).append("\n");
sb.append("当前银瓜子数量:").append(newTask.wallet.silver).append("\n");
sb.append("每日领取电池:").append(newTask.dayTask.toMessageFormat()).append("\n");
if (newTask.weekTask != null && !newTask.getWeekTask().isEmpty()) {
newTask.weekTask.forEach(task -> sb.append(task.toMessageFormat(newTask.weekTotal)).append("\n"));
}
return sb.toString();
}
public String toMessageFormat() {
StringBuilder sb = new StringBuilder();
sb.append("当前电池数量:").append(String.format("%.2f", (double) wallet.gold / 100)).append("\n");
sb.append("当前银瓜子数量:").append(wallet.silver).append("\n");
sb.append("每日领取电池:").append(dayTask.toMessageFormat()).append("\n");
weekTask.forEach(task -> sb.append(task.toMessageFormat(weekTotal)).append("\n"));
return sb.toString();
}
@Data
public static class DayTask {
private int status;
private long progress;
private long target;
public String toMessageFormat() {
return switch (getStatus()) {
case 0 -> "不可领取,需要发送弹幕数:" + getTarget() + ",进度:" + getProgress();
case 1 -> "进行中,需要发送弹幕数:" + getTarget() + ",进度:" + getProgress();
case 2 -> "可领取";
case 3 -> "已领取";
default -> "未知状态:" + this;
};
}
}
@Data
public static class Wallet {
private long gold;
private long silver;
}
// WeekTask.java
@Data
public static class WeekTask {
private long rewardNum;
private long minimalDay;
private int status;
private int id;
public String toMessageFormat(long totalNum) {
return switch (getStatus()) {
case 0 ->
"任务id:" + id + ",不可领取, 进度天数:" + totalNum + ",需要天数:" + minimalDay + ",任务奖励电池:" + rewardNum;
case 2 -> "任务id:" + id + ":可领取" + ",任务奖励电池:" + rewardNum;
case 3 -> "任务id:" + id + ":已领取" + ",任务奖励电池:" + rewardNum;
default -> "未知状态:" + this;
};
}
}
}

View File

@ -0,0 +1,191 @@
package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.BaseAPI;
import com.yutou.bilibili.api.LiveAPI;
import com.yutou.bilibili.api.VideoApi;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.BiliBili.BiliVideo;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.BiliBiliWbiSign;
import com.yutou.qqbot.utlis.HttpTools;
import javax.net.ssl.HttpsURLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class BiliBiliAppUtils {
private static final String AppKey = "1d8b6e7d45233436";
private static final String AppSec = "560c52ccd288fed045859ed18bffd973";
private BiliBiliUtils biliUtils;
public BiliBiliAppUtils(Long qq) {
biliUtils = BiliBiliUtils.getInstance(qq);
}
public String getAccessToken() {
try {
String tmpUrl = BaseAPI.MCBBS_PNG;
String sign = AppTools.getMD5("api=" + tmpUrl + AppSec);
JSONObject get = biliUtils.http_get(BaseAPI.ACCESS_TOKEN+"?appkey=" + AppKey + "&api=" + tmpUrl + "&sign=" + sign);
assert get != null;
String uri = get.getJSONObject("data").getString("confirm_uri");
HttpsURLConnection connection = biliUtils.getBiliHttpGet(uri, biliUtils.getCookie());
connection.connect();
if (connection.getResponseCode() == 200) {
Map<String, String> params = HttpTools.getUrlParams(connection.getURL().toString());
return params.get("access_key");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Map<String, String> sign(Map<String, String> map) {
map.putAll(getDefaultBody());
map = sort(map);
StringBuilder builder = new StringBuilder();
for (String key : map.keySet()) {
builder.append(key).append("=").append(map.get(key)).append("&");
}
String param = builder.substring(0, builder.length() - 1);
map.put("sign", AppTools.getMD5(param + AppSec));
return map;
}
private Map<String, String> getDefaultBody() {
Map<String, String> map = new TreeMap<>();
map.put("access_key", getAccessToken());
map.put("actionKey", "appkey");
map.put("appkey", AppKey);
map.put("build", "7120200");
map.put("c_locale", "zh_CN");
map.put("channel", "xiaomi_cn_tv.danmaku.bili_20210930");
map.put("device", "android");
map.put("disable_rcmd", "0");
map.put("mobi_app", "android");
map.put("platform", "android");
map.put("s_locale", "zh_CN");
map.put("statistics", URLEncoder.encode("{\"appId\":1,\"platform\":3,\"version\":\"7.12.0\",\"abtest\":\"\"}", Charset.defaultCharset()));
map.put("ts", (System.currentTimeMillis() / 1000) + "");
return map;
}
private LinkedHashMap<String, String> sort(Map<String, String> map) {
return new LinkedHashMap<>(new TreeMap<>(map));
}
private Map<String, String> getHeaderMap() {
String md5_1 = AppTools.getMD5(System.currentTimeMillis() + "");
String md5_2 = AppTools.getMD5(System.currentTimeMillis() + "");
String trace_id = md5_1 + ":" + md5_2.substring(0, 16) + ":0:0";
Map<String, String> map = new TreeMap<>();
map.put("x-bili-mid", "96300");
map.put("x-bili-trace-id", trace_id);
map.put("x-bili-aurora-zone", "");
map.put("x-bili-aurora-eid", "WFICRlE=");
map.put("APP-KEY", "android64");
map.put("bili-http-engine", "cronet");
map.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
map.put("session_id", md5_1.substring(0, 8));
map.put("Host", "api.live.bilibili.com");
map.put("Connection", "keep-alive");
map.put("fp_local", md5_1 + md5_2);
map.put("fp_remote", md5_1 + md5_2);
map.put("env", "prod");
map.put("buvid", "XUF43FCF17D1747514C79C6D3D43B64C8D1B2");
map.put("Accept-Encoding", "gzip, deflate, br");
map.put("User-Agent", "Mozilla/5.0 BiliDroid/7.4.0 (bbcallen@gmail.com) os/android model/22061218C mobi_app/android build/7040300 channel/xiaomi_cn_tv.danmaku.bili_20210930 innerVer/7040310 osVer/12 network/2");
return map;
}
public AppUserTask getTaskProgress() {
JSONObject task = biliUtils.http_get(LiveAPI.LIVE_TASK_PROGRESS);
System.out.println("task = " + task);
assert task != null;
return task.getObject("data", AppUserTask.class);
}
private void setUserTaskProgress(int index) {
Map<String, String> map = new TreeMap<>();
map.put("target_id", "33989");
map.put("reward_index", index + "");
JSONObject httpGet = biliUtils.http(
LiveAPI.LIVE_SET_TASK_PROGRESS,
BiliBiliUtils.HTTP.POST,
HttpTools.toUrlParams(sign(map)),
getHeaderMap(),
BiliBiliUtils.RET_MODEL.JSON
);
System.out.println("任务 " + index + " :" + httpGet);
}
public AppUserTask startAppTask() {
AppUserTask task = getTaskProgress();
if (task.getDayTask().getStatus() == 2) {
setUserTaskProgress(0);
}
List<AppUserTask.WeekTask> taskList = task.getWeekTask();
taskList.forEach(weekTask -> {
if (weekTask.getStatus() == 2) {
setUserTaskProgress(weekTask.getId());
}
});
return task;
}
public static String getVideoAI(String url){
if(url.startsWith("https://b23.tv")){
url=b23ToUrl(url);
}
JSONObject videoInfo = new BiliVideo().getVideoInfo(url);
if(videoInfo==null){
return null;
}
String cid = videoInfo.getJSONObject("data").getString("cid");
TreeMap<String,String> body=new TreeMap<>();
body.put("cid",cid);
body.put("up_mid",videoInfo.getJSONObject("data").getJSONObject("owner").getString("mid"));
body.put("bvid",videoInfo.getJSONObject("data").getString("bvid"));
BiliBiliWbiSign.getWbiSign(body);
JSONObject object = BiliBiliUtils.getInstance(QQBotManager.defQQ)
.http_get(VideoApi.VIDEO_AI +"?"+HttpTools.toUrlParams(body));
if(object.getInteger("code")==0){
if(object.getJSONObject("data").getInteger("code")==0) {
return object.getJSONObject("data").getJSONObject("model_result").getString("summary");
}else{
return "没得省流";
}
}
return null;
}
public static String b23ToUrl(String url){
try {
HttpsURLConnection connection = BiliBiliUtils.getInstance(QQBotManager.defQQ).getBiliHttpGet(url, BiliBiliUtils.getInstance(QQBotManager.defQQ).getCookie());
connection.setInstanceFollowRedirects(false);
connection.connect();
if(connection.getResponseCode()==302){
connection.setConnectTimeout(5000);
return connection.getHeaderField("Location");
}
return connection.getURL().toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws Exception {
BiliBiliWbiSign.updateRawWbiKey();
String url="https://b23.tv/NtqDorB?share_medium=android&share_source=qq&bbid=XUDCA4BDD60B5853ACDC17794BFAEF91F874A&ts=1705470976484";
// url="https://www.bilibili.com/video/BV1fw411E75p/?buvid=XUDCA4BDD60B5853ACDC17794BFAEF91F874A&from_spmid=tm.recommend.0.0&is_story_h5=false&mid=7G8S%2B4e7nx6XSaU3oMQKXA%3D%3D&p=1&plat_id=116&share_from=ugc&share_medium=android&share_plat=android&share_session_id=ab27db6e-47a5-43b5-b0ec-b027bcfdeccc&share_source=QQ&share_tag=s_i&spmid=main.ugc-video-detail.0.0&timestamp=1705470976&unique_k=NtqDorB&up_id=1156809979";
String ai = getVideoAI(url);
System.out.println("ai = " + ai);
}
}

View File

@ -2,6 +2,8 @@ package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.api.MangaApi;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.utlis.HttpTools;
import lombok.Data;
@ -12,23 +14,28 @@ import java.util.Timer;
import java.util.TimerTask;
public class BiliBiliManga {
public BiliBiliManga(long qq) {
biliUtils = BiliBiliUtils.getInstance(qq);
}
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));
return BiliBiliUtils.getInstance(QQBotManager.defQQ).http_post(MangaApi.SIGN, HttpTools.toUrlParams(body));
}
private static JSONObject getListProductDate() {
return BiliBiliUtils.http_post("https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/ListProduct", "");
return BiliBiliUtils.getInstance(QQBotManager.defQQ).http_post(MangaApi.LIST_PRODUCT_DATE, "");
}
private static boolean isPayMission = false;
private static Product missionProduct = new Product();
private static Timer mission = null;
private final List<ObjectInterface> anInterface = new ArrayList<>();
private static BiliBiliUtils biliUtils = null;
private ObjectInterface anInterface = null;
public void addInterface(ObjectInterface objectInterface) {
anInterface.add(objectInterface);
anInterface = objectInterface;
}
public static boolean isPayMission() {
@ -36,7 +43,7 @@ public class BiliBiliManga {
}
public static String getMission() {
return missionProduct+" 兑换数量:"+missionProduct.getPayAmount();
return missionProduct + " 兑换数量:" + missionProduct.getPayAmount();
}
public static List<Product> getListProduct() {
@ -59,7 +66,7 @@ public class BiliBiliManga {
}
public static int getMyPoint() {
JSONObject user = BiliBiliUtils.http_post("https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/GetUserPoint", "");
JSONObject user = biliUtils.http_post(MangaApi.USER_POINT, "");
if (user != null && user.getInteger("code") == 0) {
return user.getJSONObject("data").getInteger("point");
}
@ -70,7 +77,12 @@ public class BiliBiliManga {
JSONObject json = new JSONObject();
if (isPayMission) {
json.put("code", 2);
json.put("msg", "任务正在进行:" +getMission());
json.put("msg", "任务正在进行:" + getMission());
return json;
}
if (biliUtils == null) {
json.put("code", -1);
json.put("msg", "B站未登录");
return json;
}
int userPoint = getMyPoint();
@ -107,9 +119,9 @@ public class BiliBiliManga {
if (num == 0) {
json.put("code", 3);
json.put("msg", "商品无货,正在抢购");
}else {
} else {
json.put("code", 0);
json.put("msg", "任务创建成功:"+missionProduct+" 兑换数量:"+num);
json.put("msg", "任务创建成功:" + missionProduct + " 兑换数量:" + num);
}
return json;
}
@ -122,24 +134,18 @@ public class BiliBiliManga {
mission.schedule(new TimerTask() {
@Override
public void run() {
JSONObject post = BiliBiliUtils.http_post("https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/Exchange", HttpTools.toUrlParams(data));
JSONObject post = biliUtils.http_post(MangaApi.PAY_MISSION, HttpTools.toUrlParams(data));
if (post == null) {
for (ObjectInterface objectInterface : anInterface) {
objectInterface.out("网络请求失败,请查看日志");
}
anInterface.out("网络请求失败,请查看日志");
cancel();
return;
}
if (post.getInteger("code") == 0) {
for (ObjectInterface mInt : anInterface) {
mInt.out("兑换成功,任务已取消");
}
anInterface.out("兑换成功,任务已取消");
isPayMission = false;
cancel();
} else {
for (ObjectInterface objectInterface : anInterface) {
objectInterface.out("[" + post.getInteger("code") + "]" + post.getString("msg"));
}
anInterface.out("[" + post.getInteger("code") + "]" + post.getString("msg"));
}
}
}, 0, 1000);
@ -155,6 +161,8 @@ public class BiliBiliManga {
}
public static void main(String[] args) {
// System.out.println(BiliBiliManga.sign());
BiliBiliUtils.getInstance(583819556L).sendLiveDanmu(33989,"学学这个");
}
@Data

View File

@ -2,8 +2,14 @@ package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.api.LiveAPI;
import com.yutou.bilibili.api.LoginAPI;
import com.yutou.bilibili.api.SignApi;
import com.yutou.bilibili.api.UserApi;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.utlis.*;
import org.brotli.dec.BrotliInputStream;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
@ -13,9 +19,13 @@ import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.zip.GZIPInputStream;
public class BiliBiliUtils {
private static long oldBiliBiliHttpTime = 0;
private long qq;
private long oldBiliBiliHttpTime = 0;
public enum HTTP {
POST, GET
@ -25,22 +35,77 @@ public class BiliBiliUtils {
BYTE, JSON
}
public synchronized static JSONObject http_get(String url) {
public BiliBiliUtils(long qq) {
this.qq = qq;
}
public static BiliBiliUtils getInstance(long qq) {
return new BiliBiliUtils(qq);
}
public synchronized JSONObject http_get(String url) {
try {
// Log.i("调用url = "+url);
Log.i("调用url = " + url);
HttpsURLConnection connection = getBiliHttpGet(url, getCookie());
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = 0, size;
int len;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
String str = outputStream.toString(StandardCharsets.UTF_8);
outputStream.close();
try {
return JSON.parseObject(str);
} 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 JSONObject http_login_getSid(String url) {
try {
Log.i("调用url = " + url);
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
setConnection(null, connection);
connection.setRequestMethod("GET");
connection.connect();
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
List<String> cookie = null;
if (connection.getHeaderFields().containsKey("Set-Cookie")) {
cookie = connection.getHeaderFields().get("Set-Cookie");
}
String str = outputStream.toString(StandardCharsets.UTF_8);
outputStream.close();
try {
JSONObject json = JSON.parseObject(str);
if (cookie != null) {
StringBuilder ck = new StringBuilder();
for (String key : cookie) {
ck.append(";").append(key);
}
json.put("cookie", ck.toString());
}
return json;
} catch (Exception e) {
JSONObject json = new JSONObject();
@ -59,11 +124,15 @@ public class BiliBiliUtils {
return null;
}
public static JSONObject http_post(String url, String body) {
public JSONObject http_post(String url, String body) {
return http(url, HTTP.POST, body, RET_MODEL.JSON);
}
public static <T> T http(String url, HTTP model, String body, RET_MODEL ret_model) {
public <T> T http(String url, HTTP model, String body, RET_MODEL ret_model) {
return http(url, model, body, null, ret_model);
}
public <T> T http(String url, HTTP model, String body, Map<String, String> headers, RET_MODEL ret_model) {
JSONObject json = null;
BufferedInputStream stream = null;
ByteArrayOutputStream outputStream = null;
@ -81,9 +150,23 @@ public class BiliBiliUtils {
if (model == HTTP.POST) {
connection = getBiliHttpPost(url, getCookie());
} else {
if (body != null) {
if (url.contains("?")) {
url += "&" + body;
} else {
url += "?" + body;
}
body = null;
}
connection = getBiliHttpGet(url, getCookie());
}
if (headers != null) {
for (String key : headers.keySet()) {
connection.setRequestProperty(key, headers.get(key));
}
} else {
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
}
if (!StringUtils.isEmpty(body)) {
connectionOutputStream = connection.getOutputStream();
@ -94,7 +177,13 @@ public class BiliBiliUtils {
if (connection.getResponseCode() == 400) {
return null;
}
if (connection.getContentEncoding() != null && connection.getContentEncoding().contains("gzip")) {
stream = new BufferedInputStream(new GZIPInputStream(connection.getInputStream()));
} else if (connection.getContentEncoding() != null && connection.getContentEncoding().contains("br")) {
stream = new BufferedInputStream(new BrotliInputStream(connection.getInputStream()));
} else {
stream = new BufferedInputStream(connection.getInputStream());
}
outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = 0, size;
@ -142,12 +231,11 @@ public class BiliBiliUtils {
return null;
}
public static String getCookie() {
if (StringUtils.isEmpty(ConfigTools.readFile(new File("bilibili.cookie")))) {
public String getCookie() {
if (StringUtils.isEmpty(ConfigTools.readFile(new File(qq + "_bilibili.cookie")))) {
return "";
}
JSONObject json = JSON.parseObject(ConfigTools.readFile(new File("bilibili.cookie")));
JSONObject json = JSON.parseObject(ConfigTools.readFile(new File(qq + "_bilibili.cookie")));
StringBuilder builder = new StringBuilder();
for (String s : json.keySet()) {
builder.append(s).append("=").append(json.getString(s)).append(";");
@ -156,7 +244,7 @@ public class BiliBiliUtils {
return builder.toString();
}
public static HttpURLConnection getBiliHttpPost(String url, String cookie) throws Exception {
public HttpURLConnection getBiliHttpPost(String url, String cookie) throws Exception {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
@ -173,7 +261,7 @@ public class BiliBiliUtils {
return connection;
}
public static HttpsURLConnection getBiliHttpGet(String url, String cookie) throws IOException {
public HttpsURLConnection getBiliHttpGet(String url, String cookie) throws IOException {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
@ -182,16 +270,18 @@ public class BiliBiliUtils {
oldBiliBiliHttpTime = System.currentTimeMillis();
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
if (cookie != null) {
setConnection(cookie, connection);
}
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
return connection;
}
public static File download(final String url, final String saveName, boolean isProxy) {
public File download(final String url, final String saveName, boolean isProxy) {
File jar = null;
try {
File savePath = new File(HttpTools.downloadPath+saveName);
File savePath = new File(HttpTools.downloadPath + saveName);
Proxy proxy = null;
if (!savePath.exists()) {
savePath.mkdirs();
@ -240,7 +330,7 @@ public class BiliBiliUtils {
return null;
}
public static void download_ffmpeg(final List<String> url, final String saveName) {
public void download_ffmpeg(final List<String> url, final String saveName) {
new Thread(() -> {
StringBuilder builder = new StringBuilder();
builder.append(ConfigTools.load(ConfigTools.CONFIG, "ffmpeg", String.class)).append(" ");
@ -274,19 +364,21 @@ public class BiliBiliUtils {
}
private static void setConnection(String cookie, HttpURLConnection connection) {
private void setConnection(String cookie, HttpURLConnection connection) {
connection.addRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
connection.addRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
connection.addRequestProperty("Cache-Control", "max-age=0");
connection.setRequestProperty("Referer", "https://www.bilibili.com");
connection.addRequestProperty("Connection", "keep-alive");
connection.addRequestProperty("Upgrade-Insecure-Requests", "1");
if (!StringUtils.isEmpty(cookie)) {
connection.addRequestProperty("Cookie", cookie);
}
connection.addRequestProperty("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");
public JSONObject getLoginInfo() {
JSONObject jsonObject = http_get(UserApi.NAV);
if (jsonObject == null) {
jsonObject = new JSONObject();
jsonObject.put("code", "-1");
@ -294,4 +386,59 @@ public class BiliBiliUtils {
}
return jsonObject;
}
public static void main(String[] args) {
/* String url="https://xy218x85x123x8xy.mcdn.bilivideo.cn:4483/upgcxcode/12/12/17281212/17281212-16-80.flv?e=ig8euxZM2rNcNbNBhbdVhwdlhbUghwdVhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1660538573&gen=playurlv2&os=mcdn&oi=2936701972&trid=00006f9623cac1514d8ea18fba3a15a756cau&mid=96300&platform=pc&upsig=25ddd1da610960e8e1d2e80dc97c2361&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform&mcdnid=11000101&bvc=vod&nettype=0&orderid=0,2&agrr=1&bw=253116&logo=A0000400&requestFrom=BILIBILI_HELPER_2.5.8";
File file=download(url,"16.mp4",false);
System.out.println("file.getAbsolutePath() = " + file.getAbsolutePath());*/
/* System.out.println(getLiveRoom(42062));
System.out.println("--------------------------------------------");
System.out.println(getUserInfo(730732));*/
JSONObject sign = new BiliBiliUtils(583819556).getUserInfo(96300);
System.out.println("sign = " + sign);
}
public boolean sendLiveDanmu(long roomId, String msg) {
JSONObject body = new JSONObject();
body.put("msg", msg);
body.put("roomid", roomId);
body.put("color", 16777215);
body.put("fontsize", 25);
body.put("rnd", System.currentTimeMillis() / 1000);
body.put("csrf", BiliLogin.getCookieToken(qq));
body.put("csrf_token", BiliLogin.getCookieToken(qq));
JSONObject post = http_post(LiveAPI.LIVE_SEND_DANMU, HttpTools.toUrlParams(body));
return post.getInteger("code") == 0;
}
public String liveSignIn() {
//{"code":0,"data":{"coin":1,"gold":19500,"silver":106394,"tid":"Silver2Coin22101413201169763005873"},"message":"兑换成功"}
JSONObject body = new JSONObject();
body.put("csrf", BiliLogin.getCookieToken(qq));
body.put("csrf_token", BiliLogin.getCookieToken(qq));
JSONObject toCoin = http_post(SignApi.LIVE_SIGN_COIN, HttpTools.toUrlParams(body));
JSONObject liveSign = http_get(SignApi.LIVE_SIGN);
JSONObject vipSign = http_post(SignApi.VIP_SIGN, null);
return "银瓜子兑换硬币:" + toCoin.getString("message") + "|" + "直播签到:" + liveSign.getString("message") + "|大会员中心签到:" + vipSign.getString("message");
}
public JSONObject getLiveRoom(int roomId) {
JSONObject body = new JSONObject();
body.put("room_id", roomId);
body.put("csrf", BiliLogin.getCookieToken(qq));
body.put("csrf_token", BiliLogin.getCookieToken(qq));
return http_post(LiveAPI.LIVE_ROOM_INFO, HttpTools.toUrlParams(body));
}
public JSONObject getUserInfo(int mid) {
TreeMap<String, String> body = new TreeMap<>();
body.put("mid", mid + "");
BiliBiliWbiSign.getWbiSign(body);
return http_get(UserApi.USER_INFO_V2 + "?" + HttpTools.toUrlParams(body));
}
public boolean checkLiveRoom(int roomId) {
JSONObject post = getLiveRoom(roomId);
return post.getInteger("code") == 0;
}
}

View File

@ -3,77 +3,108 @@ package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.bilibili.api.LoginAPI;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.utlis.*;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
public class BiliLogin {
BiliBiliUtils biliUtils;
private long qq;
public JSONObject login(){
JSONObject login= JSON.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();
public BiliLogin(Long qq) {
biliUtils = BiliBiliUtils.getInstance(qq);
this.qq = qq;
}
public JSONObject login() {
JSONObject login = JSON.parseObject(HttpTools.get(LoginAPI.LOGIN_QRCODE));
JSONObject json = new JSONObject();
System.out.println("login = " + login);
json.put("code", login.getInteger("code"));
json.put("url", login.getJSONObject("data").getString("url"));
new Thread(() -> waitLogin(login.getJSONObject("data").getString("qrcode_key"))).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;
public void loginAsQQ() {
String url = login().getString("url");
File code = QRCodeUtils.createQRCode("bili_login", url);
QQBotManager.getInstance().sendMessage(code, qq, "B站未登录,请扫码登陆后再试");
}
public void waitLogin(String oauthKey) {
long time = System.currentTimeMillis();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
if((System.currentTimeMillis()-time)>5*60*1000){
String bd = "gourl=https%3A%2F%2Fpassport.bilibili.com%2Fajax%2FminiLogin%2Fredirect&oauthKey=" + oauthKey;
if ((System.currentTimeMillis() - time) > 5 * 60 * 1000) {
cancel();
return;
}
JSONObject json=JSON.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<String,String> map=HttpTools.getUrlParams(_url);
JSONObject json = biliUtils.http_login_getSid(LoginAPI.LOGIN_QRCODE_POLL + "?qrcode_key=" + oauthKey);
Log.i("B站登陆", json.toJSONString());
if (json.getInteger("code") == 0 && json.getJSONObject("data").getInteger("code") == 0) {
JSONObject cookie=new JSONObject();
JSONArray array=new JSONArray();
for (String key : map.keySet()) {
cookie.put(key,map.get(key));
String[] split = json.getString("cookie").split(";");
JSONObject ck = new JSONObject();
for (String string : split) {
if (!ck.containsKey(string) && !StringUtils.isEmpty(string) && string.contains("=")) {
String key = string.split("=")[0].trim();
String value = string.split("=")[1].trim();
if (key.contains("Expires")) {
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMMM yyyy HH:mm:ss z", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getDefault());
Date date = sdf.parse(value, new ParsePosition(0));
value = String.valueOf(date.getTime() / 1000);
}
System.out.println(array);
JSONObject tmp=BiliBiliUtils.http_post(_url,"");
System.out.println("tmp = " + tmp);
if(tmp==null){
cancel();
return;
ck.put(key, value);
}
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());
}
ck.put("gourl", bd);
ConfigTools.saveFile(new File(qq + "_bilibili.cookie"), ck.toJSONString());
cancel();
}
}
},0,3000);
}, 1000, 3000);
}
public boolean testLogin(){
JSONObject jsonObject = BiliBiliUtils.getLoginInfo();
return jsonObject.getInteger("code")==0;
public boolean testLogin() {
if (biliUtils == null) {
return false;
}
JSONObject jsonObject = biliUtils.getLoginInfo();
return jsonObject.getInteger("code") == 0;
}
public static String getCookieToken(Long qq) {
if (StringUtils.isEmpty(ConfigTools.readFile(new File(qq + "_bilibili.cookie")))) {
return null;
}
JSONObject json = JSON.parseObject(ConfigTools.readFile(new File(qq + "_bilibili.cookie")));
return json.getString("bili_jct");
}
public static void main(String[] args) {
BiliLogin login = new BiliLogin();
public static void main(String[] args) throws ParseException {
String http = "{\"code\":0,\"message\":\"0\",\"ttl\":1,\"data\":{\"url\":\"https://passport.biligame.com/x/passport-login/web/crossDomain?DedeUserID=96300&DedeUserID__ckMd5=c506a12068157a3a&Expires=1720252437&SESSDATA=c383a8e0,1720252437,9ba5c*11CjCBp3_j-6zYtK27tzUVrmFZNgjyeDW6pcdfmRBJU5cVfz4OhVmujjKCZsGAkXL6ll8SVnplZ2JONlBleHdFOGgzUzNJYUxIbzJwRVhTYVM2LWVuQnJyQVQxQnRWTUFZbUYybV95Y1RELTdGeF9mNlpXV3RDTjdsMVBaYkhxZGZyblRkTUJCMGV3IIEC&bili_jct=e786885293c24eb7198dc0538b56d6d8&gourl=https%3A%2F%2Fwww.bilibili.com\",\"refresh_token\":\"347b83e7c4a1e24f4681f06f28f71b11\",\"timestamp\":1704700437058,\"code\":0,\"message\":\"\"},\"cookie\":\";SESSDATA=c383a8e0%2C1720252437%2C9ba5c%2A11CjCBp3_j-6zYtK27tzUVrmFZNgjyeDW6pcdfmRBJU5cVfz4OhVmujjKCZsGAkXL6ll8SVnplZ2JONlBleHdFOGgzUzNJYUxIbzJwRVhTYVM2LWVuQnJyQVQxQnRWTUFZbUYybV95Y1RELTdGeF9mNlpXV3RDTjdsMVBaYkhxZGZyblRkTUJCMGV3IIEC; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT; HttpOnly; Secure;bili_jct=e786885293c24eb7198dc0538b56d6d8; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT;DedeUserID=96300; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT;DedeUserID__ckMd5=c506a12068157a3a; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT;sid=ger7871m; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT\"}";
JSONObject body = JSON.parseObject(http);
BiliLogin login = new BiliLogin(583819556L);
boolean testLogin = login.testLogin();
System.out.println("testLogin = " + testLogin);
System.out.println(BiliBiliUtils.getInstance(583819556L).getLoginInfo());
//JSONObject json = login.login();
//System.out.println("json = " + json);
// QRCodeUtils.createQRCode("bili_login", json.getString("url"));
}
}

View File

@ -0,0 +1,30 @@
package com.yutou.qqbot.data.baidu;
import lombok.Data;
@Data
public class Message {
private String role = "user";
private String content;
public Message() {
}
public boolean checkIsUser() {
return "user".equals(role);
}
public static Message create(String message) {
return create(message, false);
}
public static Message create(String message, boolean isGTP) {
Message msg = new Message();
msg.content = message;
if (isGTP) {
msg.role = "assistant";
}
return msg;
}
}

View File

@ -0,0 +1,17 @@
package com.yutou.qqbot.data.baidu;
import lombok.Data;
@Data
public class ResponseMessage {
private String id;
private String object;
private long created;
private String result;
private boolean isTruncated;
private boolean needClearHistory;
private Message usage;
public ResponseMessage() {
}
}

View File

@ -0,0 +1,50 @@
package com.yutou.qqbot.data.bili;
import lombok.Data;
@Data
public class EPInfo {
private int code;
private String message;
private MediaResult result;
@Data
public static class MediaResult {
private Media media;
// getters and setters
}
@Data
public static class Media {
private String cover;
private String horizontal_picture;
private int media_id;
private NewEp new_ep;
private Rating rating;
private int season_id;
private String share_url;
private String title;
private int type;
private String type_name;
// getters and setters
}
@Data
public static class NewEp {
private int id;
private String index;
private String index_show;
// getters and setters
}
@Data
public static class Rating {
private int count;
private double score;
// getters and setters
}
}

View File

@ -30,6 +30,20 @@ public class AndroidDevice {
public double getHeight() {
return end.getY() - start.getY();
}
public void setEnabledRandom(boolean enabled) {
if(enabled){
start.setEnableRandomY(true);
start.setEnableRandomX(true);
end.setEnableRandomX(true);
end.setEnableRandomY(true);
}else{
start.setEnableRandomX(false);
start.setEnableRandomY(false);
end.setEnableRandomY(false);
end.setEnableRandomX(false);
}
}
}
}

View File

@ -23,6 +23,13 @@ public class Vector2D {
}
return x;
}
public double getNotRandomY() {
return y;
}
public double getNotRandomX() {
return x;
}
public double getY() {
if(isEnableRandomY()){

View File

@ -271,7 +271,7 @@ public class TurnipProphet extends Model {
out.append("网页版:").append("\n").append(url).append("\n");
out.append("祝好运 :)");
Log.i("TurnipProphet", out.toString());
Log.i("TurnipProphet", out.toString()+"\n 发送QQ"+sendQQ);
QQBotManager.getInstance().sendMessage(sendQQ, getMessage(out.toString()));
return prArray.getJSONObject(0).getString(TurnipData.MODEL);
}

View File

@ -0,0 +1,143 @@
package com.yutou.qqbot.models.BiliBili;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.bilibili.AppUserTask;
import com.yutou.qqbot.bilibili.BiliBiliAppUtils;
import com.yutou.qqbot.bilibili.BiliBiliUtils;
import com.yutou.qqbot.bilibili.BiliLogin;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.QRCodeUtils;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
import java.util.Set;
@UseModel
public class BiliBiliLive extends Model {
@Override
public boolean isUserPublic() {
return false;
}
@Override
public String[] getUsePowers() {
return new String[]{
Model.QQGroupCommands.BILI_LIVE_DANMU_LIST,
Model.QQGroupCommands.BILI_LIVE_DANMU_SEND,
QQGroupCommands.BILI_LIVE_DANMU_DEL
};
}
@Override
public String getModelName() {
return "BiliBili Live Sign in";
}
@Override
public synchronized void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("00:01:00".equals(time)) {
if (!new BiliLogin(QQBotManager.defQQ).testLogin()) {
new BiliLogin(QQBotManager.defQQ).loginAsQQ();
System.out.println(BiliBiliUtils.getInstance(QQBotManager.defQQ).getLoginInfo());
return;
}
signLive(QQBotManager.defQQ, qq);
}
}
private void signLive(long qq, long sendQQ) {
if (!new BiliLogin(qq).testLogin()) {
new BiliLogin(qq).loginAsQQ();
return;
}
BiliBiliUtils biliUtils = BiliBiliUtils.getInstance(qq);
QQBotManager.getInstance().sendMessage(sendQQ, biliUtils.liveSignIn());
Set<String> biliLive = RedisTools.list_get("bili_live");
StringBuilder builder = new StringBuilder();
for (String id : biliLive) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
boolean sign = biliUtils.sendLiveDanmu(Integer.parseInt(id), "打卡");
builder.append("BiliLiveSign").append(id).append(":").append(sign).append("\n");
}
QQBotManager.getInstance().sendMessage(sendQQ, builder.toString());
/* BiliBiliAppUtils appUtils = new BiliBiliAppUtils(QQBotManager.defQQ);
AppUserTask oldTask = appUtils.startAppTask();
AppUserTask newTask = appUtils.getTaskProgress();
builder = new StringBuilder();
builder.append("执行APP任务").append("\n").append(AppUserTask.toMessageFormat(oldTask, newTask));
QQBotManager.getInstance().sendMessage(sendQQ, builder.toString());*/
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (!msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_SEND) &&
!msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_DEL) &&
!msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_LIST)) {
return;
}
if (msg.equals(QQGroupCommands.BILI_LIVE_DANMU_SEND)) {
signLive(user, qq);
return;
}
BiliBiliUtils biliUtils = BiliBiliUtils.getInstance(isGroup ? event.getSource().getFromId() : qq);
StringBuilder message;
message = new StringBuilder();
try {
boolean isDel = false;
if (msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_DEL)) {
isDel = true;
msg = msg.replace(QQGroupCommands.BILI_LIVE_DANMU_DEL, "").trim();
} else if (msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_SEND)) {
msg = msg.replace(QQGroupCommands.BILI_LIVE_DANMU_SEND, "").trim();
} else {
msg = "0";
}
Integer roomId = Integer.parseInt(msg);
if (!new BiliLogin(qq).testLogin()) {
new BiliLogin(qq).loginAsQQ();
return;
}
if (biliUtils.checkLiveRoom(roomId) && roomId != 0) {
if (isDel && RedisTools.list_isExist("bili_live", roomId + "")) {
RedisTools.list_remove("bili_live", roomId + "");
message.append("直播签到删除成功").append("\n");
} else if (!RedisTools.list_isExist("bili_live", roomId + "")) {
RedisTools.list_add("bili_live", roomId + "");
message.append("直播签到添加成功").append("\n");
}
} else if (roomId != 0) {
message.append("直播签到操作失败\n");
}
} catch (Exception e) {
message = new StringBuilder("直播签到添加失败\n");
}
message.append("-----直播签到房间号-----\n");
Set<String> biliLive = RedisTools.list_get("bili_live");
for (String id : biliLive) {
message.append(id)
.append(":")
.append(biliUtils.getUserInfo(
biliUtils.getLiveRoom(Integer.parseInt(id))
.getJSONObject("data")
.getInteger("uid"))
.getJSONObject("data")
.getString("name"))
.append("\n");
}
QQBotManager.getInstance().sendMessage(qq, message.toString());
}
public static void main(String[] args) {
new BiliBiliLive().signLive(QQBotManager.defQQ, 0);
}
}

View File

@ -3,13 +3,14 @@ package com.yutou.qqbot.models.BiliBili;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.bilibili.*;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.StringUtils;
import com.yutou.qqbot.utlis.*;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.QuoteReply;
import java.io.File;
import java.io.FileWriter;
@ -23,10 +24,22 @@ public class BiliVideo extends Model {
public String downloadPath = "tmp";
List<DanmuData> danmuDatas = new ArrayList<>();
long danmuNextTime = 0;
private BiliBiliUtils biliUtils;
private long qq;
public BiliVideo(long qq) {
this.qq = qq;
biliUtils = BiliBiliUtils.getInstance(qq);
}
public BiliVideo() {
this.qq = QQBotManager.defQQ;
biliUtils = BiliBiliUtils.getInstance(qq);
}
@Override
public boolean isUserPublic() {
return false;
return true;
}
@Override
@ -39,12 +52,62 @@ public class BiliVideo extends Model {
return "B站视频下载";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (event.getMessage().serializeToMiraiCode().contains("mirai:app")) {
int id = event.getSource().getIds()[0];
String json = event.getMessage().get(1).contentToString();
System.out.println("id = " + id);
System.out.println("json = " + json);
RedisTools.set("qq_msg_id_" + id, json, 60 * 60 * 2);
} else if (isAt()) {
if (event.getMessage().get(1) instanceof QuoteReply) {
int id = ((QuoteReply) event.getMessage().get(1)).getSource().getIds()[0];
if (msg.contains("省流") || msg.contains("总结")) {
String value = onAIVideo(id);
if(!StringUtils.isEmpty(value)){
QQBotManager.getInstance().sendMessage(qq,value);
}
}
}
}
}
private String onAIVideo(int id) {
String string = RedisTools.get("qq_msg_id_" + id);
//RedisTools.remove("qq_msg_id_"+id);
String url = null;
if (StringUtils.isEmpty(string)) {
url = ((QuoteReply) event.getMessage().get(1)).getSource().getOriginalMessage().contentToString();
} else {
JSONObject json = JSONObject.parseObject(string);
if (json.containsKey("ver")) {
url = json.getJSONObject("meta").getJSONObject("detail_1").getString("qqdocurl");
}
}
if (StringUtils.isEmpty(url)) {
return "地址不正确";
}
if (url.startsWith("BV")) {
url = "https://www.bilibili.com/video/" + url.trim();
}
if (!url.startsWith("https://www.bilibili.com/video/") && !url.startsWith("https://b23.tv")) {
return "这是B站吗?";
}
String ai = BiliBiliAppUtils.getVideoAI(url.trim());
if (!StringUtils.isEmpty(ai)) {
return ai;
}
return "省流失败";
}
public void downVideo(String url) {
downVideo(url, true, false);
}
public void downVideo(String url, boolean downDanmu, boolean merge) {
if (!new BiliLogin().testLogin()) {
if (biliUtils == null || !new BiliLogin(qq).testLogin()) {
System.err.println("未登录");
return;
}
@ -196,19 +259,19 @@ public class BiliVideo extends Model {
if (tmp.exists()) {
return;
}
JSONObject http = BiliBiliUtils.http("https://api.bilibili.com/x/player/playurl?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.JSON);
JSONObject http = biliUtils.http("https://api.bilibili.com/x/player/playurl?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.JSON);
if (http.getInteger("code") == 0) {
JSONObject data = http.getJSONObject("data");
JSONObject dash = data.getJSONObject("dash");
JSONObject video = dash.getJSONArray("video").getJSONObject(0);
JSONObject audio = dash.getJSONArray("audio").getJSONObject(0);
File videoFile = BiliBiliUtils.download(video.getString("baseUrl"), eps.getString("title") + "_video.mp4", false);
File videoFile = biliUtils.download(video.getString("baseUrl"), eps.getString("title") + "_video.mp4", false);
if (videoFile == null) {
downVideo(json, eps);
return;
}
File audioFile = BiliBiliUtils.download(audio.getString("baseUrl"), eps.getString("title") + "_audio.mp3", false);
File audioFile = biliUtils.download(audio.getString("baseUrl"), eps.getString("title") + "_audio.mp3", false);
if (audioFile == null) {
videoFile.delete();
downVideo(json, eps);
@ -255,7 +318,7 @@ public class BiliVideo extends Model {
private List<VideoDanMu.DanmakuElem> getDanmu(JSONObject json) {
try {
byte[] http = BiliBiliUtils.http("https://api.bilibili.com/x/v2/dm/web/seg.so?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.BYTE);
byte[] http = biliUtils.http("https://api.bilibili.com/x/v2/dm/web/seg.so?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.BYTE);
VideoDanMu.DmSegMobileReply parse = VideoDanMu.DmSegMobileReply.parseFrom(http);
return parse.getElemsList();
} catch (Exception e) {
@ -298,13 +361,13 @@ public class BiliVideo extends Model {
}
public JSONObject getVideoInfo(String url) {
if (!new BiliLogin().testLogin()) {
if (!new BiliLogin(qq).testLogin()) {
System.err.println("未登录");
return null;
}
JSONObject json = buildJSON(url);
if (json != null) {
return BiliBiliUtils.http("https://api.bilibili.com/x/web-interface/view?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.JSON);
return biliUtils.http("https://api.bilibili.com/x/web-interface/view?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.JSON);
}
return null;
}
@ -334,10 +397,9 @@ public class BiliVideo extends Model {
return json;
}
public static void main(String[] args) {
BiliVideo video = new BiliVideo();
JSONObject login = new BiliLogin().login();
BiliVideo video = new BiliVideo(QQBotManager.defQQ);
JSONObject login = new BiliLogin(QQBotManager.defQQ).login();
System.out.println(login);
//岚少 480
//video.downVideo("https://www.bilibili.com/video/BV1Ps411m7pt?spm_id_from=333.999.0.0");
@ -353,7 +415,7 @@ public class BiliVideo extends Model {
//video.downVideo("https://www.bilibili.com/video/BV1qF411T7Vf?spm_id_from=444.41.list.card_archive.click");
//唐诱正片
//video.downVideo("https://www.bilibili.com/video/BV1L44y147zR?spm_id_from=333.999.0.0");// ep1
video.downVideo("https://www.bilibili.com/video/BV18L4y1H7rz?spm_id_from=333.999.0.0", true, false);// ep5
//video.downVideo("https://www.bilibili`.com/video/BV1Zu4y1B7DU/?spm_id_from=333.337.search-card.all.click", true, false);// ep5
// video.downVideo("https://www.bilibili.com/video/BV1SL411g7FS/?spm_id_from=333.788.recommend_more_video.0"); //all ig 1\5
// video.downVideo("https://www.bilibili.com/video/BV18L4y1H7rz?spm_id_from=333.999.0.0");
@ -361,6 +423,7 @@ public class BiliVideo extends Model {
// int a=16|2048;
// System.out.println("a = " + a);
//video.downDanmu(428855000L,976216102L,"【都市_情感】《唐可可的诱惑》第一集",1);
video.downVideo("https://www.bilibili.com/bangumi/play/ep776259", false, false);// ep5
System.out.println("事件结束");
}
}

View File

@ -32,7 +32,7 @@ public class BTDownload extends Model {
if(msg.startsWith("magnet:?xt=")){
String builder = "已添加下载磁链" ;
QQBotManager.getInstance().sendMessage(qq, builder);
String exec = String.format("transmission-remote -n yutou:34864394 -w %sdownload_tmp/%s -a \"%s\" "
String exec = String.format("qbittorrent-nox --save-path=%sdownload_tmp/%s \"%s\" "
,DownloadHomePath
, AppTools.getToDayTime()
, msg

View File

@ -0,0 +1,45 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.baidu.ResponseMessage;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.BaiduGPTManager;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class BaiduGPT extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[]{
QQGroupCommands.GPT,
QQGroupCommands.GPT_CLEAR
};
}
@Override
public String getModelName() {
return "百度文言一心GPT";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (msg.equals(QQGroupCommands.GPT_CLEAR)) {
BaiduGPTManager.getManager().clear();
QQBotManager.getInstance().sendMessage(qq, "已经失忆捏");
} else if (isAt()) {
if(msg.contains("省流")|| msg.contains("总结")){
return;
}
ResponseMessage message = BaiduGPTManager.getManager().sendMessage(String.valueOf(user), msg.replace("@2476945931", "").trim());
QQBotManager.getInstance().sendMessage(qq, message.getResult());
}
}
}

View File

@ -88,7 +88,7 @@ public class Bangumi extends Model {
return;
}
for (String img : imgs) {
File file = HttpTools.syncDownload(img.replace("http://", "https://"), key + ".jpg");
File file = HttpTools.syncDownload(img.replace("http://", "https://"), key + ".jpg",false);
files.add(file);
send(imgs.size(), qq, text);
}

View File

@ -0,0 +1,43 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_TIMEOUT;
@UseModel
public class MaoMaoWorkWaring extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[]{QQ_TIMEOUT};
}
@Override
public String getModelName() {
return "毛毛工作提醒";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(Integer.parseInt(AppTools.getHours())>=6 && event.getSource().getFromId() == 526306604
&& "false".equals(RedisTools.get("maomao_work_"+AppTools.getToDayTime(),"false"))){
MessageChainBuilder builder=new MessageChainBuilder();
builder.append(new QuoteReply(event.getMessage()));
builder.append("别水了,快去打工,没钱氪老婆了");
QQBotManager.getInstance().sendMessage(qq,builder);
RedisTools.set("maomao_work_"+AppTools.getToDayTime(),"true",20*60*60);
}
}
}

View File

@ -12,6 +12,7 @@ import com.yutou.qqbot.utlis.Log;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
@UseModel
public class Moyu extends Model {
@Override
@ -40,23 +41,25 @@ public class Moyu extends Model {
@Override
public synchronized void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("07:00:00".equals(time)) {
downloadImage(false,qq);
if ("09:50:00".equals(time)) {
downloadImage(false, qq);
}
if ("10:00:00".equals(time)) {
send(qq);
}
}
private void downloadImage(boolean isSend,Long qq) {
Log.i(this,"下载图片");
String ret = HttpTools.get("https://api.j4u.ink/v1/store/other/proxy/remote/moyu.json");
private void downloadImage(boolean isSend, Long qq) {
Log.i(this, "下载图片");
String ret = HttpTools.get("https://api.vvhan.com/api/moyu?type=json");
JSONObject json = JSON.parseObject(ret);
HttpTools.download(json.getJSONObject("data").getString("moyu_url"), AppTools.getToDayTime() + "_moyu.jpg", new DownloadInterface() {
HttpTools.download(json.getString("url"), AppTools.getToDayTime() + "_moyu.jpg", new DownloadInterface() {
int count = 3;
@Override
public void onDownload(File file) {
super.onDownload(file);
if(isSend){
if (isSend) {
send(qq);
}
}
@ -65,18 +68,26 @@ public class Moyu extends Model {
public void onError(Exception e) {
super.onError(e);
e.printStackTrace();
downloadImage(isSend,qq);
if (count == 0) {
return;
}
downloadImage(isSend, qq);
count--;
}
});
}
private void send(Long qq) {
File file = new File(HttpTools.downloadPath + AppTools.getToDayTime() + "_moyu.jpg");
Log.i(this,"发送图片 : file.exists = "+file.exists()+" qq = "+qq);
Log.i(this, "发送图片 : file.exists = " + file.exists() + " qq = " + qq);
if (file.exists()) {
QQBotManager.getInstance().sendMessage(file, qq, "");
}else{
downloadImage(true,qq);
} else {
downloadImage(true, qq);
}
}
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,50 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_TIMEOUT;
@UseModel
public class PaoPaoSleepWaring extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[]{QQ_TIMEOUT};
}
@Override
public String getModelName() {
return "泡泡提醒";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(Integer.parseInt(AppTools.getHours())>=22 && event.getSource().getFromId() == 914520754
&& "false".equals(RedisTools.get("paopao_sleep_"+AppTools.getToDayTime(),"false"))){
MessageChainBuilder builder=new MessageChainBuilder();
builder.append(new QuoteReply(event.getMessage()));
builder.append("别水了,该睡了~");
QQBotManager.getInstance().sendMessage(qq,builder);
RedisTools.set("paopao_sleep_"+AppTools.getToDayTime(),"true",1*60*60);
}
/*if(event.getSource().getFromId() == 914520754 && msg.contains("#体力")){
MessageChainBuilder builder=new MessageChainBuilder();
builder.append(new At(369224573L));
builder.append("惠城! 体力! ");
QQBotManager.getInstance().sendMessage(qq,builder);
}*/
}
}

View File

@ -0,0 +1,54 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.contact.AudioSupported;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.Audio;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.OfflineAudio;
import net.mamoe.mirai.utils.ExternalResource;
import java.io.File;
import java.util.Objects;
import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_WOODEN;
@UseModel
public class WoodenFish extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "电子木鱼";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
File file = null;
if(msg.contains("地狱笑话")){
file=new File("muyu.mp3");
QQBotManager.getInstance().sendMessage(qq,"功德+1");
}else if(msg.contains("遥遥领先")){
file=new File("遥遥领先.silk");
}
if(file!=null){
if(file.exists()) {
OfflineAudio audio = Objects.requireNonNull(event.getBot().getGroup(qq)).uploadAudio(ExternalResource.create(file));
MessageChainBuilder builder = new MessageChainBuilder();
builder.append(audio);
QQBotManager.getInstance().sendMessage(qq,builder);
}
}
}
}

View File

@ -1,7 +1,10 @@
package com.yutou.qqbot.models;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.interfaces.ModelInterface;
import com.yutou.qqbot.utlis.ConfigTools;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.event.events.GroupMessageEvent;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.At;
@ -35,6 +38,16 @@ public abstract class Model implements ModelInterface {
public final static String QQ_BANGUMI_INFO = "!保存动画信息>";
public final static String QQ_MOYU = "!摸鱼";
public final static String BILI_LIVE_DANMU_SEND = "!b站签到";
public final static String BILI_LIVE_DANMU_LIST = "!b站列表";
public final static String BILI_LIVE_DANMU_DEL = "!b站签到删除";
public final static String QQ_WOODEN = "!电子木鱼";
public final static String QQ_TIMEOUT = "!timer";
public final static String GPT="!百度gpt";
public final static String GPT_CLEAR="!百度失忆";
}
public static class QQFromCommands {
@ -52,9 +65,12 @@ public abstract class Model implements ModelInterface {
public static List<Class<?>> classList;
long group;
public MessageEvent event;
static {
classList=new ArrayList<>();
classList = new ArrayList<>();
}
public Model() {
if (!classList.contains(getClass())) {
classList.add(getClass());
@ -65,14 +81,15 @@ public abstract class Model implements ModelInterface {
public String msg;
protected boolean isGroupPower = false;
private boolean isGroup;
private Long user;
public Long user;
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
this.event=event;
msg = event.getMessage().contentToString();
msg = msg.replace("", "!").trim();
this.isGroup = isGroup;
if (isGroup) {
user=event.getSource().getFromId();
user = event.getSource().getFromId();
GroupMessageEvent groupEvent = (GroupMessageEvent) event;
group = groupEvent.getGroup().getId();
if (QQNumberManager.getManager().isExistsPower(group, msg.split(" ")[0])) {
@ -81,7 +98,7 @@ public abstract class Model implements ModelInterface {
}
}
public synchronized void onTime(Long qq,String time) {
public synchronized void onTime(Long qq, String time) {
}
public static StringBuilder getCommands(Class<?> commands) {
@ -106,4 +123,7 @@ public abstract class Model implements ModelInterface {
chain.add(text);
return chain;
}
public boolean isAt(){
return msg.contains("@"+ ConfigTools.load(ConfigTools.CONFIG,"qq_number",String.class));
}
}

View File

@ -11,6 +11,7 @@ import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.io.File;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
@UseModel
public class BaiHeHui extends Model {
@ -43,21 +44,16 @@ public class BaiHeHui extends Model {
} catch (Exception e) {
e.printStackTrace();
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "百合会签到失败:" + AppTools.getExceptionString(e));
}finally {
} finally {
WebClient.getInstance().quit();
}
}
}
public boolean sign() {
String cookie = ConfigTools.readFile(new File("baihehui.json"));
if (StringUtils.isEmpty(cookie)) {
return false;
}
WebDriver driver = WebClient.getInstance().getWebDriver();
try {
JSONArray array = JSON.parseArray(cookie);
driver.manage().timeouts().implicitlyWait(10000, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.get("https://bbs.yamibo.com/forum.php");
login(driver);
// driver.manage().deleteAllCookies();
@ -73,9 +69,9 @@ public class BaiHeHui extends Model {
e.printStackTrace();
}
driver.navigate().refresh();
driver.get("https://bbs.yamibo.com/forum.php");
driver.get("https://bbs.yamibo.com/plugin.php?id=zqlj_sign");
for (WebElement element : driver.findElements(By.xpath("//a"))) {
if ("打卡签到".equals(element.getText())) {
if ("点击打卡".equals(element.getText())) {
element.click();
break;
}

View File

@ -10,6 +10,7 @@ import com.yutou.qqbot.utlis.QRCodeUtils;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
@UseModel
public class BiliBiliMangeSign extends Model {
@Override
@ -34,9 +35,13 @@ public class BiliBiliMangeSign extends Model {
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(user==null){
return;
}
BiliBiliManga manga = new BiliBiliManga(user);
if (msg.equals(QQFromCommands.BILI_MANGA_SIGN)) {
String msg;
if (new BiliLogin().testLogin()) {
if (new BiliLogin(user).testLogin()) {
if (BiliBiliManga.sign() == null) {
msg = "B站漫画已经签到过了";
} else {
@ -44,9 +49,7 @@ public class BiliBiliMangeSign extends Model {
}
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站未登录,请扫码登陆后再试");
new BiliLogin(user).loginAsQQ();
}
} else if (msg.equals(QQFromCommands.BILI_MANGA_PAY)) {
StringBuilder builder = new StringBuilder();
@ -72,8 +75,8 @@ public class BiliBiliMangeSign extends Model {
}
QQBotManager.getInstance().sendMessage(qq, builder.toString());
} else if (msg.equals(QQFromCommands.BILI_MANGA_PAY_STOP)) {
new BiliBiliManga().stopPayMission();
QQBotManager.getInstance().sendMessage(qq, "当前任务已取消:"+BiliBiliManga.getMission());
manga.stopPayMission();
QQBotManager.getInstance().sendMessage(qq, "当前任务已取消:" + BiliBiliManga.getMission());
} else if (msg.startsWith(QQFromCommands.BILI_MANGA_PAY)) {
msg = msg.replace(QQFromCommands.BILI_MANGA_PAY, "");
String[] message = msg.split(" ");
@ -99,7 +102,7 @@ public class BiliBiliMangeSign extends Model {
QQBotManager.getInstance().sendMessage(qq, "商城id错误");
return;
}
BiliBiliManga manga = new BiliBiliManga();
manga.addInterface(new ObjectInterface() {
@Override
public void out(String data) {
@ -115,10 +118,10 @@ public class BiliBiliMangeSign extends Model {
}
@Override
public void onTime(Long qq,String time) {
super.onTime(qq,time);
public void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("00:01:00".equals(time)) {
if (new BiliLogin().testLogin()) {
if (new BiliLogin(QQBotManager.defQQ).testLogin()) {
String msg;
if (BiliBiliManga.sign() == null) {
msg = "B站漫画已经签到过了";

View File

@ -47,7 +47,7 @@ public class MiRouter extends Model {
}
}
private static boolean isRunTime = false;
private static boolean isRunTime = true;
@Override
public void onTime(Long qq,String time) {

View File

@ -24,6 +24,7 @@ import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@UseModel
public class GetSeTu extends Model {
@Override
@ -64,7 +65,7 @@ public class GetSeTu extends Model {
private void send(Long group) {
Jedis redis = RedisTools.getRedis();
redis.select(RedisTools.QQBOT_USER);
String ret = redis.get("Setu_"+group);
String ret = redis.get("Setu_" + group);
redis.close();
MessageChainBuilder builder = null;
if (!StringUtils.isEmpty(ret)) {
@ -96,8 +97,8 @@ public class GetSeTu extends Model {
builder.append(new At(qq))
.append(":\n");
for (String tag : list) {
if(StringUtils.isEmpty(tag)){
tag="随机";
if (StringUtils.isEmpty(tag)) {
tag = "随机";
}
builder.append(tag).append("\n");
}
@ -159,10 +160,19 @@ public class GetSeTu extends Model {
}
private boolean getSeTu(String model, String key, boolean r18, boolean fuzzyR18, Long qq, MessageEvent event) {
return getSeTu(model, key, r18, fuzzyR18, qq, event, 3);
}
private boolean getSeTu(String model, String key, boolean r18, boolean fuzzyR18, Long qq, MessageEvent event, int reset) {
if (reset <= 0) {
QQBotManager.getInstance().sendMessage(qq, "获取失败喵~");
return false;
}
String url = "https://api.lolicon.app/setu/v2?r18=0&size=regular";
if (r18) {
url = "https://api.lolicon.app/setu/v2?r18=1&size=regular";
}
final String tmpKey = key;
if (!StringUtils.isEmpty(key)) {
if ("tag".equals(model)) {
String[] keys = key.split(" ");
@ -185,7 +195,7 @@ public class GetSeTu extends Model {
url = url.replace("&r18=0", "&r18=2").replace("&r18=1", "&r18=2");
}
System.out.println("url = " + url);
String ret = HttpTools.get(url);
String ret = HttpTools.http_get(url, null, false);
JSONObject json = JSON.parseObject(ret);
if (json.getJSONArray("data").size() == 0) {
return false;
@ -215,19 +225,20 @@ public class GetSeTu extends Model {
@Override
public void onDownload(File file) {
super.onDownload(file);
builder.append("\n看不到图?点这里:http://setu.cnmglz.com/setu/").append(file.getName());
QQBotManager.getInstance().sendMessage(file, qq, event.getMessage(), "");
MessageChainBuilder chain = new MessageChainBuilder();
chain.append(new QuoteReply(event.getMessage()));
chain.append(builder.toString());
MessageReceipt<?> message=QQBotManager.getInstance().sendMessage(qq,chain);
Log.i(getModelName(),message);
MessageReceipt<?> message = QQBotManager.getInstance().sendMessage(qq, chain);
Log.i(getModelName(), message);
}
@Override
public void onError(Exception e) {
super.onError(e);
QQBotManager.getInstance().sendMessage(qq, "获取失败喵~");
getSeTu(model, tmpKey, r18, fuzzyR18, qq, event, reset - 1);
e.printStackTrace();
}
});

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.interfaces.ObjectInterface;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
@ -21,6 +22,7 @@ import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.jar.JarEntry;
@ -216,4 +218,22 @@ public class AppTools {
System.out.println("上传文件保存路径:" + saveFile.getAbsolutePath());
return saveFile.getAbsolutePath();
}
public static Date timeToDate(String date,String time){
String form;
if(StringUtils.isEmpty(time)){
form="yyyy-MM-dd";
}else{
form="yyyy-MM-dd HH:mm:ss";
}
try {
return new SimpleDateFormat(form).parse(date+" "+time);
} catch (ParseException e) {
return null;
}
}
public static String getMD5(String str){
return DigestUtils.md5Hex(str);
}
}

View File

@ -30,12 +30,13 @@ public class ApplicationInit implements ApplicationRunner {
if (time.equals(oldTime)) {
return;
}
BaiduGPTManager.getManager().clear();
oldTime = time;
for (Class<?> model : Model.classList) {
new Thread(() -> {
try {
Bot bot = QQBotManager.getInstance().getBot();
if(bot==null){
if (bot == null) {
return;
}
Model useModel = (Model) model.getDeclaredConstructor().newInstance();

View File

@ -0,0 +1,88 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.data.baidu.Message;
import com.yutou.qqbot.data.baidu.ResponseMessage;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BaiduGPTManager {
private static int MAX_MESSAGE = 5;
private static BaiduGPTManager manager;
private static final String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions";
//4.0
//private static final String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro";
private static final String AppID = "36668599";
private static final String ApiKey = "eyHo6K2ILBm7i378701Az1eT";
private static final String SecretKey = "U4vXt8AOTM9FgB0Omft5IOh6vwhzoDgZ";
private final Map<String, List<Message>> msgMap;
private BaiduGPTManager() {
msgMap = new HashMap<>();
}
public static BaiduGPTManager getManager() {
if (manager == null) {
manager = new BaiduGPTManager();
}
return manager;
}
public int setMaxMessageCount(int count) {
MAX_MESSAGE = count;
return MAX_MESSAGE;
}
public void clear() {
msgMap.clear();
}
private String getToken() {
String _url = String.format("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
, ApiKey
, SecretKey
);
String get = HttpTools.get(_url);
JSONObject response = JSONObject.parseObject(get);
return response.getString("access_token");
}
public ResponseMessage sendMessage(String user, String message) {
List<Message> messages = msgMap.getOrDefault(user, new ArrayList<>());
if (messages.size() > MAX_MESSAGE * 2) {
messages.remove(0);
messages.remove(1);
}
messages.add(Message.create(message));
JSONObject json = new JSONObject();
json.put("messages", messages);
System.out.println("json = " + json);
Map<String, String> map = new HashMap<>();
map.put("Content-Type", "application/json");
map.put("Content-Length", String.valueOf(json.toJSONString().getBytes(StandardCharsets.UTF_8).length));
String post = HttpTools.http_post(url + "?access_token=" + getToken()
, json.toJSONString().getBytes(StandardCharsets.UTF_8),0,map);
System.out.println("post = " + post);
if (StringUtils.isEmpty(post)) {
clear();
return sendMessage(user, message);
}
ResponseMessage response = JSONObject.parseObject(post, ResponseMessage.class);
messages.add(Message.create(response.getResult(), true));
msgMap.put(user, messages);
System.out.println("\n\n");
return response;
}
public static void main(String[] args) throws Exception {
ResponseMessage message = BaiduGPTManager.getManager().sendMessage("test", "2023年创业什么赚钱?");
System.out.println(message.getResult());
}
}

View File

@ -345,12 +345,7 @@ public class BangumiTools {
}
public static void main(String[] args) {
List<String> list = BangumiTools.reportSearchBangumi("处刑少女的生存之道");
/*for (String s : list) {
System.out.println(s);
}*/
JSONObject test=new JSONObject();
test.put("data",JSON.toJSON(list));
System.out.println(test);
System.out.println(BangumiTools.reportToDayBangumi());
}
}

View File

@ -0,0 +1,74 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.bilibili.BiliBiliUtils;
import java.nio.charset.StandardCharsets;
import java.util.TreeMap;
public class BiliBiliWbiSign {
private static final byte[] MIXIN_KEY_ENC_TAB = {
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42,
19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60,
51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52
};
private static String rawWbiKey;
public static TreeMap<String, String> getWbiSign(TreeMap<String, String> body) {
if (rawWbiKey == null) {
updateRawWbiKey();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return getWbiSign(body);
}
body.put("wts", String.valueOf(System.currentTimeMillis() / 1000));
String params = HttpTools.toUrlParams(body);
System.out.println("params = " + params);
body.put("w_rid", AppTools.getMD5(params + genMixinKey(rawWbiKey)));
return body;
}
private static String genMixinKey(String rawWbiKey) {
byte[] rawBytes = rawWbiKey.getBytes(StandardCharsets.UTF_8);
byte[] mixinKey = new byte[32];
for (int i = 0; i < 32; i++) {
mixinKey[i] = rawBytes[MIXIN_KEY_ENC_TAB[i]];
}
return new String(mixinKey);
}
public static void updateRawWbiKey() {
JSONObject loginInfo = new BiliBiliUtils(QQBotManager.defQQ).getLoginInfo();
if (loginInfo.getInteger("code") == -1) {
rawWbiKey = null;
return;
}
JSONObject wbi = loginInfo.getJSONObject("data").getJSONObject("wbi_img");
String imgKey = wbi.getString("img_url");
String subKey = wbi.getString("sub_url");
imgKey = imgKey.substring(imgKey.lastIndexOf("/") + 1).replace(".png", "");
subKey = subKey.substring(subKey.lastIndexOf("/") + 1).replace(".png", "");
rawWbiKey = imgKey + subKey;
System.out.println(rawWbiKey);
}
public static void main(String[] args) throws Exception {
//System.out.println(genMixinKey("7cd084941338484aae1ad9425b84077c4932caff0ff746eab6f01bf08b70ac45"));
rawWbiKey = "7cd084941338484aae1ad9425b84077c4932caff0ff746eab6f01bf08b70ac45";
TreeMap<String, String> json = new TreeMap<>();
json.put("bvid", "BV1L94y1H7CV");
json.put("cid", "1335073288");
json.put("up_mid", "297242063");
json.put("web_location", "333.788");
//updateRawWbiKey();
TreeMap<String, String> sign = getWbiSign(json);
System.out.println(sign);
//https://api.bilibili.com/x/web-interface/view/conclusion/get?bvid=BV1L94y1H7CV&cid=1335073288&up_mid=297242063&web_location=333.788&w_rid=a5d90f60ac6b6b6fc9d49be3ba3fee53&wts=1705394671
//updateRawWbiKey();
}
}

View File

@ -0,0 +1,68 @@
package com.yutou.qqbot.utlis;
import net.mamoe.mirai.utils.BotConfiguration;
import java.lang.reflect.Field;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
public class FixProtocolVersion {
public static void fix(){
try {
Class<?> MiraiProtocolInternal = Class.forName("net.mamoe.mirai.internal.utils.MiraiProtocolInternal");
Field field = MiraiProtocolInternal.getFields()[0];
Object companion = field.get(Object.class);
EnumMap<BotConfiguration.MiraiProtocol, Object> protocols = (EnumMap<BotConfiguration.MiraiProtocol, Object>)companion.getClass().getMethod("getProtocols$mirai_core").invoke(companion);
Object pad = protocols.get(BotConfiguration.MiraiProtocol.ANDROID_PAD);
/*
* apkId: String,
id: Long,
ver: String,
sdkVer: String,
miscBitMap: Int,
subSigMap: Int,
mainSigMap: Int,
sign: String,
buildTime: Long,
ssoVersion: Int,
canDoQRCodeLogin: Boolean = false,
* */
Class<?> padClass = pad.getClass();
Map<String, Object> padData = new HashMap<String, Object>(){{
put("id", 537152242);
put("ver", "8.9.35.10440");
put("sdkVer", "6.0.0.2535");
put("buildTime", 1676531414L);
}};
for (Field f : padClass.getFields()) {
f.setAccessible(true);
if(padData.containsKey(f.getName())){
f.set(pad, padData.get(f.getName()));
}
f.setAccessible(false);
}
Object phone = protocols.get(BotConfiguration.MiraiProtocol.ANDROID_PHONE);
Map<String, Object> phoneData = new HashMap<String, Object>(){{
put("id", 537153294);
put("ver", "8.9.35.10440");
put("sdkVer", "6.0.0.2535");
put("buildTime", 1676531414L);
}};
for (Field f : padClass.getFields()) {
f.setAccessible(true);
if(padData.containsKey(f.getName())){
f.set(phone, phoneData.get(f.getName()));
}
f.setAccessible(false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -17,15 +17,15 @@ public class HttpTools {
private static final int HttpRequestIndex = 3;
public static String get(String url) {
return http_get(url, null);
return http_get(url, null, false);
}
public static String post(final String url, final byte[] body) {
return http_post(url, body, 0, null);
}
public static File syncDownload(final String url, final String saveName) {
return new HttpTools().http_syncDownload(url, saveName);
public static File syncDownload(final String url, final String saveName, boolean isProxy) {
return new HttpTools().http_syncDownload(url, saveName, isProxy);
}
public static String https_get(String url, Map<String, String> header) {
@ -40,10 +40,19 @@ public class HttpTools {
return null;
}
public static String http_get(String url, Map<String, String> header) {
public static String http_get(String url, Map<String, String> header, boolean isProxy) {
try {
HttpURLConnection connection;
Proxy proxy = null;
if (isProxy) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
}
if (proxy == null) {
connection = (HttpURLConnection) new URL(url).openConnection();
} else {
connection = (HttpURLConnection) new URL(url).openConnection(proxy);
}
return urlConnection(header, connection);
} catch (Exception e) {
System.err.println("error url = " + url);
@ -86,8 +95,8 @@ public class HttpTools {
connection.setDoOutput(true);
connection.setDoInput(true);
connection.addRequestProperty("User-Agent", getExtUa());
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(10 * 1000);
// connection.setConnectTimeout(5 * 1000);
// connection.setReadTimeout(10 * 1000);
//connection.addRequestProperty("Connection", "keep-alive");
//connection.addRequestProperty("User-Agent", getExtUa());
//connection.addRequestProperty("content-type", "application/json");
@ -110,10 +119,10 @@ public class HttpTools {
reader.close();
return finalStr;
} catch (Exception e) {
e.printStackTrace();
if (index < HttpRequestIndex) {
return http_post(url, body, index + 1, headers);
} else {
e.printStackTrace();
return null;
}
}
@ -145,6 +154,14 @@ public class HttpTools {
return string.toString();
}
public static String toUrlParams(Map<String, String> map) {
StringBuilder builder = new StringBuilder();
for (String key : map.keySet()) {
builder.append(key).append("=").append(map.get(key)).append("&");
}
return builder.substring(0, builder.length() - 1);
}
public static Map<String, String> getUrlParams(String url) {
Map<String, String> map = new HashMap<>();
if (url.contains("?")) {
@ -158,7 +175,7 @@ public class HttpTools {
}
public static void main(String[] args) {
File file = syncDownload("https://lain.bgm.tv/pic/cover/l/6c/2a/302128_qQIjG.jpg", "12345.jpg");
File file = syncDownload("https://lain.bgm.tv/pic/cover/l/6c/2a/302128_qQIjG.jpg", "12345.jpg", false);
System.out.println("file.length() = " + file.length());
}
@ -230,8 +247,8 @@ public class HttpTools {
if (downloadInterface != null) {
if (oldJar.exists()) {
downloadInterface.onDownload(oldJar);
}else{
downloadInterface.onError(new FileNotFoundException("文件下载失败, 网络大小 = "+fileSize+" 本地大小 = "+oldJar.length()));
} else {
downloadInterface.onError(new FileNotFoundException("文件下载失败, 网络大小 = " + fileSize + " 本地大小 = " + oldJar.length()));
}
}
@ -249,7 +266,7 @@ public class HttpTools {
}).start();
}
public synchronized File http_syncDownload(final String url, final String saveName) {
public synchronized File http_syncDownload(final String url, final String saveName, boolean isProxy) {
if (StringUtils.isEmpty(url)) {
return null;
}
@ -259,8 +276,18 @@ public class HttpTools {
if (!savePath.exists()) {
savePath.mkdirs();
}
Proxy proxy = null;
if (isProxy) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
}
Log.i("DOWNLOAD", "下载文件:" + url + " 保存文件:" + saveName);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
HttpURLConnection connection;
if (proxy == null) {
connection = (HttpURLConnection) new URL(url).openConnection();
} else {
connection = (HttpURLConnection) new URL(url).openConnection(proxy);
}
connection.addRequestProperty("User-Agent", getExtUa());
// Log.i(TAG,"获取到网络请求:"+connection.getResponseCode());

View File

@ -30,7 +30,7 @@ public class IdeaTools {
}
public static List<String> getIdeaList(String url) {
File file = HttpTools.syncDownload(url, "idea.zip");
File file = HttpTools.syncDownload(url, "idea.zip",false);
List<String> list = new ArrayList<>();
try {
ZipFile zip = new ZipFile(file, Charset.forName("gbk"));

View File

@ -1,14 +1,19 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.data.jianr.AndroidDevice;
import com.yutou.qqbot.data.jianr.JianRScriptData;
import com.yutou.qqbot.data.jianr.JianRScriptV2Data;
import com.yutou.qqbot.data.jianr.Vector2D;
import com.yutou.qqbot.interfaces.ObjectInterface;
import lombok.SneakyThrows;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;
import java.util.TreeMap;
public class JianRTaskManager {
public static final String Redis_Script = "jianrScript_Script";
@ -49,10 +54,10 @@ public class JianRTaskManager {
}
public void start() {
if (running||runStatus) {
if (running || runStatus) {
return;
}
runStatus=true;
runStatus = true;
running = true;
new Thread(new Runnable() {
@ -68,10 +73,16 @@ public class JianRTaskManager {
}
log(script.getTitle());
JianRTaskManager.this.run(device, modelId, script);
try {
/* try {
Thread.sleep((long) getRandom(0, script.getRandomNextWaitTime() * 1000, script.getNextWaitTime() * 1000));
} catch (Exception e) {
throw new RuntimeException(e);
}*/
while (true){
if(waitGame(device,modelId,script)){
System.out.println("next");
break;
}
}
}
runIndex++;
@ -82,43 +93,87 @@ public class JianRTaskManager {
}
}
runStatus=false;
runStatus = false;
log("终止任务");
}
}).start();
}
Vector2D nowVector2D = null;
private void run(AndroidDevice device, int modelId, JianRScriptV2Data.Script script) {
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
Vector2D vector2D = null;
switch (script.getActivity()) {
case JianRScriptV2Data.ScriptModel.MAP:
vector2D = getMapCoords(device, gameDisplay);
nowVector2D = getMapCoords(device, gameDisplay);
break;
case JianRScriptV2Data.ScriptModel.attack:
vector2D = getAttackCoords(device, gameDisplay);
nowVector2D = getAttackCoords(device, gameDisplay);
break;
case JianRScriptV2Data.ScriptModel.dialog_go:
vector2D = getDialogCoords(device, gameDisplay, false);
nowVector2D = getDialogCoords(device, gameDisplay, false);
break;
case JianRScriptV2Data.ScriptModel.dialog_back:
vector2D = getDialogCoords(device, gameDisplay, true);
nowVector2D = getDialogCoords(device, gameDisplay, true);
break;
case JianRScriptV2Data.ScriptModel.dialog_assets:
vector2D = getDialogAssetsCoords(device, gameDisplay);
nowVector2D = getDialogAssetsCoords(device, gameDisplay);
break;
case JianRScriptV2Data.ScriptModel.none:
vector2D=getNoneCoords(device, gameDisplay);
nowVector2D = getNoneCoords(device, gameDisplay);
break;
default:
if (script.getActivity().startsWith(JianRScriptV2Data.ScriptModel.formationType)) {
vector2D = getNextFormationCoords(device, gameDisplay, Integer.parseInt(script.getActivity().split("#")[1]));
nowVector2D = getNextFormationCoords(device, gameDisplay, Integer.parseInt(script.getActivity().split("#")[1]));
}
}
if (vector2D != null) {
adb(device, vector2D);
if (nowVector2D != null) {
adb(device, nowVector2D);
}
}
private boolean isAttack=false;
private boolean isFormation=false;
private boolean waitGame(AndroidDevice device, int modelId,JianRScriptV2Data.Script script) {
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
String ocr;
switch (script.getActivity()) {
case JianRScriptV2Data.ScriptModel.MAP:
ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
System.out.println("ocr = " + ocr);
if(ocr.trim().contains("开始出征")){
return true;
}
break;
case JianRScriptV2Data.ScriptModel.attack:
ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
System.out.println("ocr = " + ocr);
if(ocr.trim().contains("开始战斗")){
isAttack=true;
}
if(isAttack){
run(device, modelId, script);
isFormation= true;
}
if(isFormation){
ocr=screen(gameDisplay,getDialogCoords(device,gameDisplay,true));
String tmp=screen(gameDisplay,getContinueCoords(device,gameDisplay));
if(ocr.contains("放弃")||tmp.contains("继续")){
}
}
break;
case JianRScriptV2Data.ScriptModel.dialog_go:
break;
case JianRScriptV2Data.ScriptModel.dialog_back:
break;
case JianRScriptV2Data.ScriptModel.dialog_assets:
break;
case JianRScriptV2Data.ScriptModel.none:
break;
default:
}
return false;
}
public void stop() {
task = null;
@ -194,6 +249,13 @@ public class JianRTaskManager {
return v2d;
}
private Vector2D getContinueCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.8725 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.9 + gameDisplay.getStart().getY());
return v2d;
}
/**
* 获取地图点击坐标
*
@ -225,6 +287,13 @@ public class JianRTaskManager {
return v2d;
}
public Vector2D getBottomLeft(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getEnd().getY());
return v2d;
}
/**
* 获取出击坐标
*
@ -253,48 +322,110 @@ public class JianRTaskManager {
v2d.setY(gameDisplay.getHeight() * 0.5433 + gameDisplay.getStart().getY());
return v2d;
}
private Vector2D getNoneCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay){
private Vector2D getNoneCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.1 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.1 + gameDisplay.getStart().getY());
return v2d;
}
@SneakyThrows
public static void main(String[] args) {
AndroidDevice device = new AndroidDevice();
AndroidDevice.DeviceDisplay deviceDisplay = new AndroidDevice.DeviceDisplay();
AndroidDevice.GameDisplay gameDisplay = new AndroidDevice.GameDisplay();
deviceDisplay.setHeight(1800);
deviceDisplay.setWidth(2800);
Vector2D start = new Vector2D();
Vector2D end = new Vector2D();
start.setX(2000);
start.setY(57);
end.setX(2800);
end.setY(581);
gameDisplay.setStart(start);
gameDisplay.setEnd(end);
List<AndroidDevice.GameDisplay> displays = new ArrayList<>();
displays.add(gameDisplay);
device.setDeviceDisplay(displays);
device.setAndroidDevice(deviceDisplay);
device.setDeviceId("192.168.31.142:6666");
device.setTitle("SAMSUNG-TAB-S7+");
JianRTaskManager manager = new JianRTaskManager();
Vector2D mapCoords;
// mapCoords = manager.getMapCoords(device,device.getGameDisplay().get(0));
// mapCoords = manager.getAttackCoords(device,device.getGameDisplay().get(0));
// mapCoords = manager.getNextFormationCoords(device,device.getGameDisplay().get(0), 0);
mapCoords = manager.getDialogCoords(device, device.getDeviceDisplay().get(0), true);
// adb(device, mapCoords);
System.out.println("device = " + device);
String jsonString = "{\"name\":\"1-1Test\",\"script\":[{\"name\":\"点击地图\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"出击\",\"activity\":\"attack\",\"nextWaitTime\":12,\"randomNextWaitTime\":2},{\"name\":\"战斗\",\"activity\":\"attack\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"选择单纵\",\"activity\":\"formationType#0\",\"nextWaitTime\":20,\"randomNextWaitTime\":5},{\"name\":\"结算1\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"结算2\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"获取舰娘\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"前进\",\"activity\":\"dialog_go\",\"nextWaitTime\":12,\"randomNextWaitTime\":3},{\"name\":\"战斗\",\"activity\":\"attack\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"选择梯形\",\"activity\":\"formationType#3\",\"nextWaitTime\":20,\"randomNextWaitTime\":5},{\"name\":\"结算1\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"结算2\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3},{\"name\":\"获取舰娘\",\"activity\":\"map\",\"nextWaitTime\":2,\"randomNextWaitTime\":3}]}";
JianRScriptV2Data script = JSON.parseObject(jsonString, JianRScriptV2Data.class);
manager.setTask(script, device);
manager.setModelId(0);
JSONObject json = new JSONObject();
String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
if (data == null || deviceJsonString == null) {
json.put("code", -1);
json.put("msg", "没有找到该方案或设备错误,请配置");
} else {
JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
JianRTaskManager manager = JianRTaskManager.getInstance();
if (manager.isRunning()) {
manager.stop();
}
for (int i = 0; i < androidDevice.getDeviceDisplay().size(); i++) {
if (androidDevice.getDeviceDisplay().get(i).getTitle().equals("全屏模式")) {
manager.setModelId(i);
break;
}
}
manager.setTask(script, androidDevice);
manager.start();
}
}
public File cut(Vector2D v2d) {
try {
System.out.println("v2d = " + v2d);
int x = (int) v2d.getNotRandomX() - 150;
int y = (int) v2d.getNotRandomY() - 50;
if (y + 150 > device.getAndroidDevice().getHeight()) {
y -= 100;
}
if (y < 0) {
y = 0;
}
if (x + 450 > device.getAndroidDevice().getWidth()) {
x -= 300;
}
if (x < 0) {
x = 0;
}
System.out.println("x = " + x);
System.out.println("y = " + y);
BufferedImage bufImage = ImageIO.read(new File("1.png"));
BufferedImage bufferedImage = bufImage.getSubimage(x, y, 400, 100);
File imgCutFile = new File("tmp.png");
ImageIO.write(bufferedImage, "PNG", imgCutFile);
return imgCutFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static String ocr(File file) {
String exec = "\"C:\\Program Files\\Tesseract-OCR\\tesseract.exe\" " + file.getAbsolutePath() + " - -l chi_sim --psm 6";
return AppTools.exec(exec, null, false, true).replace("\r", "").replace("\n", "");
}
private String screen(AndroidDevice.GameDisplay gameDisplay, Vector2D v2d) {
AppTools.exec("adb exec-out screencap -p > 1.png", null, false, false);
gameDisplay.setEnabledRandom(false);
File file = cut(v2d);
return ocr(file);
}
public void test() {
String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
this.device = androidDevice;
this.task = script;
this.modelId = 1;
System.out.println("download image");
AppTools.exec("adb exec-out screencap -p > 1.png", new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
AndroidDevice dev = device;
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
gameDisplay.setEnabledRandom(false);
Vector2D v2d;
v2d = getBottomLeft(device, gameDisplay);
v2d = getNextFormationCoords(device, gameDisplay, 4);
v2d = getAttackCoords(device, gameDisplay);
v2d = getDialogCoords(device, device.getDeviceDisplay().get(modelId), true);
v2d = getContinueCoords(device, gameDisplay);
File file = cut(v2d);
String ocr = ocr(file);
System.out.println(ocr.trim());
}
}, false, true);
}
private void adb(AndroidDevice device, Vector2D v2d) {
String exec = String.format("adb -s %s shell input tap %f %f",

View File

@ -0,0 +1,25 @@
package com.yutou.qqbot.utlis;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTools {
private static List<String> exec(String regex, String input){
List<String> list=new ArrayList<>();
Pattern pattern=Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while(matcher.find()){
list.add(matcher.group());
}
return list;
}
public static List<String> pattern(String text,String start,String end){
return exec(String.format(".(?<=%s).*(?=%s)", start,end), text);
}
public static List<String> getQQ(String text){
return exec("(@[0-9]\\d*)",text);
}
}

View File

@ -0,0 +1,136 @@
package com.yutou.qqbot.utlis;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAUtils {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA 密钥位数
*/
private static final int KEY_SIZE = 1024;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = MAX_DECRYPT_BLOCK - 11;
private static Map<Integer,String> keyMap=new HashMap<>();
/**
* 随机生成密钥对
* @throws NoSuchAlgorithmException
*/
public static void getKeyPair() throws Exception {
//KeyPairGenerator类用于生成公钥和密钥对基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//初始化密钥对生成器密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
//生成一个密钥对保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();//得到私钥
PublicKey publicKey = keyPair.getPublic();//得到公钥
//得到公钥字符串
String publicKeyString=new String(Base64.encodeBase64(publicKey.getEncoded()));
//得到私钥字符串
String privateKeyString=new String(Base64.encodeBase64(privateKey.getEncoded()));
//将公钥和私钥保存到Map
keyMap.put(0,publicKeyString);//0表示公钥
keyMap.put(1,privateKeyString);//1表示私钥
}
/**
* <p>
* 公钥加密
* </p>
*
* @param str 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static String encryptByPublicKey(String str, String publicKey) throws Exception {
publicKey=publicKey.replace("-----BEGIN PUBLIC KEY-----","").replace("-----END PUBLIC KEY-----","");
byte[] data=Base64.decodeBase64(str);
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return new String(Base64.encodeBase64(encryptedData));
}
/**
* RSA私钥解密
*
* @param str
* 加密字符串
* @param privateKey
* 私钥
* @return 铭文
* @throws Exception
* 解密过程中的异常信息
*/
public static String decrypt(String str,String privateKey) throws Exception {
//Base64解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//Base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,priKey);
String outStr=new String(cipher.doFinal(inputByte));
return outStr;
}
}

View File

@ -168,28 +168,46 @@ public class RedisTools {
}
public static Set<String> list_get(String listName) {
Set<String> set;
try {
Jedis jedis = getRedis();
jedis.select(QQBOT_USER);
Set<String> set = jedis.smembers(listName);
set = jedis.smembers(listName);
jedis.close();
if (set == null) {
set = new HashSet<>();
}
} catch (Exception e) {
e.printStackTrace();
set = new HashSet<>();
}
return set;
}
public static boolean list_remove(String listName, String... value) {
long index = 0;
try {
Jedis jedis = getRedis();
jedis.select(QQBOT_USER);
long index = jedis.srem(listName, value);
index = jedis.srem(listName, value);
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
return index != 0;
}
public static boolean list_isExist(String listName, String value) {
boolean flag = false;
try {
Jedis jedis = getRedis();
boolean flag = jedis.sismember(listName, value);
flag = jedis.sismember(listName, value);
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
@ -204,9 +222,9 @@ public class RedisTools {
public static boolean setHashMap(String hashKey, String key, String value) {
Jedis jedis = getRedis();
long l = jedis.hsetnx(hashKey, key, value);
long l = jedis.hset(hashKey, key, value);
jedis.close();
return l > 0;
return l == 0;
}
public static boolean removeHashMap(String hashKey, String key) {

View File

@ -37,6 +37,7 @@ public class WebClient {
}
private WebClient() {
//System.setProperty("webdriver.http.factory", "jdk-http-client");
System.setProperty("webdriver.chrome.driver",
ConfigTools.load(ConfigTools.CONFIG, "chrome", String.class));
// System.setProperty("webdriver.chrome.whitelistedIps", "");
@ -84,6 +85,7 @@ public class WebClient {
public ChromeOptions getOptions() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
// options.addArguments("--disable-gpu");
// options.addArguments("blink-settings=imagesEnabled=false");
String headless = RedisTools.get("chromedrive_headless");

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#FAFAFA;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view .layui-code-ol li:first-child{padding-top:10px}.layui-code-view .layui-code-ol li:last-child{padding-bottom:10px}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:13px}.layui-code-title{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-title>.layui-code-about{position:absolute;right:10px;top:0;color:#b7b7b7}.layui-code-about>a{padding-left:10px}.layui-code-view>.layui-code-ol,.layui-code-view>.layui-code-ul{position:relative;overflow:auto}.layui-code-view>.layui-code-ol>li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view>.layui-code-ol>li:first-child,.layui-code-view>.layui-code-ul>li:first-child{padding-top:10px}.layui-code-view>.layui-code-ol>li:last-child,.layui-code-view>.layui-code-ul>li:last-child{padding-bottom:10px}.layui-code-view>.layui-code-ul>li{position:relative;line-height:20px;padding:0 10px;list-style-type:none;*list-style-type:none;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-dark{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-dark>.layui-code-title{border-bottom:none}.layui-code-dark>.layui-code-ol>li,.layui-code-dark>.layui-code-ul>li{background-color:#3f3f3f;border-left:none}.layui-code-dark>.layui-code-ul>li{margin-left:6px}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long