diff --git a/.gitignore b/.gitignore index 6347174..1dc2fe9 100644 --- a/.gitignore +++ b/.gitignore @@ -126,6 +126,13 @@ src/test/kotlin/RunTerminal.kt /data /plugins /bots +/gradle +/lib +/logs +/plugin-libraries +/plugin-shared-libraries +overflow.json # Local Test Launch Point working directory /debug-sandbox + diff --git a/build.gradle.kts b/build.gradle.kts index 87bd57e..89e07b2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,14 +18,24 @@ dependencies{ implementation ("junit:junit:4.13.2") implementation ("org.apache.logging.log4j:log4j-core:2.23.1") implementation ("org.apache.logging.log4j:log4j-api:2.23.1") + implementation("top.mrxiaom.mirai:overflow-core:0.9.9.515-f8d867b-SNAPSHOT") + } repositories { maven("https://maven.aliyun.com/repository/public") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") mavenCentral() } mirai { + noTestCore = true + setupConsoleTestRuntime { + // 移除 mirai-core 依赖 + classpath = classpath.filter { + !it.nameWithoutExtension.startsWith("mirai-core-jvm") + } + } jvmTarget = JavaVersion.VERSION_17 -} +} \ No newline at end of file diff --git a/overflow.json b/overflow.json new file mode 100644 index 0000000..10dcc3c --- /dev/null +++ b/overflow.json @@ -0,0 +1,11 @@ +{ + "no_log___DO_NOT_REPORT_IF_YOU_SWITCH_THIS_ON___开启此选项时不接受漏洞反馈": false, + "ws_host": "ws://localhost:3001", + "reversed_ws_port": -1, + "token": "", + "no_platform": false, + "use_cq_code": false, + "retry_times": 5, + "retry_wait_mills": 5000, + "retry_rest_mills": 60000 +} \ No newline at end of file diff --git a/src/main/java/plugin/App.java b/src/main/java/plugin/App.java index c855ead..ee61c5e 100644 --- a/src/main/java/plugin/App.java +++ b/src/main/java/plugin/App.java @@ -17,6 +17,9 @@ import java.util.HashMap; import java.util.List; +/** + * @author SLHAF + */ public final class App extends JavaPlugin { public static final App INSTANCE = new App(); @@ -47,16 +50,15 @@ public final class App extends JavaPlugin { } getLogger().info("ChatAI-InGroup-v2 loaded!"); - //群聊监听器 GlobalEventChannel.INSTANCE.filterIsInstance(GroupMessageEvent.class) .filter(event -> { String msg = event.getMessage().contentToString(); long groupId = event.getGroup().getId(); - return ((msg.startsWith(".") && msg.length() != 1) || msg.startsWith("@" + bot) || customCommands.containsKey(msg.split(" ")[0])) && !blacklist.contains(groupId); + return ((msg.startsWith(".") && msg.length() != 1) || msg.startsWith("@" + bot) || customCommands.containsKey(msg.split(" ")[0] + ChatConstant.BLANK)) && !blacklist.contains(groupId); }).registerListenerHost(new GroupMessageListener()); - //所有者监听 + //所有者监听--群聊 GlobalEventChannel.INSTANCE.filterIsInstance(GroupMessageEvent.class) .filter(event -> { String msg = event.getMessage().contentToString(); @@ -66,9 +68,21 @@ public final class App extends JavaPlugin { //私聊监听器 GlobalEventChannel.INSTANCE.filterIsInstance(FriendMessageEvent.class) - .filter(event -> true) + .filter(event -> { + String msg = event.getMessage().contentToString(); + String sender = String.valueOf(event.getFriend().getId()); + return !(msg.startsWith(ChatConstant.SET)&&sender.equals(owner)); + }) .registerListenerHost(new FriendMessageListener()); + //所有者监听--私聊 + GlobalEventChannel.INSTANCE.filterIsInstance(FriendMessageEvent.class) + .filter(event -> { + String msg = event.getMessage().contentToString(); + String sender = String.valueOf(event.getFriend().getId()); + return msg.startsWith(ChatConstant.SET) && sender.equals(owner); + }).registerListenerHost(new OwnerMessageListener()); + } @Override diff --git a/src/main/java/plugin/constant/ChatConstant.java b/src/main/java/plugin/constant/ChatConstant.java index c6e13e5..992601d 100644 --- a/src/main/java/plugin/constant/ChatConstant.java +++ b/src/main/java/plugin/constant/ChatConstant.java @@ -32,16 +32,6 @@ public class ChatConstant { public static final String SET = "$ "; - /** - * 切换模型 - */ - public static final String CHANGE_MODEL = "切换模型"; - - /** - * 所有者 - */ - public static final String OWNER = "owner"; - /** * 清理消息 */ @@ -51,4 +41,5 @@ public class ChatConstant { * 当前模型 */ public static final String CURRENT_MODEL = "当前模型"; + public static final String SPLIT = "|"; } diff --git a/src/main/java/plugin/listener/FriendMessageListener.java b/src/main/java/plugin/listener/FriendMessageListener.java index 5540750..2eca99c 100644 --- a/src/main/java/plugin/listener/FriendMessageListener.java +++ b/src/main/java/plugin/listener/FriendMessageListener.java @@ -5,7 +5,6 @@ import net.mamoe.mirai.event.SimpleListenerHost; import net.mamoe.mirai.event.events.FriendMessageEvent; import plugin.constant.ChatConstant; import plugin.constant.MethodsConstant; -import plugin.pojo.Config; import plugin.utils.AIUtil; import plugin.utils.ConfigUtil; @@ -40,10 +39,11 @@ public class FriendMessageListener extends SimpleListenerHost { MethodsConstant method = MethodsConstant.NORMAL; //处理消息头 - if (ConfigUtil.getConfig().getCustomCommands().containsKey(content.split(ChatConstant.BLANK)[0])) { - content = content.substring(3); + if (ConfigUtil.getConfig().getCustomCommands().containsKey(content.split(ChatConstant.BLANK)[0]+ChatConstant.BLANK)) { + String[] split = content.split(ChatConstant.BLANK); + chatCommand = split[0] + ChatConstant.BLANK; method = MethodsConstant.CUSTOM; - chatCommand = content.split(ChatConstant.BLANK)[0]; + content = split[1]; } else if (content.startsWith(ChatConstant.ONCE_MESSAGE_START)) { content = content.substring(1); method = MethodsConstant.ONCE; diff --git a/src/main/java/plugin/listener/GroupMessageListener.java b/src/main/java/plugin/listener/GroupMessageListener.java index 27be391..0231182 100644 --- a/src/main/java/plugin/listener/GroupMessageListener.java +++ b/src/main/java/plugin/listener/GroupMessageListener.java @@ -25,8 +25,7 @@ public class GroupMessageListener extends SimpleListenerHost { @Override public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) { - super.handleException(context, exception); - logger.error(exception.getMessage()); + logger.warning(exception); } /** @@ -67,11 +66,12 @@ public class GroupMessageListener extends SimpleListenerHost { //默认对话 content = content.substring((ChatConstant.DEFAULT_MESSAGE_START + event.getBot().getId()).length()); method = MethodsConstant.NORMAL; - } else if (config.getCustomCommands().containsKey(content.split(ChatConstant.BLANK)[0])) { + } else if (config.getCustomCommands().containsKey(content.split(ChatConstant.BLANK)[0]+ChatConstant.BLANK)) { //预设对话 - content = content.split(ChatConstant.BLANK)[1]; + String[] split = content.split(ChatConstant.BLANK); + chatCommand = split[0] + ChatConstant.BLANK; method = MethodsConstant.CUSTOM; - chatCommand = content.split(ChatConstant.BLANK)[0]; + content = split[1]; } //消息内容处理 if (content.isBlank()) { diff --git a/src/main/java/plugin/listener/OwnerMessageListener.java b/src/main/java/plugin/listener/OwnerMessageListener.java index d4f2d19..c974754 100644 --- a/src/main/java/plugin/listener/OwnerMessageListener.java +++ b/src/main/java/plugin/listener/OwnerMessageListener.java @@ -7,16 +7,13 @@ import net.mamoe.mirai.event.events.FriendMessageEvent; import net.mamoe.mirai.event.events.GroupMessageEvent; import net.mamoe.mirai.message.data.At; import org.jetbrains.annotations.NotNull; -import plugin.constant.AIConstant; import plugin.constant.ChatConstant; import plugin.constant.ConfigConstant; import plugin.utils.AIUtil; import plugin.utils.ConfigUtil; import java.io.IOException; -import java.util.HashMap; -import static plugin.utils.ConfigUtil.getConfig; import static plugin.utils.ConfigUtil.logger; /** @@ -34,7 +31,7 @@ public class OwnerMessageListener extends SimpleListenerHost { public void onGroupMessageEvent(GroupMessageEvent event) { String msg = event.getMessage().contentToString(); String primaryContent = msg.split(ChatConstant.BLANK)[1]; - if (!primaryContent.contains(ChatConstant.BLANK)) { + if (!primaryContent.contains(ChatConstant.SPLIT)) { String response; response = switch (primaryContent) { case "clearAll" -> AIUtil.clearAll(); @@ -46,8 +43,8 @@ public class OwnerMessageListener extends SimpleListenerHost { return; } - String command = primaryContent.split(ChatConstant.BLANK)[0]; - String arguments = primaryContent.split(ChatConstant.BLANK)[1]; + String command = primaryContent.split(ConfigConstant.CUSTOM_SPLIT)[0]; + String arguments = primaryContent.substring(primaryContent.indexOf(ChatConstant.SPLIT)+1); long id = event.getSender().getId(); String response; try { @@ -61,11 +58,12 @@ public class OwnerMessageListener extends SimpleListenerHost { @EventHandler public void onFriendMessageEvent(FriendMessageEvent event) throws IOException { + String primaryContent = event.getMessage().contentToString().split(ChatConstant.BLANK)[1]; String command; String arguments; try { - command = event.getMessage().contentToString().split(ChatConstant.BLANK)[0]; - arguments = event.getMessage().contentToString().split(ChatConstant.BLANK)[1]; + command = primaryContent.split(ConfigConstant.CUSTOM_SPLIT)[0]; + arguments = primaryContent.substring(primaryContent.indexOf(ConfigConstant.CUSTOM_SPLIT)+1); } catch (ArrayIndexOutOfBoundsException e) { event.getFriend().sendMessage("操作失败,缺少参数"); return; @@ -90,7 +88,7 @@ public class OwnerMessageListener extends SimpleListenerHost { String customContent = arguments.split(ConfigConstant.CUSTOM_SPLIT)[2]; yield ConfigUtil.addCustom(instruction, customModel, customContent); } else { - yield "格式不正确! 参数格式如下: \r\n指令|模型名称|预设\r\n例: \r\n/example|glm-4-flash|你是...\r\n注:如果不需要预设,可以将预设写为null"; + yield "格式不正确! 参数格式如下: \r\n" + ChatConstant.SET + "命令|预设指令|模型名称|预设\r\n例: \r\n"+ChatConstant.SPLIT+"/example|glm-4-flash|你是...\r\n注:如果不需要预设,可以将预设写为null"; } } case "切换模型" -> { @@ -99,7 +97,7 @@ public class OwnerMessageListener extends SimpleListenerHost { String modelName = arguments.split(ConfigConstant.CUSTOM_SPLIT)[1]; yield ConfigUtil.customModelChange(instruction, modelName); } else { - yield "格式不正确! 参数格式如下: \r\n指令|指令对应模型"; + yield "格式不正确! 参数格式如下: \r\n" + ChatConstant.SET + "命令|预设指令|指令对应模型"; } } case "更改预设" -> { @@ -108,7 +106,7 @@ public class OwnerMessageListener extends SimpleListenerHost { String customContent = arguments.split(ConfigConstant.CUSTOM_SPLIT)[1]; yield ConfigUtil.customContentChange(instruction, customContent); } else { - yield "格式不正确! 参数格式如下: \r\n指令|指令对应预设"; + yield "格式不正确! 参数格式如下: \r\n" + ChatConstant.SET + "命令|预设指令|指令对应预设"; } } case "删除预设" -> ConfigUtil.removeCustom(arguments); diff --git a/src/main/java/plugin/pojo/UserCustomLatestTime.java b/src/main/java/plugin/pojo/UserCustomLatestTime.java index 90c3dd5..558e922 100644 --- a/src/main/java/plugin/pojo/UserCustomLatestTime.java +++ b/src/main/java/plugin/pojo/UserCustomLatestTime.java @@ -47,7 +47,16 @@ public class UserCustomLatestTime { this.latestTime = latestTime; } + @Override public String toString() { return "UserCustomLatestTime{chatCommand = " + chatCommand + ", latestTime = " + latestTime + "}"; } + + @Override + public boolean equals(Object obj) { + if (obj instanceof UserCustomLatestTime other) { + return other.getChatCommand().equals(this.chatCommand); + } + return super.equals(obj); + } } diff --git a/src/main/java/plugin/pojo/UserCustomMessage.java b/src/main/java/plugin/pojo/UserCustomMessage.java index 427fd58..ecbfc64 100644 --- a/src/main/java/plugin/pojo/UserCustomMessage.java +++ b/src/main/java/plugin/pojo/UserCustomMessage.java @@ -53,4 +53,5 @@ public class UserCustomMessage { public String toString() { return "UserCustomMessage{command = " + command + ", messages = " + messages + "}"; } + } diff --git a/src/main/java/plugin/utils/AIUtil.java b/src/main/java/plugin/utils/AIUtil.java index a3737ae..b62dc05 100644 --- a/src/main/java/plugin/utils/AIUtil.java +++ b/src/main/java/plugin/utils/AIUtil.java @@ -1,6 +1,5 @@ package plugin.utils; -import cn.hutool.core.map.MapUtil; import com.zhipu.oapi.ClientV4; import com.zhipu.oapi.Constants; import com.zhipu.oapi.service.v4.model.ChatCompletionRequest; @@ -17,7 +16,6 @@ import plugin.pojo.UserCustomMessage; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.function.BiConsumer; import static plugin.utils.ConfigUtil.logger; @@ -121,6 +119,7 @@ public class AIUtil { } //查看本次id是否有记录存在 if (!userCustomMessages.containsKey(id)) { + //不存在消息记录 //创建消息list List chatMessages = new ArrayList<>(); if (!customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[1].equals(ConfigConstant.NULL)) { @@ -130,6 +129,29 @@ public class AIUtil { List userCustomMessageList = new ArrayList<>(); userCustomMessageList.add(new UserCustomMessage(chatCommand, chatMessages)); userCustomMessages.put(id, userCustomMessageList); + }else { + //存在消息记录,但需要判断是否存在该指令对应的消息记录 + List userCustomMessageList = userCustomMessages.get(id); + boolean found = false; + for (UserCustomMessage userCustomMessage : userCustomMessageList) { + if (userCustomMessage.getCommand().equals(chatCommand)) { + found = true; + break; + } + } + if (!found) { + //如果不存在该指令对应的消息记录 + UserCustomMessage userCustomMessage = new UserCustomMessage(); + userCustomMessage.setCommand(chatCommand); + List chatMessages = new ArrayList<>(); + //判断是否存在预设 + if (!customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[1].equals(ConfigConstant.NULL)){ + ChatMessage customMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(), customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[1]); + chatMessages.add(customMessage); + } + userCustomMessage.setMessages(chatMessages); + userCustomMessageList.add(userCustomMessage); + } } String modelName = customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[0]; synchronized (userCustomMessages.get(id)) { @@ -263,7 +285,7 @@ public class AIUtil { } } //更新最新操作时间 - boolean found = false; + boolean foundTime = false; List userCustomLatestTimeList; if (userLatestTimeOfCustom.containsKey(id)) { //如果存在该id对应的任一聊天记录 @@ -271,7 +293,7 @@ public class AIUtil { for (UserCustomLatestTime userCustomLatestTime : userCustomLatestTimeList) { if (userCustomLatestTime.getChatCommand().equals(chatCommand)) { userCustomLatestTime.setLatestTime(System.currentTimeMillis()); - found = true; + foundTime = true; break; } } @@ -280,8 +302,9 @@ public class AIUtil { userCustomLatestTimeList = new ArrayList<>(); userCustomLatestTimeList.add(new UserCustomLatestTime(chatCommand,System.currentTimeMillis())); userLatestTimeOfCustom.put(id,userCustomLatestTimeList); + foundTime = true; } - if (!found) { + if (!foundTime) { userCustomLatestTimeList.add(new UserCustomLatestTime(chatCommand, System.currentTimeMillis())); } } diff --git a/src/main/java/plugin/utils/ConfigUtil.java b/src/main/java/plugin/utils/ConfigUtil.java index d214525..4e1b353 100644 --- a/src/main/java/plugin/utils/ConfigUtil.java +++ b/src/main/java/plugin/utils/ConfigUtil.java @@ -1,9 +1,9 @@ package plugin.utils; import cn.hutool.core.bean.BeanUtil; -import lombok.extern.slf4j.Slf4j; import net.mamoe.mirai.utils.LoggerAdapters; import net.mamoe.mirai.utils.MiraiLogger; +import org.slf4j.Logger; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import plugin.constant.ChatConstant; @@ -19,12 +19,12 @@ import java.util.LinkedHashMap; /** * @author SLHAF */ -@Slf4j public class ConfigUtil { private static final String CONFIG_PATH = "./config/ChatAIinGroup/config.yaml"; private static final Yaml yaml; private static Config config; - public static MiraiLogger logger = LoggerAdapters.asMiraiLogger(log); + private static final Logger log = org. slf4j. LoggerFactory. getLogger("ChatAIinGroup"); + public static MiraiLogger logger = LoggerAdapters.asMiraiLogger(log);; private ConfigUtil() { } @@ -88,7 +88,7 @@ public class ConfigUtil { public static String customModelChange(String instruction, String customModel) throws IOException { HashMap customCommands = config.getCustomCommands(); if (!customCommands.containsKey(instruction)) { - return "该指令不存在!"; + return "该预设不存在!"; } String customContent = customCommands.get(instruction).split(ConfigConstant.CUSTOM_SPLIT)[1]; customCommands.put(instruction, customModel + "|" + customContent); diff --git a/src/test/java/MyTest.java b/src/test/java/MyTest.java index e490894..413ae2e 100644 --- a/src/test/java/MyTest.java +++ b/src/test/java/MyTest.java @@ -1,5 +1,8 @@ import com.alibaba.fastjson.JSONObject; import lombok.Data; +import net.mamoe.mirai.console.plugin.PluginManager; +import net.mamoe.mirai.console.terminal.MiraiConsoleImplementationTerminal; +import net.mamoe.mirai.console.terminal.MiraiConsoleTerminalLoader; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; @@ -10,6 +13,7 @@ import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; import org.junit.Test; +import plugin.App; import plugin.constant.ChatConstant; import plugin.constant.ConfigConstant; import plugin.listener.OwnerMessageListener; @@ -19,29 +23,10 @@ import plugin.utils.ConfigUtil; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import static kotlin.io.ConsoleKt.readln; public class MyTest { - public static void www(String[] args) { - String miraiCode = "看下这个题目[mirai:image:https://multimedia.nt.qq.com.cn/download?appid=1407&fileid=CgoyOTk4ODEzODgyEhQW4G7W3v2lT-NKItOqORRIbuK6rxiZzgcg_woo4u2zytCqiANQgL2jAQ&spec=0&rkey=CAMSKMa3OFokB_Tlf6uVSrtr8zFEBtyDtGIdmuztQCnfO9gIDN19LUsLquI]"; - String url = null; - if (miraiCode.matches(".*[mirai:image:(https?://[\\w./?&=]+)].*")) { - String regex = "\\[mirai:image:(.*?)]"; - Pattern pattern = Pattern.compile(regex); - - // 创建Matcher对象 - Matcher matcher = pattern.matcher(miraiCode); - - // 查找并提取链接 - if (matcher.find()) { - url = matcher.group(1); // 提取第一个括号内的内容 - } - } - System.out.println(url); - } @Test public void sseTest() throws IOException { @@ -183,4 +168,12 @@ public class MyTest { String str = "/c glm"; System.out.println(str.matches(ConfigConstant.MODEL_CHANGE)); } + + @Test + public void terminalTest() throws InterruptedException { + MiraiConsoleTerminalLoader.INSTANCE.startAsDaemon(new MiraiConsoleImplementationTerminal()); + PluginManager.INSTANCE.loadPlugin(App.INSTANCE); + PluginManager.INSTANCE.enablePlugin(App.INSTANCE); + while (true); + } }