From 51e777b6ada54aa4f0315ffb5b36d28418cf1870 Mon Sep 17 00:00:00 2001 From: cnlimiter Date: Tue, 11 Feb 2025 19:52:27 +0800 Subject: [PATCH] feat(client): upgrade SDK and add new features - Upgrade OneBot SDK from 0.3.0 to0.3.1 - Add new methods in Bot class to support additional actions - Update ActionFactory and ActionSendUnit for new functionalities - Modify build.gradle for new dependencies and versions- Update gradle.properties for new client and SDK versions - Add ReflectionUtils class for dynamic class loading - Update ConnectionUtils for better self ID parsing --- build.gradle | 15 +- gradle.properties | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../cn/evole/onebot/client/OneBotClient.java | 4 + .../onebot/client/connection/WSClient.java | 2 +- .../java/cn/evole/onebot/client/core/Bot.java | 338 +++++++++++++++++- .../instances/action/ActionFactory.java | 2 +- .../instances/action/ActionSendUnit.java | 2 +- .../client/instances/event/EventFactory.java | 2 +- .../onebot/client/utils/ConnectionUtils.java | 27 +- .../onebot/client/utils/ReflectionUtils.java | 60 ++++ src/test/java/ApiTest.java | 4 +- src/test/java/HandlerTest.java | 6 +- 13 files changed, 423 insertions(+), 47 deletions(-) create mode 100644 src/main/java/cn/evole/onebot/client/utils/ReflectionUtils.java diff --git a/build.gradle b/build.gradle index 1d9cb72..3a5966e 100644 --- a/build.gradle +++ b/build.gradle @@ -32,8 +32,9 @@ configurations { repositories { - maven { url = "https://repo.papermc.io/repository/maven-public/" } + mavenLocal() maven { url = "https://maven.nova-committee.cn/releases"} + maven { url = "https://repo.papermc.io/repository/maven-public/" } mavenCentral() } @@ -51,10 +52,10 @@ dependencies { testCompileOnly("org.projectlombok:lombok:1.18.24") testRuntimeOnly 'org.slf4j:slf4j-simple:2.0.6' - shadow "net.kyori:event-api:${eventbus_version}" - shadow "net.kyori:event-method:${eventbus_version}" - shadow "cn.evole.onebot:OneBot-SDK:${sdk_version}" - shadow "org.java-websocket:Java-WebSocket:${websocket_version}" + implementation "net.kyori:event-api:${eventbus_version}" + implementation "net.kyori:event-method:${eventbus_version}" + implementation "cn.evole.onebot:OneBot-SDK:${sdk_version}" + implementation "org.java-websocket:Java-WebSocket:${websocket_version}" annotationProcessor("org.projectlombok:lombok:1.18.24") @@ -93,8 +94,8 @@ publishing { repositories { if (System.getenv('MAVEN_USERNAME') != null && System.getenv('MAVEN_PASSWORD') != null) { maven { - name 'release' - url = 'https://maven.nova-committee.cn/releases' + name 's3' + url = 'https://maven.nova-committee.cn/s3' credentials { username System.getenv('MAVEN_USERNAME') diff --git a/gradle.properties b/gradle.properties index 97c7cfd..8039322 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,9 +4,9 @@ org.gradle.jvmargs=-Xmx1G maven_group=cn.evole.onebot archives_base_name=OneBot-Client -client_version=0.4.1 +client_version=0.4.2 java_version=8 -sdk_version=0.3.0 +sdk_version=0.3.1 eventbus_version=3.0.0 -websocket_version=1.5.7 \ No newline at end of file +websocket_version=1.6.0 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a595206..48c0a02 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/cn/evole/onebot/client/OneBotClient.java b/src/main/java/cn/evole/onebot/client/OneBotClient.java index 486c800..aabf9ee 100644 --- a/src/main/java/cn/evole/onebot/client/OneBotClient.java +++ b/src/main/java/cn/evole/onebot/client/OneBotClient.java @@ -52,6 +52,10 @@ public static OneBotClient create(BotConfig config){ return new OneBotClient(config); } + public static OneBotClient create(BotConfig config, Listener... listeners){ + return new OneBotClient(config).registerEvents(listeners); + } + public OneBotClient open() { String token = config.getToken(); long botId = config.getBotId(); diff --git a/src/main/java/cn/evole/onebot/client/connection/WSClient.java b/src/main/java/cn/evole/onebot/client/connection/WSClient.java index 589750d..7031f62 100644 --- a/src/main/java/cn/evole/onebot/client/connection/WSClient.java +++ b/src/main/java/cn/evole/onebot/client/connection/WSClient.java @@ -28,7 +28,7 @@ public Bot createBot(){ @Override public void onOpen(ServerHandshake handshake) { client.getLogger().info("▌ §c已连接到服务器 §a┈━═☆"); - //handshake.iterateHttpFields().forEachRemaining(s -> System.out.println(s + ": " + handshake.getFieldValue(s))); + handshake.iterateHttpFields().forEachRemaining(s -> System.out.println(s + ": " + handshake.getFieldValue(s))); } @Override diff --git a/src/main/java/cn/evole/onebot/client/core/Bot.java b/src/main/java/cn/evole/onebot/client/core/Bot.java index d2082ac..0359a79 100644 --- a/src/main/java/cn/evole/onebot/client/core/Bot.java +++ b/src/main/java/cn/evole/onebot/client/core/Bot.java @@ -2,15 +2,17 @@ import cn.evole.onebot.client.instances.action.ActionFactory; -import cn.evole.onebot.sdk.action.ActionData; -import cn.evole.onebot.sdk.action.ActionList; -import cn.evole.onebot.sdk.action.ActionPath; -import cn.evole.onebot.sdk.action.ActionRaw; +import cn.evole.onebot.sdk.action.BaseBot; +import cn.evole.onebot.sdk.action.misc.ActionData; +import cn.evole.onebot.sdk.action.misc.ActionList; +import cn.evole.onebot.sdk.action.misc.ActionPath; +import cn.evole.onebot.sdk.action.misc.ActionRaw; import cn.evole.onebot.sdk.entity.Anonymous; +import cn.evole.onebot.sdk.entity.ArrayMsg; import cn.evole.onebot.sdk.entity.GuildMsgId; import cn.evole.onebot.sdk.entity.MsgId; import cn.evole.onebot.sdk.enums.ActionType; -import cn.evole.onebot.sdk.event.message.GroupMessageEvent; +import cn.evole.onebot.sdk.event.message.WholeMessageEvent; import cn.evole.onebot.sdk.response.contact.FriendInfoResp; import cn.evole.onebot.sdk.response.contact.LoginInfoResp; import cn.evole.onebot.sdk.response.contact.StrangerInfoResp; @@ -19,6 +21,7 @@ import cn.evole.onebot.sdk.response.guild.*; import cn.evole.onebot.sdk.response.misc.*; import cn.evole.onebot.sdk.util.GsonUtils; +import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -38,7 +41,10 @@ * Version: 1.0 */ @SuppressWarnings("unused") -public class Bot { +public class Bot implements BaseBot { + private final Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create(); + + private long selfId; private final ActionFactory actionFactory; @@ -46,10 +52,6 @@ public class Bot { @Setter private WebSocket channel; - @Getter - @Setter - private long botId; - /** * @param channel {@link WebSocket} * @param actionFactory {@link ActionFactory} @@ -59,15 +61,20 @@ public Bot(WebSocket channel, ActionFactory actionFactory) { this.actionFactory = actionFactory; } + @Override + public long getSelfId() { + return this.selfId; + } + /** * 发送消息 * - * @param event {@link GroupMessageEvent} + * @param event {@link WholeMessageEvent} * @param msg 要发送的内容 * @param autoEscape 消息内容是否作为纯文本发送 ( 即不解析 CQ 码 ) , 只在 message 字段是字符串时有效 * @return {@link ActionData} of {@link MsgId} */ - public ActionData sendMsg(GroupMessageEvent event, String msg, boolean autoEscape) { + public ActionData sendMsg(WholeMessageEvent event, String msg, boolean autoEscape) { switch (event.getMessageType()) { case "private": { return sendPrivateMsg(event.getUserId(), msg, autoEscape); @@ -80,6 +87,11 @@ public ActionData sendMsg(GroupMessageEvent event, String msg, boolean au return null; } + @Override + public ActionData sendMsg(WholeMessageEvent wholeMessageEvent, List list, boolean b) { + return null; + } + /** * 发送私聊消息 * @@ -98,6 +110,21 @@ public ActionData sendPrivateMsg(long userId, String msg, boolean autoEsc return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() {}.getType()) : null; } + @Override + public ActionData sendPrivateMsg(long l, List list, boolean b) { + return null; + } + + @Override + public ActionData sendPrivateMsg(long l, long l1, String s, boolean b) { + return null; + } + + @Override + public ActionData sendPrivateMsg(long l, long l1, List list, boolean b) { + return null; + } + /** * 发送私聊消息 * @@ -135,6 +162,21 @@ public ActionData sendGroupMsg(long groupId, String msg, boolean autoEsca return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() {}.getType()) : null; } + @Override + public ActionData sendGroupMsg(long groupId, List msg, boolean autoEscape) { + return null; + } + + @Override + public ActionData sendGroupMsg(long groupId, long userId, String msg, boolean autoEscape) { + return null; + } + + @Override + public ActionData sendGroupMsg(long groupId, long userId, List msg, boolean autoEscape) { + return null; + } + /** * 发送群消息 * @@ -341,6 +383,17 @@ public ActionRaw deleteMsg(int msgId) { return result != null ? GsonUtils.fromJson(result.toString(), ActionRaw.class) : null; } + @Override + public ActionRaw deleteMsg(long groupId, long userId, int msgId) { + val action = ActionType.DELETE_MSG; + val params = new JsonObject(); + params.addProperty("message_id", msgId); + params.addProperty("user_id", userId); + params.addProperty("group_id", groupId); + val result = actionFactory.action(channel, action, params); + return result != null ? GsonUtils.fromJson(result.toString(), ActionRaw.class) : null; + } + /** * 群组踢人 * @@ -669,6 +722,17 @@ public ActionList getGroupMemberList(long groupId) { }.getType()) : null; } + @Override + public ActionList getGroupMemberList(long groupId, boolean noCache) { + val action = ActionType.GET_GROUP_MEMBER_LIST; + val params = new JsonObject(); + params.addProperty("group_id", groupId); + params.addProperty("no_cache", noCache); + val result = actionFactory.action(channel, action, params); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + /** * 获取群荣誉信息 * @@ -833,8 +897,7 @@ public ActionRaw uploadGroupFile(long groupId, String file, String name) { * @param duration 禁言时长,单位秒,无法取消匿名用户禁言 * @return {@link ActionRaw} */ - public ActionRaw setGroupAnonymousBan(long groupId, Anonymous anonymous, boolean duration) { - val gson = new GsonBuilder().create(); + public ActionRaw setGroupAnonymousBan(long groupId, Anonymous anonymous, int duration) { val action = ActionType.SET_GROUP_ANONYMOUS_BAN; String an = gson.toJson(anonymous, Anonymous.class); val params = new JsonObject(); @@ -846,6 +909,7 @@ public ActionRaw setGroupAnonymousBan(long groupId, Anonymous anonymous, boolean return result != null ? GsonUtils.fromJson(result.toString(),ActionRaw.class) : null; } + /** * 群组匿名用户禁言 * @@ -854,7 +918,7 @@ public ActionRaw setGroupAnonymousBan(long groupId, Anonymous anonymous, boolean * @param duration 禁言时长,单位秒,无法取消匿名用户禁言 * @return {@link ActionRaw} */ - public ActionRaw setGroupAnonymousBan(long groupId, String flag, boolean duration) { + public ActionRaw setGroupAnonymousBan(long groupId, String flag, int duration) { val action = ActionType.SET_GROUP_ANONYMOUS_BAN; val params = new JsonObject(); params.addProperty("group_id", groupId); @@ -1059,6 +1123,7 @@ public ActionData sendPrivateForwardMsg(long userId, List sendPrivateForwardMsg(long userId, List参考文档 * @return {@link ActionRaw} */ - public ActionData sendForwardMsg(GroupMessageEvent event, List> msg) { + public ActionData sendForwardMsg(WholeMessageEvent event, List> msg) { val action = ActionType.SEND_FORWARD_MSG; val params = new JsonObject(); params.addProperty("messages", GsonUtils.getGson().toJson(msg, new TypeToken>>() { @@ -1196,4 +1261,245 @@ public ActionList getUnidirectionalFriendList() { return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { }.getType()) : null; } + + /** + * 获取群文件资源链接 + * + * @param groupId 群号 + * @param fileId 文件ID + * @param busId 文件类型 + * @return result {@link ActionData} of {@link UrlResp} + */ + @Override + public ActionData getGroupFileUrl(long groupId, String fileId, int busId) { + val action = ActionType.GET_GROUP_FILE_URL; + val params = new JsonObject(); + params.addProperty("group_id", groupId); + params.addProperty("file_id", fileId); + params.addProperty("busid", busId); + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + /** + * 获取群文件资源链接 + * + * @param groupId 群号 + * @param fileId 文件ID + * @param busId 文件类型 + * @return result {@link ActionData} of {@link UrlResp} + */ + @Override + public ActionData getFile(long groupId, String fileId, int busId) { + val action = ActionType.GET_GROUP_FILE_URL; + val params = new JsonObject(); + params.addProperty("group_id", groupId); + params.addProperty("file_id", fileId); + params.addProperty("busid", busId); + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + /** + * 创建群文件文件夹 + * + * @param groupId 群号 + * @param folderName 文件夹名 + * @return result {@link ActionRaw} + */ + @Override + public ActionRaw createGroupFileFolder(long groupId, String folderName) { + val action = ActionType.CREATE_GROUP_FILE_FOLDER; + val params = new JsonObject(); + params.addProperty("group_id", groupId); + params.addProperty("name", folderName); + // 仅能在根目录创建文件夹 + params.addProperty("parent_id", "/"); + val result = actionFactory.action(channel, action, params); + return result != null ? GsonUtils.fromJson(result.toString(), ActionRaw.class) : null; + } + + /** + * 删除群文件文件夹 + * + * @param groupId 群号 + * @param folderId 文件夹ID + * @return result {@link ActionRaw} + */ + @Override + public ActionRaw deleteGroupFileFolder(long groupId, String folderId) { + val action = ActionType.DELETE_GROUP_FOLDER; + val params = new JsonObject(); + params.addProperty("group_id", groupId); + params.addProperty("folder_id", folderId); + val result = actionFactory.action(channel, action, params); + return result != null ? GsonUtils.fromJson(result.toString(), ActionRaw.class) : null; + } + + /** + * 删除群文件 + * + * @param groupId 群号 + * @param fileId 文件ID + * @param busId 文件类型 + * @return result {@link ActionRaw} + */ + @Override + public ActionRaw deleteGroupFile(long groupId, String fileId, int busId) { + val action = ActionType.DELETE_GROUP_FILE; + val params = new JsonObject(); + params.addProperty("group_id", groupId); + params.addProperty("file_id", fileId); + params.addProperty("busid", busId); + val result = actionFactory.action(channel, action, params); + return result != null ? GsonUtils.fromJson(result.toString(), ActionRaw.class) : null; + } + + /** + * 好友点赞 + * + * @param userId 目标用户 + * @param times 点赞次数(每个好友每天最多 10 次,机器人为 Super VIP 则提高到 20次) + * @return result {@link ActionRaw} + */ + @Override + public ActionRaw sendLike(long userId, int times) { + val action = ActionType.SEND_LIKE; + val params = new JsonObject(); + params.addProperty("user_id", userId); + params.addProperty("times", times); + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), ActionRaw.class) : null; + } + + @Override + public GetStatusResp getStatus() { + val action = ActionType.GET_STATUS; + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + /** + * 获取状态 + * + * @return result {@link GetStatusResp} + */ + @Override + public ActionData getVersionInfo() { + val action = ActionType.GET_VERSION_INFO; + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + /** + * 获取收藏表情 + * + * @return 表情的下载 URL + */ + @Override + public ActionList fetchCustomFace() { + val action = ActionType.FETCH_CUSTOM_FACE; + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + /** + * 获取合并转发消息Id + * + * @param msg 自定义转发消息 (可使用 BotUtils.generateForwardMsg() 方法创建) + * @return result {@link ActionData} of {@link String} 合并转发的消息Id + */ + @Override + public ActionData sendForwardMsg(List> msg) { + val action = ActionType.SEND_FORWARD_MSG; + val params = new JsonObject(); + /** + * 将msg转成string存到params中 + */ + //params.addProperty("messages", msg); + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + /** + * 设置群消息表情回应 + * + * @param groupId 群号 + * @param msgId 消息 ID + * @param code 表情 ID + * @param isAdd 添加/取消 回应 + * @return result {@link ActionRaw} + */ + @Override + public ActionRaw setGroupReaction(long groupId, int msgId, String code, boolean isAdd) { + val action = ActionType.SET_GROUP_REACTION; + val params = new JsonObject(); + params.addProperty("group_id", groupId); + params.addProperty("message_id", msgId); + params.addProperty("code", code); + params.addProperty("is_add", isAdd); + val result = actionFactory.action(channel, action, null); + return result != null ? GsonUtils.fromJson(result.toString(), ActionRaw.class) : null; + } + + + /** + * 自定义请求 + * + * @param action 请求路径 + * @param params 请求参数 + * @return result {@link ActionData} + */ + @SuppressWarnings("rawtypes") + public ActionData customRequest(ActionPath action, Map params) { + val result = actionFactory.action(channel, action, GsonUtils.parse(gson.toJson(params))); + return result != null ? GsonUtils.fromJson(result.toString(), ActionData.class) : null; + } + + /** + * 自定义请求 + * + * @param action 请求路径 + * @param params 请求参数 + * @return result {@link ActionData} + */ + public ActionData customRequest(ActionPath action, Map params, Class clazz) { + val result = actionFactory.action(channel, action, GsonUtils.parse(gson.toJson(params))); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + /** + * 自定义请求 + * + * @param action 请求路径 + * @param params 请求参数 + * @return result {@link ActionData} + */ + @SuppressWarnings("rawtypes") + public ActionData customRawRequest(ActionPath action, Map params) { + val result = actionFactory.action(channel, action, GsonUtils.parse(gson.toJson(params))); + return result != null ? GsonUtils.fromJson(result.toString(), ActionData.class) : null; + } + + /** + * 自定义请求 + * + * @param action 请求路径 + * @param params 请求参数 + * @return result {@link ActionData} + */ + public ActionData customRawRequest(ActionPath action, Map params, Class clazz) { + val result = actionFactory.action(channel, action, GsonUtils.parse(gson.toJson(params))); + return result != null ? GsonUtils.fromJson(result.toString(), new TypeToken>() { + }.getType()) : null; + } + + } diff --git a/src/main/java/cn/evole/onebot/client/instances/action/ActionFactory.java b/src/main/java/cn/evole/onebot/client/instances/action/ActionFactory.java index 622baa3..44c0902 100644 --- a/src/main/java/cn/evole/onebot/client/instances/action/ActionFactory.java +++ b/src/main/java/cn/evole/onebot/client/instances/action/ActionFactory.java @@ -1,7 +1,7 @@ package cn.evole.onebot.client.instances.action; import cn.evole.onebot.client.OneBotClient; -import cn.evole.onebot.sdk.action.ActionPath; +import cn.evole.onebot.sdk.action.misc.ActionPath; import cn.evole.onebot.sdk.util.GsonUtils; import com.google.gson.JsonObject; import lombok.val; diff --git a/src/main/java/cn/evole/onebot/client/instances/action/ActionSendUnit.java b/src/main/java/cn/evole/onebot/client/instances/action/ActionSendUnit.java index d38be1e..de78a12 100644 --- a/src/main/java/cn/evole/onebot/client/instances/action/ActionSendUnit.java +++ b/src/main/java/cn/evole/onebot/client/instances/action/ActionSendUnit.java @@ -39,7 +39,7 @@ public ActionSendUnit(OneBotClient client, WebSocket channel, long requestTimeou */ public JsonObject send(JsonObject req) throws InterruptedException { synchronized (channel) { - client.getLogger().debug(String.format("[Action] %s", req.toString())); + client.getLogger().debug("[Action] {}", req.toString()); channel.send(req.toString()); } synchronized (this) { diff --git a/src/main/java/cn/evole/onebot/client/instances/event/EventFactory.java b/src/main/java/cn/evole/onebot/client/instances/event/EventFactory.java index f0d9c3d..60b7d52 100644 --- a/src/main/java/cn/evole/onebot/client/instances/event/EventFactory.java +++ b/src/main/java/cn/evole/onebot/client/instances/event/EventFactory.java @@ -41,7 +41,7 @@ public Event createEvent(JsonObject json) { && eventType != WholeMessageEvent.class && eventType != GuildMessageEvent.class ) { - //client.getLogger().warn("▌ 命令系统尚未支持"); + client.getLogger().warn("▌ 命令系统尚未支持"); return null; } } diff --git a/src/main/java/cn/evole/onebot/client/utils/ConnectionUtils.java b/src/main/java/cn/evole/onebot/client/utils/ConnectionUtils.java index c12afc5..e13714c 100644 --- a/src/main/java/cn/evole/onebot/client/utils/ConnectionUtils.java +++ b/src/main/java/cn/evole/onebot/client/utils/ConnectionUtils.java @@ -1,9 +1,7 @@ package cn.evole.onebot.client.utils; import org.java_websocket.WebSocket; -import org.java_websocket.client.WebSocketClient; - -import java.util.Optional; +import org.java_websocket.handshake.ServerHandshake; /** * @Project: onebot-client @@ -13,13 +11,18 @@ */ public class ConnectionUtils { -// public static long parseSelfId(WebSocketClient session) { -// String selfIdStr = Optional.ofNullable(session.hea().getFirst("x-self-id")) -// .orElse((String) session.getAttributes().get("x-self-id")); -// try { -// return Long.parseLong(selfIdStr); -// } catch (NumberFormatException e) { -// return 0L; -// } -// } + /** + * 获取连接的 QQ 号 + * + * @param session {@link WebSocket} + * @return QQ 号 + */ + public static long parseSelfId(ServerHandshake session) { + String selfIdStr = session.getFieldValue("x-self-id"); + try { + return Long.parseLong(selfIdStr); + } catch (NumberFormatException e) { + return 0L; + } + } } diff --git a/src/main/java/cn/evole/onebot/client/utils/ReflectionUtils.java b/src/main/java/cn/evole/onebot/client/utils/ReflectionUtils.java new file mode 100644 index 0000000..ed1477c --- /dev/null +++ b/src/main/java/cn/evole/onebot/client/utils/ReflectionUtils.java @@ -0,0 +1,60 @@ +package cn.evole.onebot.client.utils; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +/** + * @Project: onebot-client + * @Author: cnlimiter + * @CreateTime: 2025/2/11 19:25 + * @Description: + */ +public class ReflectionUtils { + public static List> getClasses(String packageName) { + ArrayList> classes = new ArrayList<>(); + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + String path = packageName.replace('.', '/'); + Enumeration resources = classLoader.getResources(path); + List dirs = new ArrayList<>(); + while (resources.hasMoreElements()) { + URL resource = resources.nextElement(); + dirs.add(new File(resource.getFile())); + } + for (File directory : dirs) { + classes.addAll(findClasses(directory, packageName)); + } + } catch (IOException ignored){ + + } + + return classes; + } + + private static List> findClasses(File directory, String packageName){ + List> classes = new ArrayList<>(); + if (!directory.exists()) { + return classes; + } + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + assert !file.getName().contains("."); + classes.addAll(findClasses(file, packageName + "." + file.getName())); + } else if (file.getName().endsWith(".class")) { + try { + classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); + } catch (ClassNotFoundException e) { + System.out.print(e.getMessage()); + } + } + } + } + return classes; + } +} diff --git a/src/test/java/ApiTest.java b/src/test/java/ApiTest.java index 9b93fa2..1e138eb 100644 --- a/src/test/java/ApiTest.java +++ b/src/test/java/ApiTest.java @@ -1,6 +1,6 @@ import cn.evole.onebot.client.OneBotClient; import cn.evole.onebot.client.core.BotConfig; -import cn.evole.onebot.sdk.action.ActionData; +import cn.evole.onebot.sdk.action.misc.ActionData; import cn.evole.onebot.sdk.entity.MsgId; import cn.evole.onebot.sdk.util.MsgUtils; @@ -16,7 +16,7 @@ public class ApiTest { public static void main(String[] args) throws InterruptedException { - BotConfig config = new BotConfig("ws://192.168.1.25:5800"); + BotConfig config = new BotConfig("ws://192.168.1.25:5800", "123456"); OneBotClient client = OneBotClient.create(config).open(); Thread.sleep(1000); diff --git a/src/test/java/HandlerTest.java b/src/test/java/HandlerTest.java index b7abf12..9854ae7 100644 --- a/src/test/java/HandlerTest.java +++ b/src/test/java/HandlerTest.java @@ -1,4 +1,5 @@ import cn.evole.onebot.client.OneBotClient; +import cn.evole.onebot.client.annotations.EventBus; import cn.evole.onebot.client.annotations.SubscribeEvent; import cn.evole.onebot.client.core.BotConfig; import cn.evole.onebot.client.interfaces.Listener; @@ -13,6 +14,7 @@ * @Description: */ +@EventBus public class HandlerTest implements Listener { static OneBotClient client; static Logger logger; @@ -20,8 +22,8 @@ public class HandlerTest implements Listener { public static void main(String[] args) throws InterruptedException { logger = LogManager.getLogger("OneBot Client1"); BotConfig config = new BotConfig("ws://192.168.1.25:5800", "123456"); - client = OneBotClient.create(config).open(); - client.getEventsBus().register(new HandlerTest()); + client = OneBotClient.create(config, new HandlerTest()).open(); + //client.getEventsBus().register(new HandlerTest()); } @SubscribeEvent(internal = true)