diff --git a/.idea/fileTemplates/includes/Version.txt b/.idea/fileTemplates/includes/Version.txt
index 3d287b9..d12225c 100644
--- a/.idea/fileTemplates/includes/Version.txt
+++ b/.idea/fileTemplates/includes/Version.txt
@@ -1 +1 @@
-0.0.4-dev
\ No newline at end of file
+0.0.5-dev
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 474b38c..cdd1e91 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,8 +5,9 @@
-
-
+
+
+
diff --git a/build.gradle.kts b/build.gradle.kts
index be1cfa5..1112841 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,7 +4,7 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
val projectName = rootProject.name
val groupName by extra("cn.wzpmc")
val projectArtifactId by extra("my-bot")
-val projectVersion by extra("0.0.4-dev")
+val projectVersion by extra("0.0.5-dev")
plugins {
id("java")
diff --git a/src/main/java/cn/wzpmc/Main.java b/src/main/java/cn/wzpmc/Main.java
index 651e645..37e0426 100644
--- a/src/main/java/cn/wzpmc/Main.java
+++ b/src/main/java/cn/wzpmc/Main.java
@@ -1,6 +1,13 @@
package cn.wzpmc;
+import cn.wzpmc.api.events.message.group.GroupMessageEvent;
+import cn.wzpmc.api.events.message.priv.PrivateMessageEvent;
+import cn.wzpmc.api.message.StringMessage;
import cn.wzpmc.api.plugins.BasePlugin;
+import cn.wzpmc.api.plugins.event.EventHandler;
+import cn.wzpmc.api.user.Friend;
+import cn.wzpmc.api.user.group.GroupCommandSender;
+import cn.wzpmc.api.user.group.GroupUser;
import cn.wzpmc.commands.StopCommand;
import cn.wzpmc.configuration.Configuration;
import cn.wzpmc.console.MyBotConsole;
@@ -13,7 +20,6 @@ import cn.wzpmc.utils.JsonUtils;
import cn.wzpmc.utils.ReflectionUtils;
import cn.wzpmc.utils.TemplateFileUtils;
import cn.wzpmc.utils.YamlUtils;
-import io.netty.channel.ChannelFuture;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
@@ -26,7 +32,7 @@ import java.net.URL;
@Log4j2
public class Main {
private static final String DEFAULT_CONFIGURATION_FILE_PATH = "templates/config.yaml";
- private static File pluginsDir;
+
public static void initializeJVM(){
System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
System.setProperty("terminal.jline", "true");
@@ -42,10 +48,6 @@ public class Main {
log.info("首次启动,默认配置文件已创建,请填写后再次启动MyBot!");
return null;
}
- pluginsDir = new File("plugins");
- if (TemplateFileUtils.createDefaultDirectory(pluginsDir)) {
- log.debug("plugin文件夹创建");
- }
log.debug("读取配置文件 {}", configurationFile.getAbsolutePath());
return YamlUtils.readYamlFile(configurationFile, Configuration.class);
}
@@ -62,6 +64,11 @@ public class Main {
return uri;
}
public static void loadPlugins(MyBot myBot) throws MalformedURLException {
+ File pluginsDir = new File("plugins");
+ if (TemplateFileUtils.createDefaultDirectory(pluginsDir)) {
+ log.debug("plugin文件夹创建");
+ }
+ myBot.setPluginsFolder(pluginsDir);
File[] files = pluginsDir.listFiles();
if (files == null) {
log.error("没有权限读取插件目录!");
@@ -90,7 +97,7 @@ public class Main {
}
public static WebSocketConnectionHandler createConnection(MyBot myBot, URI uri){
WebSocketConnectionHandler webSocketConnectionHandler = new WebSocketConnectionHandler(myBot);
- ChannelFuture future = webSocketConnectionHandler.connect(uri);
+ webSocketConnectionHandler.connect(uri);
return webSocketConnectionHandler;
}
public static void startConsole(MyBot myBot, WebSocketConnectionHandler webSocketConnectionHandler){
@@ -107,6 +114,26 @@ public class Main {
return;
}
MyBot myBot = createBot(configuration);
+ myBot.registerEventHandler(new Object(){
+ @EventHandler
+ public void onGroupMessage(GroupMessageEvent event){
+ GroupUser sender = event.getSender();
+ System.out.println(sender.getId());
+ if (sender.getId().equals(3357223099L)) {
+ System.out.println("send");
+ GroupCommandSender.of(event).sendMessage(StringMessage.text("test"));
+ System.out.println("called-group");
+ }
+ }
+ @EventHandler
+ public void onUserMessage(PrivateMessageEvent event){
+ Friend sender = event.getSender();
+ if (sender.getId().equals(3357223099L)){
+ sender.sendMessage(StringMessage.text("test-user"));
+ System.out.println("called-user");
+ }
+ }
+ });
URI uri = getUriFromConfiguration(configuration);
if (uri == null){
log.error("无法解析websocket地址");
@@ -114,6 +141,7 @@ public class Main {
}
loadPlugins(myBot);
WebSocketConnectionHandler webSocketConnectionHandler = createConnection(myBot, uri);
+ myBot.setConnectionHandler(webSocketConnectionHandler);
startConsole(myBot, webSocketConnectionHandler);
}
}
\ No newline at end of file
diff --git a/src/main/java/cn/wzpmc/api/api/Action.java b/src/main/java/cn/wzpmc/api/api/Action.java
new file mode 100644
index 0000000..008f929
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/Action.java
@@ -0,0 +1,34 @@
+package cn.wzpmc.api.api;
+
+import lombok.*;
+
+import java.util.UUID;
+
+/**
+ * 抽象请求体
+ * @author wzp
+ * @since 2024/8/16 21:36
+ * @version 0.0.5-dev
+ */
+@Getter
+@ToString
+@EqualsAndHashCode
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Setter(AccessLevel.PROTECTED)
+public class Action {
+ /**
+ * 请求操作类型
+ * @since 2024/8/23 21:29 v0.0.5-dev
+ */
+ private Actions action;
+ /**
+ * 请求参数
+ * @since 2024/8/23 21:29 v0.0.5-dev
+ */
+ private REQUEST params;
+ /**
+ * 请求回调值(默认随机生成,不建议自己修改)
+ * @since 2024/8/23 21:29 v0.0.5-dev
+ */
+ private final UUID echo = UUID.randomUUID();
+}
diff --git a/src/main/java/cn/wzpmc/api/api/ActionResponse.java b/src/main/java/cn/wzpmc/api/api/ActionResponse.java
new file mode 100644
index 0000000..8ff65ce
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/ActionResponse.java
@@ -0,0 +1,35 @@
+package cn.wzpmc.api.api;
+
+import lombok.Data;
+
+import java.util.UUID;
+
+/**
+ * 请求操作返回
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/16 17:43
+ */
+@Data
+public class ActionResponse {
+ /**
+ * 请求返回消息
+ * @since 2024/8/23 21:30 v0.0.5-dev
+ */
+ private final String status;
+ /**
+ * 请求返回码
+ * @since 2024/8/23 21:30 v0.0.5-dev
+ */
+ private final short retcode;
+ /**
+ * 请求返回数据
+ * @since 2024/8/23 21:31 v0.0.5-dev
+ */
+ private final RESPONSE data;
+ /**
+ * 请求返回回调
+ * @since 2024/8/23 21:31 v0.0.5-dev
+ */
+ private final UUID echo;
+}
diff --git a/src/main/java/cn/wzpmc/api/api/Actions.java b/src/main/java/cn/wzpmc/api/api/Actions.java
new file mode 100644
index 0000000..5781b67
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/Actions.java
@@ -0,0 +1,85 @@
+package cn.wzpmc.api.api;
+
+import cn.wzpmc.api.api.actions.message.send.SendMessageActionResponseData;
+import cn.wzpmc.api.entities.MessageInformation;
+
+/**
+ * 操作类型
+ * @author wzp
+ * @since 2024/8/16 22:24
+ * @version 0.0.5-dev
+ */
+public enum Actions {
+ /**
+ * 发送私聊消息
+ * @since 2024/8/23 21:07 v0.0.5-dev
+ */
+ SEND_PRIVATE_MSG(SendMessageActionResponseData.class),
+ /**
+ * 发送群消息
+ * @since 2024/8/23 21:07 v0.0.5-dev
+ */
+ SEND_GROUP_MSG(SendMessageActionResponseData.class),
+ /**
+ * 撤回消息
+ * @since 2024/8/23 21:07 v0.0.5-dev
+ */
+ DELETE_MSG(),
+ /**
+ * 获取消息
+ * @since 2024/8/23 21:07 v0.0.5-dev
+ */
+ GET_MSG(MessageInformation.class),
+ /**
+ * 获取合并转发消息
+ * @since 2024/8/23 21:08 v0.0.5-dev
+ */
+ GET_FORWARD_MSG(MessageInformation.class),
+ /**
+ * 发送好友赞
+ * @since 2024/8/23 21:08 v0.0.5-dev
+ */
+ SEND_LIKE(),
+ /**
+ * 群组踢人
+ * @since 2024/8/23 21:08 v0.0.5-dev
+ */
+ SET_GROUP_KICK(),
+ /**
+ * 群组单人禁言
+ * @since 2024/8/23 21:08 v0.0.5-dev
+ */
+ SET_GROUP_BAN(),
+ /**
+ * 群组匿名用户禁言
+ * @since 2024/8/23 21:08 v0.0.5-dev
+ */
+ SET_GROUP_ANONYMOUS_BAN(),
+ /**
+ * 群组全员禁言
+ * @since 2024/8/23 21:09 v0.0.5-dev
+ */
+ SET_GROUP_WHOLE_BAN(),
+ /**
+ * 群组设置管理员
+ * @since 2024/8/23 21:09 v0.0.5-dev
+ */
+ SET_GROUP_ADMIN(),
+ /**
+ * 群组匿名
+ * @since 2024/8/23 21:09 v0.0.5-dev
+ */
+ SET_GROUP_ANONYMOUS(),
+ /**
+ * 设置群名片(群备注)
+ * @since 2024/8/23 21:09 v0.0.5-dev
+ */
+ SET_GROUP_CARD();
+ public final Class> responseClass;
+ Actions(Class> responseClass) {
+ this.responseClass = responseClass;
+ }
+ Actions(){
+ this(Void.class);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/IMainApi.java b/src/main/java/cn/wzpmc/api/api/IMainApi.java
new file mode 100644
index 0000000..269b8bb
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/IMainApi.java
@@ -0,0 +1,21 @@
+package cn.wzpmc.api.api;
+
+/**
+ * 主Api接口
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/16 17:31
+ */
+public interface IMainApi {
+ /**
+ * 进行请求操作
+ * @author wzp
+ * @since 2024/8/23 21:32 v0.0.5-dev
+ * @param packet 请求包
+ * @return 请求返回包
+ * @param 请求类型
+ * @param 返回类型
+ * @throws InterruptedException 请求过程中出现Ctrl+C时抛出
+ */
+ ActionResponse doApiCall(Action packet) throws InterruptedException;
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/delete/DeleteMessageAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/delete/DeleteMessageAction.java
new file mode 100644
index 0000000..2e627cc
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/delete/DeleteMessageAction.java
@@ -0,0 +1,36 @@
+package cn.wzpmc.api.api.actions.message.delete;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 撤回消息
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 23:02
+ */
+public class DeleteMessageAction extends Action {
+ /**
+ * 撤回消息
+ * @author wzp
+ * @since 2024/8/23 21:09 v0.0.5-dev
+ * @param messageId 消息ID
+ */
+ public DeleteMessageAction(Integer messageId){
+ super.setAction(Actions.DELETE_MSG);
+ super.setParams(new Params(messageId));
+ }
+ @Data
+ @AllArgsConstructor
+ public static class Params {
+ /**
+ * 消息ID
+ * @since 2024/8/17 23:03 v0.0.5-dev
+ */
+ @JSONField(name = "message_id")
+ private Integer messageId;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/get/GetForwardMessageAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/get/GetForwardMessageAction.java
new file mode 100644
index 0000000..2a5de92
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/get/GetForwardMessageAction.java
@@ -0,0 +1,35 @@
+package cn.wzpmc.api.api.actions.message.get;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import cn.wzpmc.api.entities.MessageInformation;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 获取合并转发消息
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 19:46
+ */
+public class GetForwardMessageAction extends Action {
+ /**
+ * 获取合并转发消息
+ * @author wzp
+ * @since 2024/8/23 21:10 v0.0.5-dev
+ * @param id 合并转发ID
+ */
+ public GetForwardMessageAction(String id){
+ super.setAction(Actions.GET_FORWARD_MSG);
+ super.setParams(new GetForwardMessageAction.Params(id));
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 合并转发ID
+ * @since 2024/8/23 19:47 v0.0.5-dev
+ */
+ private String id;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/get/GetMessageAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/get/GetMessageAction.java
new file mode 100644
index 0000000..9702841
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/get/GetMessageAction.java
@@ -0,0 +1,37 @@
+package cn.wzpmc.api.api.actions.message.get;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import cn.wzpmc.api.entities.MessageInformation;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 获取消息
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 23:07
+ */
+public class GetMessageAction extends Action {
+ /**
+ * 获取消息
+ * @author wzp
+ * @since 2024/8/23 21:11 v0.0.5-dev
+ * @param messageId 消息 ID
+ */
+ public GetMessageAction(Integer messageId){
+ super.setAction(Actions.GET_MSG);
+ super.setParams(new Params(messageId));
+ }
+ @Data
+ @AllArgsConstructor
+ public static class Params {
+ /**
+ * 消息 ID
+ * @since 2024/8/23 21:11 v0.0.5-dev
+ */
+ @JSONField(name = "message_id")
+ private Integer messageId;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/send/SendGroupMessageAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendGroupMessageAction.java
new file mode 100644
index 0000000..ce9d753
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendGroupMessageAction.java
@@ -0,0 +1,61 @@
+package cn.wzpmc.api.api.actions.message.send;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import cn.wzpmc.api.message.MessageComponent;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 发送群消息
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 22:52
+ */
+public class SendGroupMessageAction extends Action {
+ /**
+ * 发送群消息
+ * @author wzp
+ * @since 2024/8/23 21:11 v0.0.5-dev
+ * @param groupId 群号
+ * @param message 要发送的内容
+ * @param autoEscape 消息内容是否作为纯文本发送(即不解析 CQ 码),只在 message 字段是字符串时有效
+ */
+ public SendGroupMessageAction(Long groupId, MessageComponent message, boolean autoEscape){
+ super.setAction(Actions.SEND_GROUP_MSG);
+ super.setParams(new SendGroupMessageAction.Params(groupId, message, autoEscape));
+ }
+
+ /**
+ * 发送群消息
+ * @author wzp
+ * @since 2024/8/23 21:11 v0.0.5-dev
+ * @param groupId 群号
+ * @param message 要发送的内容
+ */
+ public SendGroupMessageAction(Long groupId, MessageComponent message){
+ this(groupId, message, false);
+ }
+ @Data
+ @AllArgsConstructor
+ public static class Params {
+ /**
+ * 群号
+ * @since 2024/8/17 22:54 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 要发送的内容
+ * @since 2024/8/17 22:54 v0.0.5-dev
+ */
+ private MessageComponent message;
+ /**
+ * 消息内容是否作为纯文本发送(即不解析 CQ 码),只在 message 字段是字符串时有效
+ * @since 2024/8/17 22:51 v0.0.5-dev
+ */
+ @JSONField(name = "auto_escape")
+ private boolean autoEscape;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/send/SendLikeAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendLikeAction.java
new file mode 100644
index 0000000..a0ed4d4
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendLikeAction.java
@@ -0,0 +1,53 @@
+package cn.wzpmc.api.api.actions.message.send;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 发送好友赞
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 19:49
+ */
+public class SendLikeAction extends Action {
+ /**
+ * 发送好友赞
+ * @author wzp
+ * @since 2024/8/23 21:12 v0.0.5-dev
+ * @param userId 对方 QQ 号
+ * @param times 赞的次数,每个好友每天最多 10 次
+ */
+ public SendLikeAction(Long userId, Long times){
+ super.setAction(Actions.SEND_LIKE);
+ super.setParams(new Params(userId, times));
+ }
+
+ /**
+ * 发送好友赞
+ * @author wzp
+ * @since 2024/8/23 21:12 v0.0.5-dev
+ * @param userId 对方 QQ 号
+ */
+ public SendLikeAction(Long userId){
+ this(userId, 1L);
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 对方 QQ 号
+ * @since 2024/8/23 21:12 v0.0.5-dev
+ */
+ @JSONField(name = "user_id")
+ private Long userId;
+ /**
+ * 赞的次数,每个好友每天最多 10 次
+ * @since 2024/8/23 21:12 v0.0.5-dev
+ */
+ @JSONField(defaultValue = "1")
+ private Long times;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/send/SendMessageActionResponseData.java b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendMessageActionResponseData.java
new file mode 100644
index 0000000..50dce4c
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendMessageActionResponseData.java
@@ -0,0 +1,20 @@
+package cn.wzpmc.api.api.actions.message.send;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.Data;
+
+/**
+ * 发送私聊消息返回
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 21:55
+ */
+@Data
+public class SendMessageActionResponseData {
+ /**
+ * 消息 ID
+ * @since 2024/8/17 22:51 v0.0.5-dev
+ */
+ @JSONField(name = "message_id")
+ private int messageId;
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/send/SendPrivateMessageAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendPrivateMessageAction.java
new file mode 100644
index 0000000..a6dc8fe
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/send/SendPrivateMessageAction.java
@@ -0,0 +1,61 @@
+package cn.wzpmc.api.api.actions.message.send;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import cn.wzpmc.api.message.MessageComponent;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 发送私聊消息
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 21:54
+ */
+public class SendPrivateMessageAction extends Action {
+ /**
+ * 发送私聊消息
+ * @author wzp
+ * @since 2024/8/23 21:13 v0.0.5-dev
+ * @param userId 对方 QQ 号
+ * @param message 要发送的内容
+ * @param autoEscape 消息内容是否作为纯文本发送(即不解析 CQ 码),只在 message 字段是字符串时有效
+ */
+ public SendPrivateMessageAction(Long userId, MessageComponent message, boolean autoEscape){
+ super.setAction(Actions.SEND_PRIVATE_MSG);
+ super.setParams(new Params(userId, message, autoEscape));
+ }
+
+ /**
+ * 发送私聊消息
+ * @author wzp
+ * @since 2024/8/23 21:14 v0.0.5-dev
+ * @param userId 对方 QQ 号
+ * @param message 要发送的内容
+ */
+ public SendPrivateMessageAction(Long userId, MessageComponent message){
+ this(userId, message, false);
+ }
+ @Data
+ @AllArgsConstructor
+ public static class Params {
+ /**
+ * 对方 QQ 号
+ * @since 2024/8/17 22:51 v0.0.5-dev
+ */
+ @JSONField(name = "user_id")
+ private Long userId;
+ /**
+ * 要发送的内容
+ * @since 2024/8/17 22:51 v0.0.5-dev
+ */
+ private MessageComponent message;
+ /**
+ * 消息内容是否作为纯文本发送(即不解析 CQ 码),只在 message 字段是字符串时有效
+ * @since 2024/8/17 22:51 v0.0.5-dev
+ */
+ @JSONField(name = "auto_escape")
+ private boolean autoEscape;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAdminAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAdminAction.java
new file mode 100644
index 0000000..e7bb7e6
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAdminAction.java
@@ -0,0 +1,61 @@
+package cn.wzpmc.api.api.actions.message.set;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 群组设置管理员
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 20:51
+ */
+public class SetGroupAdminAction extends Action {
+ /**
+ * 群组设置管理员
+ * @author wzp
+ * @since 2024/8/23 21:14 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要设置管理员的 QQ 号
+ * @param enable true 为设置,false 为取消
+ */
+ public SetGroupAdminAction(Long groupId, Long userId, Boolean enable){
+ super.setAction(Actions.SET_GROUP_ADMIN);
+ super.setParams(new Params(groupId, userId, enable));
+ }
+
+ /**
+ * 群组设置管理员
+ * @author wzp
+ * @since 2024/8/23 21:14 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要设置管理员的 QQ 号
+ */
+ public SetGroupAdminAction(Long groupId, Long userId) {
+ this(groupId, userId, true);
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 群号
+ * @since 2024/8/23 21:15 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 要设置管理员的 QQ 号
+ * @since 2024/8/23 21:15 v0.0.5-dev
+ */
+ @JSONField(name = "user_id")
+ private Long userId;
+ /**
+ * true 为设置,false 为取消
+ * @since 2024/8/23 21:15 v0.0.5-dev
+ */
+ @JSONField(defaultValue = "true")
+ private Boolean enable;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymous.java b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymous.java
new file mode 100644
index 0000000..d76b7c7
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymous.java
@@ -0,0 +1,53 @@
+package cn.wzpmc.api.api.actions.message.set;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 群组匿名
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 20:55
+ */
+public class SetGroupAnonymous extends Action {
+ /**
+ * 群组匿名
+ * @author wzp
+ * @since 2024/8/23 21:16 v0.0.5-dev
+ * @param groupId 群号
+ * @param enable 是否允许匿名聊天
+ */
+ public SetGroupAnonymous(Long groupId, Boolean enable) {
+ super.setAction(Actions.SET_GROUP_ANONYMOUS);
+ super.setParams(new Params(groupId, enable));
+ }
+
+ /**
+ * 群组匿名
+ * @author wzp
+ * @since 2024/8/23 21:16 v0.0.5-dev
+ * @param groupId 群号
+ */
+ public SetGroupAnonymous(Long groupId) {
+ this(groupId, true);
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 群号
+ * @since 2024/8/23 21:16 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 是否允许匿名聊天
+ * @since 2024/8/23 21:16 v0.0.5-dev
+ */
+ @JSONField(defaultValue = "true")
+ private Boolean enable;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymousBanAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymousBanAction.java
new file mode 100644
index 0000000..1b4b6c4
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymousBanAction.java
@@ -0,0 +1,102 @@
+package cn.wzpmc.api.api.actions.message.set;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import cn.wzpmc.api.message.json.parts.Anonymous;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 群组匿名用户禁言
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 20:08
+ */
+public class SetGroupAnonymousBanAction extends Action {
+ /**
+ * 群组匿名用户禁言
+ * @author wzp
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ * @param groupId 群号
+ * @param anonymous 可选,要禁言的匿名用户对象(群消息上报的 anonymous 字段)
+ * @param flag 可选,要禁言的匿名用户的 flag(需从群消息上报的数据中获得)
+ * @param duration 禁言时长,单位秒,无法取消匿名用户禁言(默认30 * 60)
+ */
+ protected SetGroupAnonymousBanAction(Long groupId, Anonymous anonymous, String flag, Long duration) {
+ super.setAction(Actions.SET_GROUP_ANONYMOUS_BAN);
+ super.setParams(new Params(groupId, anonymous, flag, duration));
+ }
+
+ /**
+ * 群组匿名用户禁言
+ * @author wzp
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ * @param groupId 群号
+ * @param anonymous 要禁言的匿名用户对象(群消息上报的 anonymous 字段)
+ * @param duration 禁言时长,单位秒,无法取消匿名用户禁言
+ */
+ public SetGroupAnonymousBanAction(Long groupId, Anonymous anonymous, Long duration) {
+ this(groupId, anonymous, null, duration);
+ }
+
+ /**
+ * 群组匿名用户禁言
+ * @author wzp
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ * @param groupId 群号
+ * @param anonymous 要禁言的匿名用户对象(群消息上报的 anonymous 字段)
+ */
+ public SetGroupAnonymousBanAction(Long groupId, Anonymous anonymous) {
+ this(groupId, anonymous, 1800L);
+ }
+
+ /**
+ * 群组匿名用户禁言
+ * @author wzp
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ * @param groupId 群号
+ * @param flag 要禁言的匿名用户的 flag(需从群消息上报的数据中获得)
+ * @param duration 禁言时长,单位秒,无法取消匿名用户禁言
+ */
+ public SetGroupAnonymousBanAction(Long groupId, String flag, Long duration) {
+ this(groupId, null, flag, duration);
+ }
+
+ /**
+ * 群组匿名用户禁言
+ * @author wzp
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ * @param groupId 群号
+ * @param flag 要禁言的匿名用户的 flag(需从群消息上报的数据中获得)
+ */
+ public SetGroupAnonymousBanAction(Long groupId, String flag) {
+ this(groupId, flag, 1800L);
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 群号
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 可选,要禁言的匿名用户对象(群消息上报的 anonymous 字段)
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ */
+ private Anonymous anonymous;
+ /**
+ * 可选,要禁言的匿名用户的 flag(需从群消息上报的数据中获得)
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ */
+ private String flag;
+ /**
+ * 禁言时长,单位秒,无法取消匿名用户禁言(默认30 * 60)
+ * @since 2024/8/23 21:17 v0.0.5-dev
+ */
+ @JSONField(defaultValue = "1800")
+ private Long duration;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupBanAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupBanAction.java
new file mode 100644
index 0000000..85a772b
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupBanAction.java
@@ -0,0 +1,61 @@
+package cn.wzpmc.api.api.actions.message.set;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 群组单人禁言
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 20:03
+ */
+public class SetGroupBanAction extends Action {
+ /**
+ * 群组单人禁言
+ * @author wzp
+ * @since 2024/8/23 21:20 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要禁言的 QQ 号
+ * @param duration 禁言时长,单位秒,0 表示取消禁言
+ */
+ public SetGroupBanAction(Long groupId, Long userId, Long duration){
+ super.setAction(Actions.SET_GROUP_BAN);
+ super.setParams(new Params(groupId, userId, duration));
+ }
+
+ /**
+ * 群组单人禁言
+ * @author wzp
+ * @since 2024/8/23 21:20 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要禁言的 QQ 号
+ */
+ public SetGroupBanAction(Long groupId, Long userId){
+ this(groupId, userId, 1800L);
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 群号
+ * @since 2024/8/23 21:20 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 要禁言的 QQ 号
+ * @since 2024/8/23 21:20 v0.0.5-dev
+ */
+ @JSONField(name = "user_id")
+ private Long userId;
+ /**
+ * 禁言时长,单位秒,0 表示取消禁言(默认30 * 60)
+ * @since 2024/8/23 21:20 v0.0.5-dev
+ */
+ @JSONField(defaultValue = "1800")
+ private Long duration;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupCardAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupCardAction.java
new file mode 100644
index 0000000..7922976
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupCardAction.java
@@ -0,0 +1,60 @@
+package cn.wzpmc.api.api.actions.message.set;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 设置群名片(群备注)
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 20:59
+ */
+public class SetGroupCardAction extends Action {
+ /**
+ * 设置群名片(群备注)
+ * @author wzp
+ * @since 2024/8/23 21:22 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要设置的 QQ 号
+ * @param card 群名片内容,不填或空字符串表示删除群名片
+ */
+ public SetGroupCardAction(Long groupId, Long userId, String card) {
+ super.setAction(Actions.SET_GROUP_CARD);
+ super.setParams(new Params(groupId, userId, card));
+ }
+
+ /**
+ * 设置群名片(群备注)
+ * @author wzp
+ * @since 2024/8/23 21:22 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要设置的 QQ 号
+ */
+ public SetGroupCardAction(Long groupId, Long userId) {
+ this(groupId, userId, "");
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 群号
+ * @since 2024/8/23 21:23 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 要设置的 QQ 号
+ * @since 2024/8/23 21:23 v0.0.5-dev
+ */
+ @JSONField(name = "user_id")
+ private Long userId;
+ /**
+ * 群名片内容,不填或空字符串表示删除群名片(默认为空)
+ * @since 2024/8/23 21:23 v0.0.5-dev
+ */
+ private String card;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupKickAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupKickAction.java
new file mode 100644
index 0000000..54d9297
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupKickAction.java
@@ -0,0 +1,61 @@
+package cn.wzpmc.api.api.actions.message.set;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 群组踢人
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 19:52
+ */
+public class SetGroupKickAction extends Action {
+ /**
+ * 群组踢人
+ * @author wzp
+ * @since 2024/8/23 21:24 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要踢的 QQ 号
+ * @param rejectAddRequest 拒绝此人的加群请求
+ */
+ public SetGroupKickAction(Long groupId, Long userId, Boolean rejectAddRequest) {
+ super.setAction(Actions.SET_GROUP_KICK);
+ super.setParams(new Params(groupId, userId, rejectAddRequest));
+ }
+
+ /**
+ * 群组踢人
+ * @author wzp
+ * @since 2024/8/23 21:24 v0.0.5-dev
+ * @param groupId 群号
+ * @param userId 要踢的 QQ 号
+ */
+ public SetGroupKickAction(Long groupId, Long userId) {
+ this(groupId, userId, false);
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 群号
+ * @since 2024/8/23 21:25 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 要踢的 QQ 号
+ * @since 2024/8/23 21:25 v0.0.5-dev
+ */
+ @JSONField(name = "user_id")
+ private Long userId;
+ /**
+ * 拒绝此人的加群请求(默认为false)
+ * @since 2024/8/23 21:25 v0.0.5-dev
+ */
+ @JSONField(name = "reject_add_request", defaultValue = "false")
+ private Boolean rejectAddRequest;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupWholeBanAction.java b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupWholeBanAction.java
new file mode 100644
index 0000000..2d33381
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupWholeBanAction.java
@@ -0,0 +1,53 @@
+package cn.wzpmc.api.api.actions.message.set;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 群组全员禁言
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/23 20:06
+ */
+public class SetGroupWholeBanAction extends Action {
+ /**
+ * 群组全员禁言
+ * @author wzp
+ * @since 2024/8/23 21:27 v0.0.5-dev
+ * @param groupId 群号
+ * @param enable 是否禁言
+ */
+ public SetGroupWholeBanAction(Long groupId, Boolean enable) {
+ super.setAction(Actions.SET_GROUP_WHOLE_BAN);
+ super.setParams(new Params(groupId, enable));
+ }
+
+ /**
+ * 群组全员禁言
+ * @author wzp
+ * @since 2024/8/23 21:28 v0.0.5-dev
+ * @param groupId 群号
+ */
+ public SetGroupWholeBanAction(Long groupId) {
+ this(groupId, true);
+ }
+ @Data
+ @AllArgsConstructor
+ public static final class Params {
+ /**
+ * 群号
+ * @since 2024/8/23 21:28 v0.0.5-dev
+ */
+ @JSONField(name = "group_id")
+ private Long groupId;
+ /**
+ * 是否禁言(默认true)
+ * @since 2024/8/23 21:28 v0.0.5-dev
+ */
+ @JSONField(defaultValue = "true")
+ private Boolean enable;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/entities/BotStatus.java b/src/main/java/cn/wzpmc/api/entities/BotStatus.java
index 015a10a..121752f 100644
--- a/src/main/java/cn/wzpmc/api/entities/BotStatus.java
+++ b/src/main/java/cn/wzpmc/api/entities/BotStatus.java
@@ -10,6 +10,14 @@ import lombok.Data;
*/
@Data
public class BotStatus {
+ /**
+ * bot是否在线
+ * @since 2024/8/23 21:33 v0.0.5-dev
+ */
private boolean online;
+ /**
+ * bot健康程度
+ * @since 2024/8/23 21:34 v0.0.5-dev
+ */
private boolean good;
}
diff --git a/src/main/java/cn/wzpmc/api/entities/MessageInformation.java b/src/main/java/cn/wzpmc/api/entities/MessageInformation.java
new file mode 100644
index 0000000..1ec7b7e
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/entities/MessageInformation.java
@@ -0,0 +1,49 @@
+package cn.wzpmc.api.entities;
+
+import cn.wzpmc.api.events.message.MessageType;
+import cn.wzpmc.api.message.MessageComponent;
+import cn.wzpmc.api.user.IUser;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.Data;
+
+/**
+ * 获取消息操作返回
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 23:08
+ */
+@Data
+public class MessageInformation {
+ /**
+ * 发送时间
+ * @since 2024/8/23 21:34 v0.0.5-dev
+ */
+ private Integer time;
+ /**
+ * 消息类型
+ * @since 2024/8/23 21:34 v0.0.5-dev
+ */
+ private MessageType type;
+ /**
+ * 消息 ID
+ * @since 2024/8/23 21:34 v0.0.5-dev
+ */
+ @JSONField(name = "message_id")
+ private Integer messageId;
+ /**
+ * 消息真实 ID
+ * @since 2024/8/23 21:34 v0.0.5-dev
+ */
+ @JSONField(name = "real_id")
+ private Integer realId;
+ /**
+ * 发送人信息
+ * @since 2024/8/23 21:35 v0.0.5-dev
+ */
+ private IUser sender;
+ /**
+ * 消息内容
+ * @since 2024/8/23 21:35 v0.0.5-dev
+ */
+ private MessageComponent message;
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java b/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java
index 5a6b0be..201076a 100644
--- a/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java
+++ b/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java
@@ -17,10 +17,24 @@ import java.util.stream.Collectors;
@Data
public class JsonMessage implements MessageComponent {
private final List messageParts = new ArrayList<>();
+
+ /**
+ * 将消息转为JSON文本
+ * @author wzp
+ * @since 2024/8/23 21:36 v0.0.5-dev
+ * @return json文本
+ */
@Override
public String toMessageString() {
return JSON.toJSONString(messageParts);
}
+
+ /**
+ * 将JSON消息转化为纯文本显示方式
+ * @author wzp
+ * @since 2024/8/23 21:35 v0.0.5-dev
+ * @return 文本
+ */
public String toTextDisplay() {
return this.messageParts.stream().map(JsonMessagePart::getTextDisplay).collect(Collectors.joining(""));
}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/At.java b/src/main/java/cn/wzpmc/api/message/json/parts/At.java
index 9384d5b..e302530 100644
--- a/src/main/java/cn/wzpmc/api/message/json/parts/At.java
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/At.java
@@ -2,6 +2,7 @@ package cn.wzpmc.api.message.json.parts;
import cn.wzpmc.api.message.json.JsonMessagePart;
import com.alibaba.fastjson2.JSONObject;
+import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -13,12 +14,13 @@ import lombok.NoArgsConstructor;
*/
@Data
@NoArgsConstructor
+@AllArgsConstructor
public class At implements JsonMessagePart {
/**
* "@"的 QQ 号,all 表示全体成员
* @since 2024/8/2 下午11:50 v0.0.3-dev
*/
- private String qq;
+ private Long qq;
@Override
public PartType getPartType() {
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Dice.java b/src/main/java/cn/wzpmc/api/message/json/parts/Dice.java
index b894cdc..c4f6eaf 100644
--- a/src/main/java/cn/wzpmc/api/message/json/parts/Dice.java
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Dice.java
@@ -6,6 +6,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
/**
+ * 掷骰子魔法表情
* @author MoYiJiangNan
* @version 0.0.3-dev
* @since 2024/8/2 下午11:26
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/PartType.java b/src/main/java/cn/wzpmc/api/message/json/parts/PartType.java
index d84259e..7d6735e 100644
--- a/src/main/java/cn/wzpmc/api/message/json/parts/PartType.java
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/PartType.java
@@ -11,27 +11,108 @@ import cn.wzpmc.api.message.json.parts.poke.Poke;
* 消息段类型
* @author wzp
* @since 2024/8/3 下午6:18
- * @version 0.0.3-dev */
+ * @version 0.0.3-dev
+ */
public enum PartType {
+ /**
+ * 文本消息
+ * @since 2024/8/23 21:37 v0.0.5-dev
+ */
TEXT(StringMessage.class),
+ /**
+ * 表情消息
+ * @since 2024/8/23 21:37 v0.0.5-dev
+ */
FACE(Face.class),
+ /**
+ * 图片消息
+ * @since 2024/8/23 21:37 v0.0.5-dev
+ */
IMAGE(Image.class),
+ /**
+ * 语音
+ * @since 2024/8/23 21:37 v0.0.5-dev
+ */
RECORD(Record.class),
+ /**
+ * 短视频
+ * @since 2024/8/23 21:37 v0.0.5-dev
+ */
VIDEO(Video.class),
+ /**
+ * "@"某人
+ * @since 2024/8/23 21:37 v0.0.5-dev
+ */
AT(At.class),
+ /**
+ * 拳魔法表情
+ * @since 2024/8/23 21:37 v0.0.5-dev
+ */
RPS(cn.wzpmc.api.message.json.parts.RPS.class),
+ /**
+ * 掷骰子魔法表情
+ * @since 2024/8/23 21:38 v0.0.5-dev
+ */
DICE(Dice.class),
+ /**
+ * 窗口抖动(戳一戳)
+ * @since 2024/8/23 21:38 v0.0.5-dev
+ */
SHAKE(Shake.class),
+ /**
+ * 戳一戳
+ * @since 2024/8/23 21:38 v0.0.5-dev
+ */
POKE(Poke.class),
+ /**
+ * 匿名发消息
+ * @since 2024/8/23 21:39 v0.0.5-dev
+ */
ANONYMOUS(Anonymous.class),
+ /**
+ * 链接分享
+ * @since 2024/8/23 21:39 v0.0.5-dev
+ */
SHARE(Share.class),
+ /**
+ * 推荐好友/群
+ * @since 2024/8/23 21:39 v0.0.5-dev
+ */
CONTACT(Contact.class),
+ /**
+ * 位置
+ * @since 2024/8/23 21:40 v0.0.5-dev
+ */
LOCATION(Location.class),
+ /**
+ * 音乐分享
+ * @since 2024/8/23 21:40 v0.0.5-dev
+ */
MUSIC(Music.class),
+ /**
+ * 回复
+ * @since 2024/8/23 21:40 v0.0.5-dev
+ */
REPLY(Reply.class),
+ /**
+ * 合并转发
+ * @since 2024/8/23 21:40 v0.0.5-dev
+ */
FORWARD(Forward.class),
+ /**
+ * 合并转发节点
+ * @since 2024/8/23 21:40 v0.0.5-dev
+ */
NODE(Node.class),
+ /**
+ * XML消息
+ * @since 2024/8/23 21:40 v0.0.5-dev
+ */
XML(XMLMessage.class),
+ /**
+ * JSON消息
+ * @since 2024/8/23 21:40 v0.0.5-dev
+ */
JSON(CustomJSONMessage.class);
public final Class extends JsonMessagePart> clazz;
PartType(Class extends JsonMessagePart> clazz){
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/contact/ContactType.java b/src/main/java/cn/wzpmc/api/message/json/parts/contact/ContactType.java
index 8557ad9..96f53a6 100644
--- a/src/main/java/cn/wzpmc/api/message/json/parts/contact/ContactType.java
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/contact/ContactType.java
@@ -16,5 +16,5 @@ public enum ContactType {
* 推荐群
* @since 2024/8/2 下午11:36 v0.0.3-dev
*/
- GROUP;
+ GROUP
}
diff --git a/src/main/java/cn/wzpmc/api/plugins/BasePlugin.java b/src/main/java/cn/wzpmc/api/plugins/BasePlugin.java
index 6ab5f64..b167e02 100644
--- a/src/main/java/cn/wzpmc/api/plugins/BasePlugin.java
+++ b/src/main/java/cn/wzpmc/api/plugins/BasePlugin.java
@@ -3,6 +3,9 @@ package cn.wzpmc.api.plugins;
import cn.wzpmc.api.user.IBot;
import org.apache.logging.log4j.Logger;
+import java.io.File;
+import java.io.InputStream;
+
/**
* 插件基类
* @author wzp
@@ -47,7 +50,57 @@ public interface BasePlugin {
*/
IPluginClassLoader getClassLoader();
+ /**
+ * 当插件被加载时调用
+ * @author wzp
+ * @since 2024/8/16 13:14 v0.0.5-dev
+ */
void onLoad();
+
+ /**
+ * 当插件被卸载时调用
+ * @author wzp
+ * @since 2024/8/16 13:14 v0.0.5-dev
+ */
void onUnload();
+
+ /**
+ * 获取日志记录器
+ * @author wzp
+ * @since 2024/8/16 13:14 v0.0.5-dev
+ * @return 日志记录器
+ */
Logger getLogger();
+
+ /**
+ * 从插件中读取资源
+ * @author wzp
+ * @since 2024/8/16 13:14 v0.0.5-dev
+ * @param name 资源路径
+ * @return 资源流
+ */
+ InputStream getResourceAsStream(String name);
+
+ /**
+ * 获取插件数据文件夹
+ * @author wzp
+ * @since 2024/8/16 13:16 v0.0.5-dev
+ * @return 插件数据文件夹
+ */
+ File getDataFolder();
+
+ /**
+ * 获取默认配置文件
+ * @author wzp
+ * @since 2024/8/16 13:16 v0.0.5-dev
+ * @return 获取默认配置文件
+ */
+ File getDefaultConfigFile();
+
+ /**
+ * 将插件默认配置文件保存到文件夹中
+ * @author wzp
+ * @since 2024/8/16 13:16 v0.0.5-dev
+ */
+ void saveDefaultConfig();
}
diff --git a/src/main/java/cn/wzpmc/api/plugins/IPluginClassLoader.java b/src/main/java/cn/wzpmc/api/plugins/IPluginClassLoader.java
index 8c78879..75089ee 100644
--- a/src/main/java/cn/wzpmc/api/plugins/IPluginClassLoader.java
+++ b/src/main/java/cn/wzpmc/api/plugins/IPluginClassLoader.java
@@ -12,7 +12,12 @@ import java.net.URLClassLoader;
* @since 2024/7/31 下午6:59
*/
public abstract class IPluginClassLoader extends URLClassLoader {
-
+ /**
+ * 创建插件类加载器
+ * @author wzp
+ * @since 2024/8/23 21:41 v0.0.5-dev
+ * @param urls jar文件路径
+ */
public IPluginClassLoader(URL[] urls) {
super(urls);
}
diff --git a/src/main/java/cn/wzpmc/api/plugins/IPluginManager.java b/src/main/java/cn/wzpmc/api/plugins/IPluginManager.java
index 655a491..967416b 100644
--- a/src/main/java/cn/wzpmc/api/plugins/IPluginManager.java
+++ b/src/main/java/cn/wzpmc/api/plugins/IPluginManager.java
@@ -4,6 +4,7 @@ import java.lang.reflect.InvocationTargetException;
import java.util.List;
/**
+ * 插件管理器
* @author wzp
* @version 0.0.4-dev
* @since 2024/8/6 下午3:19
@@ -11,7 +12,6 @@ import java.util.List;
public interface IPluginManager {
/**
* 初始化插件主类
- *
* @param 插件主类类型
* @param baseClass 插件主类
* @param name 插件名称
@@ -19,6 +19,10 @@ public interface IPluginManager {
* @return 这个插件的实例
* @author wzp
* @since 2024/8/5 上午12:58 v0.0.4-dev
+ * @throws NoSuchMethodException 初始化插件错误
+ * @throws InvocationTargetException 初始化插件错误
+ * @throws InstantiationException 初始化插件错误
+ * @throws IllegalAccessException 初始化插件错误
*/
T initPlugin(Class baseClass, String name, String version) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException;
List getPlugins();
diff --git a/src/main/java/cn/wzpmc/api/plugins/JavaPlugin.java b/src/main/java/cn/wzpmc/api/plugins/JavaPlugin.java
index 92d0580..ef12462 100644
--- a/src/main/java/cn/wzpmc/api/plugins/JavaPlugin.java
+++ b/src/main/java/cn/wzpmc/api/plugins/JavaPlugin.java
@@ -1,10 +1,17 @@
package cn.wzpmc.api.plugins;
+import cn.wzpmc.api.user.IBot;
import lombok.Getter;
import lombok.Setter;
+import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
/**
* Java插件基类
* @author wzp
@@ -13,7 +20,12 @@ import org.apache.logging.log4j.Logger;
*/
@Setter
@Getter
+@Log4j2
public abstract class JavaPlugin implements BasePlugin {
+ /**
+ * 日志处理器
+ * @since 2024/8/23 21:42 v0.0.5-dev
+ */
private Logger logger;
@Override
public IPluginClassLoader getClassLoader() {
@@ -35,4 +47,51 @@ public abstract class JavaPlugin implements BasePlugin {
}
return this.logger;
}
+
+ public InputStream getResourceAsStream(String name) {
+ return this.getClassLoader().getResourceAsStream(name);
+ }
+
+ @Override
+ public File getDataFolder() {
+ IBot bot = this.getClassLoader().getBot();
+ File pluginsFolder = bot.getPluginsFolder();
+ File file = new File(pluginsFolder, this.getClassLoader().getName());
+ if (!file.isDirectory()){
+ if (!file.mkdir()) {
+ log.error("Failed to create plugin data folder");
+ return null;
+ }
+ }
+ return file;
+ }
+
+ @Override
+ public File getDefaultConfigFile() {
+ File file = new File(this.getDataFolder(), "config.yml");
+ if (!file.isFile()){
+ try {
+ if (!file.createNewFile()){
+ log.error("cannot create default config file");
+ return null;
+ }
+ } catch (IOException e) {
+ log.error(e);
+ return null;
+ }
+ }
+ return file;
+ }
+
+ @Override
+ public void saveDefaultConfig() {
+ try(InputStream resourceAsStream = this.getResourceAsStream("config.yml")){
+ File defaultConfigFile = this.getDefaultConfigFile();
+ try(FileOutputStream fileOutputStream = new FileOutputStream(defaultConfigFile)){
+ resourceAsStream.transferTo(fileOutputStream);
+ }
+ } catch (IOException e) {
+ log.error(e);
+ }
+ }
}
diff --git a/src/main/java/cn/wzpmc/api/user/CommandSender.java b/src/main/java/cn/wzpmc/api/user/CommandSender.java
index ba7887f..734c0b1 100644
--- a/src/main/java/cn/wzpmc/api/user/CommandSender.java
+++ b/src/main/java/cn/wzpmc/api/user/CommandSender.java
@@ -2,50 +2,76 @@ package cn.wzpmc.api.user;
import cn.wzpmc.api.message.MessageComponent;
import cn.wzpmc.api.user.permission.Permissions;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
/**
- * 消息发送者
+ * 命令发送者
* @author wzp
* @version 0.0.1-dev
* @since 2024/7/31 上午2:32
*/
-@AllArgsConstructor
-@NoArgsConstructor
-@Data
-public abstract class CommandSender {
- /**
- * 用户ID
- * @since 2024/7/30 下午11:48 v0.0.1-dev
- */
- protected Long id;
- /**
- * 用户名
- * @since 2024/7/30 下午11:48 v0.0.1-dev
- */
- protected String name;
- /**
- * 权限
- * @since 2024/8/1 下午8:24 v0.0.2-dev
- */
- protected Permissions permissions;
+public interface CommandSender {
/**
* 发送消息
* @author wzp
* @since 2024/7/31 上午2:42 v0.0.1-dev
* @param messageComponent 消息组件
*/
- public abstract void sendMessage(MessageComponent messageComponent);
+ void sendMessage(MessageComponent messageComponent);
+ /**
+ * 获取用户ID
+ * @author wzp
+ * @since 2024/8/23 21:43 v0.0.5-dev
+ * @return 用户ID
+ */
+ Long getId();
+
+ /**
+ * 获取用户名
+ * @author wzp
+ * @since 2024/8/23 21:43 v0.0.5-dev
+ * @return 用户名
+ */
+ String getName();
+
+ /**
+ * 获取用户权限
+ * @author wzp
+ * @since 2024/8/23 21:43 v0.0.5-dev
+ * @return 权限
+ */
+ Permissions getPermissions();
+
+ /**
+ * 设置用户ID
+ * @author wzp
+ * @since 2024/8/23 21:43 v0.0.5-dev
+ * @param id 用户ID
+ */
+ void setId(Long id);
+
+ /**
+ * 设置用户名
+ * @author wzp
+ * @since 2024/8/23 21:43 v0.0.5-dev
+ * @param name 用户名
+ */
+ void setName(String name);
+
+ /**
+ * 设置用户权限
+ * @author wzp
+ * @since 2024/8/23 21:44 v0.0.5-dev
+ * @param permissions 用户权限
+ */
+ void setPermissions(Permissions permissions);
/**
* 指令发送者是否为管理员
* @author wzp
* @since 2024/8/1 下午4:50 v0.0.2-dev
* @return 是否为管理员
*/
- public boolean isAdmin(){
- return Permissions.ADMIN.equals(this.permissions);
+ default boolean isAdmin(){
+ return Permissions.ADMIN.equals(this.getPermissions());
}
}
diff --git a/src/main/java/cn/wzpmc/api/user/Friend.java b/src/main/java/cn/wzpmc/api/user/Friend.java
index 172a05e..4fe5cbe 100644
--- a/src/main/java/cn/wzpmc/api/user/Friend.java
+++ b/src/main/java/cn/wzpmc/api/user/Friend.java
@@ -1,10 +1,13 @@
package cn.wzpmc.api.user;
+import cn.wzpmc.api.api.IMainApi;
+import cn.wzpmc.api.api.actions.message.send.SendPrivateMessageAction;
import cn.wzpmc.api.message.MessageComponent;
import cn.wzpmc.api.user.permission.Permissions;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import lombok.SneakyThrows;
/**
* 好友
@@ -15,12 +18,22 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
-public class Friend extends IUser{
+public class Friend extends IUser implements CommandSender{
public Friend(Long id, String name, Permissions permissions, String nickname, Sex sex, Integer age) {
super(id, name, permissions, nickname, sex, age);
}
+
+ /**
+ * 发送消息
+ * @author wzp
+ * @since 2024/8/23 21:44 v0.0.5-dev
+ * @param messageComponent 消息组件
+ */
+ @SneakyThrows
@Override
public void sendMessage(MessageComponent messageComponent) {
-
+ IBot instance = IBot.getInstance();
+ IMainApi mainApi = instance.getMainApi();
+ mainApi.doApiCall(new SendPrivateMessageAction(this.id, messageComponent));
}
}
diff --git a/src/main/java/cn/wzpmc/api/user/IBot.java b/src/main/java/cn/wzpmc/api/user/IBot.java
index ff1f7f2..d50ef6c 100644
--- a/src/main/java/cn/wzpmc/api/user/IBot.java
+++ b/src/main/java/cn/wzpmc/api/user/IBot.java
@@ -1,9 +1,11 @@
package cn.wzpmc.api.user;
+import cn.wzpmc.api.api.IMainApi;
import cn.wzpmc.api.events.Event;
import cn.wzpmc.api.plugins.ICommandManager;
import cn.wzpmc.api.plugins.configuration.IConfiguration;
+import java.io.File;
import java.lang.reflect.InvocationTargetException;
/**
@@ -12,7 +14,13 @@ import java.lang.reflect.InvocationTargetException;
* @version 0.0.1-dev
* @since 2024/7/31 上午2:31
*/
-public abstract class IBot extends CommandSender {
+public abstract class IBot extends MessageSender implements CommandSender {
+ private static IBot instance = null;
+ protected IBot(){
+ if (IBot.instance == null){
+ IBot.instance = this;
+ }
+ }
/**
* 获取配置文件
* @author wzp
@@ -49,6 +57,34 @@ public abstract class IBot extends CommandSender {
* @author wzp
* @since 2024/8/16 00:49 v0.0.4-dev
* @param event 事件
+ * @throws InvocationTargetException 处理时出现错误
+ * @throws IllegalAccessException 处理时出现错误
*/
public abstract void triggerEvent(Event event) throws InvocationTargetException, IllegalAccessException;
+
+ /**
+ * 获取插件文件夹
+ * @author wzp
+ * @since 2024/8/16 12:49 v0.0.5-dev
+ * @return 插件文件夹
+ */
+ public abstract File getPluginsFolder();
+
+ /**
+ * 获取api接口
+ * @author wzp
+ * @since 2024/8/16 17:34 v0.0.5-dev
+ * @return api接口
+ */
+ public abstract IMainApi getMainApi();
+
+ /**
+ * 获取bot实例
+ * @author wzp
+ * @since 2024/8/17 23:19 v0.0.5-dev
+ * @return 一个bot实例对象
+ */
+ public static IBot getInstance(){
+ return IBot.instance;
+ }
}
diff --git a/src/main/java/cn/wzpmc/api/user/IUser.java b/src/main/java/cn/wzpmc/api/user/IUser.java
index 2587374..9f3c559 100644
--- a/src/main/java/cn/wzpmc/api/user/IUser.java
+++ b/src/main/java/cn/wzpmc/api/user/IUser.java
@@ -16,7 +16,7 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
-public abstract class IUser extends CommandSender {
+public abstract class IUser extends MessageSender {
/**
* 玩家昵称
* @since 2024/8/1 下午8:34 v0.0.2-dev
diff --git a/src/main/java/cn/wzpmc/api/user/MessageSender.java b/src/main/java/cn/wzpmc/api/user/MessageSender.java
new file mode 100644
index 0000000..c614fcf
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/user/MessageSender.java
@@ -0,0 +1,36 @@
+package cn.wzpmc.api.user;
+
+import cn.wzpmc.api.user.permission.Permissions;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 消息发送者
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/18 00:01
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MessageSender {
+ /**
+ * 用户ID
+ * @since 2024/7/30 下午11:48 v0.0.1-dev
+ */
+ @JSONField(name = "user_id")
+ protected Long id;
+ /**
+ * 用户名
+ * @since 2024/7/30 下午11:48 v0.0.1-dev
+ */
+ @JSONField(name = "nickname")
+ protected String name;
+ /**
+ * 权限
+ * @since 2024/8/1 下午8:24 v0.0.2-dev
+ */
+ protected Permissions permissions;
+}
diff --git a/src/main/java/cn/wzpmc/api/user/group/GroupCommandSender.java b/src/main/java/cn/wzpmc/api/user/group/GroupCommandSender.java
new file mode 100644
index 0000000..2c37c5d
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/user/group/GroupCommandSender.java
@@ -0,0 +1,73 @@
+package cn.wzpmc.api.user.group;
+
+import cn.wzpmc.api.api.IMainApi;
+import cn.wzpmc.api.api.actions.message.send.SendGroupMessageAction;
+import cn.wzpmc.api.events.message.group.GroupMessageEvent;
+import cn.wzpmc.api.message.MessageComponent;
+import cn.wzpmc.api.message.StringMessage;
+import cn.wzpmc.api.message.json.JsonMessage;
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.At;
+import cn.wzpmc.api.user.CommandSender;
+import cn.wzpmc.api.user.IBot;
+import cn.wzpmc.api.user.Sex;
+import cn.wzpmc.api.user.permission.Permissions;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.SneakyThrows;
+
+import java.util.List;
+
+/**
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/18 00:11
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+public class GroupCommandSender extends GroupUser implements CommandSender {
+ public GroupCommandSender(Long id, String name, Permissions permissions, String nickname, Sex sex, Integer age, String card, String area, String level, GroupUserRole role, String title, Long groupId){
+ super(id, name, permissions, nickname, sex, age, card, area, level, role, title);
+ this.groupId = groupId;
+ }
+ private Long groupId;
+
+ @SneakyThrows
+ @Override
+ public void sendMessage(MessageComponent messageComponent) {
+ IBot instance = IBot.getInstance();
+ IMainApi mainApi = instance.getMainApi();
+ JsonMessage jsonMessage = new JsonMessage();
+ List messageParts = jsonMessage.getMessageParts();
+ messageParts.add(new At(this.getId()));
+ messageParts.add(StringMessage.text(messageComponent.toMessageString()));
+ SendGroupMessageAction sendGroupMessageAction = new SendGroupMessageAction(this.groupId, jsonMessage);
+ mainApi.doApiCall(sendGroupMessageAction);
+ }
+
+ /**
+ * 将一个群消息事件转为一个群指令执行者
+ * @author wzp
+ * @since 2024/8/23 21:42 v0.0.5-dev
+ * @param event 群消息事件
+ * @return 指令执行者对象
+ */
+ public static GroupCommandSender of(GroupMessageEvent event){
+ GroupUser sender = event.getSender();
+ Long eventGroupId = event.getGroupId();
+ Long id = sender.getId();
+ String name = sender.getName();
+ Permissions permissions = sender.getPermissions();
+ String nickname = sender.getNickname();
+ Sex sex = sender.getSex();
+ Integer age = sender.getAge();
+ String card = sender.getCard();
+ String area = sender.getArea();
+ String level = sender.getLevel();
+ GroupUserRole role = sender.getRole();
+ String title = sender.getTitle();
+ return new GroupCommandSender(id, name, permissions, nickname, sex, age, card, area, level, role, title, eventGroupId);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/user/group/GroupUser.java b/src/main/java/cn/wzpmc/api/user/group/GroupUser.java
index 438ecc0..e93a05d 100644
--- a/src/main/java/cn/wzpmc/api/user/group/GroupUser.java
+++ b/src/main/java/cn/wzpmc/api/user/group/GroupUser.java
@@ -1,7 +1,8 @@
package cn.wzpmc.api.user.group;
-import cn.wzpmc.api.message.MessageComponent;
import cn.wzpmc.api.user.IUser;
+import cn.wzpmc.api.user.Sex;
+import cn.wzpmc.api.user.permission.Permissions;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -43,8 +44,12 @@ public class GroupUser extends IUser {
* @since 2024/8/1 下午8:53 v0.0.2-dev
*/
private String title;
- @Override
- public void sendMessage(MessageComponent messageComponent) {
-
+ public GroupUser(Long id, String name, Permissions permissions, String nickname, Sex sex, Integer age, String card, String area, String level, GroupUserRole role, String title) {
+ super(id, name, permissions, nickname, sex, age);
+ this.card = card;
+ this.area = area;
+ this.level = level;
+ this.role = role;
+ this.title = title;
}
}
diff --git a/src/main/java/cn/wzpmc/console/MyBotConsole.java b/src/main/java/cn/wzpmc/console/MyBotConsole.java
index fe5bf19..5fe6faa 100644
--- a/src/main/java/cn/wzpmc/console/MyBotConsole.java
+++ b/src/main/java/cn/wzpmc/console/MyBotConsole.java
@@ -1,8 +1,10 @@
package cn.wzpmc.console;
+import cn.wzpmc.api.plugins.BasePlugin;
import cn.wzpmc.entities.user.bot.MyBot;
import cn.wzpmc.network.WebSocketConnectionHandler;
import cn.wzpmc.plugins.CommandManager;
+import cn.wzpmc.plugins.PluginManager;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@@ -44,8 +46,10 @@ public class MyBotConsole extends SimpleTerminalConsole {
@Override
public void shutdown() {
- running = false;
+ PluginManager pluginManager = this.bot.getPluginManager();
+ pluginManager.getPlugins().forEach(BasePlugin::onUnload);
this.webSocketConnectionHandler.kill();
+ running = false;
}
@Override
diff --git a/src/main/java/cn/wzpmc/console/logger/PluginMessageFactory.java b/src/main/java/cn/wzpmc/console/logger/PluginMessageFactory.java
index 88f1ead..5b997ab 100644
--- a/src/main/java/cn/wzpmc/console/logger/PluginMessageFactory.java
+++ b/src/main/java/cn/wzpmc/console/logger/PluginMessageFactory.java
@@ -2,13 +2,15 @@ package cn.wzpmc.console.logger;
import cn.wzpmc.api.plugins.BasePlugin;
import cn.wzpmc.api.plugins.IPluginClassLoader;
-import org.apache.logging.log4j.message.*;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
import java.lang.reflect.InvocationTargetException;
import static org.apache.logging.log4j.spi.AbstractLogger.DEFAULT_FLOW_MESSAGE_FACTORY_CLASS;
/**
+ * 插件消息工厂
* @author wzp
* @version 0.0.4-dev
* @since 2024/8/9 00:35
diff --git a/src/main/java/cn/wzpmc/entities/api/ApiResponseRequired.java b/src/main/java/cn/wzpmc/entities/api/ApiResponseRequired.java
new file mode 100644
index 0000000..f295fed
--- /dev/null
+++ b/src/main/java/cn/wzpmc/entities/api/ApiResponseRequired.java
@@ -0,0 +1,27 @@
+package cn.wzpmc.entities.api;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.ActionResponse;
+import lombok.Data;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * api返回需求
+ * @author wzp
+ * @since 2024/8/16 22:08
+ * @version 0.0.5-dev
+ */
+@Data
+public class ApiResponseRequired {
+ /**
+ * 请求返回Promise
+ * @since 2024/8/23 21:46 v0.0.5-dev
+ */
+ private final CompletableFuture> future;
+ /**
+ * 请求体
+ * @since 2024/8/23 21:47 v0.0.5-dev
+ */
+ private final Action request;
+}
diff --git a/src/main/java/cn/wzpmc/entities/event/EventHandlerMethod.java b/src/main/java/cn/wzpmc/entities/event/EventHandlerMethod.java
index db59cee..c514c04 100644
--- a/src/main/java/cn/wzpmc/entities/event/EventHandlerMethod.java
+++ b/src/main/java/cn/wzpmc/entities/event/EventHandlerMethod.java
@@ -5,12 +5,21 @@ import lombok.Data;
import java.lang.reflect.Method;
/**
+ * 事件处理器
* @author wzp
* @version 0.0.4-dev
* @since 2024/8/15 23:53
*/
@Data
public class EventHandlerMethod {
+ /**
+ * 处理器类
+ * @since 2024/8/23 21:47 v0.0.5-dev
+ */
private final Object object;
+ /**
+ * 处理的方法
+ * @since 2024/8/23 21:47 v0.0.5-dev
+ */
private final Method method;
}
diff --git a/src/main/java/cn/wzpmc/entities/user/bot/MyBot.java b/src/main/java/cn/wzpmc/entities/user/bot/MyBot.java
index 0449394..427afe4 100644
--- a/src/main/java/cn/wzpmc/entities/user/bot/MyBot.java
+++ b/src/main/java/cn/wzpmc/entities/user/bot/MyBot.java
@@ -1,5 +1,6 @@
package cn.wzpmc.entities.user.bot;
+import cn.wzpmc.api.api.IMainApi;
import cn.wzpmc.api.events.Event;
import cn.wzpmc.api.message.MessageComponent;
import cn.wzpmc.api.message.StringMessage;
@@ -11,13 +12,16 @@ import cn.wzpmc.api.utils.IncreasbleHashMap;
import cn.wzpmc.configuration.Configuration;
import cn.wzpmc.console.MyBotConsole;
import cn.wzpmc.entities.event.EventHandlerMethod;
+import cn.wzpmc.network.WebSocketConnectionHandler;
import cn.wzpmc.plugins.CommandManager;
import cn.wzpmc.plugins.PluginManager;
+import cn.wzpmc.plugins.api.MainApi;
import cn.wzpmc.utils.ReflectionUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
+import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@@ -38,8 +42,12 @@ public class MyBot extends IBot {
private final CommandManager commandManager = new CommandManager(this);
private final PluginManager pluginManager = new PluginManager();
private final IncreasbleHashMap, EventHandlerMethod> events = new IncreasbleHashMap<>();
+ private File pluginsFolder;
@Setter
private MyBotConsole console = null;
+ @Getter
+ private IMainApi mainApi;
+ private WebSocketConnectionHandler connectionHandler;
public MyBot(Configuration configuration){
this.configuration = configuration;
this.permissions = Permissions.ADMIN;
@@ -73,8 +81,22 @@ public class MyBot extends IBot {
@Override
public void triggerEvent(Event event) throws InvocationTargetException, IllegalAccessException {
List eventHandlerMethods = this.events.get(event.getClass());
+ if (eventHandlerMethods == null){
+ return;
+ }
for (EventHandlerMethod eventHandlerMethod : eventHandlerMethods) {
eventHandlerMethod.getMethod().invoke(eventHandlerMethod.getObject(), event);
}
}
+ public void setPluginsFolder(File pluginsFolder) {
+ if (this.pluginsFolder != null){
+ throw new IllegalStateException("This bot already initialized!");
+ }
+ this.pluginsFolder = pluginsFolder;
+ }
+
+ public void setConnectionHandler(WebSocketConnectionHandler connectionHandler) {
+ this.connectionHandler = connectionHandler;
+ this.mainApi = new MainApi(this, this.connectionHandler);
+ }
}
diff --git a/src/main/java/cn/wzpmc/network/HandshakePacketHandler.java b/src/main/java/cn/wzpmc/network/HandshakePacketHandler.java
index a97df52..db8de59 100644
--- a/src/main/java/cn/wzpmc/network/HandshakePacketHandler.java
+++ b/src/main/java/cn/wzpmc/network/HandshakePacketHandler.java
@@ -4,9 +4,12 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
+import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
+import java.util.concurrent.CompletableFuture;
+
/**
* 握手包处理器
* @author wzp
@@ -17,6 +20,8 @@ import lombok.extern.log4j.Log4j2;
@RequiredArgsConstructor
public class HandshakePacketHandler extends SimpleChannelInboundHandler {
private final WebSocketClientHandshaker handshaker;
+ @Getter
+ private final CompletableFuture handshakeFuture = new CompletableFuture<>();
@Override
public void channelActive(ChannelHandlerContext ctx) {
@@ -28,6 +33,7 @@ public class HandshakePacketHandler extends SimpleChannelInboundHandler {
private final IBot bot;
-
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame webSocketFrame) {
String text = webSocketFrame.text();
+ System.out.println(text);
if (!JSON.isValidObject(text)){
log.warn("收到了无法处理的WebSocket数据包:{}", text);
return;
}
JSONObject jsonObject = JSON.parseObject(text);
if (jsonObject.containsKey("echo")) {
- handleApiEcho(jsonObject);
+ handleApiEcho(text);
return;
}
handleEvent(text);
}
+ private final ExecutorService threadPool = Executors.newFixedThreadPool(4);
+
+ /**
+ * 处理事件
+ * @author wzp
+ * @since 2024/8/23 21:47 v0.0.5-dev
+ * @param text 事件json文本
+ */
private void handleEvent(String text){
Event event = JSON.parseObject(text, Event.class);
- try {
- this.bot.triggerEvent(event);
- } catch (InvocationTargetException | IllegalAccessException e) {
- log.error(new RuntimeException(e));
- }
+ threadPool.submit(() -> {
+ try {
+ this.bot.triggerEvent(event);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ log.error(new RuntimeException(e));
+ }
+ });
}
- private void handleApiEcho(JSONObject data){
+ /**
+ * 处理api回调
+ * @author wzp
+ * @since 2024/8/23 21:48 v0.0.5-dev
+ * @param dataString 返回json文本
+ * @param 请求类型
+ * @param 返回类型
+ */
+ private void handleApiEcho(String dataString){
+ //noinspection unchecked
+ ActionResponse actionResponse = JSON.parseObject(dataString, ActionResponse.class);
+ UUID echo = actionResponse.getEcho();
+ //noinspection unchecked
+ ApiResponseRequired apiResponseRequired = (ApiResponseRequired) ActionReader.tasks.get(echo);
+ if (apiResponseRequired == null) {
+ log.warn("收到了错误的请求返回:{}", echo);
+ return;
+ }
+ ActionReader.tasks.remove(echo);
+ apiResponseRequired.getFuture().complete(actionResponse);
+ }
+
+ /**
+ * 注册返回回调
+ * @author wzp
+ * @since 2024/8/23 21:48 v0.0.5-dev
+ * @param echo 回调ID
+ * @param responsePromise 返回Promise
+ * @param request 请求体
+ * @param 请求体类型
+ * @param 返回类型
+ */
+ public void registerResponse(UUID echo, CompletableFuture> responsePromise, Action request) {
+ ActionReader.tasks.put(echo, new ApiResponseRequired<>(responsePromise, request));
}
}
diff --git a/src/main/java/cn/wzpmc/network/WebSocketConnectionHandler.java b/src/main/java/cn/wzpmc/network/WebSocketConnectionHandler.java
index dcc7ab5..424ae95 100644
--- a/src/main/java/cn/wzpmc/network/WebSocketConnectionHandler.java
+++ b/src/main/java/cn/wzpmc/network/WebSocketConnectionHandler.java
@@ -1,12 +1,16 @@
package cn.wzpmc.network;
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.ActionResponse;
import cn.wzpmc.api.user.IBot;
+import com.alibaba.fastjson2.JSON;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
@@ -14,6 +18,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import java.net.URI;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
/**
* 此类用于建立WebSocket连接
@@ -26,21 +32,23 @@ import java.net.URI;
public class WebSocketConnectionHandler {
private final EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
private final IBot bot;
+ private ChannelFuture channelFuture;
+ private PacketHandler packetHandler;
+ private HandshakePacketHandler handshakePacketHandler;
/**
* 建立连接
* @author wzp
* @since 2024/7/30 下午11:55 v0.0.1-dev
* @param websocket websocket连接地址
- * @return 一个ChannelFuture对象
*/
- public ChannelFuture connect(URI websocket){
+ public void connect(URI websocket){
log.info("正在连接websocket");
Bootstrap bootstrap = new Bootstrap();
WebSocketClientHandshaker clientHandshaker = WebSocketClientHandshakerFactory.newHandshaker(websocket, WebSocketVersion.V13, null, false, new DefaultHttpHeaders());
- HandshakePacketHandler handshakePacketHandler = new HandshakePacketHandler(clientHandshaker);
- PacketHandler handler = new PacketHandler(this.bot);
- bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new WebSocketChannelInitializer(handler, handshakePacketHandler));
- return bootstrap.connect(websocket.getHost(), websocket.getPort());
+ this.handshakePacketHandler = new HandshakePacketHandler(clientHandshaker);
+ this.packetHandler = new PacketHandler(this.bot);
+ bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new WebSocketChannelInitializer(this.packetHandler, this.handshakePacketHandler));
+ this.channelFuture = bootstrap.connect(websocket.getHost(), websocket.getPort());
}
/**
@@ -52,4 +60,31 @@ public class WebSocketConnectionHandler {
log.info("结束连接...");
this.eventLoopGroup.shutdownGracefully();
}
+
+ /**
+ * 发送请求
+ * @author wzp
+ * @since 2024/8/23 21:49 v0.0.5-dev
+ * @param request 请求
+ * @return 返回
+ * @param 请求体类型
+ * @param 返回类型
+ * @throws InterruptedException 当请求进行时按下Ctrl+C时抛出
+ */
+ public ActionResponse sendRequest(Action request) throws InterruptedException {
+ try {
+ this.handshakePacketHandler.getHandshakeFuture().get();
+ } catch (ExecutionException e) {
+ log.error(e);
+ }
+ CompletableFuture> responsePromise = new CompletableFuture<>();
+ packetHandler.registerResponse(request.getEcho(), responsePromise, request);
+ channelFuture.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(request)));
+ try {
+ return responsePromise.get();
+ } catch (ExecutionException e) {
+ log.error(e);
+ }
+ return null;
+ }
}
diff --git a/src/main/java/cn/wzpmc/plugins/PluginClassLoader.java b/src/main/java/cn/wzpmc/plugins/PluginClassLoader.java
index e7f0544..2d5c1e4 100644
--- a/src/main/java/cn/wzpmc/plugins/PluginClassLoader.java
+++ b/src/main/java/cn/wzpmc/plugins/PluginClassLoader.java
@@ -5,7 +5,6 @@ import cn.wzpmc.api.plugins.IPluginClassLoader;
import cn.wzpmc.api.user.IBot;
import lombok.EqualsAndHashCode;
import lombok.Getter;
-import lombok.Setter;
import lombok.ToString;
import java.net.URL;
diff --git a/src/main/java/cn/wzpmc/plugins/api/MainApi.java b/src/main/java/cn/wzpmc/plugins/api/MainApi.java
new file mode 100644
index 0000000..60446c3
--- /dev/null
+++ b/src/main/java/cn/wzpmc/plugins/api/MainApi.java
@@ -0,0 +1,24 @@
+package cn.wzpmc.plugins.api;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.ActionResponse;
+import cn.wzpmc.api.api.IMainApi;
+import cn.wzpmc.api.user.IBot;
+import cn.wzpmc.network.WebSocketConnectionHandler;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/16 17:32
+ */
+@RequiredArgsConstructor
+public class MainApi implements IMainApi {
+ private final IBot bot;
+ private final WebSocketConnectionHandler handler;
+
+ @Override
+ public ActionResponse doApiCall(Action packet) throws InterruptedException {
+ return handler.sendRequest(packet);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/JsonUtils.java b/src/main/java/cn/wzpmc/utils/JsonUtils.java
index c3d3e79..ab39a93 100644
--- a/src/main/java/cn/wzpmc/utils/JsonUtils.java
+++ b/src/main/java/cn/wzpmc/utils/JsonUtils.java
@@ -1,5 +1,7 @@
package cn.wzpmc.utils;
+import cn.wzpmc.api.api.ActionResponse;
+import cn.wzpmc.api.api.Actions;
import cn.wzpmc.api.events.Event;
import cn.wzpmc.api.events.message.MessageEvent;
import cn.wzpmc.api.events.meta.MetaEvent;
@@ -8,10 +10,14 @@ import cn.wzpmc.api.events.notice.notify.NotifyEvent;
import cn.wzpmc.api.events.request.RequestEvent;
import cn.wzpmc.api.message.StringMessage;
import cn.wzpmc.api.message.json.JsonMessage;
+import cn.wzpmc.api.user.IUser;
+import cn.wzpmc.utils.json.action.ActionReader;
+import cn.wzpmc.utils.json.action.ActionWriter;
import cn.wzpmc.utils.json.event.*;
import cn.wzpmc.utils.json.message.JsonMessageReader;
import cn.wzpmc.utils.json.message.JsonMessageWriter;
import cn.wzpmc.utils.json.message.StringMessageReader;
+import cn.wzpmc.utils.json.user.IUserReader;
import com.alibaba.fastjson2.JSON;
/**
@@ -21,9 +27,21 @@ import com.alibaba.fastjson2.JSON;
* @since 2024/8/2 下午2:04
*/
public class JsonUtils {
+ /**
+ * 初始化JSON反序列化相关
+ * @author wzp
+ * @since 2024/8/23 21:50 v0.0.5-dev
+ */
public static void initWriter() {
JSON.register(JsonMessage.class, new JsonMessageWriter());
+ JSON.register(Actions.class, new ActionWriter());
}
+
+ /**
+ * 初始化JSON序列化相关
+ * @author wzp
+ * @since 2024/8/23 21:50 v0.0.5-dev
+ */
public static void initReader() {
JSON.register(MessageEvent.class, new MessageEventReader());
JSON.register(MetaEvent.class, new MetaEventReader());
@@ -33,6 +51,8 @@ public class JsonUtils {
JSON.register(Event.class, new EventReader());
JSON.register(JsonMessage.class, new JsonMessageReader());
JSON.register(StringMessage.class, new StringMessageReader());
+ JSON.register(ActionResponse.class, new ActionReader());
+ JSON.register(IUser.class, new IUserReader());
}
}
diff --git a/src/main/java/cn/wzpmc/utils/json/action/ActionReader.java b/src/main/java/cn/wzpmc/utils/json/action/ActionReader.java
new file mode 100644
index 0000000..c27594b
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/action/ActionReader.java
@@ -0,0 +1,39 @@
+package cn.wzpmc.utils.json.action;
+
+import cn.wzpmc.api.api.Action;
+import cn.wzpmc.api.api.ActionResponse;
+import cn.wzpmc.api.api.Actions;
+import cn.wzpmc.entities.api.ApiResponseRequired;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/16 21:50
+ */
+public class ActionReader implements ObjectReader> {
+ public static final ConcurrentHashMap> tasks = new ConcurrentHashMap<>();
+ @Override
+ public ActionResponse> readObject(JSONReader jsonReader, Type type, Object o, long l) {
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ UUID echo = jsonObject.getObject("echo", UUID.class);
+ ApiResponseRequired, ?> apiResponseRequired = tasks.get(echo);
+ Action, ?> request = apiResponseRequired.getRequest();
+ Actions action = request.getAction();
+ String status = jsonObject.getString("status");
+ short retcode = jsonObject.getShort("retcode");
+ JSONObject data = jsonObject.getJSONObject("data");
+ Object dataObj = null;
+ if (data != null){
+ dataObj = data.to(action.responseClass);
+
+ }
+ return new ActionResponse<>(status, retcode, dataObj, echo);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/action/ActionWriter.java b/src/main/java/cn/wzpmc/utils/json/action/ActionWriter.java
new file mode 100644
index 0000000..8425b8f
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/action/ActionWriter.java
@@ -0,0 +1,20 @@
+package cn.wzpmc.utils.json.action;
+
+import cn.wzpmc.api.api.Actions;
+import com.alibaba.fastjson2.JSONWriter;
+import com.alibaba.fastjson2.writer.ObjectWriter;
+
+import java.lang.reflect.Type;
+
+/**
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 22:05
+ */
+public class ActionWriter implements ObjectWriter {
+ @Override
+ public void write(JSONWriter jsonWriter, Object o, Object fieldName, Type type, long l) {
+ Actions actions = (Actions) o;
+ jsonWriter.writeString(actions.name().toLowerCase());
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/user/IUserReader.java b/src/main/java/cn/wzpmc/utils/json/user/IUserReader.java
new file mode 100644
index 0000000..add3e97
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/user/IUserReader.java
@@ -0,0 +1,26 @@
+package cn.wzpmc.utils.json.user;
+
+import cn.wzpmc.api.user.Friend;
+import cn.wzpmc.api.user.IUser;
+import cn.wzpmc.api.user.group.GroupUser;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * @author wzp
+ * @version 0.0.5-dev
+ * @since 2024/8/17 23:12
+ */
+public class IUserReader implements ObjectReader {
+ @Override
+ public IUser readObject(JSONReader jsonReader, Type type, Object o, long l) {
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ if (jsonObject.containsKey("role")) {
+ return jsonObject.to(GroupUser.class);
+ }
+ return jsonObject.to(Friend.class);
+ }
+}
diff --git a/src/test/java/TestEventHandler.java b/src/test/java/TestEventHandler.java
index 6967b58..8e1d084 100644
--- a/src/test/java/TestEventHandler.java
+++ b/src/test/java/TestEventHandler.java
@@ -1,7 +1,3 @@
-import cn.wzpmc.api.events.Event;
-import cn.wzpmc.api.events.message.priv.PrivateMessageEvent;
-import cn.wzpmc.api.events.notice.notify.PokeNotifyEvent;
-import cn.wzpmc.api.plugins.event.EventHandler;
import cn.wzpmc.utils.ReflectionUtils;
import org.junit.jupiter.api.Test;