├── docs ├── .nojekyll ├── CNAME ├── _coverpage.md ├── index.html └── README.md ├── gradle.properties ├── src └── main │ ├── resources │ └── META-INF │ │ └── services │ │ └── net.mamoe.mirai.console.plugin.jvm.JvmPlugin │ └── java │ └── org │ └── qbot │ ├── PluginVersion.java │ ├── api │ └── API.java │ ├── thread │ ├── StartThread.java │ ├── AutoGetFortuneThread.java │ └── AutoThread.java │ ├── group │ ├── GroupManagementUtil.java │ ├── GroupManagementSetting.java │ └── GroupManagement.java │ ├── toolkit │ ├── QrCodeUtil.java │ ├── SetSetting.java │ ├── CreateFile.java │ ├── Setting.java │ ├── PluginUtil.java │ └── Utils.java │ ├── Plugin.java │ ├── music │ ├── MusicMessageDeal.java │ └── NeteaseCloudMusicTask.java │ └── msgdeal │ ├── AdminMessageDeal.java │ └── MessageDeal.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle.kts ├── CONFIG.md ├── .run └── RunTerminal.run.xml ├── README.md ├── .gitignore ├── gradlew.bat ├── UPDATE.md └── gradlew /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | www.miraiqbot.top -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin: -------------------------------------------------------------------------------- 1 | org.qbot.Plugin -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atigger/Qbot/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /docs/_coverpage.md: -------------------------------------------------------------------------------- 1 | # QQ机器人 2 | 3 | > 本项目基于 mirai 开发 4 | 5 | ![logo](https://count.getloli.com/get/@Qbot?theme=rule34) 6 | 7 | [GitHub](https://github.com/atigger/Qbot) 8 | [开始使用](#基本功能) 9 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven("https://maven.aliyun.com/repository/gradle-plugin") 4 | gradlePluginPortal() 5 | } 6 | } 7 | rootProject.name = "plugin" -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /src/main/java/org/qbot/PluginVersion.java: -------------------------------------------------------------------------------- 1 | package org.qbot; 2 | 3 | /** 4 | * PluginVersion class 5 | * 6 | * @author 649953543@qq.com 7 | * @date 2022/8/3 8 | */ 9 | public class PluginVersion { 10 | public final static String VERSION_NUM = "3.5.5"; 11 | } 12 | -------------------------------------------------------------------------------- /CONFIG.md: -------------------------------------------------------------------------------- 1 | 配置文件模板 2 | ```yaml 3 | #配置文件版本 4 | Version: 3.3 5 | #机器人QQ 6 | QQ: 0 7 | #百度语音API 8 | BaiDuAPI: 9 | APP_ID: "" 10 | API_KEY: "" 11 | SECRET_KEY: "" 12 | #发送图片数量 13 | ImageNum: 0 14 | #图片自动撤回时间(0为不撤回,单位秒) 15 | ImageRecall: 0 16 | #自动同意好友请求 17 | AgreeFriend: false 18 | #自动同意邀请入群请求 19 | AgreeGroup: false 20 | #智能聊天开关 21 | AI: 22 | Open: false 23 | Api_Key: "" 24 | Api_Secret: "" 25 | #自动化操作 26 | Auto: 27 | #自动发送运势信息 28 | AutoFortune: false 29 | #自动每日新闻信息 30 | AutoNews: false 31 | #自动发送摸鱼小提示 32 | AutoTips: false 33 | #需要自动发送的群列表 用,隔开 34 | Group: [] 35 | GroupManagement: 36 | #开启群管系统 37 | Open: false 38 | #群管系统管理员QQ 39 | AdminQQ: 0 40 | #网易云API接口网址 41 | MusicAPIURL: "" 42 | #企业微信Key 43 | QYWXKEY: "" 44 | ``` 45 | 46 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QQ机器人 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
加载中
14 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /.run/RunTerminal.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 17 | 19 | true 20 | true 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QQBOT 2 | 3 | [由于QQ官方针对协议库的围追堵截](https://github.com/Mrs4s/go-cqhttp/issues/2471),基于mirai的QQ机器人大部分已经无法正常使用,本项目不再维护 4 | 5 | 本项目已由mirai转向基于[OneBot 11](https://github.com/botuniverse/onebot-11) 6 | 的[NoneBot](https://github.com/nonebot/nonebot) 7 | 8 | # 新项目地址 9 | 10 | ## [pyQBot](https://github.com/atigger/pyQBot) 11 | 12 | --- 13 | 14 | 本项目基于 [mirai](https://github.com/mamoe/mirai) [![Version](https://img.shields.io/badge/version-2.16.0-green)](https://github.com/mamoe/mirai/releases/tag/v2.16.0) 15 | 开发 16 | 17 | [如何使用?](https://github.com/mamoe/mirai/blob/dev/mirai-console/docs/ConfiguringProjects.md) 18 | 19 | [如何配置?](CONFIG.md) 20 | 21 | [在群中使用?](https://www.miraiqbot.top) 22 | 23 | --- 24 | 25 | 已有或正在开发的功能: 26 | 27 | - [x] 今日运势查询 28 | 29 | - [x] 今日新闻查询 30 | 31 | - [x] 今日星座运势 32 | 33 | - [x] 随机求签 34 | 35 | - [x] 音乐分享(暂只支持网易云) 36 | 37 | - [x] 发送语音(需要前往[百度开发者平台](https://ai.baidu.com/tech/speech)获取key) 38 | 39 | - [x] 王者战力查询 40 | 41 | - [x] 随机发送~~美女~~图片 42 | 43 | - [x] 随机发送~~美女~~视频 44 | 45 | - [x] 支持茉莉云AI(需要前往[茉莉云官网](https://mlyai.com/)获取key)(测试中) 46 | 47 | - [x] COC鱼情查询 48 | 49 | - [x] 网易云每日签到(开发中)基于[NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 50 | 51 | - [x] 群管理插件(关键字撤回、自动审核入群申请)[帮助文档](https://www.miraiqbot.top/#/?id=群管理功能)(测试中) 52 | 53 | Tips:有想要的新功能可以提交issue 54 | 55 | --- 56 | 57 | 更新日志: 58 | 59 | 2024年7月17日v3.5.5更新 60 | 61 | 1.修复菜单命令无法发出的bug 62 | 63 | --- 64 | [更新历史](UPDATE.md) 65 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/api/API.java: -------------------------------------------------------------------------------- 1 | package org.qbot.api; 2 | 3 | /** 4 | * API class 5 | * 6 | * @author 649953543@qq.com 7 | * @date 2023/7/11 8 | */ 9 | public class API { 10 | public static final String BASE_URL = "https://api.0705.fun"; 11 | 12 | /** 13 | * 热点接口 14 | */ 15 | public static final String HOT_LIST_URL = BASE_URL + "/hotlist/index.php"; 16 | 17 | /** 18 | * 星座运势 19 | */ 20 | public static final String HOROSCOPE_URL = BASE_URL + "/horoscope/index.php"; 21 | 22 | /** 23 | * 一言 24 | */ 25 | public static final String ONE_WORD_URL = BASE_URL + "/one/index.php"; 26 | 27 | /** 28 | * 视频 29 | */ 30 | public static final String VIDEO_URL = BASE_URL + "/video/index.php"; 31 | 32 | /** 33 | * 英雄战力 34 | */ 35 | public static final String HERO_POWER_URL = BASE_URL + "/hero/index.php"; 36 | 37 | /** 38 | * 摸鱼办 39 | */ 40 | public static final String FISH_URL = BASE_URL + "/moyu/index.php"; 41 | 42 | /** 43 | * 新闻 44 | */ 45 | public static final String NEWS_URL = BASE_URL + "/news/index.php"; 46 | 47 | /** 48 | * 诸葛神签 49 | */ 50 | public static final String ZHU_GE_URL = BASE_URL + "/file/诸葛神签.txt"; 51 | 52 | /** 53 | * 图片网站二维码 54 | */ 55 | public static final String IMAGE_URL = BASE_URL + "/file/image_qr_code.png"; 56 | 57 | /** 58 | * 图片网站提示 59 | */ 60 | public static final String IMAGE_TIPS_URL = BASE_URL + "/file/image_tips.png"; 61 | 62 | /** 63 | * petpet 64 | */ 65 | public static final String PETPET_URL = BASE_URL + "/petpet/index.php"; 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/thread/StartThread.java: -------------------------------------------------------------------------------- 1 | package org.qbot.thread; 2 | 3 | import org.qbot.toolkit.Setting; 4 | 5 | /** 6 | * GetThreadState class 7 | * 8 | * @author 649953543@qq.com 9 | * @date 2021/11/01 10 | */ 11 | public class StartThread extends Thread { 12 | /** 13 | * 每隔一分钟检测一次线程运行情况 14 | */ 15 | @Override 16 | @SuppressWarnings("InfiniteLoopStatement") 17 | public void run() { 18 | boolean autoFortune = Setting.getAutoFortune(); 19 | boolean autoTips = Setting.getAutoTips(); 20 | boolean autoNews = Setting.getAutoNews(); 21 | while (true) { 22 | try { 23 | if (Setting.getBot().isOnline()) { 24 | break; 25 | } 26 | Thread.sleep(1000); 27 | } catch (Exception ignored) { 28 | } 29 | } 30 | AutoGetFortuneThread autoGetFortuneThread = new AutoGetFortuneThread(); 31 | AutoThread autoThread = new AutoThread(); 32 | if (autoFortune) { 33 | autoGetFortuneThread.start(); 34 | } 35 | if (autoTips || autoNews) { 36 | autoThread.start(); 37 | } 38 | while (true) { 39 | try { 40 | Thread.sleep(60000); 41 | if (autoFortune) { 42 | if (!autoGetFortuneThread.isAlive()) { 43 | autoGetFortuneThread = new AutoGetFortuneThread(); 44 | autoGetFortuneThread.start(); 45 | } 46 | } 47 | if (autoTips || autoNews) { 48 | if (!autoThread.isAlive()) { 49 | autoThread = new AutoThread(); 50 | autoThread.start(); 51 | } 52 | } 53 | 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | } 57 | 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/group/GroupManagementUtil.java: -------------------------------------------------------------------------------- 1 | package org.qbot.group; 2 | 3 | 4 | import net.mamoe.mirai.contact.Group; 5 | import net.mamoe.mirai.message.data.MessageChain; 6 | import net.mamoe.mirai.message.data.MessageChainBuilder; 7 | import net.mamoe.mirai.message.data.MessageSource; 8 | import net.mamoe.mirai.message.data.PlainText; 9 | import java.util.Objects; 10 | 11 | /** 12 | * GroupManagementUtil class 13 | * 14 | * @author 649953543@qq.com 15 | * @date 2022/4/7 16 | */ 17 | public class GroupManagementUtil { 18 | final GroupManagementSetting groupManagementSetting = new GroupManagementSetting(); 19 | 20 | 21 | public boolean msgDel(Group group, String msg) { 22 | 23 | 24 | String unMute = "解除禁言"; 25 | if (msg.contains(unMute)) { 26 | if (groupManagementSetting.authority(group)) { 27 | return true; 28 | } 29 | msg = msg.replace(unMute, ""); 30 | msg = msg.replace(" ", ""); 31 | msg = msg.replace("@", ""); 32 | long muteQq = Long.parseLong(msg); 33 | Objects.requireNonNull(group.get(muteQq)).unmute(); 34 | return true; 35 | } 36 | 37 | String mute = "禁言"; 38 | if (msg.contains(mute)) { 39 | if (groupManagementSetting.authority(group)) { 40 | return true; 41 | } 42 | msg = msg.replace(mute, ""); 43 | msg = msg.replace("@", ""); 44 | long muteQq = Long.parseLong(msg.substring(0, msg.indexOf(" "))); 45 | int time = Integer.parseInt(msg.substring(msg.indexOf(" ") + 1)); 46 | time = time * 60; 47 | Objects.requireNonNull(group.get(muteQq)).mute(time); 48 | return true; 49 | } 50 | return false; 51 | } 52 | 53 | public void muteGroup(Group group, long qq, int time, MessageChain groupMessageChain) { 54 | try { 55 | time = time * 60; 56 | Objects.requireNonNull(group.get(qq)).mute(time); 57 | MessageSource.recall(groupMessageChain); 58 | } catch (Exception e) { 59 | MessageChain chain = new MessageChainBuilder() 60 | .append(new PlainText("禁言失败,请检查是否有管理员权限")) 61 | .build(); 62 | group.sendMessage(chain); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | # mpeltonen/sbt-idea plugin 11 | .idea_modules/ 12 | 13 | # JIRA plugin 14 | atlassian-ide-plugin.xml 15 | 16 | # Compiled class file 17 | *.class 18 | 19 | # Log file 20 | *.log 21 | 22 | # BlueJ files 23 | *.ctxt 24 | 25 | # Package Files # 26 | *.jar 27 | *.war 28 | *.nar 29 | *.ear 30 | *.zip 31 | *.tar.gz 32 | *.rar 33 | 34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 35 | hs_err_pid* 36 | 37 | *~ 38 | 39 | # temporary files which can be created if a process still has a handle open of a deleted file 40 | .fuse_hidden* 41 | 42 | # KDE directory preferences 43 | .directory 44 | 45 | # Linux trash folder which might appear on any partition or disk 46 | .Trash-* 47 | 48 | # .nfs files are created when an open file is removed but is still being accessed 49 | .nfs* 50 | 51 | # General 52 | .DS_Store 53 | .AppleDouble 54 | .LSOverride 55 | 56 | # Icon must end with two \r 57 | Icon 58 | 59 | # Thumbnails 60 | ._* 61 | 62 | # Files that might appear in the root of a volume 63 | .DocumentRevisions-V100 64 | .fseventsd 65 | .Spotlight-V100 66 | .TemporaryItems 67 | .Trashes 68 | .VolumeIcon.icns 69 | .com.apple.timemachine.donotpresent 70 | 71 | # Directories potentially created on remote AFP share 72 | .AppleDB 73 | .AppleDesktop 74 | Network Trash Folder 75 | Temporary Items 76 | .apdisk 77 | 78 | # Windows thumbnail cache files 79 | Thumbs.db 80 | Thumbs.db:encryptable 81 | ehthumbs.db 82 | ehthumbs_vista.db 83 | 84 | # Dump file 85 | *.stackdump 86 | 87 | # Folder config file 88 | [Dd]esktop.ini 89 | 90 | # Recycle Bin used on file shares 91 | $RECYCLE.BIN/ 92 | 93 | # Windows Installer files 94 | *.cab 95 | *.msi 96 | *.msix 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | 103 | .gradle 104 | build/ 105 | 106 | # Ignore Gradle GUI config 107 | gradle-app.setting 108 | 109 | # Cache of project 110 | .gradletasknamecache 111 | 112 | **/build/ 113 | 114 | # Common working directory 115 | run/ 116 | 117 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 118 | !gradle-wrapper.jar 119 | 120 | 121 | # Local Test Launch point 122 | src/test/kotlin/RunTerminal.kt 123 | 124 | # Mirai console files with direct bootstrap 125 | /config 126 | /data 127 | /plugins 128 | /bots 129 | 130 | # Local Test Launch Point working directory 131 | /debug-sandbox 132 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/toolkit/QrCodeUtil.java: -------------------------------------------------------------------------------- 1 | package org.qbot.toolkit; 2 | 3 | import com.google.zxing.BarcodeFormat; 4 | import com.google.zxing.EncodeHintType; 5 | import com.google.zxing.MultiFormatWriter; 6 | import com.google.zxing.client.j2se.MatrixToImageWriter; 7 | import com.google.zxing.common.BitMatrix; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.File; 12 | import java.nio.file.Path; 13 | import java.nio.file.Paths; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | /** 18 | * QRCodeUtil class 19 | * 20 | * @author 649953543@qq.com 21 | * @date 2021/09/22 22 | */ 23 | 24 | public class QrCodeUtil { 25 | 26 | private static final Logger log = LoggerFactory.getLogger(QrCodeUtil.class); 27 | 28 | /** 29 | * 生成二维码 30 | * 31 | * @param text 内容,可以是链接或者文本 32 | * @param path 生成的二维码位置 33 | */ 34 | public static boolean encodeQrCode(String text, String path) { 35 | return encodeQrCode(text, path, null, null, null); 36 | } 37 | 38 | /** 39 | * 生成二维码 40 | * 41 | * @param text 内容,可以是链接或者文本 42 | * @param path 生成的二维码位置 43 | * @param width 宽度,默认300 44 | * @param height 高度,默认300 45 | * @param format 生成的二维码格式,默认png 46 | */ 47 | public static boolean encodeQrCode(String text, String path, Integer width, Integer height, String format) { 48 | try { 49 | 50 | // 得到文件对象 51 | File file = new File(path); 52 | // 判断目标文件所在的目录是否存在 53 | if (!file.getParentFile().exists()) { 54 | // 如果目标文件所在的目录不存在,则创建父目录 55 | log.info("目标文件所在目录不存在,准备创建它!"); 56 | if (!file.getParentFile().mkdirs()) { 57 | log.info("创建目标文件所在目录失败!"); 58 | return false; 59 | } 60 | } 61 | 62 | // 宽 63 | if (width == null) { 64 | width = 450; 65 | } 66 | // 高 67 | if (height == null) { 68 | height = 450; 69 | } 70 | // 图片格式 71 | if (format == null) { 72 | format = "png"; 73 | } 74 | 75 | // 设置字符集编码 76 | Map hints = new HashMap<>(); 77 | hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); 78 | // 生成二维码矩阵 79 | BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints); 80 | // 二维码路径 81 | Path outputPath = Paths.get(path); 82 | // 写入文件 83 | MatrixToImageWriter.writeToPath(bitMatrix, format, outputPath); 84 | return true; 85 | } catch (Exception e) { 86 | log.error(e.getMessage(), e); 87 | return false; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/toolkit/SetSetting.java: -------------------------------------------------------------------------------- 1 | package org.qbot.toolkit; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | 5 | import java.io.*; 6 | import java.nio.charset.StandardCharsets; 7 | 8 | /** 9 | * SetSetting class 10 | * 11 | * @author 649953543@qq.com 12 | * @date 2021/09/22 13 | */ 14 | 15 | public class SetSetting { 16 | public static void setFile(String version, long qq, String appid, String apiKey, String secretKey, int imageNum, 17 | int imageRecall, boolean agreeFriend, 18 | boolean agreeGroup, boolean AI, String aiApiKey, String aiApiSecret, boolean autoFortune, boolean autoNews, boolean autoTips, JSONArray groupList, 19 | boolean groupManagement, long adminQQ, String musicAPIurl, String QYWXKEY) { 20 | String config = "#配置文件版本\n" + 21 | "Version: " + version + "\n" + 22 | "#机器人QQ\n" + 23 | "QQ: " + qq + "\n" + 24 | "#百度语音API\n" + 25 | "BaiDuAPI:\n" + 26 | " APP_ID: \"" + appid + "\"\n" + 27 | " API_KEY: \"" + apiKey + "\"\n" + 28 | " SECRET_KEY: \"" + secretKey + "\"\n" + 29 | "#发送图片数量\n" + 30 | "ImageNum: " + imageNum + "\n" + 31 | "#图片自动撤回时间(0为不撤回,单位秒)\n" + 32 | "ImageRecall: " + imageRecall + "\n" + 33 | "#自动同意好友请求\n" + 34 | "AgreeFriend: " + agreeFriend + "\n" + 35 | "#自动同意邀请入群请求\n" + 36 | "AgreeGroup: " + agreeGroup + "\n" + 37 | "#智能聊天开关\n" + 38 | "AI:\n" + 39 | " Open: " + AI + "\n" + 40 | " Api_Key: \"" + aiApiKey + "\"\n" + 41 | " Api_Secret: \"" + aiApiSecret + "\"\n" + 42 | "#自动化操作\n" + 43 | "Auto:\n" + 44 | " #自动发送运势信息\n" + 45 | " AutoFortune: " + autoFortune + "\n" + 46 | " #自动每日新闻信息\n" + 47 | " AutoNews: " + autoNews + "\n" + 48 | " #自动发送摸鱼小提示\n" + 49 | " AutoTips: " + autoTips + "\n" + 50 | " #需要自动发送的群列表 用,隔开\n" + 51 | " Group: " + groupList + "\n" + 52 | "GroupManagement:\n" + 53 | " #开启群管系统\n" + 54 | " Open: " + groupManagement + "\n" + 55 | " #群管系统管理员QQ\n" + 56 | " AdminQQ: " + adminQQ + "\n" + 57 | "#网易云API接口网址\n" + 58 | "MusicAPIURL: \"" + musicAPIurl + "\"\n" + 59 | "#企业微信Key\n" + 60 | "QYWXKEY: \"" + QYWXKEY + "\""; 61 | 62 | File file = new File(Utils.getPluginsPath() + "/setting.yml"); 63 | try { 64 | FileOutputStream writerStream = new FileOutputStream(file); 65 | BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(writerStream, StandardCharsets.UTF_8)); 66 | writer.write(config); 67 | writer.close(); 68 | writerStream.flush(); 69 | writerStream.close(); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/thread/AutoGetFortuneThread.java: -------------------------------------------------------------------------------- 1 | package org.qbot.thread; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | import net.mamoe.mirai.Bot; 5 | import net.mamoe.mirai.contact.Group; 6 | import net.mamoe.mirai.message.data.Face; 7 | import net.mamoe.mirai.message.data.MessageChain; 8 | import net.mamoe.mirai.message.data.MessageChainBuilder; 9 | import net.mamoe.mirai.message.data.PlainText; 10 | import org.qbot.toolkit.PluginUtil; 11 | import org.qbot.toolkit.Setting; 12 | import org.qbot.toolkit.Utils; 13 | 14 | import java.io.BufferedReader; 15 | import java.io.FileReader; 16 | import java.io.IOException; 17 | import java.util.Calendar; 18 | 19 | /** 20 | * AutoGetFortuneThread class 21 | * 22 | * @author 649953543@qq.com 23 | * @date 2021/09/22 24 | */ 25 | 26 | public class AutoGetFortuneThread extends Thread { 27 | @Override 28 | @SuppressWarnings("InfiniteLoopStatement") 29 | public void run() { 30 | super.run(); 31 | String filePath = Utils.getPluginsDataPath() + "/cache/week.cache"; 32 | PluginUtil pluginUtil = new PluginUtil(); 33 | Utils utils = new Utils(); 34 | Setting.getBot().getLogger().info("开启自动获取运势线程成功!"); 35 | try { 36 | while (true) { 37 | Bot bot = Bot.getInstance(Setting.getQq()); 38 | Calendar calendar = Calendar.getInstance(); 39 | int week1 = calendar.get(Calendar.DAY_OF_WEEK); 40 | FileReader fileReader = new FileReader(filePath); 41 | BufferedReader in = new BufferedReader(fileReader); 42 | int week = Integer.parseInt(in.readLine()); 43 | fileReader.close(); 44 | in.close(); 45 | JSONArray groupList = Setting.getGroup(); 46 | if (week != week1) { 47 | String txt = pluginUtil.getFortune(); 48 | if (!txt.contains("失败")) { 49 | Setting.getBot().getLogger().info("正在发送运势"); 50 | for (int i = 0; i < groupList.size(); i++) { 51 | try { 52 | Group group = bot.getGroup(groupList.getLongValue(i)); 53 | MessageChain chain = new MessageChainBuilder() 54 | .append(new PlainText("滴滴滴")) 55 | .append(new Face(307)) 56 | .append(new PlainText("\n" + txt)) 57 | .build(); 58 | assert group != null; 59 | group.sendMessage(chain); 60 | Thread.sleep(1000); 61 | } catch (Exception e) { 62 | Setting.getBot().getLogger().info("发送运势失败"); 63 | } 64 | } 65 | Utils.rewrite(week1); 66 | } 67 | } 68 | if (!bot.isOnline()) { 69 | try { 70 | utils.sendMsgToWeChat("机器人:" + bot.getId() + "\n已离线\n" + utils.getTime4()); 71 | } catch (Exception e) { 72 | throw new RuntimeException(e); 73 | } 74 | Setting.getBot().getLogger().info("机器人已离线"); 75 | } 76 | Thread.sleep(600000); 77 | } 78 | } catch (InterruptedException | IOException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/thread/AutoThread.java: -------------------------------------------------------------------------------- 1 | package org.qbot.thread; 2 | 3 | import net.mamoe.mirai.Bot; 4 | import net.mamoe.mirai.contact.Group; 5 | import net.mamoe.mirai.message.data.Image; 6 | import net.mamoe.mirai.message.data.MessageChain; 7 | import net.mamoe.mirai.message.data.MessageChainBuilder; 8 | import net.mamoe.mirai.message.data.PlainText; 9 | import net.mamoe.mirai.utils.ExternalResource; 10 | import org.qbot.toolkit.PluginUtil; 11 | import org.qbot.toolkit.Setting; 12 | import org.qbot.toolkit.Utils; 13 | 14 | import java.io.File; 15 | 16 | /** 17 | * AutoThread class 18 | * 19 | * @author 649953543@qq.com 20 | * @date 2021/09/22 21 | */ 22 | 23 | public class AutoThread extends Thread { 24 | @Override 25 | @SuppressWarnings("InfiniteLoopStatement") 26 | public void run() { 27 | Utils utils = new Utils(); 28 | Setting.getBot().getLogger().info("开启自动发送小提醒线程成功!"); 29 | PluginUtil pluginUtil = new PluginUtil(); 30 | while (true) { 31 | try { 32 | Bot bot = Bot.getInstance(Setting.getQq()); 33 | Thread.sleep(1000); 34 | boolean autoTips = Setting.getAutoTips(); 35 | boolean autoNews = Setting.getAutoNews(); 36 | if ("08:30".equals(utils.getNowTime()) && autoNews) { 37 | for (int i = 0; i < Setting.getGroup().size(); i++) { 38 | try { 39 | Group group = bot.getGroup(Setting.getGroup().getLongValue(i)); 40 | String newsImgUrl = pluginUtil.getNews(); 41 | if (!newsImgUrl.contains("失败")) { 42 | ExternalResource img = ExternalResource.create(new File(newsImgUrl)); 43 | assert group != null; 44 | Image image = group.uploadImage(img); 45 | img.close(); 46 | MessageChain chain = new MessageChainBuilder().append(new PlainText("今日新闻")).append(image).append(new PlainText(pluginUtil.getOne())).build(); 47 | group.sendMessage(chain); 48 | } 49 | } catch (Exception e) { 50 | bot.getLogger().info("发送小提醒失败"); 51 | } 52 | } 53 | sleep(60000); 54 | } else if ("15:00".equals(utils.getNowTime()) && autoTips) { 55 | for (int i = 0; i < Setting.getGroup().size(); i++) { 56 | // try { 57 | // Group group = bot.getGroup(Setting.getGroup().getLongValue(i)); 58 | // assert group != null; 59 | // MessageChain chain = new MessageChainBuilder() 60 | // .append(new PlainText(pluginUtil.moFish())) 61 | // .build(); 62 | // group.sendMessage(chain); 63 | // } catch (Exception e) { 64 | // bot.getLogger().info("发送小提醒失败"); 65 | // } 66 | try { 67 | Group group = bot.getGroup(Setting.getGroup().getLongValue(i)); 68 | String mofishImgUrl = pluginUtil.moFishNew(); 69 | if (!mofishImgUrl.contains("失败")) { 70 | ExternalResource img = ExternalResource.create(new File(mofishImgUrl)); 71 | assert group != null; 72 | Image image = group.uploadImage(img); 73 | img.close(); 74 | MessageChain chain = new MessageChainBuilder().append(image).build(); 75 | group.sendMessage(chain); 76 | } 77 | } catch (Exception e) { 78 | bot.getLogger().info("发送小提醒失败"); 79 | } 80 | } 81 | sleep(60000); 82 | } 83 | sleep(30000); 84 | } catch (InterruptedException e) { 85 | e.printStackTrace(); 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/toolkit/CreateFile.java: -------------------------------------------------------------------------------- 1 | package org.qbot.toolkit; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | import org.qbot.Plugin; 5 | import org.qbot.api.API; 6 | 7 | import java.io.BufferedWriter; 8 | import java.io.File; 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | import java.nio.file.Path; 12 | 13 | /** 14 | * CreateFile class 15 | * 16 | * @author 649953543@qq.com 17 | * @date 2021/09/22 18 | */ 19 | 20 | public class CreateFile { 21 | Utils utils = new Utils(); 22 | public void createFile(Plugin plugin) { 23 | Path dataFolderPath = Utils.getPluginsDataPath(); 24 | Path configFolderPath = Utils.getPluginsPath(); 25 | 26 | File dataFolderDirectory = new File(String.valueOf(dataFolderPath)); 27 | dataFolderDirectory.mkdir(); 28 | 29 | File configFolderDirectory = new File(String.valueOf(configFolderPath)); 30 | configFolderDirectory.mkdir(); 31 | 32 | File cacheDirectory = new File(dataFolderPath + "/cache"); 33 | cacheDirectory.mkdir(); 34 | 35 | File imageDirectory = new File(dataFolderPath + "/cache/image"); 36 | imageDirectory.mkdir(); 37 | 38 | File heroHeadDirectory = new File(dataFolderPath + "/cache/hero"); 39 | heroHeadDirectory.mkdir(); 40 | 41 | File newsDirectory = new File(dataFolderPath + "/cache/news"); 42 | newsDirectory.mkdir(); 43 | 44 | File videoDirectory = new File(dataFolderPath + "/cache/video"); 45 | videoDirectory.mkdir(); 46 | 47 | File voiceDirectory = new File(dataFolderPath + "/cache/voice"); 48 | voiceDirectory.mkdir(); 49 | 50 | File tqDirectory = new File(dataFolderPath + "/cache/tq"); 51 | tqDirectory.mkdir(); 52 | 53 | File qqDirectory = new File(dataFolderPath + "/cache/qq"); 54 | qqDirectory.mkdir(); 55 | 56 | File musicDirectory = new File(dataFolderPath + "/cache/music"); 57 | musicDirectory.mkdir(); 58 | 59 | File mofishDirectory = new File(dataFolderPath + "/cache/mofish"); 60 | mofishDirectory.mkdir(); 61 | 62 | File groupManagementDirectory = new File(dataFolderPath + "/groupManagement"); 63 | groupManagementDirectory.mkdir(); 64 | 65 | File file = new File(configFolderPath + "/setting.yml"); 66 | 67 | if (!file.exists()) { 68 | plugin.getLogger().info("检测到配置文件不存在,生成中"); 69 | SetSetting.setFile(Setting.VERSION_NUM, 0, "", "", "", 1, 119, false, false, false, "", "", false, false, 70 | false, 71 | new JSONArray(), false, 0, "", ""); 72 | } else { 73 | plugin.getLogger().info("配置文件存在"); 74 | Setting setting1 = new Setting(); 75 | setting1.getVersion(); 76 | } 77 | File newsFile = new File(dataFolderPath + "/cache/news.cache"); 78 | File weekcacheFile = new File(dataFolderPath + "/cache/week.cache"); 79 | try { 80 | if (!newsFile.exists()) { 81 | newsFile.createNewFile(); 82 | } 83 | if (!weekcacheFile.exists()) { 84 | newsFile.createNewFile(); 85 | BufferedWriter out = new BufferedWriter(new FileWriter(weekcacheFile)); 86 | out.write("0"); 87 | out.close(); 88 | } 89 | } catch (IOException e) { 90 | e.printStackTrace(); 91 | } 92 | File cqFile = new File(dataFolderPath + "/诸葛神签.txt"); 93 | if (!cqFile.exists()) { 94 | plugin.getLogger().info("正在下载资源文件:" + cqFile.getName()); 95 | if (utils.downloadFile(API.ZHU_GE_URL, cqFile.getAbsolutePath())) { 96 | plugin.getLogger().info("下载完成"); 97 | } else { 98 | plugin.getLogger().info("下载失败"); 99 | } 100 | } 101 | //提示文件 102 | File tipsFile = new File(dataFolderPath + "/image_tips.png"); 103 | if (!tipsFile.exists()) { 104 | plugin.getLogger().info("正在下载资源文件:" + tipsFile.getName()); 105 | if (utils.downloadFile(API.IMAGE_TIPS_URL, tipsFile.getAbsolutePath())) { 106 | plugin.getLogger().info("下载完成"); 107 | } else { 108 | plugin.getLogger().info("下载失败"); 109 | } 110 | } 111 | //二维码 112 | File ewmFile = new File(dataFolderPath + "/image_qr_code.png"); 113 | if (!ewmFile.exists()) { 114 | plugin.getLogger().info("正在下载资源文件:" + ewmFile.getName()); 115 | if (utils.downloadFile(API.IMAGE_URL, ewmFile.getAbsolutePath())) { 116 | plugin.getLogger().info("下载完成"); 117 | } else { 118 | plugin.getLogger().info("下载失败"); 119 | } 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /UPDATE.md: -------------------------------------------------------------------------------- 1 | 2024年6月13日v3.5.4更新 2 | 3 | 1.修复听歌功能bug 4 | 5 | 2024年1月16日v3.5.3更新 6 | 7 | 1.修复无法获取到运势的问题 8 | 9 | 2.更新~~美女~~图片发送逻辑 10 | 11 | 2023年12月8日v3.5.2更新 12 | 13 | 1.mirai-core支持到[2.16.0](https://github.com/mamoe/mirai/releases/tag/v2.16.0) 14 | 15 | 2.修复API可能因为CDN缓存导致的无法使用的问题 16 | 17 | 2023年9月22日v3.5.1更新 18 | 19 | 1.优化可能存在的内存泄漏问题 20 | 21 | 2023年8月30日v3.5.0更新 22 | 23 | 1.新增喜报\悲报 24 | 25 | 2.新增戳一戳提醒 26 | 27 | 2023年7月27日v3.4.0更新 28 | 29 | 1.在线状态改为十分钟检测一次 30 | 31 | 2.资源文件改为从网络获取 32 | 33 | 3.针对获取的资源文件进行校验 34 | 35 | 4.优化定时任务为Bot登录后执行 36 | 37 | 5.一些回复优化 38 | 39 | 6.优化日志输出 40 | 41 | 2023年7月11日v3.3.0更新 42 | 43 | 1.接口统一修改为自建API 44 | 45 | 2.删除机器在线提示 46 | 47 | 3.删除鱼情查询 48 | 49 | 4.优化了部分提示信息 50 | 51 | 5.bug修复 52 | 53 | 2023年7月7日v3.2.0更新 54 | 55 | 1.新增美女视频 56 | 57 | 2.新增掉线提醒(企业微信提醒) 58 | 59 | 3.摸鱼办倒计时更新 60 | 61 | 4.mirai-core支持到[2.15.0-RC](https://github.com/mamoe/mirai/releases/tag/v2.15.0-RC) 62 | 63 | 5.kotlin版本更新到1.8.10 64 | 65 | 6.项目JDK版本改为17 66 | 67 | 2023年2月19日v3.2.0-RC更新 68 | 69 | 1.新增网易云签到、刷歌功能(正在测试) 70 | 71 | 2.修复更新配置文件时AI功能会重置为false的问题 72 | 73 | 2023年2月18日v3.1.5更新 74 | 75 | 1.修复群管理bug 76 | 77 | 2.每日新闻改为8:30发送,且增加一言 78 | 79 | 3.更新摸鱼办日期 80 | 81 | 4.官网地址由www.miraiqbot.xyz变更为www.miraiqbot.top,旧地址将保留两个月 82 | 83 | 5.mirai-core支持到[2.14.0](https://github.com/mamoe/mirai/releases/tag/v2.14.0) 84 | 85 | 2022年12月21日v3.1.4更新 86 | 87 | 1.更改发送图片图床 88 | 89 | 2.删除世界杯功能 90 | 91 | 2022年12月5日v3.1.3更新 92 | 93 | 1.修复获取不到淘汰赛赛程的问题 94 | 95 | 2.删除世界杯小组赛积分 96 | 97 | 3.mirai-core支持到[2.13.2](https://github.com/mamoe/mirai/releases/tag/v2.13.2) 98 | 99 | 2022年11月23日v3.1.2更新 100 | 101 | 1.新增世界杯小组赛积分 102 | 103 | 2022年11月21日v3.1.1更新 104 | 105 | 1.新增世界杯赛程,发送世界杯即可获取赛程和比分 106 | 107 | 2022年11月18日v3.1.0更新 108 | 109 | 1.mirai-core支持到[2.13.0-RC2](https://github.com/mamoe/mirai/releases/tag/v2.13.0-RC2) 110 | 111 | 2.修复获取星座运势有html标签的问题 112 | 113 | 3.修复创建config文件可能会出现错误的问题 114 | 115 | 4.kotlin版本更新到1.7.10 116 | 117 | 5.更新依赖 118 | 119 | 2022年10月30日v3.0.2更新 120 | 121 | 1.mirai-core支持到[2.12.3](https://github.com/mamoe/mirai/releases/tag/v2.12.3) 122 | 123 | 2.更新摸鱼办日期 124 | 125 | 3.更新依赖 126 | 127 | 2022年8月23日v3.0.1更新 128 | 129 | 1.mirai-core支持到[2.12.2](https://github.com/mamoe/mirai/releases/tag/v2.12.2) 130 | 131 | 2.优化发送图片 132 | 133 | 3.新增COC鱼情查询 134 | 135 | 4.增加后台统计 136 | 137 | 2022年8月3日v3.0.0更新 138 | 139 | 1.支持茉莉云AI(需要前往[茉莉云官网](https://mlyai.com/)获取key) 140 | 141 | 2022年8月2日v2.1.1更新 142 | 143 | 1.一些bug修复 144 | 145 | 2022年8月1日v2.1.0更新 146 | 147 | 1.发送美女图片将从图床拉取,无需手动放图 148 | 149 | 2022年8月1日v2.0.9更新 150 | 151 | 1.mirai-core支持到[2.12.1](https://github.com/mamoe/mirai/releases/tag/v2.12.1) 152 | 153 | 2.修复合并转发消息显示昵称错误的问题(mirai 2.12.1修复) 154 | 155 | 3.优化了一些细节 156 | 157 | 2022年7月31日v2.0.8更新 158 | 159 | 1.发送图片修改为合并转发形式(管理员可自定义发送图片数量) 160 | 161 | 2.修复一些bug 162 | 163 | 2022年7月30日v2.0.7-1更新 164 | 165 | 1.修复一些bug 166 | 167 | 2022年7月30日v2.0.7更新 168 | 169 | 1.修复更新配置文件时,更新后群列表为null的问题 170 | 171 | 2.新增群发通知功能 172 | 173 | 2022年7月29日v2.0.6更新 174 | 175 | 1.新增可以设置图片自动撤回时间 176 | 177 | 2022年7月28日v2.0.5-1更新 178 | 179 | 1.修复当群号不存在时,运势会重复发送的问题 180 | 181 | 2022年7月27日v2.0.5更新 182 | 183 | 1.新增[超级管理员功能](https://www.miraiqbot.top/#/?id=超级管理员功能) 184 | 185 | 2022年7月15日v2.0.4更新 186 | 187 | 1.mirai-core支持到[2.12.0](https://github.com/mamoe/mirai/releases/tag/v2.12.0) 188 | 189 | 2.修复了国外服务器可能获取不到歌曲目录的bug 190 | 191 | 3.发送图片由闪图改为普通图片发送 192 | 193 | 2022年6月18日v2.0.3更新 194 | 195 | 1.mirai-core支持到[2.11.1](https://github.com/mamoe/mirai/releases/tag/v2.11.1) 196 | 197 | 2.修复摸鱼办的一些bug 198 | 199 | 2022年5月7日v2.0.2更新 200 | 201 | 1.mirai-core支持到[2.11.0-RC](https://github.com/mamoe/mirai/releases/tag/v2.11.0-RC) 202 | 203 | 2.更新摸鱼办 204 | 205 | 3.依赖支持到fastjson2 206 | 207 | 2022年4月20日v2.0.1更新 208 | 209 | 1.mirai-core支持到[2.11.0-M2.2](https://github.com/mamoe/mirai/releases/tag/v2.11.0-M2.2) 210 | 211 | 2.群管理插件开放([帮助文档](https://www.miraiqbot.top/#/?id=%e7%be%a4%e7%ae%a1%e7%90%86%e5%8a%9f%e8%83%bd)) 212 | 213 | 3.[配置文件更新](https://github.com/duan649953543/Qbot/blob/main/CONFIG.md) 214 | 215 | 4.删除公告栏组件 216 | 217 | 2021年11月26日v1.1.3更新 218 | 219 | 1.新增公告栏 220 | 221 | 2.优化代码结构 222 | 223 | 下个版本将是大版本更新,将开放群管理插件,请耐心等待 224 | 225 | 2021年11月23日v1.1.2-1更新 226 | 227 | 1.mirai-core支持到[2.9.0-M1](https://github.com/mamoe/mirai/releases/tag/v2.9.0-M1) 228 | 229 | 2.修复一些BUG 230 | 231 | 2021年11月17日v1.1.2更新 232 | 233 | 1.mirai-core支持到[2.8.0](https://github.com/mamoe/mirai/releases/tag/v2.8.0) 234 | 235 | 2.新增【摸鱼办】提醒放假时间 236 | 237 | 3.修改15点的饮茶小助手为摸鱼办 238 | 239 | 2021年11月1日v1.1.1更新 240 | 241 | 1.修复了自动获取运势有可能失败的问题 242 | 243 | 2021年9月23日v1.1.0更新 244 | 245 | 1.mirai-core支持到[2.8.0-M1](https://github.com/mamoe/mirai/releases/tag/v2.8.0-M1) 246 | 247 | 2.修复获取英雄战力时英雄名为null的问题 248 | 249 | 3.新增获取战力时显示英雄头像 250 | 251 | 2021年9月22日v1.0.9更新 252 | 253 | 1.mirai-core支持到[2.7.1](https://github.com/mamoe/mirai/releases/tag/v2.7.1) 254 | 255 | 2.修复当image文件夹中只有一张图片时无法正常发送的问题 256 | 257 | 3.删除福利功能 258 | 259 | 4.优化代码结构,规范代码 260 | 261 | 注:本次更新代码改动较大,可能出现无法预知的bug,请谨慎升级 262 | 263 | 2021年9月17日v1.0.8更新 264 | 265 | 1.mirai-core支持到[2.7.0](https://github.com/mamoe/mirai/releases/tag/v2.7.0) 266 | 267 | 2.依赖更新 268 | 269 | 3.删除无用代码 270 | 271 | 2021年8月20日v1.0.7更新 272 | 273 | 1.mirai-core支持到[2.7-RC](https://github.com/mamoe/mirai/releases/tag/v2.7-RC) 274 | 275 | 2.kotlin版本更新到1.5.0 276 | 277 | 3.新增维护模式(/onwh 开启维护,/closewh 关闭维护,维护模式下将不会处理消息) 278 | 279 | 2021年8月19日v1.0.6-1更新 280 | 281 | 1.修复了可能获取不到运势的问题 282 | 283 | 2021年8月18日v1.0.6更新 284 | 285 | 1.修复了运势线程可能会中断的情况 286 | 287 | 2021年7月28日v1.0.5更新 288 | 289 | 1.新增奥运查询功能 290 | 291 | 2.mirai-core支持到[2.7-M2](https://github.com/mamoe/mirai/releases/tag/v2.7-M2) 292 | 293 | 3.删除一些无用代码 294 | 295 | 2021年7月1日v1.0.4更新 296 | 297 | 1.优化新闻获取逻辑,无需再手动更新 298 | 299 | 2.修复自动发送逻辑错误 300 | 301 | 2021年6月22日v1.0.3更新 302 | 303 | 1.新增查看羊毛福利 304 | 305 | 2.优化匹配逻辑 306 | 307 | 2021年6月21日v1.0.2更新 308 | 309 | 1.mirai-core支持到[2.7-M1](https://github.com/mamoe/mirai/releases/tag/v2.7-M1) 310 | 311 | 2.优化语言和歌曲分享逻辑 312 | 313 | 2021年6月16日 v1.0.1更新 314 | 315 | 1.优化求签功能 316 | 317 | 2.燃鹅相关菜单删除 318 | 319 | 2021年6月11日 v1.0.0更新 320 | 321 | 正式版1.0.0上线 -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # 基本功能 2 | 3 | [今日运势](#今日运势查询) 4 | 5 | [今日新闻](#今日新闻查询) 6 | 7 | [今日星座运势](#今日星座运势) 8 | 9 | [诸葛神签](#诸葛神签) 10 | 11 | [音乐分享](#音乐分享) 12 | 13 | [发送语音](#发送语音) 14 | 15 | [摸鱼办](#摸鱼办) 16 | 17 | [王者战力查询](#王者战力查询) 18 | 19 | [随机发送~~美女~~图片](#随机发送图片) 20 | 21 | [随机发送~~美女~~视频](#随机发送视频) 22 | 23 | [悲报/喜报](#悲报喜报) 24 | 25 | [AI聊天](#AI聊天) 26 | 27 | [网易云功能](#网易云功能) 28 | 29 | [定时任务](#定时任务) 30 | 31 | [菜单](#菜单) 32 | 33 | [帮助](#帮助) 34 | 35 | [群管理功能(正在内测)](#群管理功能) 36 | 37 | [超级管理员功能(正在内测)](#超级管理员功能) 38 | 39 | ## 今日运势查询 40 | 41 | * @机器人发送:今日运势 42 | 43 | * @机器人发送:运势 44 | 45 | ## 今日新闻查询 46 | 47 | * @机器人发送:今日新闻 48 | 49 | * @机器人发送:新闻 50 | 51 | ## 今日星座运势 52 | 53 | @机器人发送:星座名 54 | 55 | 例: 56 | 57 | * @机器人 白羊座 58 | 59 | * @机器人 白羊 60 | 61 | ## 诸葛神签 62 | 63 | * @机器人发送:诸葛神签 64 | 65 | * @机器人发送:求签 66 | 67 | 注:一天只能求一次签,重复求签的结果都为第一次求签的结果 68 | 69 | ## 音乐分享 70 | 71 | @机器人发送:听歌+歌曲名 72 | 73 | 例: 74 | 75 | * @机器人 听歌奇妙的约会 76 | 77 | 注:歌曲源来自网易云音乐 78 | 79 | ## 发送语音 80 | 81 | @机器人发送:说+需要转语言的文字 82 | 83 | 例: 84 | 85 | * @机器人 说我是帅哥 86 | 87 | 注:每次语音最大不超过1024个字符 88 | 89 | ## 摸鱼办 90 | 91 | * @机器人发送:摸鱼办 92 | 93 | ## 王者战力查询 94 | 95 | @机器人发送:qq+英雄名 96 | 97 | @机器人发送:微信+英雄名 98 | 99 | 例: 100 | 101 | * @机器人 qq伽罗 102 | 103 | * @机器人 微信伽罗 104 | 105 | ## 随机发送图片 106 | 107 | * @机器人发送:美女 108 | 109 | * @机器人发送:美女图片 110 | 111 | ## 随机发送视频 112 | 113 | * @机器人发送:美女视频 114 | 115 | 注:视频源来源于快手,此功能仅供学习和参考,随时可能下架 116 | 117 | ## 悲报喜报 118 | 119 | * @机器人发送:喜报xxx 120 | 121 | * @机器人发送:悲报xxx 122 | 123 | ## AI聊天 124 | 125 | * @机器人发送:任意非关键字即可 126 | 127 | * [AI功能简介](https://mlyai.com/docs) 128 | 129 | ## 网易云功能 130 | 131 | * 使用此功能有封号的风险 132 | 133 | * 使用此功能可能会使用您的账号信息(包括但不限于cookie、歌单列表) 134 | 135 | * 使用此功能仅限本地保存您的账号信息,不会上传任何您的个人账号信息 136 | 137 | * 您也可以选择手动删除本地保存的个人信息 138 | 139 | * 继续使用则默认同意上述风险和注意事项 140 | 141 | * 如出现以上风险和注意事项的问题,将由您自行承担 142 | 143 | * 不建议已认证音乐人使用此功能,可能有掉认证的风险 144 | 145 | 此功能仅供学习和参考,随时可能下架 146 | 147 | ## 定时任务 148 | 149 | 当前定时任务为 150 | 151 | 8点----今日新闻 152 | 153 | 15点----摸鱼办 154 | 155 | 不定时----今日运势 156 | 157 | ## 菜单 158 | 159 | * @机器人发送:菜单 160 | 161 | ## 帮助 162 | 163 | * @机器人发送:帮助 164 | 165 | # 群管理功能 166 | 167 | [超级管理员](#超级管理员) 168 | 169 | [管理员](#管理员) 170 | 171 | ## 超级管理员 172 | 173 | 超级管理员需配置在机器人插件配置文件中,且只能配置一个 174 | 175 | 超级管理员可以增加删除管理员 176 | 177 | 超级管理员可以跨群管理 178 | 179 | 超级管理员拥有和管理员一样的权限 180 | 181 | ### 设置管理员 182 | 183 | --- 184 | 185 | 只对超级管理员有效 186 | 187 | 在机器人所在群内发送: 188 | 189 | 设置本群管理+QQ号(可以直接使用@) 190 | 191 | * 例:设置本群管理@XXXXXXXXX 192 | 193 | ### 取消本群管理 194 | 195 | --- 196 | 197 | 只对超级管理员有效 198 | 199 | 在机器人所在群内发送: 200 | 201 | 取消本群管理+QQ号(可以直接使用@) 202 | 203 | * 例:取消本群管理@XXXXXXXXX 204 | 205 | ## 管理员 206 | 207 | 管理员只能由超级管理员添加 208 | 209 | 管理员只能管理单个群(不能跨群管理) 210 | 211 | ### 设置禁言关键字 212 | 213 | --- 214 | 215 | 对管理员和超级管理员有效 216 | 217 | 在机器人所在群内发送: 218 | 219 | 设置禁言关键字+关键字 220 | 221 | * 例:设置禁言关键字XX 222 | 223 | ### 删除禁言关键字 224 | 225 | --- 226 | 227 | 对管理员和超级管理员有效 228 | 229 | 在机器人所在群内发送: 230 | 231 | 删除禁言关键字+关键字 232 | 233 | * 例:删除禁言关键字XX 234 | 235 | ### 清空禁言关键字 236 | 237 | --- 238 | 239 | 对管理员和超级管理员有效 240 | 241 | 在机器人所在群内发送: 242 | 243 | 清空禁言关键字 244 | 245 | * 例:清空禁言关键字 246 | 247 | ### 设置禁言时间 248 | 249 | --- 250 | 251 | 对管理员和超级管理员有效 252 | 253 | 在机器人所在群内发送: 254 | 255 | 设置禁言时间+时间 256 | 257 | * 例:设置禁言时间10 258 | 259 | 注:单位分钟 260 | 261 | ### 设置撤回关键字 262 | 263 | --- 264 | 265 | 对管理员和超级管理员有效 266 | 267 | 在机器人所在群内发送: 268 | 269 | 设置撤回关键字+关键字 270 | 271 | * 例:设置撤回关键字XX 272 | 273 | ### 删除撤回关键字 274 | 275 | --- 276 | 277 | 对管理员和超级管理员有效 278 | 279 | 在机器人所在群内发送: 280 | 281 | 删除撤回关键字+关键字 282 | 283 | * 例:删除撤回关键字XX 284 | 285 | ### 清空撤回关键字 286 | 287 | --- 288 | 289 | 对管理员和超级管理员有效 290 | 291 | 在机器人所在群内发送: 292 | 293 | 清空撤回关键字 294 | 295 | * 例:清空撤回关键字 296 | 297 | ### 设置自动同意群申请 298 | 299 | --- 300 | 301 | 对管理员和超级管理员有效 302 | 303 | 在机器人所在群内发送: 304 | 305 | 设置自动同意群申请 306 | 307 | * 例:设置自动同意群申请 308 | 309 | ### 关闭自动同意群申请 310 | 311 | --- 312 | 313 | 对管理员和超级管理员有效 314 | 315 | 在机器人所在群内发送: 316 | 317 | 关闭自动同意群申请 318 | 319 | * 例:关闭自动同意群申请 320 | 321 | ### 设置自动同意关键字 322 | 323 | --- 324 | 325 | 对管理员和超级管理员有效 326 | 327 | 在机器人所在群内发送: 328 | 329 | 设置自动同意关键字+关键字 330 | 331 | * 例:设置自动同意关键字XX 332 | 333 | ### 删除自动同意关键字 334 | 335 | --- 336 | 337 | 对管理员和超级管理员有效 338 | 339 | 在机器人所在群内发送: 340 | 341 | 删除自动同意关键字+关键字 342 | 343 | * 例:删除自动同意关键字XX 344 | 345 | ### 清空自动同意关键字 346 | 347 | --- 348 | 349 | 对管理员和超级管理员有效 350 | 351 | 在机器人所在群内发送: 352 | 353 | 清空自动同意关键字 354 | 355 | * 例:清空自动同意关键字 356 | 357 | ### 设置禁言 358 | 359 | --- 360 | 361 | 对管理员和超级管理员有效 362 | 363 | 在机器人所在群内发送: 364 | 365 | 禁言+QQ号(可以直接使用@) 366 | 367 | * 例:禁言@XXXXXXXXX 368 | 369 | ### 解除禁言 370 | 371 | --- 372 | 373 | 对管理员和超级管理员有效 374 | 375 | 在机器人所在群内发送: 376 | 377 | 解除禁言+QQ号(可以直接使用@) 378 | 379 | * 例:解除禁言@XXXXXXXXX 380 | 381 | # 超级管理员功能 382 | 383 | 超级管理员可以私聊机器人发送指令,实现动态配置文件的功能。 384 | 385 | --- 386 | 387 | ## 设置一次发送图片数量 388 | 389 | 私聊机器人发送: 390 | 391 | 设置图片数量+数字 392 | 393 | * 例:设置图片数量5 394 | 395 | 注:数量不能小于1 396 | 397 | ## 设置图片撤回时间 398 | 399 | 私聊机器人发送: 400 | 401 | 设置撤回时间+数字 402 | 403 | * 例:设置撤回时间0 404 | 405 | 注:0为不撤回,撤回单位为秒,撤回时间不能大于120秒 406 | 407 | ## 开启同意好友请求 408 | 409 | 私聊机器人发送: 410 | 411 | * 开启同意好友请求 412 | 413 | ## 关闭同意好友请求 414 | 415 | 私聊机器人发送: 416 | 417 | * 关闭同意好友请求 418 | 419 | ## 开启同意入群请求 420 | 421 | 私聊机器人发送: 422 | 423 | * 开启同意入群请求 424 | 425 | ## 关闭同意入群请求 426 | 427 | 私聊机器人发送: 428 | 429 | * 关闭同意入群请求 430 | 431 | ## 开启聊天 432 | 433 | 私聊机器人发送: 434 | 435 | * 开启聊天 436 | 437 | ## 关闭聊天 438 | 439 | 私聊机器人发送: 440 | 441 | * 关闭聊天 442 | 443 | ## 开启发送运势 444 | 445 | 私聊机器人发送: 446 | 447 | * 开启发送运势 448 | 449 | ## 关闭发送运势 450 | 451 | 私聊机器人发送: 452 | 453 | * 关闭发送运势 454 | 455 | ## 开启发送新闻 456 | 457 | 私聊机器人发送: 458 | 459 | * 开启发送新闻 460 | 461 | ## 关闭发送新闻 462 | 463 | 私聊机器人发送: 464 | 465 | * 关闭发送新闻 466 | 467 | ## 开启发送摸鱼办 468 | 469 | 私聊机器人发送: 470 | 471 | * 开启发送摸鱼办 472 | 473 | ## 关闭发送摸鱼办 474 | 475 | 私聊机器人发送: 476 | 477 | * 关闭发送摸鱼办 478 | 479 | ## 设置发送消息群号 480 | 481 | 私聊机器人发送: 482 | 483 | 设置发送消息群号+群号 484 | 485 | * 例:设置发送消息群号123456789 486 | 487 | ## 删除发送消息群号 488 | 489 | 私聊机器人发送: 490 | 491 | 删除发送消息群号+群号 492 | 493 | * 例:删除发送消息群号123456789 494 | 495 | ## 开启群管系统 496 | 497 | 私聊机器人发送: 498 | 499 | * 开启群管系统 500 | 501 | ## 关闭群管系统 502 | 503 | 私聊机器人发送: 504 | 505 | * 关闭群管系统 506 | 507 | ## 发送通知 508 | 509 | 私聊机器人发送: 510 | 511 | 发送通知+文本消息 512 | 513 | * 例:发送通知+通知内容 514 | 515 | # 联系作者 516 | 517 | QQ:649953543 518 | 519 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/Plugin.java: -------------------------------------------------------------------------------- 1 | package org.qbot; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | import com.alibaba.fastjson2.JSONObject; 5 | import net.mamoe.mirai.console.plugin.jvm.JavaPlugin; 6 | import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescriptionBuilder; 7 | import net.mamoe.mirai.contact.Group; 8 | import net.mamoe.mirai.event.GlobalEventChannel; 9 | import net.mamoe.mirai.event.events.*; 10 | import net.mamoe.mirai.message.data.MessageChain; 11 | import net.mamoe.mirai.message.data.MessageChainBuilder; 12 | import net.mamoe.mirai.message.data.MessageSource; 13 | import net.mamoe.mirai.message.data.PlainText; 14 | import org.qbot.group.GroupManagement; 15 | import org.qbot.group.GroupManagementSetting; 16 | import org.qbot.group.GroupManagementUtil; 17 | import org.qbot.msgdeal.AdminMessageDeal; 18 | import org.qbot.msgdeal.MessageDeal; 19 | import org.qbot.music.MusicMessageDeal; 20 | import org.qbot.thread.StartThread; 21 | import org.qbot.toolkit.CreateFile; 22 | import org.qbot.toolkit.Setting; 23 | import org.qbot.toolkit.Utils; 24 | 25 | import java.io.File; 26 | import java.io.IOException; 27 | import java.nio.file.Path; 28 | 29 | /** 30 | * @author 64995 31 | */ 32 | @SuppressWarnings({"AlibabaMethodTooLong"}) 33 | public final class Plugin extends JavaPlugin { 34 | public static final Plugin INSTANCE = new Plugin(); 35 | 36 | public Plugin() { 37 | super(new JvmPluginDescriptionBuilder("org.qbot.plugin", PluginVersion.VERSION_NUM) 38 | .name("Qbot") 39 | .author("649953543@qq.com") 40 | .build()); 41 | } 42 | 43 | @SuppressWarnings("AlibabaMethodTooLong") 44 | @Override 45 | public void onEnable() { 46 | getLogger().info("启动中。。。"); 47 | CreateFile createFile = new CreateFile(); 48 | createFile.createFile(this); 49 | Utils utils = new Utils(); 50 | 51 | GroupManagementSetting groupManagementSetting = new GroupManagementSetting(); 52 | GroupManagementUtil groupManagementUtil = new GroupManagementUtil(); 53 | MessageDeal messagedeal = new MessageDeal(); 54 | GroupManagement groupManagement = new GroupManagement(); 55 | Long botQq = Setting.getQq(); 56 | long superAdmin = Setting.getAdminQQ(); 57 | Path dataFolderPath = Utils.getPluginsDataPath(); 58 | File groupManagementDirectory = new File(dataFolderPath + "/groupManagement"); 59 | 60 | GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, g -> { 61 | //监听群消息 62 | String groupMsg = g.getMessage().contentToString();//获取消息 63 | long senderId = g.getSender().getId(); //获取发送者QQ 64 | String senderName = g.getSenderName(); //获取发送者名字 65 | Group group = g.getGroup(); //获取群对象 66 | MessageChain groupMessageChain = g.getMessage(); //获取消息来源 67 | 68 | boolean botTag = false; 69 | if (groupMsg.contains(String.valueOf(botQq))) { 70 | botTag = true; 71 | groupMsg = groupMsg.replace("@" + botQq, ""); 72 | groupMsg = groupMsg.replace("[图片]", ""); 73 | groupMsg = groupMsg.replace(" ", ""); 74 | } 75 | try { 76 | //检测是否开启群管理 77 | if (Setting.getGroupManagement()) { 78 | File file = new File(groupManagementDirectory + "/" + group.getId() + ".txt"); 79 | if (!file.exists()) { 80 | groupManagementSetting.creatEmptyTemplate(file); 81 | } 82 | //判断是否为超级管理员 83 | if (senderId == superAdmin) { 84 | if (groupManagement.msgDel(group, groupMsg, true)) { 85 | return; 86 | } 87 | if (groupManagementUtil.msgDel(group, groupMsg)) { 88 | return; 89 | } 90 | } 91 | JSONObject jsonObject = utils.readFile(file); 92 | JSONArray adminQqArray = jsonObject.getJSONArray("AdminQQ"); 93 | //判断是否设置了普通管理员 94 | if (adminQqArray.size() > 0) { 95 | //遍历管理员 96 | for (int i = 0; i < adminQqArray.size(); i++) { 97 | long adminQq = adminQqArray.getLongValue(i); 98 | if (senderId == adminQq) { 99 | if (groupManagement.msgDel(group, groupMsg, false)) { 100 | return; 101 | } 102 | if (groupManagementUtil.msgDel(group, groupMsg)) { 103 | return; 104 | } 105 | } 106 | } 107 | } 108 | //获取禁言词汇列表 109 | JSONArray muteKeyWordsArray = jsonObject.getJSONArray("MuteKeywords"); 110 | int muteTime = jsonObject.getIntValue("MuteTime"); 111 | if (muteTime == 0) { 112 | muteTime = 10; 113 | } 114 | if (muteKeyWordsArray.size() > 0) { 115 | //遍历禁言词汇 116 | for (int i = 0; i < muteKeyWordsArray.size(); i++) { 117 | String muteKeyWords = muteKeyWordsArray.getString(i); 118 | if (groupMsg.contains(muteKeyWords)) { 119 | groupManagementUtil.muteGroup(group, senderId, muteTime, groupMessageChain); 120 | return; 121 | } 122 | } 123 | } 124 | //获取撤回词汇列表 125 | JSONArray recallKeyWordsArray = jsonObject.getJSONArray("RecallKeywords"); 126 | if (recallKeyWordsArray.size() > 0) { 127 | //遍历撤回词汇 128 | for (int i = 0; i < recallKeyWordsArray.size(); i++) { 129 | String recallKeyWords = recallKeyWordsArray.getString(i); 130 | if (groupMsg.contains(recallKeyWords)) { 131 | try { 132 | MessageSource.recall(groupMessageChain); 133 | } catch (Exception e) { 134 | MessageChain chain = new MessageChainBuilder() 135 | .append(new PlainText("撤回失败,请检查是否有管理员权限")) 136 | .build(); 137 | group.sendMessage(chain); 138 | } 139 | return; 140 | } 141 | } 142 | } 143 | } 144 | if (botTag) { 145 | messagedeal.msgDel(senderId, senderName, group, groupMsg, groupMessageChain); 146 | } 147 | } catch (Exception e) { 148 | e.printStackTrace(); 149 | } 150 | }); 151 | 152 | GlobalEventChannel.INSTANCE.subscribeAlways(NudgeEvent.class, n -> { 153 | if (n.getTarget().getId() == botQq) { 154 | try { 155 | messagedeal.nudgeDel(n.getFrom().getId(), n.getSubject().getId()); 156 | } catch (IOException e) { 157 | throw new RuntimeException(e); 158 | } 159 | } 160 | }); 161 | 162 | //监听好友消息 163 | GlobalEventChannel.INSTANCE.subscribeAlways(FriendMessageEvent.class, f -> { 164 | long senderQq = f.getSender().getId(); 165 | String msg = f.getMessage().contentToString(); 166 | MusicMessageDeal musicMessageDeal = new MusicMessageDeal(); 167 | try { 168 | if (!musicMessageDeal.msgDel(f.getFriend(), msg)) { 169 | if (senderQq == superAdmin) { 170 | getLogger().info("收到管理员消息:" + msg); 171 | try { 172 | AdminMessageDeal.msgDel(msg, f.getSender()); 173 | } catch (InterruptedException e) { 174 | throw new RuntimeException(e); 175 | } 176 | } 177 | } 178 | } catch (IOException | InterruptedException e) { 179 | getLogger().info(String.valueOf(e)); 180 | throw new RuntimeException(e); 181 | } 182 | }); 183 | 184 | GlobalEventChannel.INSTANCE.subscribeAlways(GroupTempMessageEvent.class, f -> { 185 | //监听临时消息 186 | }); 187 | 188 | GlobalEventChannel.INSTANCE.subscribeAlways(NewFriendRequestEvent.class, a -> { 189 | //监听添加好友申请 190 | boolean accept1 = Setting.getAgreeFriend(); 191 | if (accept1) { 192 | getLogger().info("昵称:" + a.getFromNick() + " QQ:" + a.getFromId() + " 请求添加好友,已同意"); 193 | a.accept(); 194 | } 195 | }); 196 | 197 | //监听入群消息 198 | GlobalEventChannel.INSTANCE.subscribeAlways(MemberJoinRequestEvent.class, a -> { 199 | try { 200 | File file = new File(groupManagementDirectory + "/" + a.getGroupId() + ".txt"); 201 | String msg = a.getMessage(); 202 | JSONObject jsonObject = utils.readFile(file); 203 | boolean accept1 = jsonObject.getBooleanValue("AutoAgreeApplication"); 204 | JSONArray acceptArray = jsonObject.getJSONArray("AgreeKeywords"); 205 | JSONArray refuseArray = jsonObject.getJSONArray("RejectKeywords"); 206 | if (accept1) { 207 | if (acceptArray.size() > 0) { 208 | for (int i = 0; i < acceptArray.size(); i++) { 209 | String acceptKeyWords = acceptArray.getString(i); 210 | if (msg.contains(acceptKeyWords)) { 211 | a.accept(); 212 | } 213 | } 214 | } 215 | if (refuseArray.size() > 0) { 216 | for (int i = 0; i < refuseArray.size(); i++) { 217 | String refuseKeyWords = refuseArray.getString(i); 218 | if (msg.contains(refuseKeyWords)) { 219 | a.reject(); 220 | } 221 | } 222 | } 223 | } 224 | 225 | } catch (IOException e) { 226 | throw new RuntimeException(e); 227 | } 228 | }); 229 | 230 | GlobalEventChannel.INSTANCE.subscribeAlways(BotInvitedJoinGroupRequestEvent.class, a -> { 231 | //监听被邀请入群消息 232 | boolean finalAutoInvited = Setting.getAgreeGroup(); 233 | if (finalAutoInvited) { 234 | a.accept(); 235 | } 236 | }); 237 | 238 | StartThread startThread = new StartThread(); 239 | getLogger().info("定时任务将在Bot登录后启动"); 240 | startThread.start(); 241 | } 242 | 243 | } -------------------------------------------------------------------------------- /src/main/java/org/qbot/toolkit/Setting.java: -------------------------------------------------------------------------------- 1 | package org.qbot.toolkit; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | import com.alibaba.fastjson2.JSONObject; 5 | import net.mamoe.mirai.Bot; 6 | import org.yaml.snakeyaml.Yaml; 7 | 8 | import java.io.FileInputStream; 9 | import java.io.IOException; 10 | import java.util.Map; 11 | 12 | /** 13 | * Setting class 14 | * 15 | * @author 649953543@qq.com 16 | * @date 2021/09/22 17 | */ 18 | 19 | public class Setting { 20 | 21 | public static Bot getBot() { 22 | return Bot.getInstance(getQq()); 23 | } 24 | 25 | public static long getQq() { 26 | try { 27 | return main().getLongValue("QQ"); 28 | } catch (Exception e) { 29 | return 0; 30 | } 31 | } 32 | 33 | public static String getAppId() { 34 | try { 35 | if (main().getJSONObject("BaiDuAPI").getString("APP_ID") == null) { 36 | return ""; 37 | } 38 | return main().getJSONObject("BaiDuAPI").getString("APP_ID"); 39 | } catch (Exception e) { 40 | return ""; 41 | } 42 | } 43 | 44 | public static String getApiKey() { 45 | try { 46 | if (main().getJSONObject("BaiDuAPI").getString("API_KEY") == null) { 47 | return ""; 48 | } 49 | return main().getJSONObject("BaiDuAPI").getString("API_KEY"); 50 | } catch (Exception e) { 51 | return ""; 52 | } 53 | } 54 | 55 | public static String getSecretKey() { 56 | try { 57 | if (main().getJSONObject("BaiDuAPI").getString("SECRET_KEY") == null) { 58 | return ""; 59 | } 60 | return main().getJSONObject("BaiDuAPI").getString("SECRET_KEY"); 61 | } catch (Exception e) { 62 | return ""; 63 | } 64 | } 65 | 66 | public static int getImageNum() { 67 | try { 68 | return main().getIntValue("ImageNum"); 69 | } catch (Exception e) { 70 | return 1; 71 | } 72 | } 73 | 74 | public static int getImageRecall() { 75 | try { 76 | return main().getIntValue("ImageRecall"); 77 | } catch (Exception e) { 78 | return 119; 79 | } 80 | } 81 | 82 | public static boolean getAgreeFriend() { 83 | try { 84 | return main().getBooleanValue("AgreeFriend"); 85 | } catch (Exception e) { 86 | return false; 87 | } 88 | } 89 | 90 | public static boolean getAgreeGroup() { 91 | try { 92 | return main().getBooleanValue("AgreeGroup"); 93 | } catch (Exception e) { 94 | return false; 95 | } 96 | } 97 | 98 | public static boolean getOldAi() { 99 | try { 100 | return main().getBooleanValue("AI"); 101 | } catch (Exception e) { 102 | return getAi(); 103 | } 104 | } 105 | 106 | public static boolean getAi() { 107 | try { 108 | return main().getJSONObject("AI").getBooleanValue("Open"); 109 | } catch (Exception e) { 110 | return false; 111 | } 112 | } 113 | 114 | public static String getAiApiKey() { 115 | try { 116 | if (main().getJSONObject("AI").getString("Api_Key") == null) { 117 | return ""; 118 | } 119 | return main().getJSONObject("AI").getString("Api_Key"); 120 | } catch (Exception e) { 121 | return ""; 122 | } 123 | } 124 | 125 | public static String getAiApiSecret() { 126 | try { 127 | if (main().getJSONObject("AI").getString("Api_Secret") == null) { 128 | return ""; 129 | } 130 | return main().getJSONObject("AI").getString("Api_Secret"); 131 | } catch (Exception e) { 132 | return ""; 133 | } 134 | } 135 | 136 | public static boolean getAutoFortune() { 137 | try { 138 | return main().getJSONObject("Auto").getBooleanValue("AutoFortune"); 139 | } catch (Exception e) { 140 | return false; 141 | } 142 | } 143 | 144 | public static boolean getAutoNews() { 145 | try { 146 | return main().getJSONObject("Auto").getBooleanValue("AutoNews"); 147 | } catch (Exception e) { 148 | return false; 149 | } 150 | } 151 | 152 | public static boolean getAutoTips() { 153 | try { 154 | return main().getJSONObject("Auto").getBooleanValue("AutoTips"); 155 | } catch (Exception e) { 156 | return false; 157 | } 158 | } 159 | 160 | public static JSONArray getGroup() { 161 | try { 162 | return main().getJSONObject("Auto").getJSONArray("Group"); 163 | } catch (Exception e) { 164 | return new JSONArray(); 165 | } 166 | } 167 | 168 | public static boolean getGroupManagement() { 169 | try { 170 | return main().getJSONObject("GroupManagement").getBooleanValue("Open"); 171 | } catch (Exception e) { 172 | return false; 173 | } 174 | } 175 | 176 | public static long getAdminQQ() { 177 | try { 178 | return main().getJSONObject("GroupManagement").getLongValue("AdminQQ"); 179 | } catch (Exception e) { 180 | return 0; 181 | } 182 | } 183 | 184 | public static String getMusicAPIURL() { 185 | try { 186 | if (main().getString("MusicAPIURL") == null) { 187 | return ""; 188 | } 189 | return main().getString("MusicAPIURL"); 190 | } catch (Exception e) { 191 | return ""; 192 | } 193 | } 194 | 195 | public static String getQYWXKEY() { 196 | try { 197 | if (main().getString("QYWXKEY") == null) { 198 | return ""; 199 | } 200 | return main().getString("QYWXKEY"); 201 | } catch (Exception e) { 202 | return ""; 203 | } 204 | } 205 | 206 | private static final String VERSION = "Version"; 207 | public static final String VERSION_NUM = "3.3"; 208 | 209 | public void getVersion() { 210 | boolean isUpdate = false; 211 | try { 212 | if (!main().getString(VERSION).equals(VERSION_NUM)) { 213 | isUpdate = true; 214 | } 215 | } catch (Exception e) { 216 | isUpdate = true; 217 | } finally { 218 | if (isUpdate) { 219 | Setting.getBot().getLogger().info("正在更新配置文件"); 220 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), getAgreeFriend(), getAgreeGroup(), getOldAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), ""); 221 | Setting.getBot().getLogger().info("更新配置文件成功"); 222 | } 223 | } 224 | 225 | } 226 | 227 | 228 | /** 229 | * 动态更新配置文件 230 | */ 231 | 232 | public static boolean updateConfig(boolean options, long value) { 233 | Setting.getBot().getLogger().info("正在更新配置文件"); 234 | JSONArray jsonArray = getGroup(); 235 | if (options) { 236 | for (int i = 0; i < jsonArray.size(); i++) { 237 | long longValue = jsonArray.getLongValue(i); 238 | if (longValue == value) { 239 | return false; 240 | } 241 | } 242 | jsonArray.set(jsonArray.size(), value); 243 | } else { 244 | for (int i = 0; i < jsonArray.size(); i++) { 245 | long longValue = jsonArray.getLongValue(i); 246 | if (longValue == value) { 247 | jsonArray.remove(i); 248 | } 249 | } 250 | } 251 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), 252 | getImageRecall(), getAgreeFriend(), getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), 253 | getAutoFortune(), getAutoNews(), getAutoTips(), jsonArray, getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 254 | return true; 255 | } 256 | 257 | public static boolean updateConfig(String options, boolean value) { 258 | Setting.getBot().getLogger().info("正在更新配置文件"); 259 | switch (options) { 260 | case "Friend": 261 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), value, getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 262 | return true; 263 | case "Group": 264 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), getAgreeFriend(), value, getAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 265 | return true; 266 | case "AI": 267 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), getAgreeFriend(), getAgreeGroup(), value, getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 268 | return true; 269 | case "Fortune": 270 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), getAgreeFriend(), getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), value, getAutoNews(), getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 271 | return true; 272 | case "News": 273 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), getAgreeFriend(), getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), value, getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 274 | return true; 275 | case "Tips": 276 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), getAgreeFriend(), getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), value, getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 277 | return true; 278 | case "GroupManagement": 279 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), getImageRecall(), getAgreeFriend(), getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), getAutoTips(), getGroup(), value, getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 280 | return true; 281 | default: 282 | Setting.getBot().getLogger().info("更新失败"); 283 | return false; 284 | } 285 | } 286 | 287 | public static boolean updateConfig(int options, int value) { 288 | try { 289 | switch (options) { 290 | case 1: 291 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), value, getImageRecall(), getAgreeFriend(), getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 292 | break; 293 | case 2: 294 | SetSetting.setFile(VERSION_NUM, getQq(), getAppId(), getApiKey(), getSecretKey(), getImageNum(), value, getAgreeFriend(), getAgreeGroup(), getAi(), getAiApiKey(), getAiApiSecret(), getAutoFortune(), getAutoNews(), getAutoTips(), getGroup(), getGroupManagement(), getAdminQQ(), getMusicAPIURL(), getQYWXKEY()); 295 | break; 296 | default: 297 | Setting.getBot().getLogger().info("更新失败"); 298 | return false; 299 | } 300 | return true; 301 | } catch (Exception e) { 302 | return false; 303 | } 304 | } 305 | 306 | public static JSONObject main() { 307 | String filePath = Utils.getPluginsPath() + "/setting.yml"; 308 | Yaml yaml = new Yaml(); 309 | Map map = null; 310 | try { 311 | FileInputStream fileInputStream = new FileInputStream(filePath); 312 | map = yaml.load(fileInputStream); 313 | fileInputStream.close(); 314 | } catch (IOException e) { 315 | e.printStackTrace(); 316 | } 317 | assert map != null; 318 | return new JSONObject(map); 319 | } 320 | 321 | } -------------------------------------------------------------------------------- /src/main/java/org/qbot/music/MusicMessageDeal.java: -------------------------------------------------------------------------------- 1 | package org.qbot.music; 2 | 3 | import com.alibaba.fastjson2.JSONObject; 4 | import net.mamoe.mirai.contact.Friend; 5 | import net.mamoe.mirai.message.MessageReceipt; 6 | import net.mamoe.mirai.message.data.Image; 7 | import net.mamoe.mirai.message.data.MessageChain; 8 | import net.mamoe.mirai.message.data.MessageChainBuilder; 9 | import net.mamoe.mirai.message.data.PlainText; 10 | import net.mamoe.mirai.utils.ExternalResource; 11 | import org.qbot.toolkit.Setting; 12 | import org.qbot.toolkit.Utils; 13 | 14 | import java.io.File; 15 | import java.io.IOException; 16 | 17 | /** 18 | * MusicMessageDeal class 19 | * 20 | * @author 649953543@qq.com 21 | * @date 2023/2/18 22 | */ 23 | public class MusicMessageDeal { 24 | 25 | NeteaseCloudMusicTask neteaseCloudMusicTask = new NeteaseCloudMusicTask(); 26 | Utils utils = new Utils(); 27 | private static final String STRING_LOGIN = "网易云登录"; 28 | private static final String STRING_SIGN = "网易云签到"; 29 | private static final String STRING_INFO = "我的网易云"; 30 | private static final String EXPIRED = "已过期"; 31 | private static final String STRING_START = "开始刷歌"; 32 | private static final String STRING_STOP = "停止刷歌"; 33 | private static final String STRING_STOP1 = "强制停止刷歌"; 34 | private static final String STRING_LOGIN_OUT = "退出登录"; 35 | 36 | public boolean msgDel(Friend frind, String msg) throws IOException, InterruptedException { 37 | Setting.getBot().getLogger().info("收到消息:" + msg); 38 | 39 | long senderId = frind.getId(); 40 | 41 | MessageChain chain; 42 | 43 | if (STRING_LOGIN.equals(msg)) { 44 | chain = new MessageChainBuilder().append(new PlainText("正在获取二维码,请稍后")).build(); 45 | MessageReceipt messageReceipts = frind.sendMessage(chain); 46 | String filename = Utils.getTime() + Utils.getRandomNum(0, 10000) + ".jpg"; 47 | try { 48 | String qrkey = neteaseCloudMusicTask.getQrKey(); 49 | String orCodeBase64 = neteaseCloudMusicTask.getQrCode(qrkey).replace("data:image/png;base64,", ""); 50 | utils.GenerateImage(orCodeBase64, filename); 51 | ExternalResource img = ExternalResource.create(new File(Utils.getPluginsDataPath() + "/cache/image/" + filename)); 52 | Image image = frind.uploadImage(img); 53 | img.close(); 54 | chain = new MessageChainBuilder().append(image).append(new PlainText("请在100秒内登录")).build(); 55 | messageReceipts.recall(); 56 | MessageReceipt messageReceipts1 = frind.sendMessage(chain); 57 | String cookie = neteaseCloudMusicTask.getCheckLogin(qrkey); 58 | if (cookie.contains(EXPIRED)) { 59 | chain = new MessageChainBuilder().append(new PlainText(cookie)).build(); 60 | frind.sendMessage(chain); 61 | } else { 62 | setFile(senderId, "Cookie", cookie); 63 | chain = new MessageChainBuilder().append(new PlainText("登录成功")).build(); 64 | frind.sendMessage(chain); 65 | setFile(senderId, "Name", neteaseCloudMusicTask.getUserInfo(cookie).getString("nickname")); 66 | setFile(senderId, "UserID", neteaseCloudMusicTask.getUserInfo(cookie).getString("userId")); 67 | setFile(senderId, "LastLoginDate", utils.getTime4()); 68 | chain = new MessageChainBuilder().append(new PlainText(getInfo(senderId))).build(); 69 | frind.sendMessage(chain); 70 | } 71 | messageReceipts1.recall(); 72 | } catch (Exception e) { 73 | chain = new MessageChainBuilder().append(new PlainText("获取失败,请重试")).build(); 74 | frind.sendMessage(chain); 75 | e.printStackTrace(); 76 | } 77 | return true; 78 | } 79 | 80 | if (STRING_SIGN.equals(msg)) { 81 | chain = new MessageChainBuilder().append(new PlainText("正在签到,请稍后")).build(); 82 | MessageReceipt messageReceipts = frind.sendMessage(chain); 83 | String cookie = getFile(senderId, "Cookie"); 84 | if (cookie == null || "".equals(cookie)) { 85 | chain = new MessageChainBuilder().append(new PlainText("请先登录")).build(); 86 | frind.sendMessage(chain); 87 | messageReceipts.recall(); 88 | return true; 89 | } 90 | chain = new MessageChainBuilder().append(new PlainText(neteaseCloudMusicTask.yunbeiSign(cookie))).build(); 91 | frind.sendMessage(chain); 92 | setFile(senderId, "Sign", "已签到"); 93 | messageReceipts.recall(); 94 | return true; 95 | } 96 | 97 | if (STRING_INFO.equals(msg)) { 98 | chain = new MessageChainBuilder().append(new PlainText(getInfo(senderId))).build(); 99 | frind.sendMessage(chain); 100 | return true; 101 | } 102 | 103 | 104 | if (STRING_START.equals(msg)) { 105 | chain = new MessageChainBuilder().append(new PlainText("正在启动刷歌,请稍后")).build(); 106 | MessageReceipt messageReceipts = frind.sendMessage(chain); 107 | String cookie = getFile(senderId, "Cookie"); 108 | if (cookie == null || "".equals(cookie)) { 109 | chain = new MessageChainBuilder().append(new PlainText("请先登录")).build(); 110 | frind.sendMessage(chain); 111 | messageReceipts.recall(); 112 | return true; 113 | } 114 | if ("已启动".equals(getFile(senderId, "Lock"))) { 115 | chain = new MessageChainBuilder().append(new PlainText("刷歌正在运行中,无需重新启动")).build(); 116 | frind.sendMessage(chain); 117 | messageReceipts.recall(); 118 | return true; 119 | } 120 | setFile(senderId, "Lock", "已启动"); 121 | if (!utils.getTime3().equals(getFile(senderId, "LastDate"))) { 122 | setFile(senderId, "NumberOfBrushes", "0"); 123 | } 124 | setFile(senderId, "LastDate", utils.getTime3()); 125 | chain = new MessageChainBuilder().append(new PlainText("刷歌已启动")).build(); 126 | frind.sendMessage(chain); 127 | messageReceipts.recall(); 128 | String txt; 129 | try { 130 | txt = neteaseCloudMusicTask.brushMusic(senderId, cookie, getFile(senderId, "UserID")); 131 | } catch (Exception e) { 132 | setFile(senderId, "Lock", "未启动"); 133 | setFile(senderId, "ExitTag", "false"); 134 | e.printStackTrace(); 135 | txt = "刷歌错误"; 136 | } 137 | chain = new MessageChainBuilder().append(new PlainText(txt)).build(); 138 | frind.sendMessage(chain); 139 | return true; 140 | } 141 | 142 | if (STRING_STOP.equals(msg)) { 143 | chain = new MessageChainBuilder().append(new PlainText("正在停止刷歌,请稍后")).build(); 144 | MessageReceipt messageReceipts = frind.sendMessage(chain); 145 | String cookie = getFile(senderId, "Cookie"); 146 | if (cookie == null || "".equals(cookie)) { 147 | chain = new MessageChainBuilder().append(new PlainText("请先登录")).build(); 148 | frind.sendMessage(chain); 149 | messageReceipts.recall(); 150 | return true; 151 | } 152 | if ("未启动".equals(getFile(senderId, "Lock"))) { 153 | chain = new MessageChainBuilder().append(new PlainText("刷歌未启动,无需停止")).build(); 154 | frind.sendMessage(chain); 155 | messageReceipts.recall(); 156 | return true; 157 | } 158 | setFile(senderId, "ExitTag", "true"); 159 | return true; 160 | } 161 | 162 | if (STRING_STOP1.equals(msg)) { 163 | chain = new MessageChainBuilder().append(new PlainText("正在强制停止刷歌,请稍后")).build(); 164 | MessageReceipt messageReceipts = frind.sendMessage(chain); 165 | String cookie = getFile(senderId, "Cookie"); 166 | if (cookie == null || "".equals(cookie)) { 167 | chain = new MessageChainBuilder().append(new PlainText("请先登录")).build(); 168 | frind.sendMessage(chain); 169 | messageReceipts.recall(); 170 | return true; 171 | } 172 | setFile(senderId, "Lock", "未启动"); 173 | setFile(senderId, "ExitTag", "false"); 174 | chain = new MessageChainBuilder().append(new PlainText("已停止")).build(); 175 | frind.sendMessage(chain); 176 | return true; 177 | } 178 | 179 | if (STRING_LOGIN_OUT.equals(msg)) { 180 | chain = new MessageChainBuilder().append(new PlainText("正在退出登录,请稍后")).build(); 181 | MessageReceipt messageReceipts = frind.sendMessage(chain); 182 | String cookie = getFile(senderId, "Cookie"); 183 | if (cookie == null || "".equals(cookie)) { 184 | chain = new MessageChainBuilder().append(new PlainText("请先登录")).build(); 185 | frind.sendMessage(chain); 186 | messageReceipts.recall(); 187 | return true; 188 | } 189 | setFile(senderId, "Cookie", ""); 190 | setFile(senderId, "Lock", "未启动"); 191 | setFile(senderId, "Sign", "未知"); 192 | setFile(senderId, "Name", "未知"); 193 | setFile(senderId, "LastDate", "未知"); 194 | setFile(senderId, "NumberOfBrushes", "0"); 195 | setFile(senderId, "UserID", "0"); 196 | setFile(senderId, "LastLoginDate", utils.getTime4()); 197 | setFile(senderId, "ExitTag", "false"); 198 | chain = new MessageChainBuilder().append(new PlainText("已退出登录")).build(); 199 | frind.sendMessage(chain); 200 | messageReceipts.recall(); 201 | return true; 202 | } 203 | 204 | return false; 205 | } 206 | 207 | 208 | /** 209 | * 设置缓存文件 210 | * 211 | * @return boolean 是否成功 212 | */ 213 | public static boolean setFile(long senderId, String key, String value) throws IOException { 214 | Utils utils1 = new Utils(); 215 | String filePath = Utils.getPluginsDataPath() + "/cache/music/" + senderId + ".txt"; 216 | File file = new File(filePath); 217 | JSONObject jsonObject = new JSONObject(); 218 | if (!file.exists()) { 219 | jsonObject.put("Cookie", ""); 220 | jsonObject.put("Lock", "未启动"); 221 | jsonObject.put("Sign", "未知"); 222 | jsonObject.put("Name", "未知"); 223 | jsonObject.put("LastDate", "未知"); 224 | jsonObject.put("NumberOfBrushes", "0"); 225 | jsonObject.put("UserID", "0"); 226 | jsonObject.put("LastLoginDate", utils1.getTime4()); 227 | jsonObject.put("ExitTag", "false"); 228 | jsonObject.put(key, value); 229 | } else { 230 | jsonObject = utils1.readFile(file); 231 | jsonObject.put(key, value); 232 | } 233 | return utils1.writeFile(file, jsonObject.toJSONString()); 234 | } 235 | 236 | /** 237 | * 获取缓存文件 238 | */ 239 | public static String getFile(long senderId, String key) { 240 | Utils utils1 = new Utils(); 241 | String filePath = Utils.getPluginsDataPath() + "/cache/music/" + senderId + ".txt"; 242 | File file = new File(filePath); 243 | if (file.exists()) { 244 | try { 245 | JSONObject jsonObject = utils1.readFile(file); 246 | return jsonObject.getString(key); 247 | } catch (IOException ignored) { 248 | } 249 | } 250 | return null; 251 | } 252 | 253 | /** 254 | * 获取个人信息 255 | */ 256 | public String getInfo(long senderId) throws IOException { 257 | String filePath = Utils.getPluginsDataPath() + "/cache/music/" + senderId + ".txt"; 258 | File file = new File(filePath); 259 | JSONObject jsonObject = utils.readFile(file); 260 | 261 | String sign = jsonObject.getString("Sign"); 262 | String numberOfBrushes = jsonObject.getString("NumberOfBrushes"); 263 | String lastDate = jsonObject.getString("LastDate"); 264 | String lock = jsonObject.getString("Lock"); 265 | if (!lastDate.equals(utils.getTime3())) { 266 | sign = "未签到"; 267 | numberOfBrushes = "0"; 268 | lock = "未启动"; 269 | setFile(senderId, "Sign", sign); 270 | setFile(senderId, "NumberOfBrushes", numberOfBrushes); 271 | setFile(senderId, "Lock", lock); 272 | setFile(senderId, "ExitTag", "false"); 273 | } 274 | 275 | return "昵称:" + jsonObject.getString("Name") + "\n" + 276 | "签到状态:" + sign + "\n" + 277 | "已刷歌次数:" + numberOfBrushes + "\n" + 278 | "上次刷歌时间:\n" + lastDate + "\n" + 279 | "刷歌状态:" + lock + "\n" + 280 | "上次登录时间:\n" + jsonObject.getString("LastLoginDate"); 281 | } 282 | 283 | } 284 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/msgdeal/AdminMessageDeal.java: -------------------------------------------------------------------------------- 1 | package org.qbot.msgdeal; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | import net.mamoe.mirai.Bot; 5 | import net.mamoe.mirai.contact.Friend; 6 | import net.mamoe.mirai.contact.Group; 7 | import net.mamoe.mirai.message.data.MessageChain; 8 | import net.mamoe.mirai.message.data.MessageChainBuilder; 9 | import net.mamoe.mirai.message.data.PlainText; 10 | import org.qbot.toolkit.Setting; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * AdminMessageDeal class 17 | * 18 | * @author 649953543@qq.com 19 | * @date 2022/7/27 20 | */ 21 | public class AdminMessageDeal { 22 | 23 | private static final String SET_IMAGE_NUM = "设置图片数量"; 24 | 25 | private static final String SET_RECALL_TIME = "设置撤回时间"; 26 | 27 | private static final String AGREE_TO_FRIEND_REQUEST = "开启同意好友请求"; 28 | 29 | private static final String DIS_AGREE_TO_FRIEND_REQUEST = "关闭同意好友请求"; 30 | 31 | private static final String AGREE_TO_THE_GROUP_REQUEST = "开启同意入群请求"; 32 | 33 | private static final String DIS_AGREE_TO_THE_GROUP_REQUEST = "关闭同意入群请求"; 34 | 35 | private static final String OPEN_AI = "开启聊天"; 36 | 37 | private static final String CLOSE_AI = "关闭聊天"; 38 | 39 | private static final String OPEN_SEND_FORTUNE = "开启发送运势"; 40 | 41 | private static final String CLOSE_SEND_FORTUNE = "关闭发送运势"; 42 | 43 | private static final String OPEN_SEND_NEWS = "开启发送新闻"; 44 | 45 | private static final String CLOSE_SEND_NEWS = "关闭发送新闻"; 46 | 47 | private static final String OPEN_SEND_FISH = "开启发送摸鱼办"; 48 | 49 | private static final String CLOSE_SEND_FISH = "关闭发送摸鱼办"; 50 | 51 | private static final String SET_GROUP = "设置发送消息群号"; 52 | 53 | private static final String DELETE_GROUP = "删除发送消息群号"; 54 | 55 | private static final String OPEN_GROUP_MANAGEMENT = "开启群管系统"; 56 | 57 | private static final String CLOSE_GROUP_MANAGEMENT = "关闭群管系统"; 58 | 59 | private static final String SEND_NOTIFICATION = "发送通知"; 60 | 61 | public static void msgDel(String msg, Friend frind) throws InterruptedException { 62 | 63 | if (msg.contains(SET_IMAGE_NUM)) { 64 | msg = msg.replace(SET_IMAGE_NUM, ""); 65 | msg = msg.replace(" ", ""); 66 | if (Setting.updateConfig(1, Integer.parseInt(msg))) { 67 | frind.sendMessage(new MessageChainBuilder() 68 | .append(new PlainText("设置成功")) 69 | .build()); 70 | } else { 71 | frind.sendMessage(new MessageChainBuilder() 72 | .append(new PlainText("设置失败")) 73 | .build()); 74 | } 75 | } 76 | 77 | if (msg.contains(SET_RECALL_TIME)) { 78 | msg = msg.replace(SET_RECALL_TIME, ""); 79 | msg = msg.replace(" ", ""); 80 | if (Setting.updateConfig(2, Integer.parseInt(msg))) { 81 | frind.sendMessage(new MessageChainBuilder() 82 | .append(new PlainText("设置成功")) 83 | .build()); 84 | } else { 85 | frind.sendMessage(new MessageChainBuilder() 86 | .append(new PlainText("设置失败")) 87 | .build()); 88 | } 89 | 90 | } 91 | 92 | if (msg.contains(AGREE_TO_FRIEND_REQUEST)) { 93 | if (Setting.updateConfig("Friend", true)) { 94 | frind.sendMessage(new MessageChainBuilder() 95 | .append(new PlainText("同意好友请求已开启")) 96 | .build()); 97 | } else { 98 | frind.sendMessage(new MessageChainBuilder() 99 | .append(new PlainText("同意好友请求开启失败")) 100 | .build()); 101 | } 102 | } 103 | if (msg.contains(DIS_AGREE_TO_FRIEND_REQUEST)) { 104 | if (Setting.updateConfig("Friend", false)) { 105 | frind.sendMessage(new MessageChainBuilder() 106 | .append(new PlainText("同意好友请求已关闭")) 107 | .build()); 108 | } else { 109 | frind.sendMessage(new MessageChainBuilder() 110 | .append(new PlainText("同意好友请求关闭失败")) 111 | .build()); 112 | } 113 | } 114 | if (msg.contains(AGREE_TO_THE_GROUP_REQUEST)) { 115 | if (Setting.updateConfig("Group", true)) { 116 | frind.sendMessage(new MessageChainBuilder() 117 | .append(new PlainText("同意入群请求已开启")) 118 | .build()); 119 | } else { 120 | frind.sendMessage(new MessageChainBuilder() 121 | .append(new PlainText("同意入群请求开启失败")) 122 | .build()); 123 | } 124 | } 125 | if (msg.contains(DIS_AGREE_TO_THE_GROUP_REQUEST)) { 126 | if (Setting.updateConfig("Group", false)) { 127 | frind.sendMessage(new MessageChainBuilder() 128 | .append(new PlainText("同意入群请求已关闭")) 129 | .build()); 130 | } else { 131 | frind.sendMessage(new MessageChainBuilder() 132 | .append(new PlainText("同意入群请求关闭失败")) 133 | .build()); 134 | } 135 | 136 | } 137 | if (msg.contains(OPEN_AI)) { 138 | if (Setting.updateConfig("AI", true)) { 139 | frind.sendMessage(new MessageChainBuilder() 140 | .append(new PlainText("聊天已开启")) 141 | .build()); 142 | } else { 143 | frind.sendMessage(new MessageChainBuilder() 144 | .append(new PlainText("聊天开启失败")) 145 | .build()); 146 | } 147 | 148 | } 149 | if (msg.contains(CLOSE_AI)) { 150 | if (Setting.updateConfig("AI", false)) { 151 | frind.sendMessage(new MessageChainBuilder() 152 | .append(new PlainText("聊天已关闭")) 153 | .build()); 154 | } else { 155 | frind.sendMessage(new MessageChainBuilder() 156 | .append(new PlainText("聊天关闭失败")) 157 | .build()); 158 | } 159 | 160 | } 161 | if (msg.contains(OPEN_SEND_FORTUNE)) { 162 | if (Setting.updateConfig("Fortune", true)) { 163 | frind.sendMessage(new MessageChainBuilder() 164 | .append(new PlainText("发送运势已开启")) 165 | .build()); 166 | } else { 167 | frind.sendMessage(new MessageChainBuilder() 168 | .append(new PlainText("发送运势开启失败")) 169 | .build()); 170 | } 171 | 172 | 173 | } 174 | if (msg.contains(CLOSE_SEND_FORTUNE)) { 175 | if (Setting.updateConfig("Fortune", false)) { 176 | frind.sendMessage(new MessageChainBuilder() 177 | .append(new PlainText("发送运势已关闭")) 178 | .build()); 179 | } else { 180 | frind.sendMessage(new MessageChainBuilder() 181 | .append(new PlainText("发送运势关闭失败")) 182 | .build()); 183 | } 184 | 185 | 186 | } 187 | if (msg.contains(OPEN_SEND_NEWS)) { 188 | if (Setting.updateConfig("News", true)) { 189 | frind.sendMessage(new MessageChainBuilder() 190 | .append(new PlainText("发送新闻已开启")) 191 | .build()); 192 | } else { 193 | frind.sendMessage(new MessageChainBuilder() 194 | .append(new PlainText("发送新闻开启失败")) 195 | .build()); 196 | } 197 | 198 | } 199 | if (msg.contains(CLOSE_SEND_NEWS)) { 200 | if (Setting.updateConfig("News", false)) { 201 | frind.sendMessage(new MessageChainBuilder() 202 | .append(new PlainText("发送新闻已关闭")) 203 | .build()); 204 | } else { 205 | frind.sendMessage(new MessageChainBuilder() 206 | .append(new PlainText("发送新闻关闭失败")) 207 | .build()); 208 | } 209 | 210 | 211 | } 212 | if (msg.contains(OPEN_SEND_FISH)) { 213 | if (Setting.updateConfig("Fish", true)) { 214 | frind.sendMessage(new MessageChainBuilder() 215 | .append(new PlainText("发送摸鱼办已开启")) 216 | .build()); 217 | } else { 218 | frind.sendMessage(new MessageChainBuilder() 219 | .append(new PlainText("发送摸鱼办开启失败")) 220 | .build()); 221 | } 222 | 223 | 224 | } 225 | if (msg.contains(CLOSE_SEND_FISH)) { 226 | if (Setting.updateConfig("Fish", false)) { 227 | frind.sendMessage(new MessageChainBuilder() 228 | .append(new PlainText("发送摸鱼办已关闭")) 229 | .build()); 230 | } else { 231 | frind.sendMessage(new MessageChainBuilder() 232 | .append(new PlainText("发送摸鱼办关闭失败")) 233 | .build()); 234 | } 235 | 236 | } 237 | if (msg.contains(SET_GROUP)) { 238 | msg = msg.replace(SET_GROUP, ""); 239 | msg = msg.replace(" ", ""); 240 | if (Setting.updateConfig(true, Long.parseLong(msg))) { 241 | frind.sendMessage(new MessageChainBuilder() 242 | .append(new PlainText("设置群组成功")) 243 | .build()); 244 | } else { 245 | frind.sendMessage(new MessageChainBuilder() 246 | .append(new PlainText("设置群组失败")) 247 | .build()); 248 | } 249 | } 250 | if (msg.contains(DELETE_GROUP)) { 251 | msg = msg.replace(DELETE_GROUP, ""); 252 | msg = msg.replace(" ", ""); 253 | if (Setting.updateConfig(false, Long.parseLong(msg))) { 254 | frind.sendMessage(new MessageChainBuilder() 255 | .append(new PlainText("删除群组成功")) 256 | .build()); 257 | } else { 258 | frind.sendMessage(new MessageChainBuilder() 259 | .append(new PlainText("删除群组失败")) 260 | .build()); 261 | } 262 | } 263 | if (msg.contains(OPEN_GROUP_MANAGEMENT)) { 264 | if (Setting.updateConfig("GroupManagement", true)) { 265 | frind.sendMessage(new MessageChainBuilder() 266 | .append(new PlainText("群组管理已开启")) 267 | .build()); 268 | } else { 269 | frind.sendMessage(new MessageChainBuilder() 270 | .append(new PlainText("群组管理开启失败")) 271 | .build()); 272 | } 273 | 274 | 275 | } 276 | if (msg.contains(CLOSE_GROUP_MANAGEMENT)) { 277 | if (Setting.updateConfig("GroupManagement", false)) { 278 | frind.sendMessage(new MessageChainBuilder() 279 | .append(new PlainText("群组管理已关闭")) 280 | .build()); 281 | } else { 282 | frind.sendMessage(new MessageChainBuilder() 283 | .append(new PlainText("群组管理关闭失败")) 284 | .build()); 285 | } 286 | } 287 | 288 | if (msg.contains(SEND_NOTIFICATION)) { 289 | Bot bot = Bot.getInstance(Setting.getQq()); 290 | msg = msg.replace(SEND_NOTIFICATION, ""); 291 | msg = msg.replace(" ", ""); 292 | JSONArray groupLists = Setting.getGroup(); 293 | int groupNum = groupLists.size(); 294 | int sendSuccess = 0; 295 | int sendFail = 0; 296 | ArrayList groupFailList = new ArrayList<>(); 297 | for (Object groupList : groupLists) { 298 | try { 299 | Group group = bot.getGroup(Long.parseLong(groupList.toString())); 300 | MessageChain chain = new MessageChainBuilder() 301 | .append(new PlainText("通知\n")) 302 | .append(new PlainText(msg)) 303 | .build(); 304 | assert group != null; 305 | group.sendMessage(chain); 306 | sendSuccess++; 307 | Thread.sleep(2500); 308 | } catch (Exception e) { 309 | groupFailList.add(Long.parseLong(groupList.toString())); 310 | sendFail++; 311 | } 312 | } 313 | StringBuilder groupFail = new StringBuilder("失败的群有:"); 314 | for (long groupId : groupFailList) { 315 | groupFail.append(groupId).append("、"); 316 | } 317 | if (sendFail == 0) { 318 | frind.sendMessage(new MessageChainBuilder() 319 | .append(new PlainText("发送完毕,共" + groupNum + "个群,发送成功:" + sendSuccess + "个,发送失败:" + sendFail + "个")) 320 | .build()); 321 | } else { 322 | frind.sendMessage(new MessageChainBuilder() 323 | .append(new PlainText("发送完毕,共" + groupNum + "个群,发送成功:" + sendSuccess + "个,发送失败:" + sendFail + "个\n")) 324 | .append(new PlainText(groupFail.toString())) 325 | .build()); 326 | } 327 | 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/group/GroupManagementSetting.java: -------------------------------------------------------------------------------- 1 | package org.qbot.group; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | import com.alibaba.fastjson2.JSONObject; 5 | import net.mamoe.mirai.contact.Group; 6 | import net.mamoe.mirai.message.data.MessageChain; 7 | import net.mamoe.mirai.message.data.MessageChainBuilder; 8 | import net.mamoe.mirai.message.data.PlainText; 9 | import org.qbot.toolkit.Utils; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.nio.file.Path; 14 | 15 | /** 16 | * GroupManagementUtil class 17 | * 18 | * @author 649953543@qq.com 19 | * @date 2022/4/6 20 | */ 21 | @SuppressWarnings("unchecked") 22 | public class GroupManagementSetting { 23 | final Utils utils = new Utils(); 24 | final Path dataFolderPath = Utils.getPluginsDataPath(); 25 | final File groupManagementDirectory = new File(dataFolderPath + "/groupManagement"); 26 | 27 | /** 28 | * 判断是否是管理员 29 | * 30 | * @param group 群对象 31 | * @return 管理员返回true,非管理员返回false 32 | */ 33 | public boolean authority(Group group) { 34 | if (group.getBotPermission().getLevel() == 0) { 35 | MessageChain chain = new MessageChainBuilder().append(new PlainText("当前不是管理员,无法使用此功能")).build(); 36 | group.sendMessage(chain); 37 | return true; 38 | } 39 | return false; 40 | } 41 | 42 | /** 43 | * 设置管理员 44 | * 45 | * @param group 群对象 46 | * @return 设置成功返回1,失败返回0、-1 47 | */ 48 | public int setAdmin(long group, long qq) throws IOException { 49 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 50 | if (!file.exists()) { 51 | creatEmptyTemplate(file); 52 | } 53 | JSONObject jsonObject = utils.readFile(file); 54 | JSONArray adminQq; 55 | try { 56 | adminQq = jsonObject.getJSONArray("AdminQQ"); 57 | } catch (Exception ignored) { 58 | adminQq = new JSONArray(); 59 | } 60 | for (int i = 0; i < adminQq.size(); i++) { 61 | if (adminQq.getLongValue(i) == qq) { 62 | return -1; 63 | } 64 | } 65 | adminQq.add(qq); 66 | jsonObject.put("AdminQQ", adminQq); 67 | if (utils.writeFile(file, jsonObject.toJSONString())) { 68 | return 1; 69 | } 70 | return 0; 71 | 72 | } 73 | 74 | /** 75 | * 删除管理员 76 | * 77 | * @param group 群对象 78 | * @param qq QQ号 79 | * @return 设置成功返回1,失败返回0、-1 80 | * @throws IOException IOException 81 | */ 82 | public int delAdmin(long group, long qq) throws IOException { 83 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 84 | if (!file.exists()) { 85 | creatEmptyTemplate(file); 86 | } 87 | JSONObject jsonObject = utils.readFile(file); 88 | JSONArray adminQq; 89 | try { 90 | adminQq = jsonObject.getJSONArray("AdminQQ"); 91 | } catch (Exception ignored) { 92 | adminQq = new JSONArray(); 93 | } 94 | for (int i = 0; i < adminQq.size(); i++) { 95 | if (adminQq.getLongValue(i) == qq) { 96 | adminQq.remove(i); 97 | jsonObject.put("AdminQQ", adminQq); 98 | if (utils.writeFile(file, jsonObject.toJSONString())) { 99 | return 1; 100 | } 101 | return 0; 102 | } 103 | } 104 | return -1; 105 | } 106 | 107 | /** 108 | * 设置禁言关键字 109 | * 110 | * @param group 群对象 111 | * @param keywords 关键字 112 | * @return 设置成功返回1,失败返回0、-1 113 | */ 114 | public int setMuteKeywords(long group, String keywords) throws IOException { 115 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 116 | if (!file.exists()) { 117 | creatEmptyTemplate(file); 118 | } 119 | JSONObject jsonObject = utils.readFile(file); 120 | JSONArray muteKeywords; 121 | try { 122 | muteKeywords = jsonObject.getJSONArray("MuteKeywords"); 123 | } catch (Exception ignored) { 124 | muteKeywords = new JSONArray(); 125 | } 126 | for (int i = 0; i < muteKeywords.size(); i++) { 127 | if (muteKeywords.getString(i).equals(keywords)) { 128 | return -1; 129 | } 130 | } 131 | muteKeywords.add(keywords); 132 | jsonObject.put("MuteKeywords", muteKeywords); 133 | if (utils.writeFile(file, jsonObject.toJSONString())) { 134 | return 1; 135 | } 136 | return 0; 137 | } 138 | 139 | /** 140 | * 删除禁言关键字 141 | * 142 | * @param group 群对象 143 | * @param keywords 关键字 144 | * @return 设置成功返回1,失败返回0、-1 145 | */ 146 | public int delMuteKeywords(long group, String keywords) throws IOException { 147 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 148 | if (!file.exists()) { 149 | creatEmptyTemplate(file); 150 | } 151 | JSONObject jsonObject = utils.readFile(file); 152 | JSONArray muteKeywords; 153 | try { 154 | muteKeywords = jsonObject.getJSONArray("MuteKeywords"); 155 | } catch (Exception ignored) { 156 | muteKeywords = new JSONArray(); 157 | } 158 | for (int i = 0; i < muteKeywords.size(); i++) { 159 | if (muteKeywords.getString(i).equals(keywords)) { 160 | muteKeywords.remove(i); 161 | jsonObject.put("MuteKeywords", muteKeywords); 162 | if (utils.writeFile(file, jsonObject.toJSONString())) { 163 | return 1; 164 | } 165 | return 0; 166 | } 167 | } 168 | return -1; 169 | } 170 | 171 | /** 172 | * 清空禁言关键字 173 | * 174 | * @param group 群对象 175 | * @return 设置成功返回1,失败返回0、-1 176 | */ 177 | public int delAllMuteKeywords(long group) throws IOException { 178 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 179 | if (!file.exists()) { 180 | creatEmptyTemplate(file); 181 | } 182 | JSONObject jsonObject = utils.readFile(file); 183 | jsonObject.put("MuteKeywords", new JSONArray()); 184 | if (utils.writeFile(file, jsonObject.toJSONString())) { 185 | return 1; 186 | } 187 | return 0; 188 | } 189 | 190 | private static final int MUTE_TIME = 43200; 191 | 192 | /** 193 | * 设置禁言时间 194 | * 195 | * @param group 群对象 196 | * @param min 分钟 197 | * @return 设置成功返回1,失败返回0、-1 198 | */ 199 | public int setMuteTime(long group, int min) throws IOException { 200 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 201 | if (!file.exists()) { 202 | creatEmptyTemplate(file); 203 | } 204 | if (min > MUTE_TIME) { 205 | return -1; 206 | } 207 | JSONObject jsonObject = utils.readFile(file); 208 | jsonObject.put("MuteTime", min); 209 | if (utils.writeFile(file, jsonObject.toJSONString())) { 210 | return 1; 211 | } 212 | return 0; 213 | } 214 | 215 | /** 216 | * 设置撤回关键字 217 | * 218 | * @param group 群对象 219 | * @param keywords 关键字 220 | * @return 设置成功返回1,失败返回0、-1 221 | */ 222 | public int setRecallWords(long group, String keywords) throws IOException { 223 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 224 | if (!file.exists()) { 225 | creatEmptyTemplate(file); 226 | } 227 | JSONObject jsonObject = utils.readFile(file); 228 | JSONArray recallWords; 229 | try { 230 | recallWords = jsonObject.getJSONArray("RecallKeywords"); 231 | } catch (Exception ignored) { 232 | recallWords = new JSONArray(); 233 | } 234 | for (int i = 0; i < recallWords.size(); i++) { 235 | if (recallWords.getString(i).equals(keywords)) { 236 | return -1; 237 | } 238 | } 239 | recallWords.add(keywords); 240 | jsonObject.put("RecallKeywords", recallWords); 241 | if (utils.writeFile(file, jsonObject.toJSONString())) { 242 | return 1; 243 | } 244 | return 0; 245 | } 246 | 247 | /** 248 | * 删除撤回关键字 249 | * 250 | * @param group 群对象 251 | * @param keywords 关键字 252 | * @return 设置成功返回1,失败返回0、-1 253 | */ 254 | public int delRecallWords(long group, String keywords) throws IOException { 255 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 256 | if (!file.exists()) { 257 | creatEmptyTemplate(file); 258 | } 259 | JSONObject jsonObject = utils.readFile(file); 260 | JSONArray recallWords; 261 | try { 262 | recallWords = jsonObject.getJSONArray("RecallKeywords"); 263 | } catch (Exception ignored) { 264 | recallWords = new JSONArray(); 265 | } 266 | for (int i = 0; i < recallWords.size(); i++) { 267 | if (recallWords.getString(i).equals(keywords)) { 268 | recallWords.remove(i); 269 | jsonObject.put("RecallKeywords", recallWords); 270 | if (utils.writeFile(file, jsonObject.toJSONString())) { 271 | return 1; 272 | } 273 | return 0; 274 | } 275 | } 276 | return -1; 277 | } 278 | 279 | /** 280 | * 清空撤回关键字 281 | * 282 | * @param group 群对象 283 | * @return 设置成功返回1,失败返回0、-1 284 | */ 285 | public int delAllRecallWords(long group) throws IOException { 286 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 287 | if (!file.exists()) { 288 | creatEmptyTemplate(file); 289 | } 290 | JSONObject jsonObject = utils.readFile(file); 291 | jsonObject.put("RecallKeywords", new JSONArray()); 292 | if (utils.writeFile(file, jsonObject.toJSONString())) { 293 | return 1; 294 | } 295 | return 0; 296 | } 297 | 298 | /** 299 | * 设置自动同意群申请 300 | * 301 | * @param group 群对象 302 | * @return 设置成功返回1,失败返回0、-1 303 | */ 304 | public int setAutoAgreeApplication(long group) throws IOException { 305 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 306 | if (!file.exists()) { 307 | creatEmptyTemplate(file); 308 | } 309 | JSONObject jsonObject = utils.readFile(file); 310 | jsonObject.put("AutoAgreeApplication", true); 311 | if (utils.writeFile(file, jsonObject.toJSONString())) { 312 | return 1; 313 | } 314 | return 0; 315 | } 316 | 317 | /** 318 | * 关闭自动同意群申请 319 | * 320 | * @param group 群对象 321 | * @return 设置成功返回1,失败返回0、-1 322 | */ 323 | public int delAutoAgreeApplication(long group) throws IOException { 324 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 325 | if (!file.exists()) { 326 | creatEmptyTemplate(file); 327 | } 328 | JSONObject jsonObject = utils.readFile(file); 329 | jsonObject.put("AutoAgreeApplication", false); 330 | if (utils.writeFile(file, jsonObject.toJSONString())) { 331 | return 1; 332 | } 333 | return 0; 334 | } 335 | 336 | /** 337 | * 设置自动同意关键字 338 | * 339 | * @param group 群对象 340 | * @param keywords 关键字 341 | * @return 设置成功返回1,失败返回0、-1 342 | */ 343 | public int setAutoAgreeKeyWords(long group, String keywords) throws IOException { 344 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 345 | if (!file.exists()) { 346 | creatEmptyTemplate(file); 347 | } 348 | JSONObject jsonObject = utils.readFile(file); 349 | JSONArray autoAgreeKeyWords; 350 | try { 351 | autoAgreeKeyWords = jsonObject.getJSONArray("AgreeKeywords"); 352 | } catch (Exception ignored) { 353 | autoAgreeKeyWords = new JSONArray(); 354 | } 355 | for (int i = 0; i < autoAgreeKeyWords.size(); i++) { 356 | if (autoAgreeKeyWords.getString(i).equals(keywords)) { 357 | return -1; 358 | } 359 | } 360 | autoAgreeKeyWords.add(keywords); 361 | jsonObject.put("AgreeKeywords", autoAgreeKeyWords); 362 | if (utils.writeFile(file, jsonObject.toJSONString())) { 363 | return 1; 364 | } 365 | return 0; 366 | } 367 | 368 | /** 369 | * 删除自动同意关键字 370 | * 371 | * @param group 群对象 372 | * @param keywords 关键字 373 | * @return 设置成功返回1,失败返回0、-1 374 | */ 375 | public int delAutoAgreeKeyWords(long group, String keywords) throws IOException { 376 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 377 | if (!file.exists()) { 378 | creatEmptyTemplate(file); 379 | } 380 | JSONObject jsonObject = utils.readFile(file); 381 | JSONArray autoAgreeKeyWords; 382 | try { 383 | autoAgreeKeyWords = jsonObject.getJSONArray("AgreeKeywords"); 384 | } catch (Exception ignored) { 385 | autoAgreeKeyWords = new JSONArray(); 386 | } 387 | for (int i = 0; i < autoAgreeKeyWords.size(); i++) { 388 | if (autoAgreeKeyWords.getString(i).equals(keywords)) { 389 | autoAgreeKeyWords.remove(i); 390 | jsonObject.put("AgreeKeywords", autoAgreeKeyWords); 391 | if (utils.writeFile(file, jsonObject.toJSONString())) { 392 | return 1; 393 | } 394 | return 0; 395 | } 396 | } 397 | return -1; 398 | } 399 | 400 | 401 | public int delAllAutoAgreeKeyWords(long group) throws IOException { 402 | File file = new File(groupManagementDirectory + "/" + group + ".txt"); 403 | if (!file.exists()) { 404 | creatEmptyTemplate(file); 405 | } 406 | JSONObject jsonObject = utils.readFile(file); 407 | jsonObject.put("AgreeKeywords", new JSONArray()); 408 | if (utils.writeFile(file, jsonObject.toJSONString())) { 409 | return 1; 410 | } 411 | return 0; 412 | } 413 | 414 | /** 415 | * 创建空白模板 416 | * 417 | * @param file 文件对象 418 | */ 419 | public void creatEmptyTemplate(File file) { 420 | JSONObject jsonObject = new JSONObject(); 421 | jsonObject.put("AdminQQ", new JSONArray()); 422 | jsonObject.put("MuteKeywords", new JSONArray()); 423 | jsonObject.put("MuteTime", 0); 424 | jsonObject.put("RecallKeywords", new JSONArray()); 425 | jsonObject.put("AutoAgreeApplication", false); 426 | jsonObject.put("AgreeKeywords", new JSONArray()); 427 | jsonObject.put("RejectKeywords", new JSONArray()); 428 | jsonObject.put("WarnKeywords", new JSONArray()); 429 | utils.writeFile(file, jsonObject.toJSONString()); 430 | } 431 | 432 | 433 | } 434 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/music/NeteaseCloudMusicTask.java: -------------------------------------------------------------------------------- 1 | package org.qbot.music; 2 | 3 | import com.alibaba.fastjson2.JSONArray; 4 | import com.alibaba.fastjson2.JSONObject; 5 | import org.qbot.toolkit.Setting; 6 | import org.qbot.toolkit.Utils; 7 | 8 | import java.io.IOException; 9 | import java.util.HashSet; 10 | import java.util.Objects; 11 | import java.util.Set; 12 | 13 | /** 14 | * NeteaseCloudMusicTask class 15 | * 16 | * @author 649953543@qq.com 17 | * @date 2023/2/18 18 | */ 19 | public class NeteaseCloudMusicTask { 20 | private final Utils utils = new Utils(); 21 | 22 | private final String baseUrl = Setting.getMusicAPIURL(); 23 | 24 | private String _csrf = ""; 25 | 26 | private String MUSIC_U = ""; 27 | 28 | private String musicCookie = ""; 29 | 30 | /** 31 | * 超时时间 32 | */ 33 | private final int TIMEOUT = 100; 34 | 35 | /** 36 | * 听歌次数 37 | */ 38 | private final int LISTEN_COUNT = 350; 39 | 40 | /** 41 | * 成功状态码 42 | */ 43 | private final int SUCCESS_CODE = 200; 44 | 45 | /** 46 | * 获取二维码key 47 | */ 48 | public String getQrKey() { 49 | return JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/login/qr/key?timerstamp=" + System.currentTimeMillis(), "")).getJSONObject("data").getString("unikey"); 50 | } 51 | 52 | /** 53 | * 生成二维码 54 | */ 55 | public String getQrCode(String qrKey) { 56 | return JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/login/qr/create?key=" + qrKey + "&qrimg=true&timerstamp=" + System.currentTimeMillis(), "")).getJSONObject("data").getString("qrimg"); 57 | } 58 | 59 | /** 60 | * 获取登录状态 61 | */ 62 | public String getCheckLogin(String qrKey) { 63 | try { 64 | for (int i = 0; i < TIMEOUT; i++) { 65 | JSONObject jsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/login/qr/check?key=" + qrKey + "&timerstamp=" + System.currentTimeMillis(), "")); 66 | int code = jsonObject.getIntValue("code"); 67 | Setting.getBot().getLogger().info(String.valueOf(jsonObject)); 68 | if (code != 801) { 69 | if (code == 803) { 70 | String cookie = jsonObject.getString("cookie"); 71 | _csrf = cookie.substring(cookie.indexOf("_csrf=") + 6, cookie.indexOf(";", cookie.indexOf("_csrf=") + 6)); 72 | MUSIC_U = cookie.substring(cookie.indexOf("MUSIC_U=") + 8, cookie.indexOf(";", cookie.indexOf("MUSIC_U=") + 8)); 73 | musicCookie = "__csrf=" + _csrf + "; MUSIC_U=" + MUSIC_U; 74 | return musicCookie; 75 | } 76 | if (code == 800) { 77 | return jsonObject.getString("message"); 78 | } 79 | if (code == 802) { 80 | continue; 81 | } 82 | break; 83 | } 84 | Thread.sleep(1000); 85 | } 86 | } catch (Exception e) { 87 | Setting.getBot().getLogger().info(e); 88 | } 89 | return "已过期请重新获取1"; 90 | } 91 | 92 | /** 93 | * 获取我喜欢列表 94 | * 95 | * @param cookie 96 | * @return 97 | */ 98 | public JSONArray getLikeList(String cookie) { 99 | String url = baseUrl + "/likelist?timerstamp=" + System.currentTimeMillis(); 100 | JSONObject jsonresult = JSONObject.parseObject(utils.okHttpClientGetMusic(url, cookie)); 101 | if (jsonresult.getInteger("code") == SUCCESS_CODE) { 102 | return jsonresult.getJSONArray("ids"); 103 | } 104 | return null; 105 | } 106 | 107 | /** 108 | * 获取歌单ID 109 | */ 110 | public String getPlaylistId(String cookie, String userId) { 111 | String url = baseUrl + "/user/playlist?uid=" + userId + "&timerstamp=" + System.currentTimeMillis(); 112 | JSONObject jsonresult = JSONObject.parseObject(utils.okHttpClientGetMusic(url, cookie)); 113 | if (jsonresult.getInteger("code") == SUCCESS_CODE) { 114 | return jsonresult.getJSONArray("playlist").getJSONObject(0).getString("id"); 115 | } 116 | return null; 117 | } 118 | 119 | /** 120 | * 获取歌单歌曲ID 121 | */ 122 | public String getPlaylistSongId(String cookie, String Id) { 123 | String url = baseUrl + "/playlist/track/all?id=" + Id + "&limit=10&offset=0&timerstamp=" + System.currentTimeMillis(); 124 | JSONObject jsonresult = JSONObject.parseObject(utils.okHttpClientGetMusic(url, cookie)); 125 | if (jsonresult.getInteger("code") == SUCCESS_CODE) { 126 | return jsonresult.getJSONArray("privileges").getJSONObject(0).getString("id"); 127 | } 128 | return null; 129 | } 130 | 131 | /** 132 | * 获取心动模式歌曲 133 | */ 134 | public JSONArray getIntelligenceList(String cookie, String SongId, String ListId) { 135 | String url = baseUrl + "/playmode/intelligence/list?id=" + SongId + "&pid=" + ListId + "&timerstamp=" + System.currentTimeMillis(); 136 | JSONObject jsonresult = JSONObject.parseObject(utils.okHttpClientGetMusic(url, cookie)); 137 | if (jsonresult.getInteger("code") == SUCCESS_CODE) { 138 | return jsonresult.getJSONArray("data"); 139 | } 140 | return null; 141 | } 142 | 143 | 144 | /** 145 | * 刷音乐 146 | * 147 | * @param cookie 148 | * @return 149 | */ 150 | public String brushMusic(long senderId, String cookie, String userId) throws InterruptedException, IOException { 151 | String likeListId = getPlaylistId(cookie, userId); 152 | if (likeListId == null) { 153 | MusicMessageDeal.setFile(senderId, "ExitTag", "false"); 154 | MusicMessageDeal.setFile(senderId, "Lock", "未启动"); 155 | return "获取歌单ID失败"; 156 | } else { 157 | Setting.getBot().getLogger().info("QQ:" + senderId + "----获取歌单ID成功:" + likeListId); 158 | } 159 | String songId1 = getPlaylistSongId(cookie, likeListId); 160 | if (songId1 == null) { 161 | MusicMessageDeal.setFile(senderId, "ExitTag", "false"); 162 | MusicMessageDeal.setFile(senderId, "Lock", "未启动"); 163 | return "获取歌曲ID失败"; 164 | } else { 165 | Setting.getBot().getLogger().info("QQ:" + senderId + "----获取歌曲ID成功:" + songId1); 166 | } 167 | JSONArray likeListArray = getIntelligenceList(cookie, songId1, likeListId); 168 | if (likeListArray == null) { 169 | MusicMessageDeal.setFile(senderId, "ExitTag", "false"); 170 | MusicMessageDeal.setFile(senderId, "Lock", "未启动"); 171 | return "获取心动模式歌曲失败"; 172 | } else { 173 | Setting.getBot().getLogger().info("QQ:" + senderId + "----获取心动模式歌曲成功,歌曲数:" + likeListArray.size()); 174 | } 175 | Set count = new HashSet<>(); 176 | int tag = 0; 177 | Setting.getBot().getLogger().info("QQ:" + senderId + "----刷歌次数:" + LISTEN_COUNT); 178 | int num = Integer.parseInt(Objects.requireNonNull(MusicMessageDeal.getFile(senderId, "NumberOfBrushes"))); 179 | while (count.size() < LISTEN_COUNT) { 180 | String songId = songId1; 181 | for (int i = 0; i < likeListArray.size(); i++) { 182 | if (Objects.equals(MusicMessageDeal.getFile(senderId, "ExitTag"), "true")) { 183 | MusicMessageDeal.setFile(senderId, "NumberOfBrushes", String.valueOf((num + count.size()))); 184 | MusicMessageDeal.setFile(senderId, "ExitTag", "false"); 185 | MusicMessageDeal.setFile(senderId, "Lock", "未启动"); 186 | return "刷歌完成:共刷歌" + count.size() + "首"; 187 | } 188 | songId = likeListArray.getJSONObject(i).getString("id"); 189 | JSONObject result = listenMusic(cookie, songId); 190 | try { 191 | if ("success".equals(result.getString("data"))) { 192 | count.add(songId); 193 | if (count.size() > LISTEN_COUNT) { 194 | break; 195 | } 196 | MusicMessageDeal.setFile(senderId, "NumberOfBrushes", String.valueOf((num + count.size()))); 197 | } 198 | } catch (Exception ignored) { 199 | } 200 | Setting.getBot().getLogger().info("QQ:" + senderId + "----第" + count.size() + "首----歌曲ID:" + songId + "----结果:" + result); 201 | Thread.sleep(Utils.getRandomNum(1000, 10000)); 202 | //防止死循环 203 | if (tag > LISTEN_COUNT * 2) { 204 | MusicMessageDeal.setFile(senderId, "ExitTag", "false"); 205 | MusicMessageDeal.setFile(senderId, "Lock", "未启动"); 206 | return "刷歌完成:共刷歌" + count.size() + "首"; 207 | } 208 | tag++; 209 | } 210 | likeListArray = getIntelligenceList(cookie, songId, likeListId); 211 | if (likeListArray == null) { 212 | MusicMessageDeal.setFile(senderId, "ExitTag", "false"); 213 | MusicMessageDeal.setFile(senderId, "Lock", "未启动"); 214 | return "更新心动模式歌曲失败,刷歌完成:共刷歌" + count.size() + "首"; 215 | } else { 216 | Setting.getBot().getLogger().info("QQ:" + senderId + "----更新心动模式歌曲成功,歌曲数:" + likeListArray.size()); 217 | } 218 | } 219 | MusicMessageDeal.setFile(senderId, "ExitTag", "false"); 220 | MusicMessageDeal.setFile(senderId, "Lock", "未启动"); 221 | return "刷歌完成:共刷歌" + count.size() + "首"; 222 | } 223 | 224 | /** 225 | * 听歌打卡 226 | */ 227 | public JSONObject listenMusic(String cookie, String songId) { 228 | int songTime = getSongDetailTime(cookie, songId) - 5; 229 | if (songTime != 0) { 230 | try { 231 | return JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/scrobble?id=" + songId + "&time=" + songTime, cookie)); 232 | } catch (Exception ignored) { 233 | } 234 | } 235 | return null; 236 | } 237 | 238 | /** 239 | * 获取歌曲时长 240 | */ 241 | public int getSongDetailTime(String cookie, String songId) { 242 | try { 243 | JSONObject jsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/song/detail?ids=" + songId, cookie)).getJSONArray("songs").getJSONObject(0); 244 | Setting.getBot().getLogger().info("歌曲ID:" + songId + "--歌曲名:" + jsonObject.getString("name") + "--时长:" + jsonObject.getInteger("dt") / 1000); 245 | return jsonObject.getInteger("dt") / 1000; 246 | } catch (Exception e) { 247 | Setting.getBot().getLogger().info("歌曲ID:" + songId + "--获取歌曲时长失败"); 248 | return 5; 249 | } 250 | } 251 | 252 | 253 | /** 254 | * 签到 255 | */ 256 | public String sign(String cookie) { 257 | try { 258 | //手机签到 259 | JSONObject phoneJsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/daily_signin?type=0", cookie)); 260 | String msg; 261 | if (phoneJsonObject.getInteger("code") == SUCCESS_CODE) { 262 | msg = "手机签到成功,获得积分:" + phoneJsonObject.getInteger("point") + "\n"; 263 | } else { 264 | msg = "手机签到失败:" + phoneJsonObject.getString("msg") + "\n"; 265 | } 266 | //PC签到 267 | JSONObject pCJsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/daily_signin?type=1", cookie)); 268 | if (pCJsonObject.getInteger("code") == SUCCESS_CODE) { 269 | msg += "PC签到成功,获得积分:" + pCJsonObject.getInteger("point"); 270 | } else { 271 | msg += "PC签到失败:" + pCJsonObject.getString("msg"); 272 | } 273 | Setting.getBot().getLogger().info(msg); 274 | return msg; 275 | } catch (Exception e) { 276 | return "签到失败"; 277 | } 278 | } 279 | 280 | /** 281 | * 云贝签到 282 | */ 283 | public String yunbeiSign(String cookie) { 284 | try { 285 | JSONObject jsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/yunbei/sign?timerstamp=" + System.currentTimeMillis(), cookie)); 286 | String msg; 287 | if (jsonObject.getInteger("code") == SUCCESS_CODE) { 288 | msg = "云贝签到成功,获得云贝:" + jsonObject.getInteger("point"); 289 | } else { 290 | msg = "云贝签到失败:" + jsonObject.getString("msg"); 291 | } 292 | Setting.getBot().getLogger().info(msg); 293 | return msg; 294 | } catch (Exception e) { 295 | return "云贝签到失败"; 296 | } 297 | } 298 | 299 | /** 300 | * 领取云贝 301 | */ 302 | public void yunbeiGet(String cookie) { 303 | JSONObject jsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/yunbei/get?timerstamp=" + System.currentTimeMillis(), cookie)); 304 | if (jsonObject.getInteger("code") == SUCCESS_CODE) { 305 | Setting.getBot().getLogger().info("领取云贝成功,获得云贝:" + jsonObject.getJSONObject("data").getInteger("point")); 306 | } else { 307 | Setting.getBot().getLogger().info("领取云贝失败:" + jsonObject.getString("msg")); 308 | } 309 | 310 | } 311 | 312 | /** 313 | * 完成云贝任务 314 | */ 315 | public void yunbeiTask(String cookie) { 316 | JSONObject jsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/yunbei/task?timerstamp=" + System.currentTimeMillis(), cookie)); 317 | if (jsonObject.getInteger("code") == SUCCESS_CODE) { 318 | Setting.getBot().getLogger().info("完成云贝任务成功,获得云贝:" + jsonObject.getJSONObject("data").getInteger("point")); 319 | } else { 320 | Setting.getBot().getLogger().info("完成云贝任务失败:" + jsonObject.getString("msg")); 321 | } 322 | } 323 | 324 | /** 325 | * 云贝推歌 326 | */ 327 | public void yunbeiPush(String cookie, String songId) { 328 | JSONObject jsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/yunbei/rcmd/song?id=" + songId, cookie)); 329 | if (jsonObject.getInteger("code") == SUCCESS_CODE) { 330 | Setting.getBot().getLogger().info("云贝推歌成功"); 331 | } else { 332 | Setting.getBot().getLogger().info("云贝推歌失败:" + jsonObject.getString("message")); 333 | } 334 | } 335 | 336 | /** 337 | * 获取用户信息 338 | */ 339 | public JSONObject getUserInfo(String cookie) { 340 | JSONObject jsonObject = JSONObject.parseObject(utils.okHttpClientGetMusic(baseUrl + "/user/account?timerstamp=" + System.currentTimeMillis(), cookie)); 341 | if (jsonObject.getInteger("code") == SUCCESS_CODE) { 342 | String nickname = jsonObject.getJSONObject("profile").getString("nickname"); 343 | String userid = jsonObject.getJSONObject("profile").getString("userId"); 344 | Setting.getBot().getLogger().info("用户信息:用户名:" + nickname + " 用户ID:" + userid); 345 | jsonObject.put("nickname", nickname); 346 | jsonObject.put("userId", userid); 347 | return jsonObject; 348 | } else { 349 | Setting.getBot().getLogger().info("获取用户信息失败:" + jsonObject.getString("msg")); 350 | } 351 | return null; 352 | } 353 | } 354 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/group/GroupManagement.java: -------------------------------------------------------------------------------- 1 | package org.qbot.group; 2 | 3 | import net.mamoe.mirai.contact.Group; 4 | import net.mamoe.mirai.message.data.At; 5 | import net.mamoe.mirai.message.data.MessageChain; 6 | import net.mamoe.mirai.message.data.MessageChainBuilder; 7 | import net.mamoe.mirai.message.data.PlainText; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * GroupManagement class 13 | * 14 | * @author 649953543@qq.com 15 | * @date 2021/11/26 16 | */ 17 | @SuppressWarnings({"ALL", "AlibabaMethodTooLong"}) 18 | public class GroupManagement { 19 | 20 | GroupManagementSetting GroupManagementSetting = new GroupManagementSetting(); 21 | 22 | @SuppressWarnings("AlibabaMethodTooLong") 23 | public boolean msgDel(Group group, String msg, boolean superAdmin) throws IOException { 24 | MessageChain chain; 25 | String setGroupManagement = "设置本群管理"; 26 | long groupId = group.getId(); 27 | if (msg.contains(setGroupManagement)) { 28 | if (GroupManagementSetting.authority(group)) { 29 | return true; 30 | } 31 | if (!superAdmin) { 32 | return false; 33 | } 34 | long setQQ = newMsg(setGroupManagement, msg); 35 | if (GroupManagementSetting.setAdmin(groupId, setQQ) == 1) { 36 | chain = new MessageChainBuilder() 37 | .append(new PlainText("设置成功")) 38 | .build(); 39 | } else if (GroupManagementSetting.setAdmin(groupId, setQQ) == -1) { 40 | chain = new MessageChainBuilder() 41 | .append(new At(setQQ)) 42 | .append(new PlainText("已经是管理员了")) 43 | .build(); 44 | } else { 45 | chain = new MessageChainBuilder() 46 | .append(new PlainText("设置失败")) 47 | .build(); 48 | } 49 | group.sendMessage(chain); 50 | return true; 51 | } 52 | 53 | String delGroupManagement = "取消本群管理"; 54 | if (msg.contains(delGroupManagement)) { 55 | if (GroupManagementSetting.authority(group)) { 56 | return true; 57 | } 58 | if (!superAdmin) { 59 | return false; 60 | } 61 | long delQQ = newMsg(delGroupManagement, msg); 62 | if (GroupManagementSetting.delAdmin(groupId, delQQ) == 1) { 63 | chain = new MessageChainBuilder() 64 | .append(new PlainText("取消成功")) 65 | .build(); 66 | 67 | } else if (GroupManagementSetting.delAdmin(groupId, delQQ) == -1) { 68 | chain = new MessageChainBuilder() 69 | .append(new At(delQQ)) 70 | .append(new PlainText("已经不是管理员了")) 71 | .build(); 72 | } else { 73 | chain = new MessageChainBuilder() 74 | .append(new PlainText("取消失败")) 75 | .build(); 76 | } 77 | group.sendMessage(chain); 78 | return true; 79 | } 80 | 81 | String setMuteKeywords = "设置禁言关键字"; 82 | if (msg.contains(setMuteKeywords)) { 83 | if (GroupManagementSetting.authority(group)) { 84 | return true; 85 | } 86 | msg = msg.replace(setMuteKeywords, ""); 87 | String setMuteKeywordsStr = msg.replace(" ", ""); 88 | if (GroupManagementSetting.setMuteKeywords(groupId, setMuteKeywordsStr) == 1) { 89 | chain = new MessageChainBuilder() 90 | .append(new PlainText("设置成功")) 91 | .build(); 92 | } else if (GroupManagementSetting.setMuteKeywords(groupId, setMuteKeywordsStr) == -1) { 93 | chain = new MessageChainBuilder() 94 | .append(new PlainText("已经设置过了")) 95 | .build(); 96 | } else { 97 | chain = new MessageChainBuilder() 98 | .append(new PlainText("设置失败")) 99 | .build(); 100 | 101 | } 102 | group.sendMessage(chain); 103 | return true; 104 | } 105 | 106 | String delMuteKeywords = "删除禁言关键字"; 107 | if (msg.contains(delMuteKeywords)) { 108 | if (GroupManagementSetting.authority(group)) { 109 | return true; 110 | } 111 | msg = msg.replace(delMuteKeywords, ""); 112 | String delMuteKeywordsStr = msg.replace(" ", ""); 113 | if (GroupManagementSetting.delMuteKeywords(groupId, delMuteKeywordsStr) == 1) { 114 | chain = new MessageChainBuilder() 115 | .append(new PlainText("删除成功")) 116 | .build(); 117 | } else if (GroupManagementSetting.delMuteKeywords(groupId, delMuteKeywordsStr) == -1) { 118 | chain = new MessageChainBuilder() 119 | .append(new PlainText("已经不是禁言词汇了")) 120 | .build(); 121 | } else { 122 | chain = new MessageChainBuilder() 123 | .append(new PlainText("取消失败")) 124 | .build(); 125 | } 126 | group.sendMessage(chain); 127 | return true; 128 | 129 | } 130 | 131 | String delAllMuteKeywords = "清空禁言关键字"; 132 | if (msg.contains(delAllMuteKeywords)) { 133 | if (GroupManagementSetting.authority(group)) { 134 | return true; 135 | } 136 | if (GroupManagementSetting.delAllMuteKeywords(groupId) == 1) { 137 | chain = new MessageChainBuilder() 138 | .append(new PlainText("清空成功")) 139 | .build(); 140 | } else { 141 | chain = new MessageChainBuilder() 142 | .append(new PlainText("清空失败")) 143 | .build(); 144 | } 145 | group.sendMessage(chain); 146 | return true; 147 | } 148 | 149 | String setMuteTime = "设置禁言时间"; 150 | if (msg.contains(setMuteTime)) { 151 | if (GroupManagementSetting.authority(group)) { 152 | return true; 153 | } 154 | msg = msg.replace(setMuteTime, ""); 155 | int setMuteTimeStr = Integer.parseInt(msg.replace(" ", "")); 156 | if (GroupManagementSetting.setMuteTime(groupId, setMuteTimeStr) == 1) { 157 | chain = new MessageChainBuilder() 158 | .append(new PlainText("设置成功")) 159 | .build(); 160 | } else if (GroupManagementSetting.setMuteTime(groupId, setMuteTimeStr) == -1) { 161 | chain = new MessageChainBuilder() 162 | .append(new PlainText("禁言时间不能超过30天")) 163 | .build(); 164 | } else { 165 | chain = new MessageChainBuilder() 166 | .append(new PlainText("设置失败")) 167 | .build(); 168 | } 169 | group.sendMessage(chain); 170 | return true; 171 | } 172 | 173 | String setRecallWords = "设置撤回关键字"; 174 | if (msg.contains(setRecallWords)) { 175 | if (GroupManagementSetting.authority(group)) { 176 | return true; 177 | } 178 | msg = msg.replace(setRecallWords, ""); 179 | String setRecallWordsStr = msg.replace(" ", ""); 180 | if (GroupManagementSetting.setRecallWords(groupId, setRecallWordsStr) == 1) { 181 | chain = new MessageChainBuilder() 182 | .append(new PlainText("设置成功")) 183 | .build(); 184 | 185 | } else if (GroupManagementSetting.setRecallWords(groupId, setRecallWordsStr) == -1) { 186 | chain = new MessageChainBuilder() 187 | .append(new PlainText("已经设置过了")) 188 | .build(); 189 | 190 | } else { 191 | chain = new MessageChainBuilder() 192 | .append(new PlainText("设置失败")) 193 | .build(); 194 | 195 | } 196 | group.sendMessage(chain); 197 | return true; 198 | } 199 | 200 | String delRecallWords = "删除撤回关键字"; 201 | if (msg.contains(delRecallWords)) { 202 | if (GroupManagementSetting.authority(group)) { 203 | return true; 204 | } 205 | msg = msg.replace(delRecallWords, ""); 206 | String delRecallWordsStr = msg.replace(" ", ""); 207 | if (GroupManagementSetting.delRecallWords(groupId, delRecallWordsStr) == 1) { 208 | chain = new MessageChainBuilder() 209 | .append(new PlainText("删除成功")) 210 | .build(); 211 | 212 | } else if (GroupManagementSetting.delRecallWords(groupId, delRecallWordsStr) == -1) { 213 | chain = new MessageChainBuilder() 214 | .append(new PlainText("没有设置过")) 215 | .build(); 216 | } else { 217 | chain = new MessageChainBuilder() 218 | .append(new PlainText("取消失败")) 219 | .build(); 220 | } 221 | group.sendMessage(chain); 222 | return true; 223 | } 224 | 225 | String delAllRecallWords = "清空撤回关键字"; 226 | if (msg.contains(delAllRecallWords)) { 227 | if (GroupManagementSetting.authority(group)) { 228 | return true; 229 | } 230 | if (GroupManagementSetting.delAllRecallWords(groupId) == 1) { 231 | chain = new MessageChainBuilder() 232 | .append(new PlainText("清空成功")) 233 | .build(); 234 | } else { 235 | chain = new MessageChainBuilder() 236 | .append(new PlainText("清空失败")) 237 | .build(); 238 | } 239 | group.sendMessage(chain); 240 | return true; 241 | 242 | } 243 | 244 | String setAutoAgreeApplication = "设置自动同意群申请"; 245 | if (msg.contains(setAutoAgreeApplication)) { 246 | if (GroupManagementSetting.authority(group)) { 247 | return true; 248 | } 249 | if (GroupManagementSetting.setAutoAgreeApplication(groupId) == 1) { 250 | chain = new MessageChainBuilder() 251 | .append(new PlainText("设置成功")) 252 | .build(); 253 | } else { 254 | chain = new MessageChainBuilder() 255 | .append(new PlainText("设置失败")) 256 | .build(); 257 | } 258 | group.sendMessage(chain); 259 | return true; 260 | 261 | } 262 | 263 | String delAutoAgreeApplication = "关闭自动同意群申请"; 264 | if (msg.contains(delAutoAgreeApplication)) { 265 | if (GroupManagementSetting.authority(group)) { 266 | return true; 267 | } 268 | if (GroupManagementSetting.delAutoAgreeApplication(groupId) == 1) { 269 | chain = new MessageChainBuilder() 270 | .append(new PlainText("关闭成功")) 271 | .build(); 272 | } else { 273 | chain = new MessageChainBuilder() 274 | .append(new PlainText("关闭失败")) 275 | .build(); 276 | } 277 | group.sendMessage(chain); 278 | return true; 279 | } 280 | 281 | String setAutoAgreeKeyWords = "设置自动同意关键字"; 282 | if (msg.contains(setAutoAgreeKeyWords)) { 283 | if (GroupManagementSetting.authority(group)) { 284 | return true; 285 | } 286 | msg = msg.replace(setAutoAgreeKeyWords, ""); 287 | String setAutoAgreeKeyWordsStr = msg.replace(" ", ""); 288 | if (GroupManagementSetting.setAutoAgreeKeyWords(groupId, setAutoAgreeKeyWordsStr) == 1) { 289 | chain = new MessageChainBuilder() 290 | .append(new PlainText("设置成功")) 291 | .build(); 292 | 293 | } else if (GroupManagementSetting.setAutoAgreeKeyWords(groupId, setAutoAgreeKeyWordsStr) == -1) { 294 | chain = new MessageChainBuilder() 295 | .append(new PlainText("已经设置过了")) 296 | .build(); 297 | 298 | } else { 299 | chain = new MessageChainBuilder() 300 | .append(new PlainText("设置失败")) 301 | .build(); 302 | } 303 | group.sendMessage(chain); 304 | return true; 305 | } 306 | 307 | String delAutoAgreeKeyWords = "删除自动同意关键字"; 308 | if (msg.contains(delAutoAgreeKeyWords)) { 309 | if (GroupManagementSetting.authority(group)) { 310 | return true; 311 | } 312 | msg = msg.replace(delAutoAgreeKeyWords, ""); 313 | String delAutoAgreeKeyWordsStr = msg.replace(" ", ""); 314 | if (GroupManagementSetting.delAutoAgreeKeyWords(groupId, delAutoAgreeKeyWordsStr) == 1) { 315 | chain = new MessageChainBuilder() 316 | .append(new PlainText("删除成功")) 317 | .build(); 318 | } else if (GroupManagementSetting.delAutoAgreeKeyWords(groupId, delAutoAgreeKeyWordsStr) == -1) { 319 | chain = new MessageChainBuilder() 320 | .append(new PlainText("没有设置过")) 321 | .build(); 322 | } else { 323 | chain = new MessageChainBuilder() 324 | .append(new PlainText("删除失败")) 325 | .build(); 326 | } 327 | group.sendMessage(chain); 328 | return true; 329 | } 330 | 331 | String delAllAutoAgreeKeyWords = "清空自动同意关键字"; 332 | if (msg.contains(delAllAutoAgreeKeyWords)) { 333 | if (GroupManagementSetting.authority(group)) { 334 | return true; 335 | } 336 | if (GroupManagementSetting.delAllAutoAgreeKeyWords(groupId) == 1) { 337 | chain = new MessageChainBuilder() 338 | .append(new PlainText("清空成功")) 339 | .build(); 340 | } else { 341 | chain = new MessageChainBuilder() 342 | .append(new PlainText("清空失败")) 343 | .build(); 344 | } 345 | group.sendMessage(chain); 346 | return true; 347 | } 348 | 349 | String managementMenu = "管理菜单"; 350 | if (msg.contains(managementMenu)) { 351 | chain = new MessageChainBuilder() 352 | .append(new PlainText("管理菜单")) 353 | .build(); 354 | group.sendMessage(chain); 355 | return true; 356 | } 357 | return false; 358 | } 359 | 360 | public long newMsg(String replaceStr, String msg) { 361 | msg = msg.replace(replaceStr, ""); 362 | msg = msg.replace("@", ""); 363 | msg = msg.replace(" ", ""); 364 | return Long.parseLong(msg); 365 | } 366 | 367 | } 368 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/toolkit/PluginUtil.java: -------------------------------------------------------------------------------- 1 | package org.qbot.toolkit; 2 | 3 | import com.alibaba.fastjson2.JSON; 4 | import com.alibaba.fastjson2.JSONArray; 5 | import com.alibaba.fastjson2.JSONObject; 6 | import net.mamoe.mirai.console.plugin.PluginManager; 7 | import net.mamoe.mirai.console.plugin.jvm.JvmPlugin; 8 | import net.mamoe.mirai.message.data.MusicKind; 9 | import net.mamoe.mirai.message.data.MusicShare; 10 | import net.mamoe.mirai.utils.ExternalResource; 11 | import okhttp3.*; 12 | import org.qbot.Plugin; 13 | import org.qbot.api.API; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.nio.file.Files; 18 | import java.nio.file.Path; 19 | import java.nio.file.Paths; 20 | import java.text.ParseException; 21 | import java.text.SimpleDateFormat; 22 | import java.util.Calendar; 23 | import java.util.Date; 24 | import java.util.Objects; 25 | 26 | /** 27 | * Plugin class 28 | * 29 | * @author 649953543@qq.com 30 | * @date 2021/09/22 31 | */ 32 | 33 | @SuppressWarnings({"ALL", "AlibabaMethodTooLong"}) 34 | public class PluginUtil { 35 | Utils utils = new Utils(); 36 | String broadcast = "播报"; 37 | String one = "1"; 38 | int statuscode = 200; 39 | 40 | /** 41 | * 获取运势 42 | */ 43 | public String getFortune() { 44 | Utils utils = new Utils(); 45 | String url = "https://m.weibo.cn/api/container/getIndex?type=uid&value=7230522444&containerid=1076037230522444"; 46 | String html = utils.okHttpClientGet(url); 47 | if (html == null) { 48 | return "获取失败"; 49 | } 50 | String txt = "获取失败"; 51 | try { 52 | JSONObject json; 53 | json = JSON.parseObject(html); 54 | JSONArray jsonArray = JSON.parseArray(String.valueOf(json.getJSONObject("data").getJSONArray("cards"))); 55 | for (int i = 0; i < jsonArray.size(); i++) { 56 | JSONObject jsonObject = jsonArray.getJSONObject(i); 57 | if (jsonObject.getString("card_type").equals("9")) { 58 | txt = String.valueOf(jsonObject.getJSONObject("mblog").getString("text")); 59 | String wbTime = String.valueOf(jsonObject.getJSONObject("mblog").getString("created_at")); 60 | String nowWeek = utils.getWeek(); 61 | if (wbTime.contains(nowWeek)) { 62 | if (txt.contains(broadcast)) { 63 | txt = txt.replace("
", "\n"); 64 | return txt; 65 | } 66 | } else { 67 | } 68 | } 69 | } 70 | txt = "获取失败"; 71 | } catch (Exception e) { 72 | 73 | } 74 | return txt; 75 | } 76 | 77 | /** 78 | * 获取新闻 79 | */ 80 | public String getNews() { 81 | String nowDay = utils.getTime1(); 82 | File newsFile = new File(utils.getPluginsDataPath() + "/cache/news/" + nowDay + ".jpg"); 83 | String filePath = utils.getPluginsDataPath() + "/cache/news/" + utils.getTime1() + ".jpg"; 84 | String url = API.NEWS_URL; 85 | if (newsFile.exists()) { 86 | return newsFile.getPath(); 87 | } else { 88 | if (utils.downloadFile(url, filePath)) { 89 | return newsFile.getPath(); 90 | } else { 91 | return "失败"; 92 | } 93 | } 94 | } 95 | 96 | 97 | /** 98 | * 获取视频 99 | */ 100 | public String getVideo() { 101 | String url = API.VIDEO_URL; 102 | String nowDay = utils.getTime1(); 103 | int randomNum = Utils.getRandomNum(0, 10000); 104 | String fileName = Utils.getTime() + randomNum; 105 | File newsFile = new File(utils.getPluginsDataPath() + "/cache/video/" + fileName + ".mp4"); 106 | String filePath = utils.getPluginsDataPath() + "/cache/video/" + fileName + ".mp4"; 107 | if (newsFile.exists()) { 108 | return newsFile.getPath(); 109 | } else { 110 | if (utils.downloadFile(url, filePath)) { 111 | return newsFile.getPath(); 112 | } else { 113 | return "失败"; 114 | } 115 | } 116 | } 117 | 118 | /** 119 | * 获取每日一句 120 | */ 121 | public String getOne() { 122 | String url = API.ONE_WORD_URL; 123 | String html = utils.okHttpClientGet(url); 124 | if (html == null) { 125 | return "获取失败"; 126 | } 127 | try { 128 | JSONObject json; 129 | json = JSON.parseObject(html); 130 | String txt = String.valueOf(json.getString("hitokoto")); 131 | String from = String.valueOf(json.getString("from")); 132 | String from_who = String.valueOf(json.getString("from_who")); 133 | String str = "每日一句:" + txt + "\n" + "出处:" + from + "\n" + "作者:" + from_who; 134 | return str; 135 | } catch (Exception e) { 136 | return "获取失败"; 137 | } 138 | } 139 | 140 | /** 141 | * 求签 142 | */ 143 | public String getCq() { 144 | String cqTxt = ""; 145 | String filePath = utils.getPluginsDataPath() + "/诸葛神签.txt"; 146 | int maxNum = utils.getFileLen(filePath); 147 | int randomNum = Utils.getRandomNum(1, maxNum); 148 | try { 149 | cqTxt = Files.readAllLines(Paths.get(filePath)).get(randomNum); 150 | } catch (IOException e) { 151 | e.printStackTrace(); 152 | } 153 | cqTxt = cqTxt.replace("【解签】", "\n【解签】"); 154 | return cqTxt; 155 | } 156 | 157 | /** 158 | * 音乐分享 159 | */ 160 | public MusicShare getMusic(String musicName) { 161 | JSONObject musicInfo = utils.getMusicInfo(musicName); 162 | return new MusicShare(MusicKind.NeteaseCloudMusic, musicInfo.getString("song_name"), 163 | musicInfo.getString("songer_name"), 164 | "https://music.163.com/song/" + musicInfo.getString("song_id") + "/?userid=380034310", 165 | musicInfo.getString("cover_url"), 166 | "https://music.163.com/song/media/outer/url?id=" + musicInfo.getString("song_id") + "&userid=380034310" 167 | ); 168 | } 169 | 170 | /** 171 | * 发语音 172 | */ 173 | 174 | public ExternalResource getVoice(String txt) { 175 | String filepath = utils.makeVoice(txt); 176 | if (one.equals(filepath)) { 177 | return null; 178 | } else { 179 | return ExternalResource.create(new File(filepath)); 180 | } 181 | } 182 | 183 | /** 184 | * 战力查询 185 | */ 186 | public JSONObject getPower(String hero, String qu) { 187 | String heroUrl = API.HERO_POWER_URL + "?hero=" + hero + "&type=" + qu; 188 | String data = utils.okHttpClientGet(heroUrl); 189 | JSONObject jsonData = JSON.parseObject(data); 190 | int code = jsonData.getInteger("code"); 191 | if (code == statuscode) { 192 | String heroName = jsonData.getJSONObject("data").getString("name"); 193 | String area = jsonData.getJSONObject("data").getString("area"); 194 | String areaPower = jsonData.getJSONObject("data").getString("areaPower"); 195 | String city = jsonData.getJSONObject("data").getString("city"); 196 | String cityPower = jsonData.getJSONObject("data").getString("cityPower"); 197 | String province = jsonData.getJSONObject("data").getString("province"); 198 | String provincePower = jsonData.getJSONObject("data").getString("provincePower"); 199 | String heroPhoto = jsonData.getJSONObject("data").getString("photo"); 200 | String heroPower = "英雄名:" + heroName + "\n最低县标:" + area + "\n县标战力:" + areaPower + "\n最低市标:" + city + "\n市标战力:" + cityPower + "\n最低省标:" + province + "\n省标战力:" + provincePower; 201 | JSONObject heroInfo = new JSONObject(); 202 | heroInfo.put("data", heroPower); 203 | String filePath = utils.getPluginsDataPath() + "/cache/hero/" + heroName + ".jpg"; 204 | File heroImgPath = new File(filePath); 205 | if (heroImgPath.exists()) { 206 | heroInfo.put("img", heroImgPath.toString()); 207 | return heroInfo; 208 | } else { 209 | if (utils.downloadFile(heroPhoto, filePath)) { 210 | heroInfo.put("img", heroImgPath.toString()); 211 | return heroInfo; 212 | } 213 | return null; 214 | } 215 | 216 | } 217 | return null; 218 | } 219 | 220 | /** 221 | * 获取随机图片 222 | */ 223 | public String getImage() { 224 | JvmPlugin jvmPlugin = new Plugin(); 225 | Path newsFilePath = PluginManager.INSTANCE.getPluginsDataPath().resolve(jvmPlugin.getDescription().getName()); 226 | String path = newsFilePath + "/image"; 227 | //获取其file对象 228 | File file = new File(path); 229 | //遍历path下的文件和目录,放在File数组中 230 | File[] fs = file.listFiles(); 231 | assert fs != null; 232 | int maxFile = fs.length; 233 | if (maxFile == 0) { 234 | return "获取失败,请联系管理员添加照片"; 235 | } else if (maxFile == 1) { 236 | return String.valueOf(fs[0]); 237 | } 238 | int randomNum = Utils.getRandomNum(0, maxFile - 1); 239 | return String.valueOf(fs[randomNum]); 240 | } 241 | 242 | /** 243 | * 摸鱼办 244 | */ 245 | @SuppressWarnings("AlibabaMethodTooLong") 246 | public String moFish() throws ParseException { 247 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 248 | Date nowdate = sdf.parse(utils.getTime3()); 249 | String txt = ""; 250 | 251 | String sjd = ""; 252 | int hh = Integer.parseInt(utils.getNowTime1()); 253 | if (hh < 6) { 254 | sjd = "凌晨"; 255 | } 256 | if (hh >= 6 && hh < 9) { 257 | sjd = "早上"; 258 | } 259 | if (hh >= 9 && hh < 11) { 260 | sjd = "上午"; 261 | } 262 | if (hh >= 11 && hh < 14) { 263 | sjd = "中午"; 264 | } 265 | if (hh >= 14 && hh < 19) { 266 | sjd = "下午"; 267 | } 268 | if (hh >= 19) { 269 | sjd = "晚上"; 270 | } 271 | String statementAtTheBeginning = "\n工作再累,一定不要忘记摸鱼哦!有事没事起身去茶水间,去厕所,去廊道走走别老在工位上坐着,钱是老板的,但命是自己的!"; 272 | String statementAtTheEnd = "\n上班是帮老板赚钱,摸鱼是赚老板的钱!最后,祝愿天下所有摸鱼人,都能愉快的渡过每一天!"; 273 | String superThursday = "\n今天星期四,明天星期五,再坚持一天,然后星期天!"; 274 | String theWeekendToRemind = "\n不是吧不是吧,不会有人还在996、997吧?"; 275 | 276 | Date cjdate = sdf.parse("2024-02-10"); 277 | int cj = utils.daysBetween(nowdate, cjdate); 278 | Date qmjdate = sdf.parse("2024-04-04"); 279 | int qmj = utils.daysBetween(nowdate, qmjdate); 280 | Date ndjdate = sdf.parse("2024-05-01"); 281 | int ndj = utils.daysBetween(nowdate, ndjdate); 282 | Date dwjdate = sdf.parse("2024-06-10"); 283 | int dwj = utils.daysBetween(nowdate, dwjdate); 284 | Date zqjdate = sdf.parse("2023-09-28"); 285 | int zqj = utils.daysBetween(nowdate, zqjdate); 286 | Date gqjdate = sdf.parse("2023-10-01"); 287 | int gqj = utils.daysBetween(nowdate, gqjdate); 288 | Date ydjdate = sdf.parse("2024-01-01"); 289 | int ydj = utils.daysBetween(nowdate, ydjdate); 290 | 291 | String title = "【摸鱼办】提醒您:\n" + utils.getTime2() + sjd + "好,摸鱼人!"; 292 | txt = txt + title; 293 | Calendar calendar = Calendar.getInstance(); 294 | int week = calendar.get(Calendar.DAY_OF_WEEK); 295 | if (cj == 0 || qmj == 0 || ndj == 0 || dwj == 0 || zqj == 0 || gqj == 0 || ydj == 0) { 296 | if (cj == 0) { 297 | txt = txt + "\n今天是春节哦,祝大家新年快乐!"; 298 | } 299 | if (qmj == 0) { 300 | txt = txt + "\n今天是清明节哦,祝大家....算了..."; 301 | } 302 | if (ndj == 0) { 303 | txt = txt + "\n今天是劳动节哦,祝大家劳动节快乐!"; 304 | } 305 | if (dwj == 0) { 306 | txt = txt + "\n今天是端午节哦,祝大家端午节快乐!"; 307 | } 308 | if (zqj == 0) { 309 | txt = txt + "\n今天是中秋节哦,祝大家中秋节快乐!"; 310 | } 311 | if (gqj == 0) { 312 | txt = txt + "\n今天是国庆节哦,祝大家国庆节快乐!"; 313 | } 314 | if (ydj == 0) { 315 | txt = txt + "\n今天是元旦节哦,祝大家元旦节快乐!"; 316 | } 317 | } else { 318 | String[] stringWeek = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"}; 319 | if (week == 5) { 320 | txt = txt + superThursday; 321 | } else if (week == 7 || week == 1) { 322 | txt = txt + theWeekendToRemind; 323 | } else { 324 | txt = txt + statementAtTheBeginning; 325 | } 326 | int day = week - 1; 327 | txt = txt + "\n今天【" + stringWeek[day] + "】"; 328 | if (week > 1 && week < 7) { 329 | int jg = 7 - week; 330 | txt = txt + "\n距离【周末】还有:" + jg + "天"; 331 | } 332 | } 333 | 334 | if (zqj > 0) { 335 | txt = txt + "\n距离【中秋】还有:" + zqj + "天"; 336 | } 337 | if (gqj > 0) { 338 | txt = txt + "\n距离【国庆】还有:" + gqj + "天"; 339 | } 340 | if (ydj > 0) { 341 | txt = txt + "\n距离【元旦】还有:" + ydj + "天"; 342 | } 343 | if (cj > 0) { 344 | txt = txt + "\n距离【新年】还有:" + cj + "天"; 345 | } 346 | if (qmj > 0) { 347 | txt = txt + "\n距离【清明】还有:" + qmj + "天"; 348 | } 349 | if (ndj > 0) { 350 | txt = txt + "\n距离【劳动】还有:" + ndj + "天"; 351 | } 352 | if (dwj > 0) { 353 | txt = txt + "\n距离【端午】还有:" + dwj + "天"; 354 | } 355 | txt = txt + statementAtTheEnd; 356 | return txt; 357 | } 358 | 359 | /** 360 | * 摸鱼办新 361 | */ 362 | public String moFishNew() { 363 | File File = new File(utils.getPluginsDataPath() + "/cache/mofish/" + utils.getTime1() + ".jpg"); 364 | if (File.exists()) { 365 | return File.getPath(); 366 | } else { 367 | if (utils.downloadFile(API.FISH_URL, File.getPath())) { 368 | return File.getPath(); 369 | } else { 370 | return "失败"; 371 | } 372 | } 373 | } 374 | 375 | public String generatePicture(String key, String text, String type) { 376 | String nowDay = utils.getTime1(); 377 | File file = new File(utils.getPluginsDataPath() + "/cache/image/" + Utils.getTime() + Utils.getRandomNum(0, 10000) + ".jpg"); 378 | String url = null; 379 | switch (type) { 380 | case "txt": 381 | url = API.PETPET_URL + "?key=" + key + "&textList=" + text; 382 | break; 383 | case "img": 384 | url = API.PETPET_URL + "?key=" + key + "&toAvatar=" + text; 385 | break; 386 | case "gif": 387 | url = API.PETPET_URL + "?key=" + key + "&toAvatar=" + text; 388 | file = new File(utils.getPluginsDataPath() + "/cache/image/" + Utils.getTime() + Utils.getRandomNum(0, 10000) + ".gif"); 389 | break; 390 | } 391 | if (file.exists()) { 392 | file.delete(); 393 | } 394 | if (utils.downloadFile(url, file.getPath())) { 395 | return file.getPath(); 396 | } else { 397 | return "失败"; 398 | } 399 | } 400 | 401 | 402 | /** 403 | * Ai回复 404 | */ 405 | public String aiReply(Long senderID, String senderName, long groupID, String msg) { 406 | String apiKey = Setting.getAiApiKey(); 407 | String apiSecret = Setting.getAiApiSecret(); 408 | if (apiKey.equals("") || apiSecret.equals("")) { 409 | return "请先联系管理员配置API"; 410 | } 411 | JSONObject jsonObject = new JSONObject(); 412 | jsonObject.put("content", msg); 413 | jsonObject.put("type", 2); 414 | jsonObject.put("from", senderID); 415 | jsonObject.put("fromName", senderName); 416 | jsonObject.put("to", groupID); 417 | jsonObject.put("tomName", senderName); 418 | MediaType JSON = MediaType.parse("application/json; charset=utf-8"); 419 | RequestBody body = RequestBody.create(JSON, String.valueOf(jsonObject)); 420 | OkHttpClient httpClient = new OkHttpClient(); 421 | Request postRequest = new Request.Builder() 422 | .url("https://api.mlyai.com/reply") 423 | .addHeader("Api-Key", apiKey) 424 | .addHeader("Api-Secret", apiSecret) 425 | .post(body) 426 | .build(); 427 | Call call = httpClient.newCall(postRequest); 428 | try { 429 | Response response = call.execute(); 430 | JSONObject responseJSON = JSONObject.parseObject(Objects.requireNonNull(response.body()).string()); 431 | if (responseJSON.getInteger("code") == 0) { 432 | JSONArray data = responseJSON.getJSONArray("data"); 433 | String reply = ""; 434 | if (data.getJSONObject(0).getInteger("typed") == 1) { 435 | reply = data.getJSONObject(0).getString("content"); 436 | } else { 437 | reply = "暂不支持的消息,消息类型为:" + data.getJSONObject(0).getInteger("typed"); 438 | } 439 | return reply; 440 | } else { 441 | return "AI回复失败"; 442 | } 443 | 444 | } catch (IOException e) { 445 | e.printStackTrace(); 446 | return "网络连接失败"; 447 | } 448 | 449 | } 450 | 451 | 452 | /** 453 | * 网易云任务 454 | */ 455 | 456 | } -------------------------------------------------------------------------------- /src/main/java/org/qbot/msgdeal/MessageDeal.java: -------------------------------------------------------------------------------- 1 | package org.qbot.msgdeal; 2 | 3 | import com.alibaba.fastjson2.JSONObject; 4 | import net.mamoe.mirai.contact.Group; 5 | import net.mamoe.mirai.contact.file.AbsoluteFile; 6 | import net.mamoe.mirai.message.MessageReceipt; 7 | import net.mamoe.mirai.message.data.*; 8 | import net.mamoe.mirai.utils.ExternalResource; 9 | import org.qbot.PluginVersion; 10 | import org.qbot.toolkit.PluginUtil; 11 | import org.qbot.toolkit.Setting; 12 | import org.qbot.toolkit.Utils; 13 | 14 | import javax.script.ScriptException; 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.nio.file.Path; 18 | import java.text.ParseException; 19 | import java.util.Arrays; 20 | import java.util.List; 21 | import java.util.concurrent.ExecutorService; 22 | import java.util.concurrent.Executors; 23 | 24 | /** 25 | * MessageDeal class 26 | * 27 | * @author 649953543@qq.com 28 | * @date 2021/09/22 29 | */ 30 | 31 | @SuppressWarnings({"ALL", "AlibabaMethodTooLong"}) 32 | public class MessageDeal { 33 | PluginUtil pluginUtil = new PluginUtil(); 34 | Utils utils = new Utils(); 35 | Group group = null; 36 | 37 | Path dataFolderPath = Utils.getPluginsDataPath(); 38 | 39 | private static final String STRING_LISTENTOMUSIC = "听歌"; 40 | private static final String STRING_QQ = "qq"; 41 | private static final String STRING_SAY = "说"; 42 | private static final String STRING_WE_CHAT = "微信"; 43 | private static final String STRING_HOROSCOPE = "星座运势"; 44 | private static final String STRING_COMBAT_POWER_QUERY = "战力查询"; 45 | private static final String STRING_MUSIC_SYSTEM = "音乐系统"; 46 | private static final String STRING_FAIL = "失败"; 47 | private static final String STRING_FORTUNE = "运势"; 48 | private static final String STRING_TODAY_FORTUNE = "今日运势"; 49 | private static final String STRING_GET_FAILED = "获取失败"; 50 | private static final String STRING_NEWS = "新闻"; 51 | private static final String STRING_TODAY_NEWS = "今日新闻"; 52 | private static final String STRING_BEAUTY = "美女"; 53 | private static final String STRING_BEAUTY_PICTURES = "美女图片"; 54 | private static final String STRING_GET_SIGN = "求签"; 55 | private static final String STRING_GUANYIN_GET_SIGN = "诸葛神签"; 56 | private static final String STRING_MENU = "菜单"; 57 | private static final String STRING_WEATHER = "天气"; 58 | private static final String STRING_HELP = "帮助"; 59 | private static final String STRING_FISH = "摸鱼办"; 60 | private static final String STRING_BEAUTY_VIDEO = "美女视频"; 61 | private static final String STRING_GOOD_NEWS = "喜报"; 62 | private static final String STRING_BAD_NEWS = "悲报"; 63 | private static final String NUM_ONE = "1"; 64 | private static final JSONObject TWELVE_HOROSCOPE = JSONObject.parseObject("{'白羊':'aries','金牛':'taurus','双子':'gemini','巨蟹':'cancer','狮子':'leo','处女':'virgo','天秤':'libra','天蝎':'scorpio','射手':'sagittarius','摩羯':'capricorn','水瓶':'aquarius','双鱼':'pisces'}"); 65 | private static final JSONObject HOT_LIST = JSONObject.parseObject("{'微博热搜':'wbHot'}"); 66 | ExecutorService executorService = Executors.newCachedThreadPool(); 67 | 68 | @SuppressWarnings("AlibabaMethodTooLong") 69 | public void msgDel(Long senderId, String senderName, Group group, String msg, MessageChain msgchains) throws IOException, 70 | InterruptedException, 71 | ScriptException, NoSuchMethodException, ParseException { 72 | MessageChain chain; 73 | this.group = group; 74 | Setting.getBot().getLogger().info("收到的消息:" + msg + " 消息长度:" + msg.length()); 75 | if (STRING_FISH.equals(msg)) { 76 | // chain = new MessageChainBuilder().append(new PlainText(pluginUtil.moFish())).build(); 77 | // group.sendMessage(chain); 78 | // return; 79 | String mofishImgUrl = pluginUtil.moFishNew(); 80 | if (!mofishImgUrl.contains(STRING_FAIL)) { 81 | Image image = getImageAdd(mofishImgUrl); 82 | chain = new MessageChainBuilder().append(image).build(); 83 | } else { 84 | chain = new At(senderId).plus(new PlainText("\n获取失败")); 85 | } 86 | group.sendMessage(chain); 87 | return; 88 | } 89 | 90 | 91 | if ("".equals(msg)) { 92 | String ImgUrl = pluginUtil.generatePicture("crawl", java.net.URLEncoder.encode("http://q.qlogo.cn/g?b=qq&nk=" + senderId + "&s=640", "UTF-8"), "img"); 93 | if (!ImgUrl.contains(STRING_FAIL)) { 94 | Image image = getImageAdd(ImgUrl); 95 | chain = new MessageChainBuilder().append(image).append("\n发送<菜单>命令可获取菜单\n发送<帮助>命令可获取帮助文档").build(); 96 | } else { 97 | chain = new At(senderId).plus(new PlainText("\n发送<菜单>命令可获取菜单\n发送<帮助>命令可获取帮助文档")); 98 | } 99 | group.sendMessage(chain); 100 | return; 101 | } 102 | 103 | 104 | if (msg.contains(STRING_BEAUTY_VIDEO)) { 105 | try { 106 | MessageSource.recall(msgchains); 107 | } catch (Exception e) { 108 | Setting.getBot().getLogger().info("撤回失败1"); 109 | } 110 | MessageReceipt messageReceipts = group.sendMessage("正在上传,请稍后..."); 111 | String filePath = pluginUtil.getVideo(); 112 | File video = new File(filePath); 113 | try (ExternalResource resource = ExternalResource.create(video)) { 114 | AbsoluteFile uploadFile = group.getFiles().getRoot().uploadNewFile("/" + video.getName(), resource); 115 | messageReceipts.recall(); 116 | int recallTimes = Setting.getImageRecall(); 117 | try { 118 | if (recallTimes != 0) { 119 | Thread.sleep(recallTimes * 1000); 120 | uploadFile.delete(); 121 | } 122 | } catch (Exception e) { 123 | Setting.getBot().getLogger().info("撤回失败"); 124 | } 125 | } catch (Exception e) { 126 | messageReceipts.recall(); 127 | group.sendMessage("发送失败,请重试"); 128 | } 129 | return; 130 | } 131 | 132 | if (msg.startsWith(STRING_LISTENTOMUSIC)) { 133 | msg = msg.replace(STRING_LISTENTOMUSIC, ""); 134 | if ("".equals(msg)) { 135 | chain = new PlainText("? \n你总得告诉我要听什么吧?").plus(new Face(244)); 136 | group.sendMessage(chain); 137 | return; 138 | } 139 | PluginUtil pluginUtil = new PluginUtil(); 140 | MusicShare musicShare = pluginUtil.getMusic(msg); 141 | group.sendMessage(musicShare); 142 | return; 143 | } 144 | 145 | if (msg.startsWith(STRING_SAY)) { 146 | msg = msg.replaceFirst(STRING_SAY, ""); 147 | if ("".equals(msg)) { 148 | chain = new PlainText("? \n你总得告诉我要说什么吧?").plus(new Face(244)); 149 | group.sendMessage(chain); 150 | return; 151 | } 152 | PluginUtil pluginUtil = new PluginUtil(); 153 | ExternalResource audio = pluginUtil.getVoice(msg); 154 | if (audio == null) { 155 | group.sendMessage("语音系统未配置,请联系管理员"); 156 | return; 157 | } 158 | Audio audio1 = group.uploadAudio(audio); 159 | group.sendMessage(audio1); 160 | audio.close(); 161 | return; 162 | } 163 | 164 | if (msg.startsWith(STRING_QQ)) { 165 | msg = msg.replace(STRING_QQ, ""); 166 | msg = msg.replace(" ", ""); 167 | JSONObject jsonObject = pluginUtil.getPower(msg, "qq"); 168 | if (jsonObject == null) { 169 | group.sendMessage("获取失败"); 170 | return; 171 | } 172 | String heroInfo = jsonObject.getString("data"); 173 | String heroImg = jsonObject.getString("img"); 174 | Image image = getImageAdd(heroImg); 175 | chain = new MessageChainBuilder().append(new At(senderId)).append(image).append(new PlainText("\n" + heroInfo)).build(); 176 | group.sendMessage(chain); 177 | return; 178 | } 179 | 180 | if (msg.startsWith(STRING_WE_CHAT)) { 181 | msg = msg.replace(STRING_WE_CHAT, ""); 182 | msg = msg.replace(" ", ""); 183 | JSONObject jsonObject = pluginUtil.getPower(msg, "wx"); 184 | if (jsonObject == null) { 185 | group.sendMessage("获取失败"); 186 | return; 187 | } 188 | String heroInfo = jsonObject.getString("data"); 189 | String heroImg = jsonObject.getString("img"); 190 | Image image = getImageAdd(heroImg); 191 | chain = new MessageChainBuilder().append(new At(senderId)).append(image).append(new PlainText("\n" + heroInfo)).build(); 192 | group.sendMessage(chain); 193 | return; 194 | } 195 | 196 | if (STRING_HOROSCOPE.equals(msg)) { 197 | chain = new MessageChainBuilder().append(new At(senderId)).append(new PlainText("\n请@我并发送星座名\n例如 <@运势小助手 白羊>")).build(); 198 | group.sendMessage(chain); 199 | return; 200 | } 201 | 202 | if (STRING_COMBAT_POWER_QUERY.equals(msg)) { 203 | chain = new MessageChainBuilder().append(new At(senderId)).append(new PlainText("\n请@我并发送qq/微信+英雄名\n例如 <@运势小助手 qq 伽罗>")).build(); 204 | group.sendMessage(chain); 205 | return; 206 | } 207 | 208 | if (STRING_MUSIC_SYSTEM.equals(msg)) { 209 | chain = new MessageChainBuilder().append(new At(senderId)).append(new PlainText("\n请@我并发送听歌+音乐名\n注歌曲源来自网易云\n例如 <@运势小助手 听歌稻香>")).build(); 210 | group.sendMessage(chain); 211 | return; 212 | } 213 | 214 | if (STRING_FORTUNE.equals(msg) || STRING_TODAY_FORTUNE.equals(msg)) { 215 | String replaceMsg = pluginUtil.getFortune(); 216 | chain = new At(senderId).plus(new PlainText("\n" + replaceMsg)); 217 | group.sendMessage(chain); 218 | return; 219 | } 220 | 221 | if (STRING_NEWS.equals(msg) || STRING_TODAY_NEWS.equals(msg)) { 222 | String newsImgUrl = pluginUtil.getNews(); 223 | if (!newsImgUrl.contains(STRING_FAIL)) { 224 | Image image = getImageAdd(newsImgUrl); 225 | chain = new MessageChainBuilder().append(image).build(); 226 | } else { 227 | chain = new At(senderId).plus(new PlainText("\n获取失败")); 228 | } 229 | group.sendMessage(chain); 230 | return; 231 | } 232 | 233 | if (STRING_BEAUTY.equals(msg) || STRING_BEAUTY_PICTURES.equals(msg)) { 234 | chain = new MessageChainBuilder().append(new LightApp("{\"app\":\"com.tencent.imagetextbot\",\"desc\":\"\",\"view\":\"index\",\"ver\":\"1.0.0.14\",\"prompt\":\"美女图\",\"appID\":\"\",\"sourceName\":\"\",\"actionData\":\"\",\"actionData_A\":\"\",\"sourceUrl\":\"\",\"meta\":{\"robot\":{\"cover\":\"https:\\/\\/qq.lolimi.cn\\/img\\/api.php?url=https:\\/\\/api.lolimi.cn\\/API\\/tup\\/xjj.php\",\"jump_url\":\"\",\"subtitle\":\"\",\"title\":\"每次打开都会刷新\"}},\"config\":{\"autosize\":1,\"ctime\":1695818144,\"token\":\"a19ec2c7d68007d24235ab986e9a8845\"},\"text\":\"\",\"sourceAd\":\"\",\"extra\":\"\"}")).build(); 235 | group.sendMessage(chain); 236 | return; 237 | } 238 | 239 | //获取星座运势 240 | for (String s : TWELVE_HOROSCOPE.keySet()) { 241 | if (msg.equals(s) || msg.equals(s + "座") || msg.equals(s + "座运势")) { 242 | chain = new MessageChainBuilder().append(new At(senderId)).append(new PlainText("\n" + utils.getHoroscope(TWELVE_HOROSCOPE.getString(s)))).build(); 243 | group.sendMessage(chain); 244 | return; 245 | } 246 | } 247 | 248 | //获取热点 249 | for (String s : HOT_LIST.keySet()) { 250 | if (msg.equals(s)) { 251 | chain = new MessageChainBuilder().append(s + ":\n" + utils.getHotList(HOT_LIST.getString(s))).build(); 252 | group.sendMessage(chain); 253 | return; 254 | } 255 | } 256 | 257 | if (msg.contains(STRING_HELP)) { 258 | chain = new MessageChainBuilder().append(new At(senderId)).append(new PlainText("\n帮助文档:\nhttps://www" + 259 | ".miraiqbot.top/\n当前版本:" + PluginVersion.VERSION_NUM)).build(); 260 | group.sendMessage(chain); 261 | return; 262 | } 263 | 264 | if (STRING_GET_SIGN.equals(msg) || STRING_GUANYIN_GET_SIGN.equals(msg)) { 265 | File qqFile = new File(utils.getPluginsDataPath() + "/cache/qq/" + senderId + ".cache"); 266 | String qian; 267 | if (qqFile.exists()) { 268 | qian = utils.readData(qqFile); 269 | if (NUM_ONE.equals(qian)) { 270 | qian = pluginUtil.getCq(); 271 | utils.rewriteData(qqFile, qian); 272 | } 273 | } else { 274 | qian = pluginUtil.getCq(); 275 | utils.rewriteData(qqFile, qian); 276 | } 277 | chain = new MessageChainBuilder().append(new At(senderId)).append(new PlainText("\n" + qian)).build(); 278 | group.sendMessage(chain); 279 | return; 280 | } 281 | 282 | if (STRING_MENU.equals(msg)) { 283 | group.sendMessage(getMenuTxt()); 284 | return; 285 | } 286 | 287 | if (msg.contains(STRING_GOOD_NEWS)) { 288 | msg = msg.replace("喜报", ""); 289 | msg = msg.replace(" ", ""); 290 | String ImgUrl = pluginUtil.generatePicture("certificate", msg, "txt"); 291 | if (!ImgUrl.contains(STRING_FAIL)) { 292 | Image image = getImageAdd(ImgUrl); 293 | chain = new MessageChainBuilder().append(image).build(); 294 | } else { 295 | chain = new At(senderId).plus(new PlainText("\n获取失败")); 296 | } 297 | group.sendMessage(chain); 298 | return; 299 | } 300 | 301 | if (msg.contains(STRING_BAD_NEWS)) { 302 | msg = msg.replace("悲报", ""); 303 | msg = msg.replace(" ", ""); 304 | String ImgUrl = pluginUtil.generatePicture("sad_news", msg, "txt"); 305 | if (!ImgUrl.contains(STRING_FAIL)) { 306 | Image image = getImageAdd(ImgUrl); 307 | chain = new MessageChainBuilder().append(image).build(); 308 | } else { 309 | chain = new At(senderId).plus(new PlainText("\n获取失败")); 310 | } 311 | group.sendMessage(chain); 312 | return; 313 | } 314 | 315 | if (Setting.getAi()) { 316 | String reply = pluginUtil.aiReply(senderId, senderName, group.getId(), msg); 317 | if (reply.equals("你干嘛!哎哟~")) { 318 | String ImgUrl = pluginUtil.generatePicture("crawl", java.net.URLEncoder.encode("http://q.qlogo.cn/g?b=qq&nk=" + senderId + "&s=640", "UTF-8"), "img"); 319 | if (!ImgUrl.contains(STRING_FAIL)) { 320 | Image image = getImageAdd(ImgUrl); 321 | chain = new MessageChainBuilder().append(image).append("\n发送<菜单>命令可获取菜单\n发送<帮助>命令可获取帮助文档").build(); 322 | } else { 323 | chain = new At(senderId).plus(new PlainText("\n发送<菜单>命令可获取菜单\n发送<帮助>命令可获取帮助文档")); 324 | } 325 | } else { 326 | chain = new MessageChainBuilder().append(new PlainText(reply)).build(); 327 | } 328 | group.sendMessage(chain); 329 | return; 330 | } 331 | 332 | } 333 | 334 | public void nudgeDel(Long formId, Long groupId) throws IOException { 335 | MessageChain chain; 336 | List keyList = Arrays.asList("breakdown", "bite", "cast", "crawl", "dont_touch", "eat", "hammer", "knock", "pat", "petpet", "play", "pound", "roll", "suck", "tear", "thump", "tightly"); 337 | String ImgUrl = pluginUtil.generatePicture(keyList.get(Utils.getRandomNum(0, 16)), java.net.URLEncoder.encode("http://q.qlogo.cn/g?b=qq&nk=" + formId + "&s=640", "UTF-8"), "gif"); 338 | this.group = Setting.getBot().getGroup(groupId); 339 | if (!ImgUrl.contains(STRING_FAIL)) { 340 | Image image = getImageAdd(ImgUrl); 341 | chain = new MessageChainBuilder().append(image).build(); 342 | } else { 343 | chain = new At(formId).plus(new PlainText("\n你戳我干啥")); 344 | } 345 | this.group.sendMessage(chain); 346 | return; 347 | } 348 | 349 | /** 350 | * 菜单 351 | */ 352 | public MessageChain getMenuTxt() { 353 | return new MessageChainBuilder().append(new Face(147)).append(new PlainText(" 菜单 ")).append(new Face(147)).append(new PlainText("\n◇━━━━━━━━◇\n")).append(new Face(333)).append(new PlainText("今日运势 今日新闻")).append(new Face(333)).append(new PlainText("\n")).append(new Face(333)).append(new PlainText("星座运势 诸葛神签")).append(new Face(333)).append(new PlainText("\n")).append(new Face(333)).append(new PlainText("音乐系统 语音系统")).append(new Face(333)).append(new PlainText("\n")).append(new Face(333)).append(new PlainText("美女图片 美女视频")).append(new Face(333)).append(new PlainText("\n")).append(new Face(333)).append(new PlainText("战力查询 帮助文档")).append(new Face(333)).append(new PlainText("\n")).append(new Face(333)).append(new PlainText("喜报悲报 敬请期待")).append(new Face(333)).append(new PlainText("\n◇━━━━━━━━◇\nPS:@我并发相应文字查看指令\n当前版本:" + PluginVersion.VERSION_NUM)).build(); 354 | } 355 | 356 | 357 | public Image getImageAdd(String filepath) throws IOException { 358 | ExternalResource img = ExternalResource.create(new File(filepath)); 359 | Image image = this.group.uploadImage(img); 360 | img.close(); 361 | return image; 362 | } 363 | 364 | 365 | } 366 | -------------------------------------------------------------------------------- /src/main/java/org/qbot/toolkit/Utils.java: -------------------------------------------------------------------------------- 1 | package org.qbot.toolkit; 2 | 3 | import com.alibaba.fastjson2.JSON; 4 | import com.alibaba.fastjson2.JSONArray; 5 | import com.alibaba.fastjson2.JSONObject; 6 | import com.baidu.aip.speech.AipSpeech; 7 | import com.baidu.aip.speech.TtsResponse; 8 | import com.baidu.aip.util.Util; 9 | import net.mamoe.mirai.console.plugin.PluginManager; 10 | import net.mamoe.mirai.console.plugin.jvm.JvmPlugin; 11 | import okhttp3.*; 12 | import org.qbot.Plugin; 13 | import org.qbot.api.API; 14 | 15 | import java.io.*; 16 | import java.nio.file.Path; 17 | import java.text.SimpleDateFormat; 18 | import java.util.*; 19 | import java.util.concurrent.TimeUnit; 20 | 21 | /** 22 | * Utils class 23 | * 24 | * @author 649953543@qq.com 25 | * @date 2021/09/22 26 | */ 27 | 28 | public class Utils { 29 | 30 | /** 31 | * okhttp get请求 32 | */ 33 | public String okHttpClientGet(String url) { 34 | OkHttpClient httpClient = new OkHttpClient(); 35 | Request getRequest = new Request.Builder() 36 | .url(url) 37 | .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36") 38 | .get() 39 | .build(); 40 | Call call = httpClient.newCall(getRequest); 41 | try { 42 | Response response = call.execute(); 43 | return Objects.requireNonNull(response.body()).string(); 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | return null; 47 | } 48 | 49 | } 50 | 51 | /** 52 | * okhttp get请求,X-Real-Ip 53 | */ 54 | public String okHttpClientGet(String url, String ip) { 55 | OkHttpClient httpClient = new OkHttpClient(); 56 | Request getRequest = new Request.Builder() 57 | .url(url) 58 | .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36") 59 | .addHeader("X-Real-Ip", ip) 60 | .get() 61 | .build(); 62 | Call call = httpClient.newCall(getRequest); 63 | try { 64 | Response response = call.execute(); 65 | return Objects.requireNonNull(response.body()).string(); 66 | } catch (IOException e) { 67 | e.printStackTrace(); 68 | return null; 69 | } 70 | 71 | } 72 | 73 | /** 74 | * okhttp get请求 75 | */ 76 | public String okHttpClientGetMusic(String url, String cookie) { 77 | OkHttpClient httpClient = new OkHttpClient(); 78 | Request getRequest = new Request.Builder() 79 | .url(url) 80 | .addHeader("Cookie", cookie) 81 | .get() 82 | .build(); 83 | Call call = httpClient.newCall(getRequest); 84 | try { 85 | Response response = call.execute(); 86 | return Objects.requireNonNull(response.body()).string(); 87 | } catch (IOException e) { 88 | return null; 89 | } 90 | } 91 | 92 | /** 93 | * 获取插件配置文件目录 94 | */ 95 | public static Path getPluginsPath() { 96 | JvmPlugin jvmPlugin = new Plugin(); 97 | return PluginManager.INSTANCE.getPluginsConfigPath().resolve(jvmPlugin.getDescription().getId()); 98 | } 99 | 100 | /** 101 | * 获取插件数据文件目录 102 | */ 103 | public static Path getPluginsDataPath() { 104 | JvmPlugin jvmPlugin = new Plugin(); 105 | return PluginManager.INSTANCE.getPluginsDataPath().resolve(jvmPlugin.getDescription().getId()); 106 | } 107 | 108 | /** 109 | * 获取星期 110 | */ 111 | public String getWeek() { 112 | Date date = new Date(); 113 | SimpleDateFormat formatter = new SimpleDateFormat("E", Locale.ENGLISH); 114 | return formatter.format(date); 115 | } 116 | 117 | /** 118 | * 获取日期 119 | */ 120 | public static String getTime() { 121 | // 格式化时间 122 | SimpleDateFormat sdf = new SimpleDateFormat(); 123 | // a为am/pm的标记 124 | sdf.applyPattern("MMddHHmmss"); 125 | // 获取当前时间 126 | Date date = new Date(); 127 | return sdf.format(date); 128 | 129 | } 130 | 131 | public String formatText(String text) { 132 | text = text.replace("\n" + 133 | " \n" + 134 | " \n" + 135 | " \n" + 137 | " \n" + 139 | " \n" + 141 | " \n" + 142 | " \n" + 143 | " \n" + 145 | " \n" + 148 | " \n" + 150 | " \n" + 151 | " \n" + 152 | "
", ""); 136 | text = text.replace("", ":"); 138 | text = text.replace("", "\n"); 140 | text = text.replace("
", "\n"); 144 | text = text.replace("", ":"); 146 | text = text.replace("精评:", ""); 147 | text = text.replace("", ":"); 149 | text = text.replace("
", ""); 153 | text = text.replace("。", ""); 154 | return text; 155 | } 156 | 157 | /** 158 | * 获取星座运势 159 | * 160 | * @param msg 161 | * @return 162 | */ 163 | public String getHoroscope(String msg) { 164 | String url = API.HOROSCOPE_URL + "?type=" + msg + "&time=today"; 165 | try { 166 | JSONObject jsonObject = JSONObject.parseObject(okHttpClientGet(url)).getJSONObject("data"); 167 | String title = jsonObject.getString("title") + jsonObject.getString("type") + "\n"; 168 | String todo = "宜:" + jsonObject.getJSONObject("todo").getString("yi") + "\n忌:" + jsonObject.getJSONObject("todo").getString("ji") + "\n"; 169 | String fortune = "总运势:" + jsonObject.getJSONObject("index").getString("all") + "\n" + jsonObject.getJSONObject("fortunetext").getString("all") + "\n" + 170 | "爱情运势:" + jsonObject.getJSONObject("index").getString("love") + "\n" + jsonObject.getJSONObject("fortunetext").getString("love") + "\n" + 171 | "财富运势:" + jsonObject.getJSONObject("index").getString("money") + "\n" + jsonObject.getJSONObject("fortunetext").getString("money") + "\n" + 172 | "工作运势:" + jsonObject.getJSONObject("index").getString("work") + "\n" + jsonObject.getJSONObject("fortunetext").getString("work") + "\n" + 173 | "健康运势:" + jsonObject.getJSONObject("index").getString("health") + "\n" + jsonObject.getJSONObject("fortunetext").getString("health") + "\n"; 174 | String luckyNumber = "幸运数字:" + jsonObject.getString("luckynumber") + "\n"; 175 | String luckyColor = "幸运颜色:" + jsonObject.getString("luckycolor") + "\n"; 176 | String shortComment = "短评:" + jsonObject.getString("shortcomment"); 177 | return title + todo + luckyNumber + luckyColor + todo + fortune + shortComment; 178 | } catch (Exception e) { 179 | return "\n获取失败"; 180 | } 181 | } 182 | 183 | 184 | /** 185 | * 获取热点 186 | * 187 | * @param msg 188 | * @return 189 | */ 190 | public String getHotList(String msg) { 191 | String url = API.HOT_LIST_URL + "?type=" + msg; 192 | try { 193 | JSONArray jsonArray = JSONObject.parseObject(okHttpClientGet(url)).getJSONArray("data"); 194 | StringBuilder data = new StringBuilder(); 195 | for (int i = 0; i < 10; i++) { 196 | JSONObject jsonObject = jsonArray.getJSONObject(i); 197 | int num = i + 1; 198 | data.append(num).append(" ").append(jsonObject.getString("title")).append("\n"); 199 | } 200 | return data.toString(); 201 | } catch (Exception e) { 202 | return "\n获取失败"; 203 | } 204 | } 205 | 206 | /** 207 | * 获取范围随机数 208 | */ 209 | public static int getRandomNum(int min, int max) { 210 | Random random = new Random(); 211 | return random.nextInt(max) % (max - min + 1) + min; 212 | } 213 | 214 | /** 215 | * 获取文件行数 216 | */ 217 | public int getFileLen(String path) { 218 | try { 219 | File file = new File(path); 220 | if (file.exists()) { 221 | FileReader fr = new FileReader(file); 222 | LineNumberReader lnr = new LineNumberReader(fr); 223 | int linenumber = 0; 224 | while (lnr.readLine() != null) { 225 | linenumber++; 226 | } 227 | fr.close(); 228 | lnr.close(); 229 | return linenumber; 230 | } 231 | return 1; 232 | } catch (IOException e) { 233 | e.printStackTrace(); 234 | return 1; 235 | } 236 | } 237 | 238 | /** 239 | * 生成随机ip 240 | */ 241 | public String generateRandomChinaIP() { 242 | Random random = new Random(); 243 | // China IP address ranges from 58.16.0.0 to 58.25.255.255 244 | int firstPart = 58; 245 | int secondPart = 16 + random.nextInt(10); // 16 to 25 246 | int thirdPart = random.nextInt(256); // 0 to 255 247 | int fourthPart = random.nextInt(256); // 0 to 255 248 | return firstPart + "." + secondPart + "." + thirdPart + "." + fourthPart; 249 | } 250 | 251 | /** 252 | * 获取音乐信息 253 | */ 254 | public JSONObject getMusicInfo(String musicName) { 255 | String url = "https://music.163.com/api/search/get/web?s=" + musicName + "&type=1&limit=1"; 256 | String html = okHttpClientGet(url, generateRandomChinaIP()); 257 | JSONObject json = JSONObject.parseObject(html); 258 | JSONObject musicInfoJson = json.getJSONObject("result").getJSONArray("songs").getJSONObject(0); 259 | JSONObject artists = musicInfoJson.getJSONArray("artists").getJSONObject(0); 260 | String songName = musicInfoJson.getString("name"); 261 | String songerName = artists.getString("name"); 262 | String coverUrl = musicInfoJson.getJSONObject("album").getJSONObject("artist").getString("img1v1Url"); 263 | int songId = musicInfoJson.getInteger("id"); 264 | 265 | JSONObject musicInfo = new JSONObject(); 266 | musicInfo.put("song_name", songName); 267 | musicInfo.put("songer_name", songerName); 268 | musicInfo.put("cover_url", coverUrl); 269 | musicInfo.put("song_id", songId); 270 | return musicInfo; 271 | } 272 | 273 | /** 274 | * 获取二维码路径 275 | */ 276 | public String getCode(String url) { 277 | String codePath = getPluginsDataPath() + "/code.png"; 278 | // 生成二维码 279 | QrCodeUtil.encodeQrCode(url, codePath); 280 | return codePath; 281 | } 282 | 283 | 284 | /** 285 | * 生成语音文件并返回目录 286 | */ 287 | public String makeVoice(String txt) { 288 | String appId = Setting.getAppId(); 289 | String apiKey = Setting.getApiKey(); 290 | String secretKey = Setting.getSecretKey(); 291 | 292 | if ("".equals(appId)) { 293 | return "1"; 294 | } 295 | Path newsFilePath = getPluginsDataPath(); 296 | int randomNum = getRandomNum(0, 10000); 297 | String filename = getTime() + randomNum + ".mp3"; 298 | // 初始化一个AipSpeech 299 | AipSpeech client = new AipSpeech(appId, apiKey, secretKey); 300 | 301 | // 可选:设置网络连接参数 302 | client.setConnectionTimeoutInMillis(2000); 303 | client.setSocketTimeoutInMillis(60000); 304 | 305 | // 调用接口 306 | TtsResponse res = client.synthesis(txt, "zh", 1, null); 307 | byte[] data = res.getData(); 308 | org.json.JSONObject res1 = res.getResult(); 309 | if (data != null) { 310 | try { 311 | String filepath = newsFilePath + "/cache/voice/" + filename; 312 | Util.writeBytesToFileSystem(data, filepath); 313 | return filepath; 314 | } catch (IOException e) { 315 | e.printStackTrace(); 316 | return "0"; 317 | } 318 | } 319 | if (res1 != null) { 320 | Setting.getBot().getLogger().info(res1.toString(2)); 321 | return "0"; 322 | } 323 | return "0"; 324 | } 325 | 326 | /** 327 | * 获取当前小时分钟 328 | */ 329 | public String getNowTime() { 330 | // 格式化时间 331 | SimpleDateFormat sdf = new SimpleDateFormat(); 332 | // a为am/pm的标记 333 | sdf.applyPattern("HH:mm"); 334 | // 获取当前时间 335 | Date date = new Date(); 336 | // 输出已经格式化的现在时间(24小时制) 337 | return sdf.format(date); 338 | } 339 | 340 | /** 341 | * 获取当前小时分钟1 342 | */ 343 | public String getNowTime1() { 344 | // 格式化时间 345 | SimpleDateFormat sdf = new SimpleDateFormat(); 346 | // a为am/pm的标记 347 | sdf.applyPattern("HH"); 348 | // 获取当前时间 349 | Date date = new Date(); 350 | // 输出已经格式化的现在时间(24小时制) 351 | return sdf.format(date); 352 | } 353 | 354 | 355 | /** 356 | * 获取时间 357 | */ 358 | public String getTime1() { 359 | // 格式化时间 360 | SimpleDateFormat sdf = new SimpleDateFormat(); 361 | // a为am/pm的标记 362 | sdf.applyPattern("MMdd"); 363 | // 获取当前时间 364 | Date date = new Date(); 365 | return sdf.format(date); 366 | 367 | } 368 | 369 | /** 370 | * 获取时间2 371 | */ 372 | public String getTime2() { 373 | // 格式化时间 374 | SimpleDateFormat sdf = new SimpleDateFormat(); 375 | // a为am/pm的标记 376 | sdf.applyPattern("MM月dd日"); 377 | // 获取当前时间 378 | Date date = new Date(); 379 | return sdf.format(date); 380 | 381 | } 382 | 383 | /** 384 | * 获取时间3 385 | */ 386 | public String getTime3() { 387 | // 格式化时间 388 | SimpleDateFormat sdf = new SimpleDateFormat(); 389 | // a为am/pm的标记 390 | sdf.applyPattern("yyyy-MM-dd"); 391 | // 获取当前时间 392 | Date date = new Date(); 393 | return sdf.format(date); 394 | } 395 | 396 | /** 397 | * 获取时间4 398 | */ 399 | public String getTime4() { 400 | // 格式化时间 401 | SimpleDateFormat sdf = new SimpleDateFormat(); 402 | // a为am/pm的标记 403 | sdf.applyPattern("yyyy-MM-dd HH:mm:ss"); 404 | // 获取当前时间 405 | Date date = new Date(); 406 | return sdf.format(date); 407 | } 408 | 409 | 410 | /** 411 | * 重写星期文件 412 | */ 413 | public static void rewrite(int week) { 414 | try { 415 | File weekcacheFile = new File(getPluginsDataPath() + "/cache/week.cache"); 416 | BufferedWriter out = new BufferedWriter(new FileWriter(weekcacheFile)); 417 | out.write(String.valueOf(week)); 418 | out.close(); 419 | } catch (IOException e) { 420 | e.printStackTrace(); 421 | } 422 | } 423 | 424 | /** 425 | * 重写日期文件 426 | */ 427 | public void rewriteData(File file, String qian) { 428 | try { 429 | BufferedWriter out = new BufferedWriter(new FileWriter(file)); 430 | JSONObject jsonObject = new JSONObject(); 431 | jsonObject.put("date", getTime1()); 432 | jsonObject.put("qian", qian); 433 | out.write(String.valueOf(jsonObject)); 434 | out.close(); 435 | } catch (IOException e) { 436 | e.printStackTrace(); 437 | } 438 | } 439 | 440 | /** 441 | * 获取已抽签文件 442 | */ 443 | public String readData(File file) { 444 | BufferedReader in; 445 | try { 446 | in = new BufferedReader(new FileReader(file)); 447 | String data = in.readLine(); 448 | JSONObject jsonObject = JSON.parseObject(data); 449 | String time = jsonObject.getString("date"); 450 | String qian = jsonObject.getString("qian"); 451 | in.close(); 452 | if (time.equals(getTime1())) { 453 | return qian; 454 | } else { 455 | return "1"; 456 | } 457 | } catch (IOException e) { 458 | e.printStackTrace(); 459 | } 460 | return "0"; 461 | } 462 | 463 | public boolean downloadFile(String url, String filePath) { 464 | OkHttpClient okHttpClient = new OkHttpClient(); 465 | Request getRequest = new Request.Builder() 466 | .url(url) 467 | .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36") 468 | .get() 469 | .build(); 470 | Call call = okHttpClient.newCall(getRequest); 471 | try { 472 | Response response = call.execute(); 473 | ResponseBody body = response.body(); 474 | //获取流 475 | assert body != null; 476 | InputStream in = body.byteStream(); 477 | //转化为bitmap 478 | FileOutputStream fo = new FileOutputStream(filePath); 479 | byte[] buf = new byte[1024]; 480 | int length; 481 | while ((length = in.read(buf, 0, buf.length)) != -1) { 482 | fo.write(buf, 0, length); 483 | } 484 | in.close(); 485 | fo.close(); 486 | //检测下载是否成功 487 | File file = new File(filePath); 488 | if (file.exists()) { 489 | //基本上没那么小的文件 490 | if (file.length() < 1000) { 491 | file.delete(); 492 | return false; 493 | } 494 | } else { 495 | return false; 496 | } 497 | return true; 498 | } catch (IOException e) { 499 | e.printStackTrace(); 500 | return false; 501 | } 502 | } 503 | 504 | /** 505 | * 取得两个日期之间的相差多少天 506 | **/ 507 | public int daysBetween(Date early, Date late) { 508 | 509 | Calendar calst = Calendar.getInstance(); 510 | Calendar caled = Calendar.getInstance(); 511 | calst.setTime(early); 512 | caled.setTime(late); 513 | //设置时间为0时 514 | calst.set(Calendar.HOUR_OF_DAY, 0); 515 | calst.set(Calendar.MINUTE, 0); 516 | calst.set(Calendar.SECOND, 0); 517 | caled.set(Calendar.HOUR_OF_DAY, 0); 518 | caled.set(Calendar.MINUTE, 0); 519 | caled.set(Calendar.SECOND, 0); 520 | //得到两个日期相差的天数 521 | int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst 522 | .getTime().getTime() / 1000)) / 3600 / 24; 523 | 524 | return days; 525 | } 526 | 527 | public JSONObject readFile(File file) throws IOException { 528 | BufferedReader in = new BufferedReader(new FileReader(file)); 529 | String data = in.readLine(); 530 | JSONObject jsonObject = JSON.parseObject(data); 531 | in.close(); 532 | return jsonObject; 533 | } 534 | 535 | public boolean writeFile(File file, String data) { 536 | try { 537 | BufferedWriter out = new BufferedWriter(new FileWriter(file)); 538 | out.write(data); 539 | out.close(); 540 | return true; 541 | } catch (IOException e) { 542 | e.printStackTrace(); 543 | return false; 544 | } 545 | } 546 | 547 | public void GenerateImage(String imgStr, String img_name) { //对字节数组字符串进行Base64解码并生成图片 548 | Base64.Decoder decoder = Base64.getDecoder(); 549 | try { 550 | //Base64解码 551 | byte[] b = decoder.decode(imgStr); 552 | for (int i = 0; i < b.length; ++i) { 553 | if (b[i] < 0) {//调整异常数据 554 | b[i] += 256; 555 | } 556 | } 557 | //生成jpeg图片 558 | 559 | String imgFilePath = getPluginsDataPath() + "/cache/image/" + img_name;//新生成的图片 560 | OutputStream out = new FileOutputStream(imgFilePath); 561 | out.write(b); 562 | out.flush(); 563 | out.close(); 564 | } catch (Exception e) { 565 | } 566 | } 567 | 568 | public void sendMsgToWeChat(String msg) throws Exception { 569 | String botKeyUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + Setting.getQYWXKEY(); 570 | JSONObject text = new JSONObject(); 571 | text.put("content", msg); 572 | JSONObject reqBody = new JSONObject(); 573 | reqBody.put("msgtype", "text"); 574 | reqBody.put("text", text); 575 | reqBody.put("safe", 0); 576 | 577 | MediaType contentType = MediaType.parse("application/json; charset=utf-8"); 578 | RequestBody body = RequestBody.create(contentType, reqBody.toString()); 579 | String respMsg = okHttp(body, botKeyUrl); 580 | if ("0".equals(respMsg.substring(11, 12))) { 581 | Setting.getBot().getLogger().info("发送消息成功!"); 582 | } else { 583 | Setting.getBot().getLogger().info("请求失败!"); 584 | Setting.getBot().getLogger().info("群机器人推送消息失败,错误信息:\n" + respMsg); 585 | } 586 | } 587 | 588 | public String okHttp(RequestBody body, String url) throws Exception { 589 | // 构造和配置OkHttpClient 590 | OkHttpClient client; 591 | 592 | client = new OkHttpClient.Builder() 593 | .connectTimeout(10, TimeUnit.SECONDS) // 设置连接超时时间 594 | .readTimeout(20, TimeUnit.SECONDS) // 设置读取超时时间 595 | .build(); 596 | 597 | 598 | // 构造Request对象 599 | Request request = new Request.Builder() 600 | .url(url) 601 | .post(body) 602 | .addHeader("cache-control", "no-cache") // 响应消息不缓存 603 | .build(); 604 | 605 | // 构建Call对象,通过Call对象的execute()方法提交异步请求 606 | Response response = null; 607 | try { 608 | response = client.newCall(request).execute(); 609 | } catch (IOException e) { 610 | e.printStackTrace(); 611 | } 612 | 613 | // 请求结果处理 614 | byte[] datas = response.body().bytes(); 615 | String respMsg = new String(datas); 616 | 617 | return respMsg; 618 | } 619 | 620 | } 621 | 622 | --------------------------------------------------------------------------------