27 Commits

Author SHA1 Message Date
864d5960a7 commit feat: 新增和改进HTTP请求处理及文件下载功能
- 新增文件下载功能:
  - 新增 `FileBody.java` 类,定义文件下载的数据结构。
  - 新增 `FileCallback.java` 类,处理文件下载的回调逻辑,包括线程池管理和下载进度报告。
  - 新增 `HttpDownloadUtils.java` 工具类,提供异步和同步的文件下载方法,并支持下载接口回调。

- 改进HTTP请求处理:
  - 修改 `NapCatQQ.java` 的 `onResponse` 方法,增加对响应头(`Headers`)的处理。
  - 修改 `GetRequestParams.java` 和 `PostRequestParams.java` 的 `getRequest` 方法,支持在请求中添加自定义Header。
  - 修改 `HttpCallback.java` 的 `onResponse` 方法,增加对响应头(`Headers`)的处理。

- 优化HTTP日志记录:
  - 修改 `HttpLoggingInterceptor.java`,调整日志级别为默认输出响应体,修复日志输出格式和异常处理问题。

- 改进BaseApi类:
  - 修改 `BaseApi.java`,增加对请求头的支持,并优化错误处理逻辑。
  - 在拦截器中处理非成功的响应码,返回统一格式的错误信息,避免业务逻辑中重复处理。

- 更新QQBotManager API回调:
  - 修改 `QQBotManager.java`,更新API回调方法以处理响应头(`Headers`),确保所有回调方法一致。

- 新增GPT API交互功能:
  - 新增 `OpenAiBean.java` 类,定义与OpenAI交互的数据结构,包含响应中的各个字段。
  - 新增 `SiliconGPTManager.java` 类,实现新的GPT管理器,处理与Silicon GPT API的交互。
  - 新增 `GPTApi.java` 类,提供与GPT API交互的基础配置和API调用方法。
  - 新增 `GPTBuilder.java` 类,用于构建发送给GPT API的请求对象。

- 改进GPT管理器:
  - 修改 `AbsGPTManager.java`,添加锁机制,防止同一用户同时发起多个请求。
  - 提供获取消息列表的方法,限制历史消息的最大数量。
  - 支持设置模型版本。
  - 修改 `BaiduGPTManager.java`,移除重复的清除方法,继承自父类。
  - 使用父类提供的方法获取消息列表,简化代码逻辑。

- 优化和重构:
  - 进一步优化 `HttpLoggingInterceptor.java` 的日志记录逻辑,提高性能和可读性。
  - 重构 `BaseApi.java` 初始化方法,简化代码逻辑,提高可读性。

这些改动增强了HTTP请求处理能力,增加了文件下载功能,并为与GPT API的交互提供了支持。
2025-02-08 18:27:00 +08:00
94890f001c feat(gpt): 更新模型并优化版本显示
- 将 ERNIE-3.5-8K 模型替换为 ERNIE-Speed-128K 模型
- 修改 getGPTVersion 方法以直接返回当前模型名称
- 更新 QQBot 版本号至 1.7.10
2025-02-05 18:18:48 +08:00
73566a41e5 build:升级 qianfan 依赖版本
- 将 qianfan 依赖版本从 0.1.1 升级到 0.1.3
2025-02-05 10:40:02 +08:00
56774792c1 feat(gpt): 重构 GPT 管理器并添加新功能
- 重构 AbsGPTManager 抽象类,添加多个新方法
- 新增 sendMessage、textToImage、imageToText、getGPTVersion 等方法
- 添加 setMaxMessageCount 方法,用于设置最大消息数量
- 实现 getManager 方法,根据类获取相应的 GPT 管理器实例
- 更新 BaiduGPTManager 类,实现新增的方法
2025-02-05 10:33:12 +08:00
e7fae929a1 refactor(gpt): 重构 GPT 相关代码并优化功能
- 新增 AbsGPTManager 抽象类,定义 GPT 管理器的通用接口
- 重命名 BaiduGPTManager 类,使其位于 com.yutou.qqbot.gpt 包中
- 更新相关引用和依赖
- 优化部分代码结构,提高可维护性
2025-02-04 18:15:15 +08:00
09305ae824 feat(BaiduGPTManager):优化图片描述功能并添加翻译功能
- 更新图片转文本的提示语,要求更详细的描述
- 添加将英文结果翻译成中文的功能
- 优化翻译提示语,确保准确翻译
- 更新版本号至 QQBot v.1.7.9.1
-调整日志设置的加载顺序
2025-02-04 18:00:07 +08:00
1041dfa909 feat(bot): 增加图片处理功能并优化日志系统
- 新增 textToImage 和 imageToText 功能,实现文本与图片的相互转换
- 优化日志系统,使用 log4j2 实现动态日志记录- 重构 BaiduGPTManager 类,增加多线程支持和错误处理
- 更新 MessageHandleBuild 类,支持 message_id 参数
- 修复部分功能的逻辑错误,提高系统稳定性
2025-02-04 17:13:48 +08:00
237c9273ca feat(QQBot): 更新版本并优化消息发送功能
- 将版本号从 v.1.7.7 升级到 v.1.7.8
-重构 sendMessage 方法,支持发送包含图片和回复的消息
- 更新服务器版本查询 URL 为 HTTPS
- 注释掉版本查询时的服务器消息发送
2025-02-03 14:45:00 +08:00
607c05e028 更新B站相关签到时间 2024-10-09 10:18:21 +08:00
df0337b006 更新为1.7.7 2024-09-20 09:31:59 +08:00
ebe96127e5 调整QQ对外接口 2024-06-09 11:37:39 +08:00
120392be17 更新小米路由器API调用接口
更新小米路由器获取公网IP的接口
2024-06-03 22:01:05 +08:00
6ed42d3e80 update 2024-05-21 16:26:21 +08:00
9903056551 修复百度没有上下文问题 2024-05-21 16:24:25 +08:00
10c4459936 移除多余输出 2024-05-10 13:25:46 +08:00
632b11d242 Merge pull request '改成onebot-11通用接口' (#9) from dev_HTTP服务化 into master
Reviewed-on: #9
OJBK
2024-05-10 13:09:42 +08:00
b4230a4809 调整动画key 2024-05-10 13:06:30 +08:00
604d186cc2 修复百度版本保存失败问题 2024-05-10 13:03:23 +08:00
2c37c19cc9 替换百度key 2024-05-06 10:51:47 +08:00
808ec3bd0a 更新 src/main/java/com/yutou/qqbot/utlis/BaiduGPTManager.java 2024-05-05 20:24:28 +08:00
400f2df6ab 优化百度文心一言保存版本到文件 2024-05-05 17:13:10 +08:00
7e9fa60f6a 新增图片支持File
调整涩图模块为先自己下载,无法下载再丢url给qq机器人
移除部分日志
2024-05-05 16:50:37 +08:00
d4b0a78fa9 修改日志 2024-05-04 18:25:15 +08:00
4ccaa4b78e 修改日志 2024-05-04 18:23:47 +08:00
c74033fed7 修改日志 2024-05-04 18:21:46 +08:00
5a7382d02c 完成基本功能转移 2024-05-04 17:26:27 +08:00
3b52742ac1 Merge pull request 'dev_该合并了' (#8) from dev_ into master
Reviewed-on: #8
2024-01-17 17:23:44 +08:00
113 changed files with 4697 additions and 751 deletions

75
pom.xml
View File

@@ -32,11 +32,6 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>net.mamoe</groupId>
<artifactId>mirai-core-jvm</artifactId>
<version>2.15.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.jetbrains.kotlinx</groupId> <groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-jdk8</artifactId> <artifactId>kotlinx-coroutines-jdk8</artifactId>
@@ -77,19 +72,6 @@
<scope>system</scope> <scope>system</scope>
<systemPath>${project.basedir}/libs/json-jena-1.0.jar</systemPath> <systemPath>${project.basedir}/libs/json-jena-1.0.jar</systemPath>
</dependency> </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 --> <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency> <dependency>
<groupId>org.seleniumhq.selenium</groupId> <groupId>org.seleniumhq.selenium</groupId>
@@ -163,6 +145,63 @@
<version>0.1.2</version> <version>0.1.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<!-- jsoup HTML parser library @ https://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
<dependency>
<groupId>com.baidubce</groupId>
<artifactId>qianfan</artifactId>
<version>0.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.24.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>2.24.1</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.24.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -0,0 +1,65 @@
package com.yutou.napcat;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.enums.MessageEnum;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.*;
import com.yutou.napcat.model.*;
import com.yutou.okhttp.HttpCallback;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.utlis.Base64Tools;
import lombok.val;
import okhttp3.Headers;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class NapCatQQ {
private NapCatQQ() {
}
public static void main(String[] args) {
/* List<BaseHandle<?>> list = new ArrayList<>();
list.add(new Text("1", false));
list.add(new Text("2", false));
list.add(new Text("3"));
list.add(new Text("4", false));
list.add(new At(583819556L));
list.add(new Text("5"));
QQBotManager.getInstance().sendMessage(false, 891655174L, list);*/
NapCatApi.setLog(false);
File file = new File("C:\\Users\\58381\\Downloads\\0074TT8Yly1hp5mqidwqeg30g20f27wh.gif");
NapCatApi.getMessageApi().sendPrivateMsg(
MessageHandleBuild.create()
.setQQNumber(583819556L)
//.add(new Image(file))
.add(new Text("abc"))
.build()
).enqueue(new HttpCallback<SendMessageResponse>() {
@Override
public void onResponse(Headers headers, int code, String status, SendMessageResponse response, String rawResponse) {
System.out.println("code = " + code + ", status = " + status + ", response = " + response + ", rawResponse = " + rawResponse);
}
@Override
public void onFailure(Throwable throwable) {
throwable.printStackTrace();
}
});
}
/**
* 私聊
{"self_id":240828363,"user_id":583819556,"time":1714472684,"message_id":376,"real_id":376,"message_type":"private","sender":{"user_id":583819556,"nickname":"魔芋","card":""},"raw_message":"123","font":14,"sub_type":"friend","message":[{"data":{"text":"123"},"type":"text"}],"message_format":"array","post_type":"message"}
*/
/**
* 群聊
* {"self_id":240828363,"user_id":583819556,"time":1714472695,"message_id":377,"real_id":377,"message_type":"group","sender":{"user_id":583819556,"nickname":"魔芋","card":"","role":"owner"},"raw_message":"222","font":14,"sub_type":"normal","message":[{"data":{"text":"222"},"type":"text"}],"message_format":"array","post_type":"message","group_id":891655174}
*/
}

View File

@@ -0,0 +1,54 @@
package com.yutou.napcat;
import com.yutou.napcat.model.FriendBean;
import com.yutou.napcat.model.GroupBean;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class QQDatabase {
private static Map<Long, Object> data = new HashMap<>();
@Getter
@Setter
private static FriendBean me;
public static void addUser(Long qq, FriendBean bean) {
data.put(qq, bean);
}
public static void addGroup(Long qq, GroupBean bean) {
data.put(qq, bean);
}
public static boolean checkFriend(Long qq) {
if (data.containsKey(qq)) {
return data.get(qq) instanceof FriendBean;
}
return false;
}
public static boolean checkGroup(Long qq) {
if (data.containsKey(qq)) {
return data.get(qq) instanceof GroupBean;
}
return false;
}
public static List<GroupBean> getGroups() {
List<GroupBean> numbers = new ArrayList<>();
for (Long qq : data.keySet()) {
if (data.get(qq) instanceof GroupBean) {
{
numbers.add((GroupBean) data.get(qq));
}
}
}
return numbers;
}
}

View File

@@ -0,0 +1,29 @@
package com.yutou.napcat.enums;
public enum MessageEnum {
TEXT("text"),
IMAGE("image"),
AT("at"),
REPLY("reply"),
JSON("json");
String type;
MessageEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
public static MessageEnum of(String type) {
for (MessageEnum messageEnum : MessageEnum.values()) {
if (messageEnum.getType().equals(type)) {
return messageEnum;
}
}
return null;
}
}

View File

@@ -0,0 +1,28 @@
package com.yutou.napcat.enums;
public enum RecordFormatEnum {
MP3("mp3"),
AMR("amr"),
WMA("wma"),
M4A("m4a"),
SPX("spx"),
OGG("ogg"),
WAV("wav"),
FLAC("flac");
private final String format;
RecordFormatEnum(String format) {
this.format = format;
}
public String getFormat() {
return format;
}
@Override
public String toString() {
return format;
}
}

View File

@@ -0,0 +1,13 @@
package com.yutou.napcat.event;
import com.yutou.napcat.model.GroupFrom;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class GroupMessageEvent extends MessageEvent {
private GroupFrom group;
}

View File

@@ -0,0 +1,197 @@
package com.yutou.napcat.event;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.enums.MessageEnum;
import com.yutou.napcat.handle.*;
import com.yutou.napcat.model.AppShareBean;
import com.yutou.napcat.model.Message;
import com.yutou.napcat.model.SourceFrom;
import lombok.Data;
import lombok.val;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Data
public class MessageEvent {
@JSONField(name = "self_id")
private Long selfId;
@JSONField(name = "user_id")
private Long userId;
@JSONField(name = "time")
private Long time;
@JSONField(name = "message_id")
private Integer messageId;
@JSONField(name = "real_id")
private Integer realId;
@JSONField(name = "message_type")
private String messageType;
@JSONField(name = "sender")
private SourceFrom source;
@JSONField(name = "raw_message")
private String rawMessage;
@JSONField(name = "font")
private Integer font;
@JSONField(name = "sub_type")
private String subType;
@JSONField(name = "message")
private List<BaseHandle<?>> message;
@JSONField(name = "message_format")
private String messageFormat;
@JSONField(name = "post_type")
private String postType;
@JSONField(name = "group_id")
private Long groupId;
public static MessageEvent parseHandleHttp(String jsonString) {
return parseHandle(JSONObject.parseObject(jsonString).getJSONObject("data").toString());
}
public static MessageEvent parseHandle(String jsonString) {
JSONObject json = JSONObject.parseObject(jsonString);
JSONArray array = json.getJSONArray("message");
List<BaseHandle<?>> messageList = new ArrayList<>();
if (array != null) {
for (Object o : array) {
JSONObject _json = (JSONObject) o;
Type classType = null;
MessageEnum _type = MessageEnum.of(_json.getString("type"));
classType = switch (_type) {
case TEXT -> Text.TextInfo.class;
case IMAGE -> Image.ImageInfo.class;
case AT -> At.AtData.class;
case JSON -> OtherHandle.OtherInfo.class;
case REPLY -> Reply.ReplyInfo.class;
default -> classType;
};
BaseHandle<?> handle = new BaseHandle<>(_type.getType());
if (_type == MessageEnum.JSON) {
handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").getString("data"), classType));
} else {
handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").toString(), classType));
}
messageList.add(handle);
}
}
MessageEvent event = new MessageEvent();
event.setTime(json.getLong("time"));
event.setSelfId(json.getLong("self_id"));
event.setPostType(json.getString("post_type"));
event.setGroupId(json.getLong("group_id"));
event.setUserId(json.getLong("user_id"));
event.setSubType(json.getString("sub_type"));
try {
SourceFrom sender = new SourceFrom();
sender.setUserId(event.getUserId());
event.setSource(sender);
sender.setUserId(json.getJSONObject("sender").getLong("user_id"));
sender.setNickname(json.getJSONObject("sender").getString("nickname"));
sender.setCard(json.getJSONObject("sender").getString("card"));
event.setMessageId(json.getInteger("message_id"));
event.setRealId(json.getInteger("real_id"));
event.setMessageType(json.getString("message_type"));
event.setSource(sender);
event.setRawMessage(json.getString("raw_message"));
event.setFont(json.getInteger("font"));
event.setMessageFormat(json.getString("message_format"));
event.setMessage(messageList);
return event;
} catch (Exception e) {
System.err.println("jsonString:\n" + jsonString);
}
return event;
}
public boolean hasType(MessageEnum messageEnum) {
if(message==null||message.isEmpty()){
return false;
}
for (BaseHandle<?> handle : message) {
if (MessageEnum.of(handle.getType()) == messageEnum) {
return true;
}
}
return false;
}
public <T extends BaseHandle> List<T> findAllType(Class<T> t) {
List<T> tmp = new ArrayList<>();
if (message == null || message.isEmpty()) {
return tmp;
}
try {
T newed = t.getDeclaredConstructor().newInstance();
for (BaseHandle<?> baseHandle : message) {
if (baseHandle.getType().equals(newed.getType())) {
newed.setData(baseHandle.getData());
tmp.add(newed);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return tmp;
}
public <T extends BaseHandle> T findType(Class<T> tClass) {
List<T> list = findAllType(tClass);
if (list == null || list.isEmpty()) {
return null;
}
return list.get(0);
}
public boolean isAtMe() {
if (!hasType(MessageEnum.AT)) {
return false;
}
List<At> list = findAllType(At.class);
for (At handle : list) {
if (handle.getData().getQq() == QQDatabase.getMe().getUserId()) {
return true;
}
}
return false;
}
public String getTextMessage() {
val texts = findAllType(Text.class);
StringBuilder sb = new StringBuilder();
for (Text text : texts) {
sb.append(text);
}
return sb.toString().trim();
}
public boolean isUser() {
return "private".equals(messageType);
}
public boolean isGroup() {
return "group".equals(messageType);
}
}

View File

@@ -0,0 +1,32 @@
package com.yutou.napcat.handle;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
public class At extends BaseHandle<At.AtData> {
public At() {
super("at");
}
public At(Long userId) {
super("at");
data = new AtData(userId);
}
@Override
public String toString() {
if (data == null) {
return null;
}
return String.format("[CQ:at,qq=%d]", data.qq);
}
@Data
public class AtData extends BaseBean {
private Long qq;
public AtData(Long qq) {
this.qq = qq;
}
}
}

View File

@@ -0,0 +1,28 @@
package com.yutou.napcat.handle;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.enums.MessageEnum;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
@Data
public class BaseHandle<T> extends BaseBean {
protected String type;
protected T data;
protected String src;
public BaseHandle(String type) {
this.type = type;
}
public BaseHandle(String type, Object obj) {
super();
this.type = type;
this.data= (T) obj;
}
}

View File

@@ -0,0 +1,35 @@
package com.yutou.napcat.handle;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.qqbot.utlis.Base64Tools;
import lombok.Data;
import java.io.File;
public class Image extends BaseHandle<Image.ImageInfo> {
public Image() {
super("image");
}
public Image(String imageUrl) {
super("image");
data = new ImageInfo(imageUrl);
}
public Image(File imageFile){
super("image");
data=new ImageInfo("base64://"+ Base64Tools.encode(imageFile));
}
@Data
public static class ImageInfo {
String file;
String url;
@JSONField(name = "file_size")
String fileSize;
public ImageInfo(String file) {
this.file = file;
}
}
}

View File

@@ -0,0 +1,64 @@
package com.yutou.napcat.handle;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.okhttp.BaseBean;
import com.yutou.qqbot.utlis.StringUtils;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
public class MessageHandleBuild {
private List<BaseHandle<?>> msgList = new ArrayList<>();
private long qq;
private boolean autoEscape;
private boolean isGroup;
private String messageId;
public static MessageHandleBuild create() {
return new MessageHandleBuild();
}
private MessageHandleBuild() {
msgList = new ArrayList<>();
}
public MessageHandleBuild setQQNumber(long qq) {
this.qq = qq;
return this;
}
public MessageHandleBuild setAutoEscape(boolean autoEscape) {
this.autoEscape = autoEscape;
return this;
}
public MessageHandleBuild add(BaseHandle<?> msg) {
msgList.add(msg);
return this;
}
public MessageHandleBuild setGroup(boolean group) {
isGroup = group;
return this;
}
public MessageHandleBuild setMessageId(String messageId) {
this.messageId = messageId;
return this;
}
public JSONObject build() {
JSONObject json=new JSONObject();
if(isGroup){
json.put("group_id", qq);
}else {
json.put("user_id", qq);
}
json.put("auto_escape", autoEscape);
json.put("message", msgList);
if(!StringUtils.isEmpty(messageId)){
json.put("message_id",messageId);
}
return json;
}
}

View File

@@ -0,0 +1,20 @@
package com.yutou.napcat.handle;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.model.AppShareBean;
import lombok.Data;
public class OtherHandle extends BaseHandle<OtherHandle.OtherInfo>{
public OtherHandle() {
super("json");
data= new OtherInfo();
}
@Data
public static class OtherInfo extends AppShareBean{
}
}

View File

@@ -0,0 +1,14 @@
package com.yutou.napcat.handle;
public class QuoteReply {
private final String messageId;
public QuoteReply(String messageId) {
this.messageId = messageId;
}
@Override
public String toString() {
return String.format("[CQ:reply,id=%s]",messageId);
}
}

View File

@@ -0,0 +1,38 @@
package com.yutou.napcat.handle;
import com.yutou.qqbot.utlis.ConfigTools;
import lombok.Data;
public class Record extends BaseHandle<Record.RecordInfo> {
public Record() {
super("record");
}
public Record(String file) {
super("record");
data = new RecordInfo(file);
}
public Record(String file, boolean proxy) {
super("record");
data = new RecordInfo(file);
data.proxy = proxy ? "1" : "0";
}
@Data
public static class RecordInfo {
String file;
int magic;
String url;
String cache;
String proxy;
String timeout;
public RecordInfo(String file) {
this.file = ConfigTools.getServerUrl()+file;
}
}
}

View File

@@ -0,0 +1,24 @@
package com.yutou.napcat.handle;
import lombok.Data;
public class Reply extends BaseHandle<Reply.ReplyInfo> {
public Reply() {
super("reply");
}
public Reply(long id) {
super("reply");
data = new ReplyInfo(id);
}
@Data
public static class ReplyInfo {
private long id;
public ReplyInfo(long id) {
this.id = id;
}
}
}

View File

@@ -0,0 +1,53 @@
package com.yutou.napcat.handle;
import lombok.Data;
import java.lang.reflect.Type;
public class Text extends BaseHandle<Text.TextInfo> {
public Text() {
super("text");
}
public Text(String text) {
super("text");
data = new TextInfo(text + "\n");
}
public Text(String text, boolean isNewLine) {
super("text");
if (isNewLine) {
data = new TextInfo(text + "\n");
} else {
data = new TextInfo(text);
}
}
public Text(boolean isNewLine, String... text) {
super("text");
StringBuilder sb = new StringBuilder();
for (String s : text) {
sb.append(s);
}
if (isNewLine) {
data = new TextInfo(sb + "\n");
} else {
data = new TextInfo(sb.toString());
}
}
@Override
public String toString() {
return data.text.trim();
}
@Data
public static class TextInfo {
String text;
public TextInfo(String text) {
this.text = text.trim();
}
}
}

View File

@@ -0,0 +1,17 @@
package com.yutou.napcat.http;
import com.yutou.napcat.model.FriendBean;
import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.HttpBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
import java.util.List;
public interface FriendApi {
@POST("/get_friend_list")
Call<HttpBody<List<FriendBean>>> getFriendList(
);
}

View File

@@ -0,0 +1,89 @@
package com.yutou.napcat.http;
import com.yutou.napcat.model.FriendBean;
import com.yutou.napcat.model.GroupBean;
import com.yutou.napcat.model.GroupUserBean;
import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.HttpBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
import java.util.List;
public interface GroupApi {
/**
* 禁言
*
* @param group 群号
* @param user 用户
* @param duration 禁言时长,单位秒
*/
@FormUrlEncoded
@POST("/set_group_ban")
Call<HttpBody<BaseBean>> groupBan(
@Field("group_id") long group,
@Field("user_id") long user,
@Field("duration") long duration
);
/**
* 禁言群组全体成员
*
* @param group 群号
*/
@FormUrlEncoded
@POST("/set_group_whole_ban")
Call<HttpBody<BaseBean>> groupBanAll(
@Field("group_id") long group
);
/**
* 获取群组列表
*/
@POST("/get_group_list")
Call<HttpBody<List<GroupBean>>> getGroupList(
);
/**
* 获取群组信息
*/
@POST("/get_group_info")
Call<HttpBody<GroupBean>> getGroupInfo(
);
/**
* 获取群组成员信息
*/
@POST("/get_group_member_info")
Call<HttpBody<GroupUserBean>> getGroupUserInfo(
);
/**
* 获取群组成员列表
*
* @param group 群号
*/
@FormUrlEncoded
@POST("/get_group_member_list")
Call<HttpBody<List<GroupUserBean>>> getGroupUserList(
@Field("group_id") long group,
@Field("no_cache")boolean noCache
);
/**
* 设置群组专属头衔
* @param group 群号
* @param user 用户
* @param title 头衔
* @param duration 持续时间,单位秒
*/
@POST("/set_group_special_title")
@FormUrlEncoded
Call<HttpBody<BaseBean>> setGroupSpecialTitle(
@Field("group_id") long group,
@Field("user_id") long user,
@Field("special_title") String title,
@Field("duration") long duration );
}

View File

@@ -0,0 +1,52 @@
package com.yutou.napcat.http;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.handle.BaseHandle;
import com.yutou.napcat.model.MessageBean;
import com.yutou.napcat.model.SendMessageResponse;
import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.HttpBody;
import kotlin.jvm.JvmSuppressWildcards;
import retrofit2.Call;
import retrofit2.http.*;
import java.util.List;
public interface MessageAPI {
/**
* 发送私聊消息
* @param message {@link com.yutou.napcat.handle.MessageHandleBuild}
* @return 消息id
*/
@POST("/send_private_msg")
Call<HttpBody<SendMessageResponse>> sendPrivateMsg(
@Body
JSONObject message);
/**
* 发送群聊消息
* @param message 消息内容
* @return 消息id
*/
@POST("/send_group_msg")
Call<HttpBody<SendMessageResponse>> sendGroupMsg(
@Body
JSONObject message
);
/**
* 撤回消息
* @param messageId 消息id
*/
@FormUrlEncoded
@POST("/delete_msg")
Call<HttpBody<BaseBean>> delMsg(
@Field("message_id") long messageId
);
@POST("/get_msg")
Call<HttpBody<MessageBean>> getMessage(
@Body
JSONObject message
);
}

View File

@@ -0,0 +1,29 @@
package com.yutou.napcat.http;
import com.yutou.okhttp.HttpLoggingInterceptor;
import com.yutou.okhttp.api.BaseApi;
import com.yutou.qqbot.utlis.ConfigTools;
public class NapCatApi extends BaseApi {
private static final String URL;
static {
URL= ConfigTools.load(ConfigTools.CONFIG,ConfigTools.NAPCAT_URL,String.class);
}
public static void setLog(boolean log){
HttpLoggingInterceptor.setLog(log);
}
public static MessageAPI getMessageApi(){
return new NapCatApi().setURL(URL).createApi(MessageAPI.class);
}
public static UtilsApi getUtilsApi(){
return new NapCatApi().setURL(URL).createApi(UtilsApi.class);
}
public static GroupApi getGroupApi(){
return new NapCatApi().setURL(URL).createApi(GroupApi.class);
}
public static FriendApi getFriendApi(){
return new NapCatApi().setURL(URL).createApi(FriendApi.class);
}
}

View File

@@ -0,0 +1,80 @@
package com.yutou.napcat.http;
import com.yutou.napcat.model.*;
import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.HttpBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface UtilsApi {
/**
* 获取语音
*
* @param fileId 收到的语音文件名(消息段的 file 参数),如 0B38145AA44505000B38145AA4450500.silk
* @param format 要转换到的格式,目前支持 mp3、amr、wma、m4a、spx、ogg、wav、flac {@link com.yutou.napcat.enums.RecordFormatEnum}
* @return 转换后的语音文件路径
*/
@FormUrlEncoded
@POST("/get_record")
Call<HttpBody<String>> getMessageRecord(
@Field("file") String fileId,
@Field("out_format") String format
);
/**
* 获取图片
*
* @param fileId 收到的图片文件名(消息段的 file 参数)
* @return 下载后的图片文件路径
*/
@FormUrlEncoded
@POST("/get_image")
Call<HttpBody<String>> getMessageImage(
@Field("file") String fileId
);
/**
* 检查是否可以发送图片
*/
@POST("/can_send_image")
Call<HttpBody<CheckSendImageBean>> checkSendImage(
);
/**
* 检查是否可以发送语音
*/
@POST("/can_send_record")
Call<HttpBody<CheckSendRecordBean>> checkSendRecord(
);
/**
* 获取机器人状态
*/
@POST("/get_status")
Call<HttpBody<QQBotStatusBean>> checkQQBotStatus(
);
/**
* 获取机器人版本信息
*/
@POST("/get_version_info")
Call<HttpBody<QQBotVersionBean>> checkQQBotVersion(
);
/**
* 清理缓存
*/
@POST("/clean_cache")
Call<HttpBody<BaseBean>> cleanCache(
);
/**
* 获取登录信息
*/
@POST("/get_login_info")
Call<HttpBody<FriendBean>> getLoginInfo(
);
}

View File

@@ -0,0 +1,139 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
import java.util.Map;
@Data
public class AppShareBean extends BaseBean {
@JSONField(name = "ver")
private String version;
@JSONField(name = "prompt")
private String prompt;
@JSONField(name = "config")
private Config config;
@JSONField(name = "needShareCallBack")
private boolean needShareCallBack;
@JSONField(name = "app")
private String app;
@JSONField(name = "view")
private String view;
@JSONField(name = "meta")
private Meta meta;
// getters and setters...
// Inner classes
@Data
public static class Config {
@JSONField(name = "type")
private String type;
@JSONField(name = "width")
private int width;
@JSONField(name = "height")
private int height;
@JSONField(name = "forward")
private int forward;
@JSONField(name = "autoSize")
private int autoSize;
@JSONField(name = "ctime")
private long ctime;
@JSONField(name = "token")
private String token;
// getters and setters...
}
@Data
public static class Meta {
@JSONField(name = "detail_1")
private Detail detail1;
// If there can be multiple "detail_X" entries, you might need a Map
// @JSONField(name = "detail_X")
// private Map<String, Detail> details;
// getters and setters...
}
@Data
public static class Detail {
@JSONField(name = "appid")
private String appid;
@JSONField(name = "appType")
private int appType;
@JSONField(name = "title")
private String title;
@JSONField(name = "desc")
private String desc;
@JSONField(name = "icon")
private String icon;
@JSONField(name = "preview")
private String preview;
@JSONField(name = "url")
private String url;
@JSONField(name = "scene")
private int scene;
@JSONField(name = "host")
private Host host;
@JSONField(name = "shareTemplateId")
private String shareTemplateId;
// Since "shareTemplateData" is an empty object, it can be left as a Map or a specific class
// if you know the structure of the data that might be there
@JSONField(name = "shareTemplateData")
private Map<String, Object> shareTemplateData;
@JSONField(name = "qqdocurl")
private String qqdocurl;
@JSONField(name = "showLittleTail")
private String showLittleTail;
@JSONField(name = "gamePoints")
private String gamePoints;
@JSONField(name = "gamePointsUrl")
private String gamePointsUrl;
// getters and setters...
}
@Data
public static class Host {
@JSONField(name = "uin")
private long uin;
@JSONField(name = "nick")
private String nick;
// getters and setters...
}
}

View File

@@ -0,0 +1,12 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
@Data
public class CheckSendImageBean extends BaseBean {
@JSONField(name = "yes")
private boolean yes;
}

View File

@@ -0,0 +1,12 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
@Data
public class CheckSendRecordBean extends BaseBean {
@JSONField(name = "yes")
private boolean yes;
}

View File

@@ -0,0 +1,15 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
@Data
public class FriendBean extends BaseBean {
@JSONField(name = "user_id")
private long userId;//qq号
@JSONField(name = "nickname")
private String nickName;//昵称
@JSONField(name = "remark")
private String remark;//备注
}

View File

@@ -0,0 +1,18 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
@Data
public class GroupBean extends BaseBean {
@JSONField(name = "group_id")
private long groupId;
@JSONField(name = "group_name")
private String groupName;
@JSONField(name = "member_count")
private int userCount;
@JSONField(name = "max_member_count")
private int userMaxCount;
}

View File

@@ -0,0 +1,8 @@
package com.yutou.napcat.model;
import lombok.Data;
@Data
public class GroupFrom {
private long id;
}

View File

@@ -0,0 +1,72 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
@Data
public class GroupUserBean extends BaseBean {
// 群号
@JSONField(name = "group_id")
private long groupId;
// QQ号
@JSONField(name = "user_id")
private long userId;
// 昵称
@JSONField(name = "nickname")
private String nickname;
// 群名片/备注
@JSONField(name = "card")
private String card;
// 性别male 或 female 或 unknown
@JSONField(name = "sex")
private String sex;
// 年龄
@JSONField(name = "age")
private int age;
// 地区
@JSONField(name = "area")
private String area;
// 加群时间戳
@JSONField(name = "join_time")
private int joinTime;
// 最后发言时间戳
@JSONField(name = "last_sent_time")
private int lastSentTime;
// 成员等级
@JSONField(name = "level")
private String level;
// 角色owner 或 admin 或 member
@JSONField(name = "role")
private String role;
// 是否不良记录成员
@JSONField(name = "unfriendly")
private boolean unfriendly;
// 专属头衔
@JSONField(name = "title")
private String title;
// 专属头衔过期时间戳
@JSONField(name = "title_expire_time")
private int titleExpireTime;
// 是否允许修改群名片
@JSONField(name = "card_changeable")
private boolean cardChangeable;
// 禁言剩余时间
@JSONField(name = "shut_up_timestamp")
private long shutUpTimestamp;
}

View File

@@ -0,0 +1,23 @@
package com.yutou.napcat.model;
import lombok.Data;
@Data
public class Message {
private String message;
private String srcMessage;
private String id;
public Message(String message, String srcMessage) {
this.message = message;
this.srcMessage = srcMessage;
}
public String serializeToMiraiCode(){
return srcMessage;
}
public String contentToString(){
return message;
}
}

View File

@@ -0,0 +1,50 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.BaseHandle;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
import java.lang.reflect.Type;
/**
* 消息
* @see <a href="https://github.com/botuniverse/onebot-11/blob/master/api/public.md#get_msg-%E8%8E%B7%E5%8F%96%E6%B6%88%E6%81%AF">文档</a>
*/
@Data
public class MessageBean extends BaseBean {
/**
*发送时间
*/
@JSONField(name = "time")
private long time;
/**
* 消息类型,同 <a href="https://github.com/botuniverse/onebot-11/blob/master/event/message.md">消息事件</a>
*/
@JSONField(name = "message_type")
private String type;
/**
* 消息 ID
*/
@JSONField(name = "message_id")
private int messageId;
/**
* 消息真实 ID
*/
@JSONField(name = "real_id")
private int realId;
/**
* 发送人信息,同 <a href="https://github.com/botuniverse/onebot-11/blob/master/event/message.md">消息事件</a>
*/
@JSONField(name = "sender")
private SenderBean sender;
/**
* 消息内容
*/
@JSONField(name = "message")
private String message;
}

View File

@@ -0,0 +1,13 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
@Data
public class QQBotStatusBean extends BaseBean {
@JSONField(name = "online")
private String online;//当前 QQ 在线null 表示无法查询到在线状态
@JSONField(name = "good")
private String good;//状态符合预期,意味着各模块正常运行、功能正常,且 QQ 在线
}

View File

@@ -0,0 +1,17 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
@Data
public class QQBotVersionBean {
@JSONField(name = "app_name")
private String appName;//应用标识,如 mirai-native
@JSONField(name = "app_version")
private String appVersion;//应用版本,如 1.2.3
@JSONField(name = "protocol_version")
private String protocolVersion;//OneBot 标准版本,如 v11
}

View File

@@ -0,0 +1,21 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.google.gson.annotations.SerializedName;
import com.yutou.napcat.handle.BaseHandle;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
public class SendMessageRequest extends BaseBean {
@JSONField(name = "user_id")
private long userId;
@JSONField
List<BaseHandle<?>> message;
@SerializedName("auto_escape")
private boolean notCQCode;
}

View File

@@ -0,0 +1,17 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.google.gson.annotations.SerializedName;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class SendMessageResponse extends BaseBean {
@JSONField( name = "message_id")
private int id;
private String e;
}

View File

@@ -0,0 +1,24 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.yutou.okhttp.BaseBean;
import lombok.Data;
/**
* 发送人结构体
*
*/
@Data
public class SenderBean extends BaseBean {
@JSONField(name = "user_id")
private long userId;
@JSONField(name = "nickname")
private String nickName;
/**
* male 或 female 或 unknown
*/
@JSONField(name = "sex")
private String sex;
@JSONField(name = "age")
private int age;
}

View File

@@ -0,0 +1,17 @@
package com.yutou.napcat.model;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
@Data
public class SourceFrom {
@JSONField(name = "user_id")
private long userId;
private String nickname;
private String card;
private String role;
public Long getFromId() {
return userId;
}
}

View File

@@ -0,0 +1,6 @@
package com.yutou.okhttp;
import java.io.Serializable;
public class BaseBean implements Serializable {
}

View File

@@ -0,0 +1,11 @@
package com.yutou.okhttp;
import lombok.Data;
import java.io.InputStream;
@Data
public class FileBody<T> {
InputStream inputStream;
T t;
}

View File

@@ -0,0 +1,112 @@
package com.yutou.okhttp;
import com.yutou.qqbot.utlis.Log;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public abstract class FileCallback<T> implements Callback<FileBody<T>> {
private static ThreadPoolExecutor executor;
private final T bean;
private String savePath;
public FileCallback(T bean, String savePath) {
this.bean = bean;
this.savePath = savePath;
if (executor == null) {
executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
}
}
private class DownloadTask implements Runnable {
private T bean;
private Headers headers;
private HttpUrl url;
private InputStream inputStream;
public DownloadTask(T bean, Headers headers, HttpUrl url, InputStream inputStream) {
this.bean = bean;
this.headers = headers;
this.url = url;
this.inputStream = inputStream;
}
@Override
public void run() {
try {
Log.i("开始下载");
File file = new File(savePath);
onStart(bean);
if (!file.exists()) {
boolean mkdirs = file.getParentFile().mkdirs();
Log.i("mkdirs = " + mkdirs);
}
FileOutputStream outputStream = new FileOutputStream(file);
int len;
long total = 0;
byte[] bytes = new byte[4096];
boolean isDownload = true;
long available = inputStream.available();
while ((len = inputStream.read(bytes)) != -1 && isDownload) {
total += len;
outputStream.write(bytes, 0, len);
outputStream.flush();
isDownload = onDownload(headers, bean, total, available);
}
Log.i("下载完成");
outputStream.close();
} catch (Exception e) {
Log.e(e);
onFailure(bean,e);
} finally {
onFinish(bean);
try {
inputStream.close();
} catch (IOException e) {
Log.e(e);
}
}
}
}
public abstract void onStart(T bean);
public abstract boolean onDownload(Headers headers, T bean, long len, long total);
public abstract void onFinish(T bean);
public abstract void onFailure(T bean, Throwable throwable);
@Override
public void onResponse(Call<FileBody<T>> call, Response<FileBody<T>> response) {
try {
executor.execute(new DownloadTask(bean, response.headers(), call.request().url(), response.body().getInputStream()));
} catch (Exception e) {
Log.e(e);
onFailure(bean,e);
call.cancel();
}
}
@Override
public void onFailure(Call<FileBody<T>> call, Throwable throwable) {
onFailure(bean, throwable);
call.cancel();
}
}

View File

@@ -0,0 +1,32 @@
package com.yutou.okhttp;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.Request;
import java.util.HashMap;
public class GetRequestParams implements IRequestParam {
/**
* 构建Request
*
* @param request
* @return
*/
@Override
public Request getRequest(HashMap<String, String> headerMap, HashMap<String, String> map, Request request) {
Headers.Builder headerBuild = request.headers().newBuilder();
if (!headerMap.isEmpty()) {
for (String key : headerMap.keySet()) {
headerBuild.add(key, headerMap.get(key));
}
}
//添加公共参数
HttpUrl.Builder builder = request.url().newBuilder();
for (String key : map.keySet()) {
builder.addQueryParameter(key, String.valueOf(map.get(key)));
}
return request.newBuilder().url(builder.build()).headers(headerBuild.build()).build();
}
}

View File

@@ -0,0 +1,14 @@
package com.yutou.okhttp;
import lombok.Data;
@Data
public class HttpBody<T> {
private String msg;
private String status;
private int code;
private int retcode;
private T data;
private String src;
}

View File

@@ -0,0 +1,35 @@
package com.yutou.okhttp;
import okhttp3.Headers;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public abstract class HttpCallback<T> implements Callback<HttpBody<T>> {
public abstract void onResponse(Headers headers,int code, String status, T response, String rawResponse);
public abstract void onFailure(Throwable throwable);
@Override
public void onResponse(Call<HttpBody<T>> call, Response<HttpBody<T>> response) {
if (response.body() != null) {
onResponse(
response.headers(),
response.body().getRetcode(),
response.body().getStatus(),
response.body().getData(),
response.body().getSrc()
);
} else {
onFailure(new NullPointerException("response body is null"));
}
call.cancel();
}
@Override
public void onFailure(Call<HttpBody<T>> call, Throwable throwable) {
onFailure(throwable);
call.cancel();
}
}

View File

@@ -0,0 +1,145 @@
package com.yutou.okhttp;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.Log;
import lombok.Data;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public class HttpDownloadUtils {
public static void download(Builder builder) {
createHttpClient(builder).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
if (builder.downloadInterface != null) {
builder.downloadInterface.onError(e);
}
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
InputStream inputStream = Objects.requireNonNull(response.body()).byteStream();
File target;
if (StringUtils.hasText(builder.fileName)) {
target = new File(builder.path, builder.fileName);
} else {
target = new File(builder.path);
}
FileOutputStream fileOutputStream = new FileOutputStream(target);
if (builder.downloadInterface != null) {
builder.downloadInterface.onDownloadStart();
}
try {
byte[] buffer = new byte[2048];
int len;
long soFarBytes = 0;
long totalBytes = inputStream.available();
while ((len = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
soFarBytes += len;
if (builder.downloadInterface != null) {
if (!builder.downloadInterface.onDownloading(soFarBytes, totalBytes)) {
break;
}
}
}
fileOutputStream.flush();
} catch (IOException e) {
Log.e(e,"download error:", builder.url);
} finally {
if (builder.downloadInterface != null) {
builder.downloadInterface.onDownload(target);
}
}
}
});
}
public static File downloadSync(Builder builder) {
try {
Response response = createHttpClient(builder).execute();
InputStream inputStream = Objects.requireNonNull(response.body()).byteStream();
File target;
if (StringUtils.hasText(builder.fileName)) {
target = new File(builder.path, builder.fileName);
} else {
target = new File(builder.path);
}
try (FileOutputStream fileOutputStream = new FileOutputStream(target)) {
byte[] buffer = new byte[2048];
int len;
while ((len = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.flush();
return target;
} catch (IOException e) {
Log.e(e,"download error:" , builder.url);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
private static Call createHttpClient(Builder builder) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.MINUTES)
.readTimeout(2, TimeUnit.MINUTES)
.build();
Request.Builder rb = new Request.Builder()
.get()
.addHeader("User-Agent", ConfigTools.getUserAgent())
.url(builder.url);
if (StringUtils.hasText(builder.cookie)) {
rb.addHeader("Set-Cookie", builder.cookie);
rb.addHeader("Cookie", builder.cookie);
}
Request request = rb.build();
return okHttpClient.newCall(request);
}
@Data
public static class Builder {
String url;
String path;
String fileName;
DownloadInterface downloadInterface;
String cookie;
public Builder setUrl(String url) {
this.url = url;
return this;
}
public Builder setPath(String path) {
this.path = path;
return this;
}
public Builder setFileName(String fileName) {
this.fileName = fileName;
return this;
}
public Builder setDownloadInterface(DownloadInterface downloadInterface) {
this.downloadInterface = downloadInterface;
return this;
}
public Builder setCookie(String cookie) {
this.cookie = cookie;
return this;
}
}
}

View File

@@ -0,0 +1,215 @@
package com.yutou.okhttp;
import com.yutou.qqbot.utlis.Log;
import lombok.val;
import okhttp3.*;
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;
import okio.BufferedSource;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
public class HttpLoggingInterceptor implements Interceptor {
private static final String TAG = "HttpLogging";
private static final Charset UTF8 = StandardCharsets.UTF_8;
private volatile Level printLevel = Level.BODY;
private java.util.logging.Level colorLevel;
private Logger logger;
private static boolean prLog;
public static void setLog(boolean log) {
prLog = log;
}
public enum Level {
NONE, //不打印log
BASIC, //只打印 请求首行 和 响应首行
HEADERS, //打印请求和响应的所有 Header
BODY //所有数据全部打印
}
public HttpLoggingInterceptor(String tag) {
logger = Logger.getLogger(tag);
colorLevel = java.util.logging.Level.INFO;
}
public void setPrintLevel(Level level) {
if (printLevel == null)
throw new NullPointerException("printLevel == null. Use Level.NONE instead.");
printLevel = level;
}
public void setColorLevel(java.util.logging.Level level) {
colorLevel = level;
}
private void log(String message) {
//logger.log(colorLevel, message);
if (prLog) {
Log.getDynamicLogger(TAG).info(message);
}
//Log.e(TAG,message);
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (request.body() != null && request.body().contentLength() == 0) {
val headers = request.headers();
request = chain.call().request().newBuilder()
.headers(headers)
.build();
}
if (printLevel == Level.NONE) {
return chain.proceed(request);
}
//请求日志拦截
logForRequest(request, chain.connection());
//执行请求,计算请求时间
long startNs = System.nanoTime();
Response response;
try {
response = chain.proceed(request);
} catch (Exception e) {
log("<-- HTTP FAILED: " + e);
throw e;
}
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
//响应日志拦截
return logForResponse(response, tookMs);
}
private void logForRequest(Request request, Connection connection) throws IOException {
boolean logBody = (printLevel == Level.BODY);
boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
RequestBody requestBody = request.body();
boolean hasRequestBody = requestBody != null;
Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
try {
String requestStartMessage = "--> " + request.method() + ' ' + request.url() + ' ' + protocol;
log(requestStartMessage);
if (logHeaders) {
if (hasRequestBody) {
if (requestBody.contentType() != null) {
log("\tContent-Type: " + requestBody.contentType());
}
if (requestBody.contentLength() != -1) {
log("\tContent-Length: " + requestBody.contentLength());
}
}
Headers headers = request.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
String name = headers.name(i);
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
log("\t" + name + ": " + headers.value(i));
}
}
log(" ");
if (logBody && hasRequestBody) {
if (isPlaintext(requestBody.contentType())) {
bodyToString(request);
} else {
log("\tbody: maybe [binary body], omitted!");
}
}
}
} catch (Exception e) {
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
} finally {
log("--> END " + request.method());
}
}
private Response logForResponse(Response response, long tookMs) {
Response.Builder builder = response.newBuilder();
Response clone = builder.build();
ResponseBody responseBody = clone.body();
boolean logBody = (printLevel == Level.BODY);
boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
try {
log("<-- " + clone.code() + ' ' + clone.message() + ' ' + clone.request().url() + " (" + tookMs + "ms)");
if (logHeaders) {
Headers headers = clone.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
log("\t" + headers.name(i) + ": " + headers.value(i));
}
log(" ");
if (logBody && HttpHeaders.hasBody(clone)) {
if (responseBody == null) return response;
if (isPlaintext(responseBody.contentType())) {
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // 请求整个流
Buffer buffer = source.buffer();
Charset charset = getCharset(responseBody.contentType());
String body = buffer.clone().readString(charset);
log("\tbody:" + body);
} else {
log("\tbody: maybe [binary body], omitted!");
}
}
}
} catch (Exception e) {
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
} finally {
log("<-- END HTTP");
}
return response;
}
private static Charset getCharset(MediaType contentType) {
Charset charset = contentType != null ? contentType.charset(UTF8) : UTF8;
if (charset == null) charset = UTF8;
return charset;
}
/**
* Returns true if the body in question probably contains human readable text. Uses a small sample
* of code points to detect unicode control characters commonly used in binary file signatures.
*/
private static boolean isPlaintext(MediaType mediaType) {
if (mediaType == null) return false;
if (mediaType.type() != null && mediaType.type().equals("text")) {
return true;
}
String subtype = mediaType.subtype();
if (subtype != null) {
subtype = subtype.toLowerCase();
if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html")) //
return true;
}
return false;
}
private void bodyToString(Request request) {
try {
Request copy = request.newBuilder().build();
RequestBody body = copy.body();
if (body == null) return;
Buffer buffer = new Buffer();
body.writeTo(buffer);
Charset charset = getCharset(body.contentType());
log("\tbody:" + buffer.readString(charset));
// 重置请求体以确保后续处理不受影响
buffer.clear();
} catch (Exception e) {
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
}
}
}

View File

@@ -0,0 +1,9 @@
package com.yutou.okhttp;
import okhttp3.Request;
import java.util.HashMap;
public interface IRequestParam {
Request getRequest(HashMap<String,String> header, HashMap<String,String> map, Request request);
}

View File

@@ -0,0 +1,44 @@
package com.yutou.okhttp;
import com.yutou.qqbot.utlis.ConfigTools;
import okhttp3.Request;
import java.util.HashMap;
public class ParamsContext {
private IRequestParam iRequestParam;
private Request request;
private HashMap<String, String> map;
private HashMap<String, String> headerMap;
public ParamsContext(HashMap<String, String> map, Request request) {
if (map == null) {
map = new HashMap<>();
}
this.map = map;
this.request = request;
this.headerMap = new HashMap<>();
}
public ParamsContext(HashMap<String, String> headerMap, HashMap<String, String> map, Request request) {
if (map == null) {
map = new HashMap<>();
}
this.map = map;
this.request = request;
this.headerMap = headerMap;
}
public Request getInRequest() {
switch (request.method()) {
case "GET":
iRequestParam = new GetRequestParams();
break;
case "POST":
iRequestParam = new PostRequestParams();
break;
}
headerMap.put("User-Agent", ConfigTools.getUserAgent());
return iRequestParam.getRequest(headerMap, map, request);
}
}

View File

@@ -0,0 +1,74 @@
package com.yutou.okhttp;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.utlis.Log;
import okhttp3.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class PostRequestParams implements IRequestParam {
@Override
public Request getRequest(HashMap<String, String> headerMap, HashMap<String, String> map, Request request) {
Headers.Builder headerBuilder = request.headers().newBuilder();
if (!headerMap.isEmpty()) {
for (String key : headerMap.keySet()) {
headerBuilder.add(key, headerMap.get(key));
}
}
if (request.body() instanceof FormBody) {
FormBody.Builder bodyBuilder = new FormBody.Builder();
FormBody formBody = (FormBody) request.body();
for (int i = 0; i < formBody.size(); i++) {
bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
}
for (String key : map.keySet()) {
bodyBuilder.addEncoded(key, String.valueOf(map.get(key)));
}
formBody = bodyBuilder.build();
request = request.newBuilder().headers(headerBuilder.build()).post(formBody).build();
} else if (request.body() != null) {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), toUrlParams(map));
request = request.newBuilder()
.headers(headerBuilder.build())
.post(request.body())
.post(requestBody).build();
}
return request;
}
public static String toUrlParams(JSONObject json) {
StringBuilder string = new StringBuilder();
Set<String> keys = json.keySet();
for (String key : keys) {
try {
string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8"));
} catch (Exception e) {
Log.e(e);
try {
string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("=");
// string += "&" + key + "=";
} catch (Exception e1) {
string.append("&").append(key).append("=");
}
}
}
string = new StringBuilder(string.substring(1, string.length()).replaceAll(" ", ""));
return string.toString();
}
public static String toUrlParams(Map<String, String> map) {
if (map.isEmpty()) {
return "";
}
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);
}
}

View File

@@ -0,0 +1,136 @@
package com.yutou.okhttp.api;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.bind.DateTypeAdapter;
import com.yutou.okhttp.HttpBody;
import com.yutou.okhttp.HttpLoggingInterceptor;
import com.yutou.okhttp.ParamsContext;
import com.yutou.okhttp.converter.JsonCallAdapter;
import com.yutou.okhttp.converter.JsonConverterFactory;
import lombok.val;
import okhttp3.*;
import retrofit2.CallAdapter;
import retrofit2.Converter;
import retrofit2.Retrofit;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.logging.Level;
public class BaseApi {
private String URL;
private HashMap<String, String> params = new HashMap<>();
private HashMap<String, String> headers = new HashMap<>();
public BaseApi setURL(String URL) {
this.URL = URL;
return this;
}
public BaseApi setHeaders(HashMap<String, String> headers) {
this.headers = headers;
return this;
}
public void addHeader(HashMap<String, String> headers) {
this.headers.putAll(headers);
}
public BaseApi setParams(HashMap<String, String> params) {
this.params = params;
return this;
}
public void useCookie(JSONObject json) {
StringBuilder ck = new StringBuilder();
json.remove("sql_time");
json.remove("gourl");
for (String key : json.keySet()) {
ck.append(key).append("=").append(json.getString(key)).append(";");
}
headers.put("Cookie", ck.toString());
setHeaders(headers);
}
/**
* 创建一个接口方法
*
* @param okHttpClient okhttp客户端
* @param converterFactory 处理工厂类
* @param callAdapterFactory 请求适配器工厂
* @param baseUrl 基础地质
* @param service 接口
* @param <T> 接口泛型
* @return 接口
*/
public <T> T create(OkHttpClient okHttpClient, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory, String baseUrl, Class<T> service) {
Retrofit.Builder builder = new Retrofit.Builder()
//基础url
.baseUrl(baseUrl)
//客户端OKHttp
.client(okHttpClient);
//添加转换工厂
if (null != converterFactory) {
builder.addConverterFactory(converterFactory);
}
//添加请求工厂
if (null != callAdapterFactory) {
builder.addCallAdapterFactory(callAdapterFactory);
}
//创建retrofit对象
Retrofit retrofit = builder.build();
//返回创建的api
return retrofit.create(service);
}
public <T> T createApi(Class<T> apiClass) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateTypeAdapter())
.create();
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("http");
loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient()
.newBuilder()
.addInterceptor(initQuery())
.addInterceptor(loggingInterceptor);
return create(builder.build(),
JsonConverterFactory.create(gson),
JsonCallAdapter.create(),
URL,
apiClass);
}
public Interceptor initQuery() {
Interceptor addQueryParameterInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//配置公共参数
request = new ParamsContext(headers, params, request).getInRequest();
val proceed = chain.proceed(request);
if (!proceed.isSuccessful()) {
HttpBody<?> httpBody = new HttpBody<>();
httpBody.setCode(200);
val parse = JSONObject.parse(proceed.body().string());
httpBody.setRetcode(parse.getInteger("code"));
httpBody.setMsg(parse.getString("message"));
ResponseBody errorResponseBody = ResponseBody.create(
JSONObject.toJSONString(httpBody),
MediaType.get("application/json; charset=utf-8"));
val newResponse=proceed.newBuilder()
.code(200)
.body(errorResponseBody).build();
return newResponse;
}
return proceed;
}
};
return addQueryParameterInterceptor;
}
}

View File

@@ -0,0 +1,19 @@
package com.yutou.okhttp.converter;
import org.jetbrains.annotations.Nullable;
import retrofit2.CallAdapter;
import retrofit2.Retrofit;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
public class JsonCallAdapter extends CallAdapter.Factory{
public static JsonCallAdapter create(){
return new JsonCallAdapter();
}
@Nullable
@Override
public CallAdapter<?, ?> get(Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
}

View File

@@ -0,0 +1,41 @@
package com.yutou.okhttp.converter;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import retrofit2.Converter;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import org.jetbrains.annotations.Nullable;
import retrofit2.Retrofit;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
public class JsonConverterFactory extends Converter.Factory {
Gson gson;
public static JsonConverterFactory create(Gson gson) {
return new JsonConverterFactory(gson);
}
private JsonConverterFactory(Gson gson) {
this.gson = gson;
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
// return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new JsonRequestBodyConverter<>(gson,adapter);
}
@Nullable
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
// return super.responseBodyConverter(type, annotations, retrofit);
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new JsonResponseBodyConverter<>(gson,adapter,type);
}
}

View File

@@ -0,0 +1,37 @@
package com.yutou.okhttp.converter;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonWriter;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import org.jetbrains.annotations.Nullable;
import retrofit2.Converter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class JsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
Gson gson;
TypeAdapter<T> adapter;
public JsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson=gson;
this.adapter=adapter;
}
@Nullable
@Override
public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), StandardCharsets.UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
byte[] bytes = buffer.readByteArray();
return RequestBody.create(MediaType.parse("application/json; charset=UTF-8"),bytes );
}
}

View File

@@ -0,0 +1,58 @@
package com.yutou.okhttp.converter;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.yutou.okhttp.HttpBody;
import okhttp3.ResponseBody;
import org.jetbrains.annotations.Nullable;
import retrofit2.Converter;
import java.io.IOException;
import java.lang.reflect.Type;
public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
Gson gson;
TypeAdapter<?> adapter;
Type type;
public JsonResponseBodyConverter(Gson gson, TypeAdapter<?> adapter, Type type) {
this.gson = gson;
this.adapter = adapter;
this.type = type;
}
@Nullable
@Override
public T convert(ResponseBody responseBody) throws IOException {
String string = new String(responseBody.bytes());
responseBody.close();
HttpBody<T> body;
try {
body = JSONObject.parseObject(string, type);
if(body.getData()==null){
JSONObject jt=JSONObject.parseObject(JSONObject.toJSONString(new HttpBody<>()));
jt.put("data",JSONObject.parseObject(string));
HttpBody<T> bt=JSONObject.parseObject(jt.toJSONString(),type);
body.setData(bt.getData());
}
body.setSrc(string);
return (T) body;
} catch (Exception e) {
e.printStackTrace();
try {
body = new HttpBody<>();
body.setData(JSONObject.parseObject(string, type));
body.setSrc(string);
} catch (Exception e2) {
e2.printStackTrace();
body = new HttpBody<>();
body.setSrc(string);
}
}
return (T) body;
}
}

View File

@@ -1,12 +1,17 @@
package com.yutou.qqbot.Controllers; package com.yutou.qqbot.Controllers;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.handle.At;
import com.yutou.napcat.handle.BaseHandle;
import com.yutou.napcat.handle.Image;
import com.yutou.napcat.handle.Text;
import com.yutou.napcat.model.SendMessageResponse;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.HttpTools; import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.StringUtils; import com.yutou.qqbot.utlis.StringUtils;
import net.mamoe.mirai.message.MessageReceipt;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@@ -18,6 +23,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Controller @Controller
public class AppController { public class AppController {
@@ -64,15 +71,19 @@ public class AppController {
@RequestMapping("/qq/send.do") @RequestMapping("/qq/send.do")
public String sendQQ(@RequestBody JSONObject json) { public String sendQQ(@RequestBody JSONObject json) {
File image = null; File image = null;
MessageReceipt<?> ret;
if (json.getString("message").isEmpty()) { if (json.getString("message").isEmpty()) {
return "not message"; return "not message";
} }
if (json.containsKey("image")) { List<BaseHandle<?>> list=new ArrayList<>();
image = HttpTools.syncDownload(json.getString("image"), System.currentTimeMillis() + ".png",true); list.add(new Text(json.getString("message")));
if(json.getString("image")!=null&&!json.getString("image").isEmpty()){
list.add(new Image(json.getString("image")));
} }
ret = QQBotManager.getInstance().sendMessage(image, json.getLong("qq"), json.getString("message")); SendMessageResponse sent = QQBotManager.getInstance().sendMessage(QQDatabase.checkFriend(json.getLong("qq")),
return ret==null?"message send fail":"message send success"; json.getLong("qq"),
list
);
return sent == null ? "0" : sent.getId() + "";
} }
@ResponseBody @ResponseBody
@@ -86,6 +97,7 @@ public class AppController {
QQBotManager.getInstance().sendMessage(_file, 583819556L, "time = " + AppTools.getToDayNowTimeToString()); QQBotManager.getInstance().sendMessage(_file, 583819556L, "time = " + AppTools.getToDayNowTimeToString());
return "ok"; return "ok";
} }
@RequestMapping("/test.do") @RequestMapping("/test.do")
@ResponseBody @ResponseBody
public String test(HttpServletResponse response) { public String test(HttpServletResponse response) {
@@ -98,6 +110,7 @@ public class AppController {
// return HttpTools.http_get("http://192.168.31.88:9999/live/index.m3u8",null); // return HttpTools.http_get("http://192.168.31.88:9999/live/index.m3u8",null);
return "1"; return "1";
} }
@RequestMapping("*.ts") @RequestMapping("*.ts")
public void test2(HttpServletResponse response, HttpServletRequest request) { public void test2(HttpServletResponse response, HttpServletRequest request) {
try { try {

View File

@@ -63,7 +63,7 @@ public class MiRouterDevices {
} }
private String getRemoteAddress(String ip) { private String getRemoteAddress(String ip) {
JSONObject data = JSON.parseObject(HttpTools.get(XiaoMiRouter.getDeviceListUrl())); JSONObject data = JSON.parseObject(HttpTools.get(XiaoMiRouter.getInstance().getDeviceListUrl()));
if (data.getInteger("code") == 0) { if (data.getInteger("code") == 0) {
JSONArray array=data.getJSONArray("list"); JSONArray array=data.getJSONArray("list");
for (Object o : array) { for (Object o : array) {

View File

@@ -4,25 +4,19 @@ import com.yutou.qqbot.MessageEvent.AdminMessage;
import com.yutou.qqbot.QQNumberManager; import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import kotlin.coroutines.CoroutineContext; import kotlin.coroutines.CoroutineContext;
import net.mamoe.mirai.event.EventHandler;
import net.mamoe.mirai.event.ListeningStatus;
import net.mamoe.mirai.event.SimpleListenerHost;
import net.mamoe.mirai.event.events.GroupMessageEvent;
import net.mamoe.mirai.event.events.MessageEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class QQMessageListener extends SimpleListenerHost { public class QQMessageListener {
@Override
public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) { public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) {
// super.handleException(context, exception); // super.handleException(context, exception);
exception.printStackTrace(); exception.printStackTrace();
} }
@EventHandler public void onMessage() {
public ListeningStatus onMessage(MessageEvent event) { /* long qqNumber;
long qqNumber;
boolean isGroup; boolean isGroup;
if (event instanceof GroupMessageEvent) { if (event instanceof GroupMessageEvent) {
qqNumber = ((GroupMessageEvent) event).getGroup().getId(); qqNumber = ((GroupMessageEvent) event).getGroup().getId();
@@ -51,7 +45,7 @@ public class QQMessageListener extends SimpleListenerHost {
} }
} }
return ListeningStatus.LISTENING; // 表示继续监听事件 return ListeningStatus.LISTENING; // 表示继续监听事件*/
} }

View File

@@ -1,18 +1,24 @@
package com.yutou.qqbot; package com.yutou.qqbot;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.okhttp.HttpLoggingInterceptor;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import lombok.val;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @SpringBootApplication
public class QQBotApplication { public class QQBotApplication {
public static final String version="QQBot v.1.6.2"; public static final String version = "QQBot v.1.7.10";
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("version = " + version); System.out.println("version = " + version);
SpringApplication.run(QQBotApplication.class, args); SpringApplication.run(QQBotApplication.class, args);
RedisTools.initRedisPoolSub(); RedisTools.initRedisPoolSub();
QQBotManager.getInstance(); QQBotManager.getInstance();
//1 val log = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.QQ_LOG, Boolean.class,true);
NapCatApi.setLog(log);
} }
} }

View File

@@ -1,13 +1,27 @@
package com.yutou.qqbot; package com.yutou.qqbot;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.enums.MessageEnum;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.BaseHandle;
import com.yutou.napcat.handle.OtherHandle;
import com.yutou.qqbot.MessageEvent.AdminMessage;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.XiaoMiRouter;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Set;
@Controller @Controller
public class QQBotController { public class QQBotController {
@@ -33,4 +47,58 @@ public class QQBotController {
AppTools.sendServer(title, msg); AppTools.sendServer(title, msg);
return "ok"; return "ok";
} }
@ResponseBody
@RequestMapping("/napcat/qq/bot.do")
public String qq_bot(HttpServletRequest request, HttpServletResponse response) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
BufferedInputStream stream = new BufferedInputStream(request.getInputStream());
byte[] bytes = new byte[1024];
int len = 0, size;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
String str = outputStream.toString(StandardCharsets.UTF_8);
MessageEvent event = MessageEvent.parseHandle(str);
long qqNumber = event.isGroup() ? event.getGroupId() : event.getUserId();
boolean isGroup = event.isGroup();
if ((event.isGroup() && event.getSource().getUserId() == 583819556L) || (!event.isGroup() && event.getUserId() == 583819556L)) {
new AdminMessage(qqNumber, event.getRawMessage());
}
for (Class<?> model : Model.classList) {
if (QQNumberManager.getManager().isUseModel(qqNumber, model) || !isGroup) {
try {
Model useModel = (Model) model.getDeclaredConstructor().newInstance();
if (!useModel.isUserPublic()) {
if (!QQNumberManager.getManager().isExistsPower(event.getSource().getFromId(), useModel.getUsePowers())) {
continue;
}
}
useModel.onMessage(qqNumber, event, isGroup);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "200";
}
@ResponseBody
@RequestMapping("/router/wan1ip.do")
public String getWan1IP(){
return XiaoMiRouter.getInstance().getWan1IPAddress();
}
@ResponseBody
@RequestMapping("/router/wan2ip.do")
public String getWan2IP(){
return XiaoMiRouter.getInstance().getWan2IPAddress();
}
} }

View File

@@ -2,22 +2,27 @@ package com.yutou.qqbot;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Listeners.QQMessageListener; import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.handle.*;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.napcat.model.FriendBean;
import com.yutou.napcat.model.GroupBean;
import com.yutou.napcat.model.GroupUserBean;
import com.yutou.napcat.model.SendMessageResponse;
import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.HttpBody;
import com.yutou.okhttp.HttpCallback;
import com.yutou.qqbot.data.MessageChainBuilder;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.utlis.*; import com.yutou.qqbot.utlis.*;
import net.mamoe.mirai.Bot; import okhttp3.Headers;
import net.mamoe.mirai.BotFactory; import retrofit2.Response;
import net.mamoe.mirai.auth.BotAuthorization;
import net.mamoe.mirai.event.GlobalEventChannel;
import net.mamoe.mirai.message.MessageReceipt;
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.File;
import java.io.IOException; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
public class QQBotManager { public class QQBotManager {
@@ -26,7 +31,6 @@ public class QQBotManager {
private static QQBotManager botManager = null; private static QQBotManager botManager = null;
private Bot bot;
private static final long qqGroup = 891655174L; private static final long qqGroup = 891655174L;
private boolean isLogin = false; private boolean isLogin = false;
private static boolean isInit = false; private static boolean isInit = false;
@@ -41,71 +45,48 @@ public class QQBotManager {
} }
private void init() { private void init() {
new Thread(new Runnable() { sendMessage(true, 583819556L, "姬妻酱上线拉~☆Daze~ 当前版本:" + QQBotApplication.version);
private void reset() { NapCatApi.getGroupApi().getGroupList().enqueue(new HttpCallback<List<GroupBean>>() {
try { @Override
Log.i("QQBot", "签名加密服务未启动,1分钟后重试"); public void onResponse(Headers headers, int code, String status, List<GroupBean> response, String rawResponse) {
Thread.sleep(60 * 1000); for (GroupBean groupBean : response) {
init(); QQDatabase.addGroup(groupBean.getGroupId(), groupBean);
} catch (InterruptedException e) { QQNumberManager.getManager().addNumber(groupBean.getGroupId(), true);
e.printStackTrace();
} }
} }
@Override @Override
public void run() { public void onFailure(Throwable throwable) {
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"))) {
noBotLog();
noNetworkLog();
}
} }
}); });
//Events.registerEvents(bot, new MessageListener()); NapCatApi.getFriendApi().getFriendList().enqueue(new HttpCallback<List<FriendBean>>() {
GlobalEventChannel.INSTANCE.registerListenerHost(new QQMessageListener());
// GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, new MessageListener());
bot.login();
new Thread(new Runnable() {
@Override @Override
public void run() { public void onResponse(Headers headers, int code, String status, List<FriendBean> response, String rawResponse) {
try { for (FriendBean friendBean : response) {
Thread.sleep(1000); QQDatabase.addUser(friendBean.getUserId(), friendBean);
} catch (InterruptedException e) { QQNumberManager.getManager().addNumber(friendBean.getUserId(), false);
e.printStackTrace();
} }
String str = sendMessage("姬妻酱上线拉~☆Daze~ 当前版本:" + QQBotApplication.version); }
Log.i(str);
@Override
public void onFailure(Throwable throwable) {
}
});
NapCatApi.getUtilsApi().getLoginInfo().enqueue(new HttpCallback<FriendBean>() {
@Override
public void onResponse(Headers headers,int code, String status, FriendBean response, String rawResponse) {
QQDatabase.setMe(response);
}
@Override
public void onFailure(Throwable throwable) {
}
});
isInit = true; isInit = true;
} }
}).start();
bot.join();
}
}).start();
}
public synchronized static QQBotManager getInstance() { public synchronized static QQBotManager getInstance() {
if (botManager == null && !isInit) { if (botManager == null && !isInit) {
@@ -114,135 +95,162 @@ public class QQBotManager {
return botManager; return botManager;
} }
public boolean isLogin() {
return isLogin;
}
private Image getImage(File file, Long qq) {
if (file == null) {
return null;
}
if (bot != null) {
ExternalResource resource = ExternalResource.create(file);
Image image;
if (QQNumberManager.getManager().isGroup(qq)) {
image = Objects.requireNonNull(bot.getGroup(qq)).uploadImage(resource);
} else {
image = Objects.requireNonNull(bot.getFriend(qq)).uploadImage(resource);
}
try {
resource.close();
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
return null;
}
private String getNotLoginQQ() { private String getNotLoginQQ() {
return "没有登录QQ"; return "没有登录QQ";
} }
public SendMessageResponse sendPrivateMessage(Long qq, BaseHandle<?>... items) {
return sendMessage(true, qq, items);
}
private SendMessageResponse sendGroupMessage(Long group, BaseHandle<?>... items) {
return sendMessage(false, group, items);
}
public SendMessageResponse sendMessage(boolean user, Long qq, String msg) {
return sendMessage(user, qq, new Text(msg));
}
public SendMessageResponse sendMessage(Long qq, BaseHandle<?>... items) {
return sendMessage(QQDatabase.checkFriend(qq), qq, Arrays.asList(items));
}
public SendMessageResponse sendMessage(boolean isUser, Long qq, BaseHandle<?>... items) {
return sendMessage(isUser, qq, Arrays.asList(items));
}
public SendMessageResponse sendMessage(boolean isUser, Long qq, List<BaseHandle<?>> items) {
try {
if (!ConfigTools.load(ConfigTools.CONFIG, ConfigTools.QQ, Boolean.class)) {
return null;
}
MessageHandleBuild handleBuild = MessageHandleBuild
.create()
.setGroup(!isUser)
.setQQNumber(qq);
for (BaseHandle<?> item : items) {
if (item.getData() == null) {
continue;
}
if (item instanceof Reply) {
if (((Reply) item).getData().getId() == -1) {
continue;
}
}
handleBuild.add(item);
}
Response<HttpBody<SendMessageResponse>> response;
if (isUser) {
response = NapCatApi.getMessageApi().sendPrivateMsg(
handleBuild.build()
).execute();
} else {
response = NapCatApi.getMessageApi().sendGroupMsg(
handleBuild.build()
).execute();
}
if (response.body() != null) {
return response.body().getData();
}
} catch (Exception e) {
e.printStackTrace();
SendMessageResponse response = new SendMessageResponse();
response.setId(-1);
response.setE(e.getMessage());
return response;
}
return null;
}
public String sendMessage(String text) { public String sendMessage(String text) {
if (bot != null && !StringUtils.isEmpty(text)) {
try { return sendMessage(false,defGroup,text).toString();
return Objects.requireNonNull(bot.getGroup(qqGroup)).sendMessage(text).toString();
} catch (Exception e) {
e.printStackTrace();
}
}
return getNotLoginQQ();
} }
public MessageReceipt<?> sendMessage(Long group, String text) { public SendMessageResponse sendMessage(Long group, String text) {
if (bot != null) { return sendMessage(QQDatabase.checkFriend(group), group, new Text(text));
try {
if (QQNumberManager.getManager().isGroup(group)) {
return Objects.requireNonNull(bot.getGroup(group)).sendMessage(text);
} else {
return Objects.requireNonNull(bot.getFriend(group)).sendMessage(text);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
} }
public MessageReceipt<?> sendMessage(Long group, MessageChainBuilder builder) { public void sendMessage(Long group, MessageChainBuilder builder) {
if (bot != null) {
if (QQNumberManager.getManager().isGroup(group)) { if (QQNumberManager.getManager().isGroup(group)) {
System.out.println("发群"); System.out.println("发群");
return Objects.requireNonNull(bot.getGroup(group)).sendMessage(builder.asMessageChain());
} else { } else {
System.out.println("发个人"); System.out.println("发个人");
return Objects.requireNonNull(bot.getFriend(group)).sendMessage(builder.asMessageChain());
} }
} }
return null;
}
public MessageReceipt<?> sendMessage(File imageFile, Long qq, String text) { public void sendMessage(File imageFile, Long qq, String text) {
return sendMessage(imageFile, qq, null, text); sendMessage(imageFile, qq, null, text);
} }
public MessageReceipt<?> sendMessage(File imageFile, Long qq, MessageChain replyMessage, String text) { public void sendMessage(File imageFile, Long qq, String replyMessageId, String text) {
try { List<BaseHandle<?>> items = new ArrayList<>();
if (bot != null) {
Image image = getImage(imageFile, qq); if (imageFile != null) {
MessageChainBuilder builder = new MessageChainBuilder(); items.add(new Image(imageFile));
if (replyMessage != null) {
builder.append(new QuoteReply(replyMessage));
}
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());
} else {
return Objects.requireNonNull(bot.getFriend(qq)).sendMessage(builder.asMessageChain());
}
}
} catch (Exception e) {
e.printStackTrace();
} }
return null; if (replyMessageId != null && !replyMessageId.isEmpty()) {
items.add(new Reply(Long.parseLong(replyMessageId)));
} }
public MessageReceipt<?> sendMessage(File imageFile, String text) { if (text != null && !text.isEmpty()) {
return sendMessage(imageFile, qqGroup, text); items.add(new Text(text));
} }
public String sendMessage(List<File> imgs, Long qq, String text) { if (!items.isEmpty()) {
System.out.println("imgs.size() = " + imgs.size()); sendMessage(QQDatabase.checkFriend(qq),qq, items);
if (bot != null) {
MessageChainBuilder builder = new MessageChainBuilder();
for (File img : imgs) {
builder.append(Objects.requireNonNull(getImage(img, qq)));
} }
builder.append(text);
if (QQNumberManager.getManager().isGroup(qq)) {
return Objects.requireNonNull(bot.getGroup(qq)).sendMessage(builder.asMessageChain()).toString();
} else {
return Objects.requireNonNull(bot.getFriend(qq)).sendMessage(builder.asMessageChain()).toString();
}
}
return getNotLoginQQ();
} }
public void sendMessage(File imageFile, String text) {
sendMessage(true,defQQ,new Image(imageFile),new Text(text));
}
public void sendMessage(List<File> imgs, Long qq, String text) {
}
public void groupBan(long qqGroup, long user, int timer, ObjectInterface objectInterface) {
NapCatApi.getGroupApi().groupBan(qqGroup, user, timer).enqueue(new HttpCallback<BaseBean>() {
@Override
public void onResponse(Headers headers,int code, String status, BaseBean response, String rawResponse) {
if (objectInterface != null) {
objectInterface.out("1");
}
}
@Override
public void onFailure(Throwable throwable) {
if (objectInterface != null) {
objectInterface.out(null);
}
}
});
}
public void getShutUpList(long qqGroup, HttpCallback<List<GroupUserBean>> callback) {
NapCatApi.getGroupApi().getGroupUserList(qqGroup,true).enqueue(callback);
}
public void setGroupSpecialTitle(long group,
long user,
String title,
long duration) {
NapCatApi.getGroupApi().setGroupSpecialTitle(group, user, title, duration).enqueue(new HttpCallback<BaseBean>() {
@Override
public void onResponse(Headers headers,int code, String status, BaseBean response, String rawResponse) {
}
@Override
public void onFailure(Throwable throwable) {
}
});
}
public static void main(String[] args) { public static void main(String[] args) {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
@@ -256,14 +264,15 @@ public class QQBotManager {
public void sendVersion() { public void sendVersion() {
String localVersion = QQBotApplication.version; String localVersion = QQBotApplication.version;
String serverVersion = HttpTools.get("http://tools.yutou233.cn:8000/public/version.do?token=zIrsh9TUZP2lfRW753PannG49E7VJvor"); String serverVersion = HttpTools.get("https://tools.yutou233.cn/public/version.do?token=zIrsh9TUZP2lfRW753PannG49E7VJvor");
String msg = "本地版本:" + localVersion + "\n" + "服务器版本:" + serverVersion; String msg = "本地版本:" + localVersion + "\n" + "服务器版本:" + serverVersion;
QQBotManager.getInstance().sendMessage(msg); QQBotManager.getInstance().sendMessage(msg);
AppTools.sendServer("服务版本查询", msg); // AppTools.sendServer("服务版本查询", msg);
}
public boolean isLogin() {
return true;
} }
public Bot getBot() {
return bot;
}
} }

View File

@@ -333,7 +333,7 @@ public class BiliBiliUtils {
public void download_ffmpeg(final List<String> url, final String saveName) { public void download_ffmpeg(final List<String> url, final String saveName) {
new Thread(() -> { new Thread(() -> {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append(ConfigTools.load(ConfigTools.CONFIG, "ffmpeg", String.class)).append(" "); builder.append(ConfigTools.load(ConfigTools.CONFIG, ConfigTools.FFMPEG, String.class)).append(" ");
/* builder.append("-user_agent").append(" "); /* builder.append("-user_agent").append(" ");
builder.append("\"").append("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 Referer:https://live.bilibili.com").append("\"").append(" "); builder.append("\"").append("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 Referer:https://live.bilibili.com").append("\"").append(" ");
builder.append("-cookies").append(" "); builder.append("-cookies").append(" ");

View File

@@ -0,0 +1,16 @@
package com.yutou.qqbot.data;
public class MessageChainBuilder {
StringBuilder sb;
public MessageChainBuilder() {
sb=new StringBuilder();
}
public MessageChainBuilder append(String s){
sb.append(s);
return this;
}
public MessageChainBuilder append(Object o){
sb.append(o.toString());
return this;
}
}

View File

@@ -22,9 +22,7 @@ public class Message {
public static Message create(String message, boolean isGTP) { public static Message create(String message, boolean isGTP) {
Message msg = new Message(); Message msg = new Message();
msg.content = message; msg.content = message;
if (isGTP) { msg.role = isGTP ? "assistant" : "user";
msg.role = "assistant";
}
return msg; return msg;
} }
} }

View File

@@ -0,0 +1,90 @@
package com.yutou.qqbot.data.gpt;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import java.util.List;
@Data
public class OpenAiBean {
@JSONField(name = "id")
private String id;
@JSONField(name = "choices")
private List<Choice> choices;
@JSONField(name = "tool_calls")
private List<ToolCall> toolCalls;
@JSONField(name = "usage")
private Usage usage;
@JSONField(name = "created")
private long created;
@JSONField(name = "model")
private String model;
@JSONField(name = "object")
private String object;
@JSONField(name = "system_fingerprint")
private String systemFingerprint;
@Data
public static class Choice {
@JSONField(name = "index")
private int index;
@JSONField(name = "message")
private Message message;
@JSONField(name = "finish_reason")
private String finishReason;
}
@Data
public static class Message {
@JSONField(name = "role")
private String role;
@JSONField(name = "content")
private String content;
@JSONField(name = "reasoning_content")
private String reasoningContent;
}
@Data
public static class ToolCall {
@JSONField(name = "id")
private String id;
@JSONField(name = "type")
private String type;
@JSONField(name = "function")
private Function function;
}
@Data
public static class Function {
@JSONField(name = "name")
private String name;
@JSONField(name = "arguments")
private String arguments;
}
@Data
public static class Usage {
@JSONField(name = "prompt_tokens")
private int promptTokens;
@JSONField(name = "completion_tokens")
private int completionTokens;
@JSONField(name = "total_tokens")
private int totalTokens;
}
}

View File

@@ -0,0 +1,138 @@
package com.yutou.qqbot.gpt;
import com.yutou.qqbot.data.baidu.Message;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class AbsGPTManager {
protected static final AtomicInteger MAX_MESSAGE = new AtomicInteger(20);
protected final ConcurrentHashMap<String, List<Message>> msgMap= new ConcurrentHashMap<>();
// 新增锁映射表
protected final ConcurrentHashMap<String, AtomicBoolean> userLocks = new ConcurrentHashMap<>();
protected String model ;
/**
* 清除与GPT管理器相关的所有缓存或状态信息。
*/
/**
* 这里确实是需要清空所有数据
*/
public synchronized void clear() { // 添加同步
msgMap.clear();
for (AtomicBoolean value : userLocks.values()) {
value.set(false);
}
userLocks.forEachValue(1, atomicBoolean -> atomicBoolean.set(false));
userLocks.clear();
}
/**
* 发送消息到指定用户。
*
* @param user 接收消息的用户标识符。
* @param message 要发送的消息内容。
* @return 包含消息发送结果的Message对象。
*/
public abstract Message sendMessage(String user, String message);
/**
* 将文本转换为图像。
*
* @param user 用户标识符。
* @param text 要转换为图像的文本内容。
* @return 包含生成图像的File对象。
*/
public abstract File textToImage(String user, String text);
/**
* 将图像转换为文本。
*
* @param user 用户标识符。
* @param file 包含要转换为文本的图像文件。
* @return 提取的文本内容。
*/
public abstract String imageToText(String user, File file);
/**
* 获取当前使用的GPT版本信息。
*
* @return GPT版本字符串。
*/
public abstract String getGPTVersion();
/**
* 设置最大消息数量。
*
* @param count 最大消息数量。
* @return 设置后的最大消息数量。
*/
public abstract int setMaxMessageCount(int count);
public List<Message> getMessageList(String user){
List<Message> list = msgMap.computeIfAbsent(user, k -> Collections.synchronizedList(new ArrayList<>()));
// 限制历史消息的最大数量
synchronized (list) {
if (list.size() >= MAX_MESSAGE.get()) {
int removeCount = list.size() - MAX_MESSAGE.get() + 1; // 腾出空间给新消息
list.subList(0, removeCount).clear();
}
}
return list;
}
/**
* 根据指定的类获取相应的GPT管理器实例。
*
* @param tClass GPT管理器的具体实现类。
* @return GPT管理器实例。
*/
public static <T extends AbsGPTManager> AbsGPTManager getManager(Class<T> tClass) {
if (tClass == BaiduGPTManager.class) {
return BaiduGPTManager.getManager();
}else if(tClass== SiliconGPTManager.class){
return SiliconGPTManager.getInstance();
}
return new AbsGPTManager() {
@Override
public void clear() {
}
@Override
public Message sendMessage(String user, String message) {
return null;
}
@Override
public File textToImage(String user, String text) {
return null;
}
@Override
public String imageToText(String user, File file) {
return "";
}
@Override
public String getGPTVersion() {
return "";
}
@Override
public int setMaxMessageCount(int count) {
return 0;
}
};
}
protected AbsGPTManager setModel(String model) {
this.model=model;
return this;
}
}

View File

@@ -0,0 +1,205 @@
package com.yutou.qqbot.gpt;
import com.baidubce.qianfan.Qianfan;
import com.baidubce.qianfan.model.chat.ChatResponse;
import com.baidubce.qianfan.model.image.Image2TextResponse;
import com.baidubce.qianfan.model.image.Text2ImageResponse;
import com.yutou.qqbot.data.baidu.Message;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.StringUtils;
import lombok.val;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class BaiduGPTManager extends AbsGPTManager {
private static final String AppID = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_APPID, String.class);
private static final String ApiKey = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_API_KEY, String.class);
//ConfigTools.load操作可以确保获取到相关参数所以无需关心
private static final String AccessKey = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_ACCESS_KEY, String.class);
private static final String SecretKey = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_SECRET_KEY, String.class);
private final static String modelFor40 = "ERNIE-4.0-8K";
private final static String modelFor35 = "ERNIE-Speed-128K";
private final Qianfan qianfan;
private BaiduGPTManager() {
qianfan = new Qianfan(AccessKey, SecretKey);
String savedVersion = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_VERSION, String.class);
if (StringUtils.isEmpty(savedVersion) || (!"3.5".equals(savedVersion) && !"4.0".equals(savedVersion))) {
savedVersion = "3.5";
ConfigTools.save(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_VERSION, savedVersion);
}
model = "3.5".equals(savedVersion) ? modelFor35 : modelFor40;
}
private static volatile BaiduGPTManager manager;
public static BaiduGPTManager getManager() {
if (manager == null) {
synchronized (BaiduGPTManager.class) {
if (manager == null) {
manager = new BaiduGPTManager();
}
}
}
return manager;
}
@Override
public int setMaxMessageCount(int count) {
MAX_MESSAGE.set(count);
return count;
}
public synchronized void setModelFor40() {
model = modelFor40;
ConfigTools.save(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_VERSION, "4.0");
}
public synchronized void setModelFor35() {
model = modelFor35;
ConfigTools.save(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_VERSION, "3.5");
}
// 这个是官方的示例代码,表示连续对话
private static void exampleChat() {
Qianfan qianfan = new Qianfan();
ChatResponse response = qianfan.chatCompletion()
// 设置需要使用的模型与endpoint同时只能设置一种
.model("ERNIE-Bot")
// 通过传入历史对话记录来实现多轮对话
.addMessage("user", "你好!你叫什么名字?")
.addMessage("assistant", "你好我是文心一言英文名是ERNIE Bot。")
// 传入本轮对话的用户输入
.addMessage("user", "刚刚我的问题是什么?")
.execute();
System.out.println("输出内容:" + response.getResult());
}
@Override
public Message sendMessage(String user, String message) {
// 获取或创建用户锁
AtomicBoolean lock = userLocks.computeIfAbsent(user, k -> new AtomicBoolean(false));
// 尝试加锁(如果已被锁定则立即返回提示)
if (!lock.compareAndSet(false, true)) {
return Message.create("您有请求正在处理中,请稍后再试", true);
}
try {
List<Message> list = getMessageList(user);
list.add(Message.create(message));
val builder = qianfan.chatCompletion()
.model(model);
for (Message msg : list) {
builder.addMessage(msg.getRole(), msg.getContent());
}
ChatResponse chatResponse = builder.execute();
Message response = Message.create(chatResponse.getResult(), true);
synchronized (list) {
list.add(response);
if (list.size() > MAX_MESSAGE.get()) {
int overflow = list.size() - MAX_MESSAGE.get();
list.subList(0, overflow).clear();
}
}
// msgMap.put(user, list);
return response;
} catch (Exception e) {
Log.e(e, message);
return Message.create("请求失败,请重试", true);
} finally {
lock.set(false);
userLocks.remove(user, lock);
}
}
/**
* 将文本转换为图像文件
* 该方法使用预训练的AI模型将给定的文本转换为图像并将其保存为文件
*
* @param user 用户标识符,用于为生成的图像文件命名
* @param text 要转换为图像的文本
* @return 返回生成的图像文件对象如果转换过程中发生错误则返回null
*/
@Override
public File textToImage(String user, String text) {
// 使用QianFan的text2Image方法将文本转换为图像数据
Text2ImageResponse response = qianfan.text2Image()
.prompt(text)
.execute();
// 获取转换后的图像数据以Base64编码的图像字符串形式
val b64Image = response.getData().get(0).getB64Image();
// 将Base64编码的图像数据转换为图像文件
// 创建一个临时目录下的图像文件,文件名包含用户标识符和当前时间戳,以确保唯一性
val imageFile = new File("tmp" + File.separator + user + "_" + System.currentTimeMillis() + ".png");
try (val inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(b64Image))) {
// 将解码后的图像数据复制到图像文件中,替换现有文件
Files.copy(inputStream, imageFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
return imageFile;
} catch (Exception e) {
// 如果在图像文件生成过程中发生错误,记录错误信息
Log.e(e);
}
// 如果发生错误返回null
return null;
}
/**
* 将图片转换为文本描述
*
* @param user 使用该功能的用户标识
* @param file 要转换的图片文件
* @return 转换后的文本描述如果转换失败则返回null
*/
@Override
public String imageToText(String user, File file) {
// 将file文件转换成base64的代码
try {
// 读取文件内容并转换为Base64编码
val base64 = Base64.getEncoder().encodeToString(Files.readAllBytes(file.toPath()));
// 调用图像转文本的API
Image2TextResponse response = qianfan.image2Text()
.image(base64)
.prompt("请描述这张图片中的主要内容和细节,以及它们之间的关系\n")
.execute();
String translationPrompt = "将以下英文内容严格翻译为简体中文不要解释、不要添加额外内容保留专业术语和名称如Star Wars保持英文\n" + response.getResult();
// 获取API返回的结果
return sendMessage("bot", translationPrompt).getContent();
} catch (Exception e) {
// 异常处理:记录错误日志
Log.e(e);
}
// 如果发生异常返回null
return null;
}
@Override
public String getGPTVersion() {
return model;
}
public static void main(String[] args) throws Exception {
// BaiduGPTManager.getManager().textToImage("user","画一个猫娘,用二次元动画画风,她是粉色头发,坐在地上");
// BaiduGPTManager.getManager().imageToText("user",new File("test.png"));
// Message message = BaiduGPTManager.getManager().sendMessage("user", "现在假设小猪等于1,小猴等于2");
// System.out.println(message.getContent());
// message = BaiduGPTManager.getManager().sendMessage("user", "那么小猪加上小猴等于多少?");
// System.out.println(message.getContent());
System.out.println(BaiduGPTManager.getManager().sendMessage("user", "分析这个网页链接的页面内容,而非链接本身:https://www.bilibili.com/video/BV1TTf5YrESz/").getContent());
}
}

View File

@@ -0,0 +1,117 @@
package com.yutou.qqbot.gpt;
import com.yutou.okhttp.HttpLoggingInterceptor;
import com.yutou.qqbot.data.baidu.Message;
import com.yutou.qqbot.data.gpt.OpenAiBean;
import com.yutou.qqbot.http.GPTApi;
import com.yutou.qqbot.http.GPTBuilder;
import lombok.val;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class SiliconGPTManager extends AbsGPTManager {
//生成单例模式
private volatile static SiliconGPTManager instance = new SiliconGPTManager();
private SiliconGPTManager() {
}
public static SiliconGPTManager getInstance() {
if (instance == null) {
synchronized (SiliconGPTManager.class) {
if (instance == null) {
instance = new SiliconGPTManager();
}
}
}
return instance;
}
@Override
public synchronized Message sendMessage(String user, String message) {
// 获取或创建用户锁
AtomicBoolean lock = userLocks.computeIfAbsent(user, k -> new AtomicBoolean(false));
try {
GPTApi.setLog(false);
// 尝试加锁(如果已被锁定则立即返回提示)
if (!lock.compareAndSet(false, true)) {
return Message.create("您有请求正在处理中,请稍后再试", true);
}
val builder = GPTBuilder.create(model);
List<Message> list=getMessageList(user);
list.add(Message.create(message));
for (Message msg : list) {
builder.addMessage(msg.getRole(),msg.getContent());
}
val response = GPTApi.getApi().completions(builder.build()).execute();
if (!response.isSuccessful()) {
return Message.create("API请求失败", true);
}
val body = response.body();
if (body == null || body.getData() == null) {
return Message.create("API请求为空", true);
}
if (body.getRetcode() != 0) {
return Message.create(body.getMsg(), true);
}
val choices = body.getData().getChoices();
if (choices == null || choices.isEmpty()) {
return Message.create("没有对话信息", true);
}
val choice = choices.get(choices.size() - 1);
val bot = Message.create(choice.getMessage().getContent(), true);
list.add(bot);
return bot;
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
lock.set(false);
userLocks.remove(user, lock);
}
}
@Override
public File textToImage(String user, String text) {
return null;
}
@Override
public String imageToText(String user, File file) {
return "";
}
@Override
public String getGPTVersion() {
return model;
}
@Override
public int setMaxMessageCount(int count) {
MAX_MESSAGE.set(count);
return count;
}
public static void main(String[] args) {
String model="THUDM/glm-4-9b-chat";
val message = AbsGPTManager.getManager(SiliconGPTManager.class)
.setModel(model)
.sendMessage("user", "宫廷玉液酒的下一句是什么?");
System.out.println(message);
System.out.println(AbsGPTManager.getManager(SiliconGPTManager.class)
.setModel(model)
.sendMessage("user", "宫廷玉液酒减去大锤等于多少")
);
}
}

View File

@@ -0,0 +1,26 @@
package com.yutou.qqbot.http;
import com.yutou.okhttp.HttpLoggingInterceptor;
import com.yutou.okhttp.api.BaseApi;
import com.yutou.qqbot.utlis.ConfigTools;
import lombok.val;
import java.util.HashMap;
public class GPTApi extends BaseApi {
public static void setLog(boolean log) {
HttpLoggingInterceptor.setLog(log);
}
public static SiliconGPTApi getApi() {
val api = new GPTApi();
api.setURL("https://api.siliconflow.cn/v1/");
// api.setURL("http://127.0.0.1:8080/");
HashMap<String, String> header = new HashMap<>();
header.put("Authorization", "Bearer sk-dcmhlbhyitcdnjbjfgflhwimahdmygfrcaopzjjcpgsfzmzo");
header.put("Content-Type", "application/json");
api.addHeader(header);
return api.createApi(SiliconGPTApi.class);
}
}

View File

@@ -0,0 +1,127 @@
package com.yutou.qqbot.http;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import lombok.val;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Data
class Message {
@JSONField(name = "role")
String role;
@JSONField(name = "content")
String content;
public Message(String role, String content) {
this.role = role;
this.content = content;
}
}
@Data
class GPTRequest {
@JSONField(name = "model")
String model;
@JSONField(name = "messages")
List<Message> messages = new ArrayList<>();
@JSONField(name = "stream")
boolean stream = false;
@JSONField(name = "max_tokens")
int maxTokens;
@JSONField(name = "stop")
List<String> stop = new ArrayList<>(List.of("null"));
@JSONField(name = "temperature")
float temperature ;
@JSONField(name = "top_p")
float topP ;
@JSONField(name = "top_k")
int topK ;
@JSONField(name = "frequency_penalty")
float frequencyPenalty;
}
public class GPTBuilder {
private final GPTRequest request;
private GPTBuilder(String model) {
request = new GPTRequest();
request.model = model;
}
public static GPTBuilder create(String model) {
return new GPTBuilder(model);
}
public GPTBuilder addMessage(String content,boolean isGPT) {
request.messages.add(new Message(isGPT ? "assistant" : "user", content));
return this;
}
public GPTBuilder addMessage(String role, String content) {
request.messages.add(new Message(role, content));
return this;
}
public GPTBuilder setMaxTokens(int maxTokens) {
request.maxTokens = maxTokens;
return this;
}
public GPTBuilder setStream(boolean stream) {
request.stream = stream;
return this;
}
public GPTBuilder setTemperature(float temperature) {
request.temperature = temperature;
return this;
}
public GPTBuilder setTopP(float topP) {
request.topP = topP;
return this;
}
public GPTBuilder setTopK(int topK) {
request.topK = topK;
return this;
}
public GPTBuilder setFrequencyPenalty(float frequencyPenalty) {
request.frequencyPenalty = frequencyPenalty;
return this;
}
// 可以根据需要添加更多配置方法
public JSONObject build() {
val json = JSONObject.parse(JSONObject.toJSONString(request));
// 创建一个迭代器来遍历JSON对象的键
Iterator<String> keys = json.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
Object value = json.get(key);
// 检查值是否为0或为空字符串
if (value == null || value.equals(0) || (value instanceof String && ((String) value).isEmpty())) {
keys.remove(); // 移除键值对
}
}
return json;
}
}

View File

@@ -0,0 +1,17 @@
package com.yutou.qqbot.http;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.model.MessageBean;
import com.yutou.okhttp.HttpBody;
import com.yutou.qqbot.data.gpt.OpenAiBean;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface SiliconGPTApi {
@POST("/chat/completions")
Call<HttpBody<OpenAiBean>> completions(
@Body
JSONObject message
);
}

View File

@@ -3,7 +3,9 @@ package com.yutou.qqbot.interfaces;
import java.io.File; import java.io.File;
public abstract class DownloadInterface { public abstract class DownloadInterface {
public void onDownloading(double soFarBytes, double totalBytes){};
public void onDownload(File file){}; public void onDownload(File file){};
public void onError(Exception e){}; public void onError(Exception e){};
public void onDownloadStart(){}
public boolean onDownloading(double soFarBytes, double totalBytes){return true;}
} }

View File

@@ -3,11 +3,11 @@ package com.yutou.qqbot.models.Animal;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*; import com.yutou.qqbot.utlis.*;
import net.mamoe.mirai.event.events.MessageEvent;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@@ -17,6 +17,7 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@UseModel @UseModel
public class TurnipProphet extends Model { public class TurnipProphet extends Model {
public static class TurnipData { public static class TurnipData {
@@ -69,7 +70,7 @@ public class TurnipProphet extends Model {
user = qq; user = qq;
sendQQ = qq; sendQQ = qq;
if (isGroup) { if (isGroup) {
if (!event.getMessage().serializeToMiraiCode().contains("[mirai:at:2476945931]")) { if (!event.isAtMe()) {
return; return;
} }
user = event.getSource().getFromId(); user = event.getSource().getFromId();
@@ -271,6 +272,11 @@ public class TurnipProphet extends Model {
out.append("网页版:").append("\n").append(url).append("\n"); out.append("网页版:").append("\n").append(url).append("\n");
out.append("祝好运 :)"); out.append("祝好运 :)");
if (ConfigTools.load(ConfigTools.CONFIG, ConfigTools.TURNIP_PROPHET_SEND_TMP_GROUP, Boolean.class)) {
out.append("\n使用者:").append(sendQQ);
sendQQ = 891655174L;
}
Log.i("TurnipProphet", out.toString() + "\n 发送QQ" + sendQQ); Log.i("TurnipProphet", out.toString() + "\n 发送QQ" + sendQQ);
QQBotManager.getInstance().sendMessage(sendQQ, getMessage(out.toString())); QQBotManager.getInstance().sendMessage(sendQQ, getMessage(out.toString()));
return prArray.getJSONObject(0).getString(TurnipData.MODEL); return prArray.getJSONObject(0).getString(TurnipData.MODEL);
@@ -304,7 +310,8 @@ public class TurnipProphet extends Model {
public Map<String, String> openTurnip(String prices, String pattern) throws Exception { public Map<String, String> openTurnip(String prices, String pattern) throws Exception {
String url = String.format("http://192.168.31.88:7000/?prices=%s%s", String url = String.format("http://%s/?prices=%s%s",
ConfigTools.load(ConfigTools.CONFIG, ConfigTools.TURNIP_PROPHET_SERVER, String.class),
prices, prices,
pattern == null ? "" : "&pattern=" + pattern pattern == null ? "" : "&pattern=" + pattern
); );

View File

@@ -1,17 +1,13 @@
package com.yutou.qqbot.models.BiliBili; package com.yutou.qqbot.models.BiliBili;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; 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.BiliBiliUtils;
import com.yutou.qqbot.bilibili.BiliLogin; import com.yutou.qqbot.bilibili.BiliLogin;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.QRCodeUtils;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
import java.util.Set; import java.util.Set;
@UseModel @UseModel
@@ -38,7 +34,7 @@ public class BiliBiliLive extends Model {
@Override @Override
public synchronized void onTime(Long qq, String time) { public synchronized void onTime(Long qq, String time) {
super.onTime(qq, time); super.onTime(qq, time);
if ("00:01:00".equals(time)) { if ("07:01:00".equals(time)) {
if (!new BiliLogin(QQBotManager.defQQ).testLogin()) { if (!new BiliLogin(QQBotManager.defQQ).testLogin()) {
new BiliLogin(QQBotManager.defQQ).loginAsQQ(); new BiliLogin(QQBotManager.defQQ).loginAsQQ();
System.out.println(BiliBiliUtils.getInstance(QQBotManager.defQQ).getLoginInfo()); System.out.println(BiliBiliUtils.getInstance(QQBotManager.defQQ).getLoginInfo());

View File

@@ -2,20 +2,30 @@ package com.yutou.qqbot.models.BiliBili;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.enums.MessageEnum;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.MessageHandleBuild;
import com.yutou.napcat.handle.OtherHandle;
import com.yutou.napcat.handle.Reply;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.napcat.model.MessageBean;
import com.yutou.okhttp.HttpBody;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.bilibili.*; import com.yutou.qqbot.bilibili.*;
import com.yutou.qqbot.interfaces.ObjectInterface; import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*; import com.yutou.qqbot.utlis.AppTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.qqbot.utlis.ConfigTools;
import net.mamoe.mirai.message.data.QuoteReply; import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.StringUtils;
import retrofit2.Response;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -55,15 +65,9 @@ public class BiliVideo extends Model {
@Override @Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) { public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup); super.onMessage(qq, event, isGroup);
if (event.getMessage().serializeToMiraiCode().contains("mirai:app")) { if (event.isAtMe() && event.hasType(MessageEnum.REPLY)) {
int id = event.getSource().getIds()[0]; Reply reply = event.findType(Reply.class);
String json = event.getMessage().get(1).contentToString(); long id = reply.getData().getId();
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("总结")) { if (msg.contains("省流") || msg.contains("总结")) {
String value = onAIVideo(id); String value = onAIVideo(id);
if (!StringUtils.isEmpty(value)) { if (!StringUtils.isEmpty(value)) {
@@ -72,20 +76,17 @@ public class BiliVideo extends Model {
} }
} }
} }
}
private String onAIVideo(int id) { private String onAIVideo(long id) {
String string = RedisTools.get("qq_msg_id_" + id); try {
//RedisTools.remove("qq_msg_id_"+id); Response<HttpBody<MessageBean>> execute = NapCatApi.getMessageApi().getMessage(MessageHandleBuild.create().setMessageId(String.valueOf(id)).build()).execute();
String url = null; if(execute.body()==null){
if (StringUtils.isEmpty(string)) { return "省流失败";
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");
}
} }
MessageEvent handle = MessageEvent.parseHandleHttp(execute.body().getSrc());
if (handle.hasType(MessageEnum.JSON)) {
OtherHandle type = handle.findType(OtherHandle.class);
String url = type.getData().getMeta().getDetail1().getQqdocurl();
if (StringUtils.isEmpty(url)) { if (StringUtils.isEmpty(url)) {
return "地址不正确"; return "地址不正确";
} }
@@ -99,6 +100,12 @@ public class BiliVideo extends Model {
if (!StringUtils.isEmpty(ai)) { if (!StringUtils.isEmpty(ai)) {
return ai; return ai;
} }
}
} catch (Exception e) {
e.printStackTrace();
}
return "省流失败"; return "省流失败";
} }

View File

@@ -1,14 +1,21 @@
package com.yutou.qqbot.models.Commands; package com.yutou.qqbot.models.Commands;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface; import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.HttpTools;
import java.nio.charset.StandardCharsets;
@UseModel @UseModel
public class BTDownload extends Model { public class BTDownload extends Model {
private static final String DownloadHomePath = "/media/yutou/disk_lvm/public/download/"; private static final String DownloadHomePath = "/media/yutou/disk_lvm/public/download/";
@Override @Override
public boolean isUserPublic() { public boolean isUserPublic() {
return false; return false;
@@ -31,18 +38,12 @@ public class BTDownload extends Model {
super.onMessage(qq, event, isGroup); super.onMessage(qq, event, isGroup);
if (msg.startsWith("magnet:?xt=")) { if (msg.startsWith("magnet:?xt=")) {
String builder = "已添加下载磁链"; String builder = "已添加下载磁链";
QQBotManager.getInstance().sendMessage(qq, builder); JSONObject json = new JSONObject();
String exec = String.format("qbittorrent-nox --save-path=%sdownload_tmp/%s \"%s\" " json.put("url", msg.trim());
,DownloadHomePath json.put("title", "qqbot/" + System.currentTimeMillis() + ".torrent");
, AppTools.getToDayTime() String post = HttpTools.post(ConfigTools.getServerUrl()+"qq/bt/download.do", json.toString().getBytes(StandardCharsets.UTF_8));
, msg builder += "\n" + post;
); QQBotManager.getInstance().sendMessage(event.isUser(), qq, builder);
AppTools.exec(exec, new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
}
},true,false);
} }
} }
} }

View File

@@ -1,14 +1,16 @@
package com.yutou.qqbot.models.Commands; package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.handle.Text;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface; import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.Log; import com.yutou.qqbot.utlis.Log;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import java.io.File; import java.io.File;
@UseModel @UseModel
public class BaiduDown extends Model { public class BaiduDown extends Model {
@Override @Override
@@ -32,7 +34,7 @@ public class BaiduDown extends Model {
public void onMessage(Long qq, MessageEvent event, boolean isGroup) { public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup); super.onMessage(qq, event, isGroup);
if (msg.startsWith(QQFromCommands.BAIDU_DOWN)) { if (msg.startsWith(QQFromCommands.BAIDU_DOWN)) {
QQBotManager.getInstance().sendMessage(qq,"开始同步百度云"); QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text("开始同步百度云"));
AppTools.exec("cd " + new File("baidupan").getAbsolutePath() + " && bypy downdir -v", new ObjectInterface() { AppTools.exec("cd " + new File("baidupan").getAbsolutePath() + " && bypy downdir -v", new ObjectInterface() {
@Override @Override
public void out(String data) { public void out(String data) {

View File

@@ -1,11 +1,22 @@
package com.yutou.qqbot.models.Commands; package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.handle.*;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.baidu.ResponseMessage; import com.yutou.qqbot.data.baidu.Message;
import com.yutou.qqbot.gpt.AbsGPTManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.BaiduGPTManager; import com.yutou.qqbot.gpt.BaiduGPTManager;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.HttpTools;
import lombok.val;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@UseModel @UseModel
public class BaiduGPT extends Model { public class BaiduGPT extends Model {
@@ -31,15 +42,99 @@ public class BaiduGPT extends Model {
@Override @Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) { public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup); super.onMessage(qq, event, isGroup);
if (msg.equals(QQGroupCommands.GPT_CLEAR)) { if (event.getTextMessage().equals(QQGroupCommands.GPT_CLEAR)) {
BaiduGPTManager.getManager().clear(); BaiduGPTManager.getManager().clear();
QQBotManager.getInstance().sendMessage(qq, "已经失忆捏"); QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text("已经失忆捏"));
} else if (isAt()) { } else if (event.isAtMe()) {
if(msg.contains("省流")|| msg.contains("总结")){ if (event.getTextMessage().contains("省流") || event.getTextMessage().contains("总结")) {
return; return;
} }
ResponseMessage message = BaiduGPTManager.getManager().sendMessage(String.valueOf(user), msg.replace("@2476945931", "").trim()); if ("GPT切换到4.0".equals(event.getTextMessage())) {
QQBotManager.getInstance().sendMessage(qq, message.getResult()); List<BaseHandle<?>> list = new ArrayList<>();
if (isAdmin()) {
list.add(new At(user));
list.add(new Text("切换为4.0了"));
BaiduGPTManager.getManager().clear();
BaiduGPTManager.getManager().setModelFor40();
QQBotManager.getInstance().sendMessage(event.isUser(), qq, list);
} else {
list.add(new At(user));
list.add(new Text("你没有权限"));
QQBotManager.getInstance().sendMessage(event.isUser(), qq, list);
}
return;
} else if ("GPT切换到3.5".equals(event.getTextMessage())) {
List<BaseHandle<?>> list = new ArrayList<>();
if (isAdmin()) {
list.add(new At(user));
list.add(new Text("切换为3.5了"));
BaiduGPTManager.getManager().clear();
BaiduGPTManager.getManager().setModelFor35();
QQBotManager.getInstance().sendMessage(event.isUser(), qq, list);
}else {
list.add(new At(user));
list.add(new Text("你没有权限"));
QQBotManager.getInstance().sendMessage(event.isUser(), qq, list);
}
return;
}else if(event.getTextMessage().contains("画画")){
val file = BaiduGPTManager.getManager().textToImage(String.valueOf(qq), event.getTextMessage().replace("@" + QQDatabase.getMe().getUserId(), "").replace("画画", "").trim());
if(file==null){
QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text("画不出"));
}else{
QQBotManager.getInstance().sendMessage(file,qq, event.getMessageId().toString(), "好嘞");
}
return;
}
if(checkImage()) {
parseImage(event, qq);
return;
}
Message message = BaiduGPTManager.getManager().sendMessage(
String.valueOf(qq),
event.getTextMessage().replace("@" + QQDatabase.getMe().getUserId(), "").trim());
String sb = "调用版本:" +
BaiduGPTManager.getManager().getGPTVersion() +
"\n" +
message.getContent();
QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text(sb));
} }
} }
private void parseImage(MessageEvent event, Long qq) {
Image imageHandle = event.findType(Image.class);
val replyHandle = event.findType(Reply.class);
if (replyHandle != null &&imageHandle==null) {
imageHandle = getReply(replyHandle.getData().getId()).findType(Image.class);
}
if(imageHandle==null){
return;
}
HttpTools.download(imageHandle.getData().getUrl(), "gpt_parse_image.png", new DownloadInterface() {
@Override
public void onDownload(File file) {
super.onDownload(file);
if(file==null){
return;
}
val text = BaiduGPTManager.getManager().imageToText(String.valueOf(qq), file);
QQBotManager.getInstance().sendMessage(event.isUser(),qq,new Reply(event.getMessageId()),new Text(text));
}
});
}
public static void main(String[] args) {
System.out.println(ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_VERSION));
val messageEvent = new MessageEvent();
messageEvent.setMessage(new ArrayList<>());
messageEvent.setRawMessage("");
new BaiduGPT().onMessage(123456789L, messageEvent, false);
BaiduGPTManager.getManager().clear();
BaiduGPTManager.getManager().setModelFor40();
new BaiduGPT().onMessage(123456789L, messageEvent, false);
/* BaiduGPTManager.getManager().clear();
BaiduGPTManager.getManager().setModelFor35();
new BaiduGPT().onMessage(123456789L, messageEvent, false);*/
}
} }

View File

@@ -1,20 +1,20 @@
package com.yutou.qqbot.models.Commands; package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.handle.BaseHandle;
import com.yutou.napcat.handle.Image;
import com.yutou.napcat.handle.Text;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.BangumiTools; import com.yutou.qqbot.utlis.BangumiTools;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@UseModel @UseModel
public class Bangumi extends Model { public class Bangumi extends Model {
@@ -25,13 +25,13 @@ public class Bangumi extends Model {
switch (msg) { switch (msg) {
case QQGroupCommands.QQ_BANGUMI_TODAY -> { case QQGroupCommands.QQ_BANGUMI_TODAY -> {
QQBotManager.getInstance().sendMessage(qq, "获取中..."); QQBotManager.getInstance().sendMessage(event.isUser(), qq, "获取中...");
RedisTools.remove("reportToDayBangumi"); RedisTools.remove("reportToDayBangumi");
QQBotManager.getInstance().sendMessage(qq, BangumiTools.reportToDayBangumi()); QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text(BangumiTools.reportToDayBangumi()));
} }
case QQGroupCommands.QQ_BANGUMI_LIST -> { case QQGroupCommands.QQ_BANGUMI_LIST -> {
QQBotManager.getInstance().sendMessage(qq, "获取中..."); QQBotManager.getInstance().sendMessage(event.isUser(), qq, "获取中...");
QQBotManager.getInstance().sendMessage(qq, BangumiTools.reportBangumiList()); QQBotManager.getInstance().sendMessage(event.isUser(), qq, BangumiTools.reportBangumiList());
} }
default -> { default -> {
if (msg.startsWith(QQGroupCommands.QQ_BANGUMI_SUB)) { if (msg.startsWith(QQGroupCommands.QQ_BANGUMI_SUB)) {
@@ -44,7 +44,7 @@ public class Bangumi extends Model {
private void subBanGumi(long qq, String msg) { private void subBanGumi(long qq, String msg) {
List<String> infos = null; List<String> infos = null;
QQBotManager.getInstance().sendMessage(qq, "获取中..."); QQBotManager.getInstance().sendMessage(event.isUser(), qq, "获取中...");
try { try {
int id = Integer.parseInt(msg.replace(QQGroupCommands.QQ_BANGUMI_SUB, "").trim()); int id = Integer.parseInt(msg.replace(QQGroupCommands.QQ_BANGUMI_SUB, "").trim());
infos = BangumiTools.reportBangumiInfo(id); infos = BangumiTools.reportBangumiInfo(id);
@@ -77,28 +77,20 @@ public class Bangumi extends Model {
return list; return list;
} }
private List<File> files;
private int index = 0; private int index = 0;
private void sendImagesMsg(List<String> imgs, Long qq, String text, String key) { private void sendImagesMsg(List<String> imgs, Long qq, String text, String key) {
files = new ArrayList<>();
index = 0; index = 0;
if (imgs.size() == 0) { if (imgs.size() == 0) {
QQBotManager.getInstance().sendMessage(qq, text); QQBotManager.getInstance().sendMessage(event.isUser(), qq, text);
return; return;
} }
List<BaseHandle<?>> list = new ArrayList<>();
for (String img : imgs) { for (String img : imgs) {
File file = HttpTools.syncDownload(img.replace("http://", "https://"), key + ".jpg",false); list.add(new Image(img.replace("http://", "https://")));
files.add(file);
send(imgs.size(), qq, text);
}
}
private void send(int size, Long qq, String text) {
if ((files.size() + index) == size) {
String str = QQBotManager.getInstance().sendMessage(files, qq, text);
Log.i("str = " + str);
} }
list.add(new Text(text));
QQBotManager.getInstance().sendMessage(event.isUser(), qq, list);
} }
@Override @Override
@@ -124,7 +116,8 @@ public class Bangumi extends Model {
public void onTime(Long qq, String time) { public void onTime(Long qq, String time) {
super.onTime(qq, time); super.onTime(qq, time);
switch (time) { switch (time) {
case "08:00:00", "20:00:00" -> QQBotManager.getInstance().sendMessage(qq, BangumiTools.reportToDayBangumi()); case "08:00:00", "20:00:00" ->
QQBotManager.getInstance().sendMessage(qq, BangumiTools.reportToDayBangumi());
} }
} }
} }

View File

@@ -1,13 +1,15 @@
package com.yutou.qqbot.models.Commands; package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.handle.QuoteReply;
import com.yutou.napcat.handle.Reply;
import com.yutou.napcat.handle.Text;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.MessageChainBuilder;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.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; import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_TIMEOUT;
@@ -33,10 +35,10 @@ public class MaoMaoWorkWaring extends Model {
super.onMessage(qq, event, isGroup); super.onMessage(qq, event, isGroup);
if (Integer.parseInt(AppTools.getHours()) >= 6 && event.getSource().getFromId() == 526306604 if (Integer.parseInt(AppTools.getHours()) >= 6 && event.getSource().getFromId() == 526306604
&& "false".equals(RedisTools.get("maomao_work_" + AppTools.getToDayTime(), "false"))) { && "false".equals(RedisTools.get("maomao_work_" + AppTools.getToDayTime(), "false"))) {
MessageChainBuilder builder=new MessageChainBuilder(); QQBotManager.getInstance().sendMessage(event.isUser(), qq,
builder.append(new QuoteReply(event.getMessage())); new Reply(user),
builder.append("别水了,快去打工,没钱氪老婆了"); new Text("别水了,快去打工,没钱氪老婆了")
QQBotManager.getInstance().sendMessage(qq,builder); );
RedisTools.set("maomao_work_" + AppTools.getToDayTime(), "true", 20 * 60 * 60); RedisTools.set("maomao_work_" + AppTools.getToDayTime(), "true", 20 * 60 * 60);
} }
} }

View File

@@ -2,6 +2,8 @@ package com.yutou.qqbot.models.Commands;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.handle.Image;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.DownloadInterface; import com.yutou.qqbot.interfaces.DownloadInterface;
@@ -9,7 +11,7 @@ import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.HttpTools; import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.Log; import com.yutou.qqbot.utlis.Log;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import java.io.File; import java.io.File;
@@ -42,7 +44,7 @@ public class Moyu extends Model {
public synchronized void onTime(Long qq, String time) { public synchronized void onTime(Long qq, String time) {
super.onTime(qq, time); super.onTime(qq, time);
if ("09:50:00".equals(time)) { if ("09:50:00".equals(time)) {
downloadImage(false, qq); // downloadImage(false, qq);
} }
if ("10:00:00".equals(time)) { if ("10:00:00".equals(time)) {
send(qq); send(qq);
@@ -78,13 +80,12 @@ public class Moyu extends Model {
} }
private void send(Long qq) { private void send(Long qq) {
File file = new File(HttpTools.downloadPath + AppTools.getToDayTime() + "_moyu.jpg");
Log.i(this, "发送图片 : file.exists = " + file.exists() + " qq = " + qq); String ret = HttpTools.get("https://api.vvhan.com/api/moyu?type=json");
if (file.exists()) { JSONObject json = JSON.parseObject(ret);
QQBotManager.getInstance().sendMessage(file, qq, ""); QQBotManager.getInstance().sendMessage(QQDatabase.checkFriend(qq), qq,
} else { new Image(json.getString("url"))
downloadImage(true, qq); );
}
} }
public static void main(String[] args) { public static void main(String[] args) {

View File

@@ -1,14 +1,15 @@
package com.yutou.qqbot.models.Commands; package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.handle.QuoteReply;
import com.yutou.napcat.handle.Reply;
import com.yutou.napcat.handle.Text;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.MessageChainBuilder;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.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; import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_TIMEOUT;
@@ -34,10 +35,11 @@ public class PaoPaoSleepWaring extends Model {
super.onMessage(qq, event, isGroup); super.onMessage(qq, event, isGroup);
if(Integer.parseInt(AppTools.getHours())>=22 && event.getSource().getFromId() == 914520754 if(Integer.parseInt(AppTools.getHours())>=22 && event.getSource().getFromId() == 914520754
&& "false".equals(RedisTools.get("paopao_sleep_"+AppTools.getToDayTime(),"false"))){ && "false".equals(RedisTools.get("paopao_sleep_"+AppTools.getToDayTime(),"false"))){
MessageChainBuilder builder=new MessageChainBuilder(); // builder.append(new QuoteReply(event.getMessage().getId()));
builder.append(new QuoteReply(event.getMessage())); QQBotManager.getInstance().sendMessage(event.isUser(),qq,
builder.append("别水了,该睡了~"); new Reply(user),
QQBotManager.getInstance().sendMessage(qq,builder); new Text("别水了,该睡了~")
);
RedisTools.set("paopao_sleep_"+AppTools.getToDayTime(),"true",1*60*60); RedisTools.set("paopao_sleep_"+AppTools.getToDayTime(),"true",1*60*60);
} }
/*if(event.getSource().getFromId() == 914520754 && msg.contains("#体力")){ /*if(event.getSource().getFromId() == 914520754 && msg.contains("#体力")){

View File

@@ -0,0 +1,149 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.At;
import com.yutou.napcat.handle.Text;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.napcat.model.GroupUserBean;
import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.HttpCallback;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools;
import okhttp3.Headers;
import java.text.SimpleDateFormat;
import java.util.*;
@UseModel
public class QQBean extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "QQ禁言";
}
Random random = new Random();
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (!isGroup) return;
if ("抽奖".equals(msg)) {
int hour = 60;
int day = 1440;
int max = 30 * day;
int time = 1;
if (random.nextInt(100) == 23) {
releaseAll(qq, true);
} else if (random.nextInt(10) > 2) {
time = random.nextInt(hour);
} else if (random.nextInt(10) > 4) {
time = random.nextInt(day);
} else if (random.nextInt(10) > 5) {
time = random.nextInt(day, 3 * day);
} else {
time = random.nextInt(max);
}
int sendTime = time;
QQBotManager.getInstance().groupBan(qq, user, sendTime * 60, new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
if (data != null) {
QQBotManager.getInstance().sendMessage(event.isUser(), qq,
new Text("恭喜"),
new At(user),
new Text("获得了" + sendTime + "分钟的禁言," + sendAchievement(qq, user, sendTime))
);
if (sendTime > day && random.nextInt(10) >= 3) {
int tmp = random.nextInt(sendTime / 2, sendTime);
QQBotManager.getInstance().groupBan(qq, user, (sendTime - tmp) * 60, null);
QQBotManager.getInstance().sendMessage(qq, "触发减伤:-" + tmp);
}
}
}
});
} else if ("大赦天下".equals(msg) && isAdmin()) {
releaseAll(qq, true);
} else if ("查看禁言列表".equals(msg) && isAdmin()) {
releaseAll(qq, false);
}
}
String sendAchievement(long qq, long user, int timer) {
Calendar data1 = Calendar.getInstance();
Calendar data2 = Calendar.getInstance();
data1.setTime(new Date());
data2.set(Calendar.HOUR_OF_DAY, 23);
data2.set(Calendar.MINUTE, 59);
data2.set(Calendar.SECOND, 59);
long time = data2.getTimeInMillis() - data1.getTimeInMillis();
String achievement = RedisTools.get("shut_" + qq + "_" + user);
int achievementTimer = timer;
if (achievement != null) {
achievementTimer += Integer.parseInt(achievement);
}
RedisTools.set("shut_" + qq + "_" + user, achievementTimer + "", time / 1000);
return "今日累计" + achievementTimer + "分钟禁言";
}
void releaseAll(long qq, boolean isRelease) {
QQBotManager.getInstance().getShutUpList(qq, new HttpCallback<List<GroupUserBean>>() {
@Override
public void onResponse(Headers headers, int code, String status, List<GroupUserBean> response, String rawResponse) {
List<GroupUserBean> shutList = new ArrayList<>();
for (GroupUserBean bean : response) {
if (bean.getShutUpTimestamp() > 60) {
shutList.add(bean);
}
}
if (!shutList.isEmpty()) {
if (!isRelease) {
StringBuilder sb = new StringBuilder();
for (GroupUserBean bean : shutList) {
sb.append(bean.getNickname()).append(":").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA).format(new Date(bean.getShutUpTimestamp()))).append("\n");
}
QQBotManager.getInstance().sendMessage(qq, "当前塞了:" + shutList.size() + "" + "\n" + sb);
return;
}
QQBotManager.getInstance().sendMessage(qq, "触发自动解禁,解禁人数:" + shutList.size() + "");
for (GroupUserBean bean : shutList) {
NapCatApi.getGroupApi().groupBan(qq, bean.getUserId(), 0).enqueue(new HttpCallback<BaseBean>() {
@Override
public void onResponse(Headers headers, int code, String status, BaseBean response, String rawResponse) {
}
@Override
public void onFailure(Throwable throwable) {
}
});
}
} else {
QQBotManager.getInstance().sendMessage(qq, "阿巴阿巴");
}
}
@Override
public void onFailure(Throwable throwable) {
}
});
}
}

View File

@@ -3,7 +3,7 @@ package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.models.audio.QQAudio; import com.yutou.qqbot.models.audio.QQAudio;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class Audio extends Model { public class Audio extends Model {

View File

@@ -4,7 +4,7 @@ import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.HttpTools; import com.yutou.qqbot.utlis.HttpTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class BtFlash extends Model { public class BtFlash extends Model {
@Override @Override

View File

@@ -3,7 +3,7 @@ package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class Cmd extends Model { public class Cmd extends Model {
@Override @Override

View File

@@ -3,7 +3,7 @@ package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class Help extends Model { public class Help extends Model {

View File

@@ -3,7 +3,7 @@ package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class IP extends Model { public class IP extends Model {
@Override @Override

View File

@@ -3,7 +3,7 @@ package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;

View File

@@ -4,7 +4,7 @@ import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class Restart extends Model { public class Restart extends Model {
@Override @Override

View File

@@ -1,12 +1,14 @@
package com.yutou.qqbot.models.Commands.System; package com.yutou.qqbot.models.Commands.System;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.handle.Text;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.IdeaTools; import com.yutou.qqbot.utlis.IdeaTools;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.StringUtils; import com.yutou.qqbot.utlis.StringUtils;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class ToolsIdea extends Model { public class ToolsIdea extends Model {
@Override @Override
@@ -49,7 +51,10 @@ public class ToolsIdea extends Model {
RedisTools.set("ideaUrl", msg.replace(QQGroupCommands.QQ_TOOLS_IDEA_URL, "").trim()); RedisTools.set("ideaUrl", msg.replace(QQGroupCommands.QQ_TOOLS_IDEA_URL, "").trim());
QQBotManager.getInstance().sendMessage(qq, "已设定下载地址:" + RedisTools.get("ideaUrl")); QQBotManager.getInstance().sendMessage(qq, "已设定下载地址:" + RedisTools.get("ideaUrl"));
} else if (msg.startsWith(QQGroupCommands.QQ_TOOLS_IDEA_FILE)) { } else if (msg.startsWith(QQGroupCommands.QQ_TOOLS_IDEA_FILE)) {
QQBotManager.getInstance().sendMessage(qq, IdeaTools.getIdea(event.getMessage().contentToString().replace(QQGroupCommands.QQ_TOOLS_IDEA_FILE, ""))); QQBotManager.getInstance().sendMessage(event.isUser(),qq,
new Text(msg.replace(QQGroupCommands.QQ_TOOLS_IDEA_FILE, ""))
);
// QQBotManager.getInstance().sendMessage(qq, IdeaTools.getIdea(event.getMessage().contentToString().replace(QQGroupCommands.QQ_TOOLS_IDEA_FILE, "")));
} }
} }
} }

View File

@@ -3,7 +3,7 @@ package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class UpdateIP extends Model { public class UpdateIP extends Model {
@Override @Override

View File

@@ -3,7 +3,7 @@ package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
@UseModel @UseModel
public class Version extends Model { public class Version extends Model {
@Override @Override

View File

@@ -1,14 +1,10 @@
package com.yutou.qqbot.models.Commands; package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.handle.Record;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.contact.AudioSupported; import com.yutou.napcat.event.MessageEvent;
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.io.File;
import java.util.Objects; import java.util.Objects;
@@ -35,20 +31,11 @@ public class WoodenFish extends Model {
@Override @Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) { public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup); super.onMessage(qq, event, isGroup);
File file = null;
if (msg.contains("地狱笑话")) { if (msg.contains("地狱笑话")) {
file=new File("muyu.mp3"); QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Record("muyu.mp3"));
QQBotManager.getInstance().sendMessage(qq,"功德+1"); QQBotManager.getInstance().sendMessage(event.isUser(), qq, "功德+1");
} else if (msg.contains("遥遥领先")) { } else if (msg.contains("遥遥领先")) {
file=new File("遥遥领先.silk"); QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Record("遥遥领先.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,15 +1,19 @@
package com.yutou.qqbot.models; package com.yutou.qqbot.models;
import com.yutou.qqbot.QQBotManager; import com.yutou.napcat.event.GroupMessageEvent;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.*;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.napcat.model.MessageBean;
import com.yutou.okhttp.HttpBody;
import com.yutou.qqbot.QQNumberManager; import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.interfaces.ModelInterface; import com.yutou.qqbot.interfaces.ModelInterface;
import com.yutou.qqbot.utlis.ConfigTools; import com.yutou.qqbot.utlis.ConfigTools;
import net.mamoe.mirai.Bot; import com.yutou.qqbot.utlis.Log;
import net.mamoe.mirai.event.events.GroupMessageEvent; import lombok.val;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -25,7 +29,7 @@ public abstract class Model implements ModelInterface {
public final static String QQ_GET_VERSION = "!version"; public final static String QQ_GET_VERSION = "!version";
public final static String QQ_CMD = "!cmd"; public final static String QQ_CMD = "!cmd";
public final static String QQ_BANGUMI_TODAY = "!今日动画"; public final static String QQ_BANGUMI_TODAY = "!今日动画";
public final static String QQ_BANGUMI_LIST = "!新番"; public final static String QQ_BANGUMI_LIST = "!动画";
public final static String QQ_BANGUMI_SUB = "!查动画"; public final static String QQ_BANGUMI_SUB = "!查动画";
public final static String QQ_AUDIO = "!语音"; public final static String QQ_AUDIO = "!语音";
public final static String QQ_AUDIO_OPEN_LAMP = "!开灯"; public final static String QQ_AUDIO_OPEN_LAMP = "!开灯";
@@ -85,16 +89,20 @@ public abstract class Model implements ModelInterface {
public void onMessage(Long qq, MessageEvent event, boolean isGroup) { public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
this.event = event; this.event = event;
msg = event.getMessage().contentToString(); msg = event.getRawMessage();
if(msg==null){
msg="";
}
msg = msg.replace("", "!").trim(); msg = msg.replace("", "!").trim();
this.isGroup = isGroup; this.isGroup = event.isGroup();
if (isGroup) { if (isGroup) {
user = event.getSource().getFromId(); user = event.getSource().getFromId();
GroupMessageEvent groupEvent = (GroupMessageEvent) event; group = event.getGroupId();
group = groupEvent.getGroup().getId();
if (QQNumberManager.getManager().isExistsPower(group, msg.split(" ")[0])) { if (QQNumberManager.getManager().isExistsPower(group, msg.split(" ")[0])) {
isGroupPower = true; isGroupPower = true;
} }
} else {
user = qq;
} }
} }
@@ -114,16 +122,49 @@ public abstract class Model implements ModelInterface {
return builder; return builder;
} }
public MessageChainBuilder getMessage(String text) { public String getMessage(String text) {
MessageChainBuilder chain = new MessageChainBuilder(); StringBuilder chain = new StringBuilder();
if (isGroup) { if (isGroup) {
chain.add(new At(user)); chain.append(new At(user));
chain.add("\n"); chain.append("\n");
} }
chain.add(text); chain.append(text);
return chain; return chain.toString();
} }
public boolean isAt() { public boolean isAt() {
return msg.contains("@"+ ConfigTools.load(ConfigTools.CONFIG,"qq_number",String.class)); return msg.contains("@" + ConfigTools.load(ConfigTools.CONFIG, ConfigTools.QQ_NUMBER, String.class));
}
public boolean checkImage(){
val image = event.findType(Image.class);
if(image!=null){
return true;
}
val reply = event.findType(Reply.class);
if(reply!=null){
val replyEvent = getReply(reply.getData().getId());
if(replyEvent!=null){
return replyEvent.findType(Image.class)!=null;
}
}
return false;
}
public MessageEvent getReply(long replyId){
HttpBody<MessageBean> body = null;
try {
body = NapCatApi.getMessageApi().getMessage(MessageHandleBuild.create().setMessageId(String.valueOf(replyId)).build()).execute().body();
if (body == null) {
return null;
}
return MessageEvent.parseHandleHttp(body.getSrc());
} catch (IOException e) {
Log.e(e);
}
return null;
}
public boolean isAdmin() {
return user == 583819556L;
} }
} }

View File

@@ -7,7 +7,7 @@ import com.yutou.qqbot.bilibili.BiliLogin;
import com.yutou.qqbot.interfaces.ObjectInterface; import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.QRCodeUtils; import com.yutou.qqbot.utlis.QRCodeUtils;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import java.io.File; import java.io.File;
@@ -120,7 +120,7 @@ public class BiliBiliMangeSign extends Model {
@Override @Override
public void onTime(Long qq, String time) { public void onTime(Long qq, String time) {
super.onTime(qq, time); super.onTime(qq, time);
if ("00:01:00".equals(time)) { if ("07:05:00".equals(time)) {
if (new BiliLogin(QQBotManager.defQQ).testLogin()) { if (new BiliLogin(QQBotManager.defQQ).testLogin()) {
String msg; String msg;
if (BiliBiliManga.sign() == null) { if (BiliBiliManga.sign() == null) {

View File

@@ -7,7 +7,7 @@ import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*; import com.yutou.qqbot.utlis.*;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import org.openqa.selenium.*; import org.openqa.selenium.*;
import java.io.File; import java.io.File;

View File

@@ -9,7 +9,7 @@ import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.HttpTools; import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.XiaoMiRouter; import com.yutou.qqbot.utlis.XiaoMiRouter;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.napcat.event.MessageEvent;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -64,7 +64,7 @@ public class MiRouter extends Model {
isRunTime = false; isRunTime = false;
} }
private void run()throws Exception{ private void run()throws Exception{
String url = XiaoMiRouter.getDeviceListUrl(); String url = XiaoMiRouter.getInstance().getDeviceListUrl();
JSONObject json = JSON.parseObject(HttpTools.get(url)); JSONObject json = JSON.parseObject(HttpTools.get(url));
if (json.getInteger("code") == 0) { if (json.getInteger("code") == 0) {
String _tmp = RedisTools.get(redis_key); String _tmp = RedisTools.get(redis_key);
@@ -114,7 +114,7 @@ public class MiRouter extends Model {
} }
RedisTools.set(redis_key, devs.toString()); RedisTools.set(redis_key, devs.toString());
}else { }else {
XiaoMiRouter.setNotToken(); XiaoMiRouter.getInstance().setNotToken();
} }
} }

View File

@@ -3,19 +3,19 @@ package com.yutou.qqbot.models.setu;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.*;
import com.yutou.napcat.model.SourceFrom;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.MessageChainBuilder;
import com.yutou.qqbot.interfaces.DownloadInterface; import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.HttpTools; import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.Log; import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.StringUtils; import com.yutou.qqbot.utlis.StringUtils;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.MessageReceipt;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import java.io.File; import java.io.File;
@@ -111,7 +111,7 @@ public class GetSeTu extends Model {
builder.append("明天见~"); builder.append("明天见~");
} }
if (builder != null) { if (builder != null) {
QQBotManager.getInstance().sendMessage(group, builder); QQBotManager.getInstance().sendMessage(QQDatabase.checkFriend(group), group, builder.toString());
} }
} }
@@ -218,41 +218,52 @@ public class GetSeTu extends Model {
for (Object tags : item.getJSONArray("tags")) { for (Object tags : item.getJSONArray("tags")) {
builder.append(tags).append(""); builder.append(tags).append("");
} }
builder.append("\n看不到图?点这里:").append(item.getJSONObject("urls").getString("regular"));
QQBotManager.getInstance().sendMessage(false, qq,
new Reply(event.getMessageId()),
new Text(builder.toString())
);
HttpTools.download(item.getJSONObject("urls").getString("regular"), HttpTools.download(item.getJSONObject("urls").getString("regular"),
System.currentTimeMillis() + "_setu.jpg", System.currentTimeMillis() + ".png",
true true,
, new DownloadInterface() { new DownloadInterface() {
@Override @Override
public void onDownload(File file) { public void onDownload(File file) {
super.onDownload(file); super.onDownload(file);
builder.append("\n看不到图?点这里:http://setu.cnmglz.com/setu/").append(file.getName()); Log.i("下载完成");
QQBotManager.getInstance().sendMessage(file, qq, event.getMessage(), ""); QQBotManager.getInstance().sendMessage(false, qq,
MessageChainBuilder chain = new MessageChainBuilder(); new Image(file),
chain.append(new QuoteReply(event.getMessage())); new Reply(event.getMessageId())
chain.append(builder.toString()); );
MessageReceipt<?> message = QQBotManager.getInstance().sendMessage(qq, chain);
Log.i(getModelName(), message);
} }
@Override @Override
public void onError(Exception e) { public void onError(Exception e) {
super.onError(e); super.onError(e);
getSeTu(model, tmpKey, r18, fuzzyR18, qq, event, reset - 1); QQBotManager.getInstance().sendMessage(false, qq,
e.printStackTrace(); new Image(item.getJSONObject("urls").getString("regular")),
new Reply(event.getMessageId())
);
} }
}); }
);
return true; return true;
} }
public static void main(String[] args) { public static void main(String[] args) {
String msg = "来点1色图"; String msg = "来点色图";
Pattern pattern = Pattern.compile("来点(.*?)色图"); Pattern pattern = Pattern.compile("来点(.*?)色图");
Matcher matcher = pattern.matcher(msg); Matcher matcher = pattern.matcher(msg);
String key = null; MessageEvent event = new MessageEvent();
if (matcher.find()) { SourceFrom sourceFrom = new SourceFrom();
key = matcher.group(1); sourceFrom.setUserId(891655174L);
} event.setMessageType("private");
System.out.println("key = " + key); event.setSource(sourceFrom);
event.setGroupId(891655174L);
event.setMessageId(-1);
event.setRawMessage(msg);
new GetSeTu().onMessage(891655174L, event, true);
} }
} }

View File

@@ -4,17 +4,22 @@ package com.yutou.qqbot.models.setu;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.enums.MessageEnum;
import com.yutou.napcat.event.GroupMessageEvent;
import com.yutou.napcat.handle.*;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.napcat.model.MessageBean;
import com.yutou.okhttp.HttpBody;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager; import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.MessageChainBuilder;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools; import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.Log; import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.RedisTools; import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.GroupMessageEvent; import com.yutou.napcat.event.MessageEvent;
import net.mamoe.mirai.event.events.MessageEvent; import com.yutou.qqbot.utlis.StringUtils;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.Image;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
@@ -31,7 +36,7 @@ public class QQSetu extends Model {
private Timer timer; private Timer timer;
private static final Map<String, Float> setuScore = new HashMap<>(); private static final Map<String, Float> setuScore = new HashMap<>();
public void printTodaySetu() { public void printTodaySetu() throws Exception {
String redisKey = AppTools.getToDayTime() + "_setu"; String redisKey = AppTools.getToDayTime() + "_setu";
Log.i("今日涩图 redisKey = " + redisKey); Log.i("今日涩图 redisKey = " + redisKey);
String js = RedisTools.get(redisKey, db_print); String js = RedisTools.get(redisKey, db_print);
@@ -62,13 +67,34 @@ public class QQSetu extends Model {
RedisTools.set(db_print, redisKey, json.toJSONString()); RedisTools.set(db_print, redisKey, json.toJSONString());
JSONObject info = setu.getJSONObject("info"); JSONObject info = setu.getJSONObject("info");
JSONObject score = setu.getJSONObject("score"); JSONObject score = setu.getJSONObject("score");
MessageChainBuilder builder = new MessageChainBuilder(); HttpBody<MessageBean> body = NapCatApi.getMessageApi().getMessage(
builder.append(Image.fromId(info.getString("id"))); MessageHandleBuild.create().setMessageId(String.valueOf(info.getLong("id"))).build()
builder.append("本日最佳涩图由").append(new At(info.getLong("sourQQ"))).append("提供\n"); ).execute().body();
builder.append("获得分数 ").append(String.valueOf(setu.getFloat("average"))).append("\n"); List<BaseHandle<?>> sendList = new ArrayList<>();
builder.append("共有 ").append(String.valueOf(score.getIntValue("userNumber"))).append(" 人参与投票"); if (body == null) {
QQBotManager.getInstance().sendMessage(info.getLong("group"),builder); sendList.add(new Text("[图片获取失败]"));
Log.i("今日涩图:"+builder.toString()); return;
}
MessageEvent handle = MessageEvent.parseHandleHttp(body.getSrc());
Image image = handle.findType(Image.class);
if (image == null) {
sendList.add(new Text("[图片获取失败]"));
} else {
sendList.add(image);
}
//builder.append(Image.fromId(info.getString("id")));
sendList.add(new Text(
"本日最佳涩图由", false
));
sendList.add(new At(handle.getSource().getUserId()));
sendList.add(new Text("提供", false));
sendList.add(new Text("获得分数 ", false));
sendList.add(new Text(String.valueOf(setu.getFloat("average")), false));
sendList.add(new Text("共有 ", false));
sendList.add(new Text(String.valueOf(score.getIntValue("userNumber")), false));
sendList.add(new Text(" 人参与投票", false));
QQBotManager.getInstance().sendMessage(handle.isUser(), handle.getGroupId(), sendList);
} }
} }
} else { } else {
@@ -76,37 +102,21 @@ public class QQSetu extends Model {
} }
} }
private boolean isSetu(Image image) { private boolean isSetu(Long length) {
String url = Image.queryUrl(image); return length > 50000;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
int length = connection.getContentLength();
connection.disconnect();
if (length > 50000) {
return true;
}
} catch (IOException e) {
e.printStackTrace();
return false;
} }
return false; private void setuBuilder(Image image, MessageEvent event) {
} if (StringUtils.isEmpty(image.getData().getFileSize()) || !isSetu(Long.parseLong(image.getData().getFileSize()))) {
private void setuBuilder(Image image, GroupMessageEvent event) {
if (!isSetu(image)) {
return; return;
} }
if (RedisTools.get(event.getGroup().getId()+"setu", db_user) != null) { if (RedisTools.get(event.getGroupId() + "setu", db_user) != null) {
printSetu(event.getGroup().getId()); printSetu(event.getGroupId());
} }
setuScore.clear(); setuScore.clear();
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("id", image.getImageId()); json.put("id", event.getMessageId());
json.put("sourName", event.getSenderName()); RedisTools.set(event.getGroupId() + "setu", json.toJSONString(), 6 * 60, db_user);
json.put("sourQQ", event.getSender().getId());
json.put("group", event.getGroup().getId());
RedisTools.set(event.getGroup().getId()+"setu", json.toJSONString(),6*60, db_user);
if (timer != null) { if (timer != null) {
timer.cancel(); timer.cancel();
timer = null; timer = null;
@@ -189,28 +199,29 @@ public class QQSetu extends Model {
RedisTools.remove(group + "setu", db_user); RedisTools.remove(group + "setu", db_user);
setuScore.clear(); setuScore.clear();
} }
@Override @Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) { public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
if (!isGroup) { if (!isGroup) {
return; return;
} }
group=qq; Image image = event.hasType(MessageEnum.IMAGE) ? event.findType(Image.class) : null;
String msg=event.getMessage().contentToString();
if ("[图片]".equals(msg.trim())) {
Image image = (Image) event.getMessage().stream().filter(Image.class::isInstance).findFirst().orElse(null);
if (image != null) { if (image != null) {
setuBuilder(image, (GroupMessageEvent) event); setuBuilder(image, event);
return; return;
} }
Text text = event.hasType(MessageEnum.TEXT) ? event.findType(Text.class) : null;
if (text == null) {
return;
} }
try { try {
if(msg.trim().length()>3){ if (text.toString().trim().length() > 3) {
return; return;
} }
float i = Float.parseFloat(msg.trim()); float i = Float.parseFloat(text.toString().trim());
if (i > 0 && i <= 10) { if (i > 0 && i <= 10) {
String name = event.getSenderName(); String name = event.getSource().getNickname();
String sender=event.getSender().getId()+""; String sender = event.getSource().getUserId() + "";
if (!setuScore.containsKey(name)) { if (!setuScore.containsKey(name)) {
setuScore.put(name + "|" + sender, i); setuScore.put(name + "|" + sender, i);
} }
@@ -223,7 +234,11 @@ public class QQSetu extends Model {
public void onTime(Long qq, String time) { public void onTime(Long qq, String time) {
super.onTime(qq, time); super.onTime(qq, time);
if ("23:59:00".equals(time)) { if ("23:59:00".equals(time)) {
try {
printTodaySetu(); printTodaySetu();
} catch (Exception e) {
e.printStackTrace();
}
} }
} }

View File

@@ -153,7 +153,7 @@ public class AppTools {
Log.i("title=" + title + " msg=" + msg); Log.i("title=" + title + " msg=" + msg);
HttpTools.post("https://sctapi.ftqq.com/SCT2619Tpqu93OYtQCrK4LOZYEfr2irm.send", HttpTools.post("https://sctapi.ftqq.com/SCT2619Tpqu93OYtQCrK4LOZYEfr2irm.send",
("title="+ URLEncoder.encode(title, "UTF-8") + "&desp=" + URLEncoder.encode(msg, "UTF-8")).getBytes(StandardCharsets.UTF_8)); ("title="+ URLEncoder.encode(title, "UTF-8") + "&desp=" + URLEncoder.encode(msg, "UTF-8")).getBytes(StandardCharsets.UTF_8));
if (ConfigTools.load(ConfigTools.CONFIG, "model").equals("nas")) { if (ConfigTools.load(ConfigTools.CONFIG, ConfigTools.MODEL).equals("nas")) {
String img = null; String img = null;
msg = msg.replace("<br/>", "\n"); msg = msg.replace("<br/>", "\n");
if (msg.contains("![logo]")) { if (msg.contains("![logo]")) {

View File

@@ -1,17 +1,18 @@
package com.yutou.qqbot.utlis; package com.yutou.qqbot.utlis;
import com.yutou.napcat.QQDatabase;
import com.yutou.napcat.model.GroupBean;
import com.yutou.qqbot.Annotations.UseModel; import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager; import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.gpt.BaiduGPTManager;
import com.yutou.qqbot.models.Model; import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.contact.Group;
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@@ -30,19 +31,15 @@ public class ApplicationInit implements ApplicationRunner {
if (time.equals(oldTime)) { if (time.equals(oldTime)) {
return; return;
} }
BaiduGPTManager.getManager().clear();
oldTime = time; oldTime = time;
for (Class<?> model : Model.classList) { for (Class<?> model : Model.classList) {
new Thread(() -> { new Thread(() -> {
try { try {
Bot bot = QQBotManager.getInstance().getBot(); List<GroupBean> groups = QQDatabase.getGroups();
if (bot == null) {
return;
}
Model useModel = (Model) model.getDeclaredConstructor().newInstance(); Model useModel = (Model) model.getDeclaredConstructor().newInstance();
for (Group group : bot.getGroups()) { for (GroupBean group : groups) {
if (QQNumberManager.getManager().isUseModel(group.getId(), model)) { if (QQNumberManager.getManager().isUseModel(group.getGroupId(), model)) {
useModel.onTime(group.getId(), time); useModel.onTime(group.getGroupId(), time);
} }
} }
} catch (Exception e) { } catch (Exception e) {
@@ -50,6 +47,34 @@ public class ApplicationInit implements ApplicationRunner {
} }
}).start(); }).start();
} }
//用switch判断timecase是整点
switch (time) {
case "00:00":
case "01:00":
case "02:00":
case "03:00":
case "04:00":
case "05:00":
case "06:00":
case "07:00":
case "08:00":
case "09:00":
case "10:00":
case "11:00":
case "12:00":
case "13:00":
case "14:00":
case "15:00":
case "16:00":
case "17:00":
case "18:00":
case "19:00":
case "20:00":
case "21:00":
case "22:00":
case "23:00":
BaiduGPTManager.getManager().clear();
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -1,88 +0,0 @@
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());
}
}

Some files were not shown because too many files have changed in this diff Show More