From a1d18b1277d8486444cff89b7a2dad28654dfa16 Mon Sep 17 00:00:00 2001 From: wzp Date: Fri, 23 Aug 2024 21:58:29 +0800 Subject: [PATCH] feat: adding api invoke function feat: adding some api --- .idea/fileTemplates/includes/Version.txt | 2 +- .idea/misc.xml | 5 +- build.gradle.kts | 2 +- src/main/java/cn/wzpmc/Main.java | 42 ++++++-- src/main/java/cn/wzpmc/api/api/Action.java | 34 ++++++ .../java/cn/wzpmc/api/api/ActionResponse.java | 35 ++++++ src/main/java/cn/wzpmc/api/api/Actions.java | 85 +++++++++++++++ src/main/java/cn/wzpmc/api/api/IMainApi.java | 21 ++++ .../message/delete/DeleteMessageAction.java | 36 +++++++ .../message/get/GetForwardMessageAction.java | 35 ++++++ .../actions/message/get/GetMessageAction.java | 37 +++++++ .../message/send/SendGroupMessageAction.java | 61 +++++++++++ .../actions/message/send/SendLikeAction.java | 53 +++++++++ .../send/SendMessageActionResponseData.java | 20 ++++ .../send/SendPrivateMessageAction.java | 61 +++++++++++ .../message/set/SetGroupAdminAction.java | 61 +++++++++++ .../message/set/SetGroupAnonymous.java | 53 +++++++++ .../set/SetGroupAnonymousBanAction.java | 102 ++++++++++++++++++ .../message/set/SetGroupBanAction.java | 61 +++++++++++ .../message/set/SetGroupCardAction.java | 60 +++++++++++ .../message/set/SetGroupKickAction.java | 61 +++++++++++ .../message/set/SetGroupWholeBanAction.java | 53 +++++++++ .../java/cn/wzpmc/api/entities/BotStatus.java | 8 ++ .../api/entities/MessageInformation.java | 49 +++++++++ .../wzpmc/api/message/json/JsonMessage.java | 14 +++ .../cn/wzpmc/api/message/json/parts/At.java | 4 +- .../cn/wzpmc/api/message/json/parts/Dice.java | 1 + .../api/message/json/parts/PartType.java | 83 +++++++++++++- .../json/parts/contact/ContactType.java | 2 +- .../java/cn/wzpmc/api/plugins/BasePlugin.java | 53 +++++++++ .../wzpmc/api/plugins/IPluginClassLoader.java | 7 +- .../cn/wzpmc/api/plugins/IPluginManager.java | 6 +- .../java/cn/wzpmc/api/plugins/JavaPlugin.java | 59 ++++++++++ .../java/cn/wzpmc/api/user/CommandSender.java | 78 +++++++++----- src/main/java/cn/wzpmc/api/user/Friend.java | 17 ++- src/main/java/cn/wzpmc/api/user/IBot.java | 38 ++++++- src/main/java/cn/wzpmc/api/user/IUser.java | 2 +- .../java/cn/wzpmc/api/user/MessageSender.java | 36 +++++++ .../api/user/group/GroupCommandSender.java | 73 +++++++++++++ .../cn/wzpmc/api/user/group/GroupUser.java | 13 ++- .../java/cn/wzpmc/console/MyBotConsole.java | 6 +- .../console/logger/PluginMessageFactory.java | 4 +- .../entities/api/ApiResponseRequired.java | 27 +++++ .../entities/event/EventHandlerMethod.java | 9 ++ .../cn/wzpmc/entities/user/bot/MyBot.java | 22 ++++ .../wzpmc/network/HandshakePacketHandler.java | 6 ++ .../java/cn/wzpmc/network/PacketHandler.java | 67 ++++++++++-- .../network/WebSocketConnectionHandler.java | 47 ++++++-- .../cn/wzpmc/plugins/PluginClassLoader.java | 1 - .../java/cn/wzpmc/plugins/api/MainApi.java | 24 +++++ src/main/java/cn/wzpmc/utils/JsonUtils.java | 20 ++++ .../wzpmc/utils/json/action/ActionReader.java | 39 +++++++ .../wzpmc/utils/json/action/ActionWriter.java | 20 ++++ .../cn/wzpmc/utils/json/user/IUserReader.java | 26 +++++ src/test/java/TestEventHandler.java | 4 - 55 files changed, 1774 insertions(+), 71 deletions(-) create mode 100644 src/main/java/cn/wzpmc/api/api/Action.java create mode 100644 src/main/java/cn/wzpmc/api/api/ActionResponse.java create mode 100644 src/main/java/cn/wzpmc/api/api/Actions.java create mode 100644 src/main/java/cn/wzpmc/api/api/IMainApi.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/delete/DeleteMessageAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/get/GetForwardMessageAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/get/GetMessageAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/send/SendGroupMessageAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/send/SendLikeAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/send/SendMessageActionResponseData.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/send/SendPrivateMessageAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAdminAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymous.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupAnonymousBanAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupBanAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupCardAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupKickAction.java create mode 100644 src/main/java/cn/wzpmc/api/api/actions/message/set/SetGroupWholeBanAction.java create mode 100644 src/main/java/cn/wzpmc/api/entities/MessageInformation.java create mode 100644 src/main/java/cn/wzpmc/api/user/MessageSender.java create mode 100644 src/main/java/cn/wzpmc/api/user/group/GroupCommandSender.java create mode 100644 src/main/java/cn/wzpmc/entities/api/ApiResponseRequired.java create mode 100644 src/main/java/cn/wzpmc/plugins/api/MainApi.java create mode 100644 src/main/java/cn/wzpmc/utils/json/action/ActionReader.java create mode 100644 src/main/java/cn/wzpmc/utils/json/action/ActionWriter.java create mode 100644 src/main/java/cn/wzpmc/utils/json/user/IUserReader.java 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 clazz; PartType(Class 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;