用kotlin/java构建一个Mirai插件
/ 11 min read
Table of Contents
前言
构建mirai的mirai-console插件教程
用到的概念有
mcl
- 指mirai-console-loader,mirai-console官方启动器
mirai
- mirai 是一个在全平台下运行,提供 QQ Android 协议支持的高效率机器人库,根据AGPLv3
开源
资料列表
以下为一些官方资料 mirai官方github库 mirai-console官方github库 mirai-console-loader(mcl)官方启动器官方github库 这三者的关系可以参考这里 官方实例 mirai官方论坛 官方demo mirai在线api文档
另,以下是一些资源: 笔者整理的mirai-console插件实例包含kt和java)
可能遇到的问题
- MiraiOK已经没用了,用mcl(网址在上面)
- 最好用openjdk不过甲骨文的jdk好像也可以(建议用openjdk, 解释在下面)
- 根据issue#959目前邀请机器人进200+人的群都不会触发事件
- 插件id必须为类包格式(xxx.xxx.xxx)
- 有的时候收不到机器人的信息是因为被tx风控了换号或多发几次以及多挂(可以去论坛看看)
- 建议看一遍官方文档虽然有点乱
- 如果遇到问题,可以去mirai论坛上问
- 如果要在mcl内改登录协议,在login命令后加参数或在config/console/autologin.yml里面设置自动登录命令和登录的协议
- mcl登录报错
环境异常
,参考论坛解决方案 - 改了入口点包路径需要到
resources\META-INF\services\net.mamoe.mirai.console.plugin.jvm.JvmPlugin
改成对应的类包路径
1.准备
i. 配置java环境
下载mcl所需要的是>=11版本的openjdk,openjdk下载地址,下载教程参考搜索引擎
最好用openjdk而不是甲骨文(Oracle)的jdk,原因
ii. 配置IDE
推荐IDEA吧,其他的也可以,主要是IDEA挺好用的 可以选择安装的官方插件: Mirai Console IntelliJ 提供错误检查等功能 Kotlin Jvm Blocking Bridge 帮助 Java 用户调用 Kotlin suspend 函数 详细参考官方文档
iii. 下载mirai-console-loader(mcl)作为启动器
官方地址 教程同见官方说明
其他启动器
目前也出了其他启动器,查看这里
2.创建mirai-console插件项目
i. 下载
- 从官方实例或笔者整理的mirai-console插件实例中下载最新版的框架到本地,然后用IDE打开文件夹
- 使用插件生成,详细查看官网
ii. 个性化项目
- 在
settings.gradle.kts
里改生成的插件.jar名称也就是项目名称, 或者在build.gradle.kts里面获取shadowjar任务改如:
tasks { afterEvaluate { named<net.mamoe.mirai.console.gradle.BuildMiraiPluginTask>("buildPlugin") { archiveBaseName.set("name") archiveClassifier.set("") archiveVersion.set(version) } }}
- 用
RunMiraikt
这个文件(在test文件夹下)可以在ide里运行,不用复制到mcl或其他启动器 - 用
buildPlugin
这个gradle任务可以生成.jar插件 - 在
src/main/kotlin/PluginMain
主类内可以修改插件信息(mcl用) - 最好修改
PluginMain.kt
或JavaPluginMain.java
的包名避免插件载入冲突,然后在resources\META-INF\services\net.mamoe.mirai.console.plugin.jvm.JvmPlugin
中更改类包名到你改后的名,路径见下面
3. 文件夹结构解析
插件实例代码文件结构
│ build.gradle.kts gradle依赖列表│ settings.gradle.kts gradle设置│├─.run│ RunMiraiKt.run.xml IDE中运行任务配置,即RunMiraiKt源文件│├─run RunMiraiKt默认运行目录│└─src ├─main │ ├─kotlin │ │ PluginMain.kt kotlin插件主类 │ ├─Java │ │ JavaPluginMain.java java插件主类 │ │ │ ├─resources\META-INF\services │ │ net.mamoe.mirai.console.plugin.jvm.JvmPlugin Mirai加载的主类 └─test └─kotlin RunMirai.kt RunMiraiKt任务配置
4.kotlin插件代码解析
代码以github上的代码为准,可能会有更新
i.所有在以下代码中要引入的库
//插件信息import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription//主类继承import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin//机器人被拉进群的事件import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent//收到好友信息事件import net.mamoe.mirai.event.events.FriendMessageEvent//收到群消息事件import net.mamoe.mirai.event.events.GroupMessageEvent//新好友申请事件import net.mamoe.mirai.event.events.NewFriendRequestEvent//日志组件(logger)发控制台信息函数import net.mamoe.mirai.utils.info//消息(messageChain)中的图片类型import net.mamoe.mirai.message.data.Image//消息(messageChain)中的纯文本类型import net.mamoe.mirai.message.data.PlainText//监听器import net.mamoe.mirai.event.Listener//监听范围import net.mamoe.mirai.event.globalEventChannel//协程范围?import kotlin.coroutines.EmptyCoroutineContext
监听和事件参考官方文档
ii.构建主类
object PluginMain : KotlinPlugin( JvmPluginDescription( id = "org.example.mirai-example", version = "0.1.0" )) {}
其中,kotlinPlugin
指继承plugin父类,JvmPluginDescription
指声明插件消息和版本
iii.覆盖插件启用函数
override fun onEnable() { //或logger.info("xxx")作用一样 logger.info { "Plugin loaded" }}
用kotlin关键字override
实现插件启用函数,然后用logger.info()
进行日志输出,其中logger
是kotlinPlugin
类内成员,除了.info()
还有.warning()
输出警告和.error()
输出报错
iv.监听事件
用 subscribeAlways<>{}
这个函数在onEnable
函数中开启监听(还可以subscribe
或subscribeOnce
见mirai文档)
globalEventChannel().subscribeAlways<GroupMessageEvent>{ //群消息 if (message.contentToString().startsWith("复读")) { group.sendMessage(message.contentToString().replace("复读", "")) } if (message.contentToString() == "hi") { group.sendMessage("hi") } message.forEach { //循环每个元素在消息里 if (it is Image) { //如果消息这一部分是图片 } if (it is PlainText) { //如果消息这一部分是纯文本 } } } globalEventChannel().subscribeAlways<FriendMessageEvent>{ //好友信息 } globalEventChannel().subscribeAlways<NewFriendRequestEvent>{ //自动同意好友申请 accept() } globalEventChannel().subscribeAlways<BotInvitedJoinGroupRequestEvent>{ //自动同意加群申请 accept() }
v. 全部代码
这些代码是笔者整理的mirai-console插件kotlin版实例中的内容
package org.example.mirai.plugin
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescriptionimport net.mamoe.mirai.console.plugin.jvm.KotlinPluginimport net.mamoe.mirai.event.Listenerimport net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEventimport net.mamoe.mirai.event.events.FriendMessageEventimport net.mamoe.mirai.event.events.GroupMessageEventimport net.mamoe.mirai.event.events.NewFriendRequestEventimport net.mamoe.mirai.event.globalEventChannelimport net.mamoe.mirai.message.code.MiraiCodeimport net.mamoe.mirai.utils.infoimport net.mamoe.mirai.message.data.Imageimport net.mamoe.mirai.message.data.Image.Key.queryUrlimport net.mamoe.mirai.message.data.PlainText
/*使用kotlin版请把src/main/resources/META-INF.services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin文件内容改成"org.example.mirai.plugin.PluginMain"也就是当前主类使用kt可以把java文件夹删除不会对项目有影响
在settings.gradle.kts里改生成的插件.jar名称build.gradle.kts里改依赖库和插件版本在主类下的JvmPluginDescription改插件名称,id和版本用runmiraikt这个配置可以在ide里运行,不用复制到mcl或其他启动器 */
object PluginMain : KotlinPlugin( JvmPluginDescription( id = "org.example.mirai-example", name = "插件示例", version = "0.1.0" )) { override fun onEnable() { logger.info { "Plugin loaded" } //配置文件目录 "${dataFolder.absolutePath}/"
globalEventChannel().subscribeAlways<GroupMessageEvent>{ //群消息 group.sendMessage("\uD83D\uDE03") } globalEventChannel().subscribeAlways<FriendMessageEvent>{ //好友信息 sender.sendMessage("hi") } globalEventChannel().subscribeAlways<NewFriendRequestEvent>{ //自动同意好友申请 accept() } globalEventChannel().subscribeAlways<BotInvitedJoinGroupRequestEvent>{ //自动同意加群申请 accept() } }}
vi. gradle部分代码
plugins { val kotlinVersion = "1.4.30" kotlin("jvm") version kotlinVersion kotlin("plugin.serialization") version kotlinVersion id("net.mamoe.mirai-console") version "2.3.2"}
group = "org.example"version = "0.1.0"
repositories { jcenter() //国内镜像源 //华为云 maven { url =uri("https://mirrors.huaweicloud.com/repository/maven") } //阿里云 maven { url =uri("https://maven.aliyun.com/nexus/content/repositories/jcenter")} //mirai-console的仓库 maven {url = uri("https://dl.bintray.com/him188moe/mirai")} //滑动模块的仓库 // maven { url = uri("https://dl.bintray.com/karlatemp/misc") } mavenLocal() mavenCentral()}dependencies{ //在IDE内运行的mcl添加滑块模块,请参考https://github.com/project-mirai/mirai-login-solver-selenium把版本更新为最新 //runtimeOnly("net.mamoe:mirai-login-solver-selenium:1.0-dev-15")}
其中2.3.2
是目前最新开发版本,请自行通过官方文档选择版本并更改
5. Java插件代码解析
i. 在下面代码中要引入的库
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;//继承对象import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescriptionBuilder;//构造插件信息import net.mamoe.mirai.event.GlobalEventChannel;//全局监听通道import net.mamoe.mirai.event.events.FriendMessageEvent;//好友信息事件import net.mamoe.mirai.event.events.GroupMessageEvent;//群消息事件
ii. 构建主类
构建mirai插件的主类也就是入口点,必须要继承JavaPlugin
public final class JavaPluginMain extends JavaPlugin { public static final JavaPluginMain INSTANCE = new JavaPluginMain(); private JavaPluginMain() { super(new JvmPluginDescriptionBuilder("org.example.mirai-example", "0.1.0") .info("EG") .build()); } }
其中JvmPluginDescriptionBuilder
的声明插件信息
iii. 覆盖插件启用函数
@Override public void onEnable() { getLogger().info("日志"); }
用getLogger()
获取日志对象,然后用.info()
发送普通日志
iv. 监听事件
GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, g -> { //监听群消息 getLogger().info(g.getMessage().contentToString());
}); GlobalEventChannel.INSTANCE.subscribeAlways(FriendMessageEvent.class, f -> { //监听好友消息 getLogger().info(f.getMessage().contentToString()); });
v. 全部代码
package org.example.mirai.plugin;
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescriptionBuilder;import net.mamoe.mirai.event.GlobalEventChannel;import net.mamoe.mirai.event.events.FriendMessageEvent;import net.mamoe.mirai.event.events.GroupMessageEvent;
public final class JavaPluginMain extends JavaPlugin { public static final JavaPluginMain INSTANCE = new JavaPluginMain(); private JavaPluginMain() { super(new JvmPluginDescriptionBuilder("org.example.mirai-example", "0.1.0") .info("EG") .build()); }
@Override public void onEnable() { getLogger().info("日志");
GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, g -> { //监听群消息 getLogger().info(g.getMessage().contentToString());
}); GlobalEventChannel.INSTANCE.subscribeAlways(FriendMessageEvent.class, f -> { //监听好友消息 getLogger().info(f.getMessage().contentToString()); }); }}
vi. gradle 部分代码
同#4-vi.-gradle-部分代码
6. 在IDE内运行
i. 更改MiraiRunKt配置
把/src/test/kotlin/RunMirai.kt
中的qq号和密码改成你的
如果在根目录下没有run文件夹,则可能报错,新建一个就好了
ii.运行MiraiRunKt任务
如果任务报错先配置任务
然后检查根目录下有没有run文件夹,就是这里的路径,如果没有则创建
然后配置登录配置
7. 生成插件并运行
i. 生成插件
用IDE中gradle的buldplugin
任务可以在buid/mirai/
下生成一个.jar插件文件
ii.在mcl中运行
把这个.jar文件放到mcl的plugin文件夹下,然后用cmd或者直接打开mcl.cmd运行
有什么评论区问,以后再补充