开发入门篇 /01/ 部署开发环境


提示

「入门开发篇」仅适用于原生 mirai 的开发,使用的语言为 kotlin 或 java。如需使用其他语言编写 mirai 衍生程序,请查阅 官方文档→社区 SDKopen in new window

选择类型

当前主流的原生 mirai 程序有两种类型,一种是基于 mirai-core 开发,一种是基于 mirai-console 开发 (即插件)。

基于 mirai-core

基于 mirai-core 开发的程序一般将 mirai-core 作为程序的支持库。 若基于 mirai-core 开发,你将无法载入 mirai-console 插件,该程序也无法被 mirai-console 当作插件加载 (如果你写了两份主类可以当我没说,但完全没必要) , 但你可以只把 mirai 仅当作你程序中的一个支持库来使用,登录、发消息、注册事件等等 mirai 已经给你封装好了,直接使用即可。

提示

适合那些机器人自用,不发布内容到社区的开发者使用。

转跳到 部署 mirai-core 开发环境

基于 mirai-console

基于 mirai-console 开发的程序,就是我们所说的插件。 若基于 mirai-console 开发,你的插件可以发布到论坛给别人使用。虽说基于 mirai-core 开发也能发布给别人使用,但插件的通用性明显更强。
基于 mirai-console 开发可以享受 mirai-core 没有的命令系统、配置文件系统 (可自动保存) 等等,

提示

适合那些需要分享自己的插件到社区的开发者使用。

转跳到 部署插件开发环境

部署 mirai-core 开发环境

选择这条路,你可能会在本文遇到一些仅支持 mirai-console 不支持 mirai-core 的特性,但大多无伤大雅,这会在文中标注「不支持 mirai-core」。

添加依赖

Gradle

请编辑你的构建脚本,根据情况添加内容

// Gradle Kotlin DSL (build.gradle.kts)
plugins {
    kotlin("jvm") version "1.5.30" // 确保添加 Kotlin
}
dependencies {
    api("net.mamoe", "mirai-core", "2.9.1")
}
// Gradle Groovy DSL (build.gradle)
plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.5.30' // 确保添加 Kotlin
}
dependencies {
    implementation 'net.mamoe:mirai-core:2.9.1'
}

完成之后,可进行一个可选操作: 分离 API 和实现open in new window

Maven

在 pom.xml 中添加

<!-- 若你的项目有其他库依赖了 kotlin,容易造成冲突,此时需要手动添加 kotlin 标准库依赖 (因为有时 maven 无法正确处理冲突) -->
<properties>
    <kotlin.version>1.5.10</kotlin.version>
</properties>
<dependencies>
    <dependency>
        <groupId>net.mamoe</groupId>
        <artifactId>mirai-core-jvm</artifactId>
        <version>2.9.1</version> 
    </dependency>
    <!-- 同上注释 -->
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib-jdk8</artifactId>
        <version>${kotlin.version}</version>
    </dependency>
</dependencies>

需要注意的是,导入到 Maven 中的 mirai-core 包需要带有 -jvm 后缀

导入Jar包

警告

已经 2023 年了,非常不推荐这样做。

下载以下包的 all.jar

或者下载以下包的 all.jar

并将其作为库导入到项目即可。

部署插件开发环境

注意

从 2.11 开始,mirai-console 的插件加载机制有所改动,如果你不想或者不会处理打包,请使用 IDEA 插件模板项目Gradle 插件 中的其中一种方法来新建项目。

本文不推荐的方法只一略而过,配置项目的官方原文在此open in new window。在 2.11 之前,你用什么写插件都行,只要能引用 mirai 作为依赖,但从 2.11 开始,如果不使用官方给的 Gradle 插件,你将需要自己处理打包,比较麻烦。

关于一些 2.11 开始关于打包的新特性可参见以下文档:
打包和分发插件open in new window | 类加载隔离open in new window

创建项目

你有多种方式可以创建项目,任选一种即可,一般建议使用 IntelliJ 插件。

IntelliJ 插件

Jetbrains 插件仓库open in new window 即可一键安装该插件到你的 IntelliJ IDEA,你也可以在 IDEA 的插件 Marketplace 搜索 mirai-console 来安装该插件。安装完毕后,点击「新建项目」,你就能在「生成器」找到「Mirai Console 插件」了,如图,填写信息就能创建插件项目,非常方便。

完成

新建项目后需要进行额外配置

intellij_插件.jpg

模板项目

我觉得官方的文档非常详细 https://github.com/project-mirai/how-to-use-plugin-template

完成

新建项目后需要进行额外配置

Gradle 插件

请编辑你的构建脚本,根据情况添加内容,自行将 VERSION 替换为你想要使用的 mirai-console 版本。版本通常与 mirai 的 Releasesopen in new window 中的版本相同。

// Gradle Kotlin DSL (build.gradle.kts)
plugins {
    kotlin("jvm") version "1.5.10"
    kotlin("plugin.serialization") version "1.5.10"
    
    id("net.mamoe.mirai-console") version "VERSION"
}
// Gradle Groovy DSL (build.gradle)
plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.5.10'
    id 'org.jetbrains.kotlin.plugin.serialization' version '1.5.10'
    
    id 'net.mamoe.mirai-console' version 'VERSION'
}

是的,加入这段内容后重新加载你的 Gradle 项目就完成了。

完成

新建项目后需要进行额外配置新建主类

添加库

能用插件最好别用这种方法

以上 3 种方法均为使用 Gradle 插件,不使用 Gradle 插件的方法即为添加以下几个库作为依赖并配置主类服务即可。都是重复操作,先按照 部署 mirai-core 开发环境 操作然后补以下依赖,再「手动配置主类服务」即可。

(提示: 点进链接选择版本,然后就会有选择不同构建工具生成不同添加依赖代码的选项卡。导入Jar包的方法依然是下载 all.jar)

完成

新建项目后需要进行手动配置主类服务新建主类

额外配置

这些都是 mirai-console 相关的,如果你不是基于 mirai-console 开发的,这部分与你无关,你可以直接跳到完成部分。

Gradle 插件的额外配置

项目默认使用的 jvm 版本为 1.8,而很多常用的特性要在 11 或以上才有,部分库也要求使用 11 或以上,故最好指定 jvm 版本

// 若已安装 Mirai Console 的 Gradle 插件需要使用以下代码指定打包使用的 jvm 目标
mirai {
    jvmTarget = JavaVersion.VERSION_11
}

手动配置主类服务

mirai-console 使用了 Java SPI,SPI 将服务接口和具体的服务实现分离开来,将服务调用方和服务实现者解耦,能够提升程序的扩展性、可维护性。修改或者替换服务实现并不需要修改调用方。(转自知乎open in new window)

要使 mirai-console 能够认出你的插件,你需要在 /META-INF/services/ 下新建文件 net.mamoe.mirai.console.plugin.jvm.JvmPlugin,在该文件内键入插件主类路径,且保证该文件内只有一行插件主类路径。如

org.example.mirai.plugin.ExamplePluginMain

你也可使用 AutoServiceopen in new window 来自动配置服务信息。

新建主类

新建的主类在 Kotlin 要继承 KotlinPlugin,在 Java 要继承 JavaPlugin。

// kotlin
object ExamplePluginMain : KotlinPlugin(
    JvmPluginDescription(
        // 插件ID
        id = "org.example.mirai.plugin",
        // 版本
        version = "1.0.0",
    ) {
        // 插件名
        name("示例插件")
        // 作者
        author("MrXiaoM")
        // 描述
        info("An example plugin for tutorial")
    }
)

在 Java 要新建一个无参数的构造函数并在里面填入插件描述,必须要无参数的构造函数,并使用公开静态字段将其实例化,使其成为与 Kotlin 类似的单例类。

// java
public class ExamplePluginMain extends JavaPlugin {
    public static final ExamplePluginMain INSTANCE = new ExamplePluginMain();
    private ExamplePluginMain() {
        super(new JvmPluginDescriptionBuilder(
            // 插件ID
            "org.example.mirai.plugin",
            // 版本
            "1.0.0"
        )
        // 插件名
        .name("示例插件")
        // 作者
        .author("MrXiaoM")
        // 描述
        .info("An example plugin for tutorial")
        .build());
    }
} 

之后,该重写插件加载/启用/卸载方法了。

重写插件加载/启用/卸载方法

这三个方法分别为onLoadonEnableonDisable。 加载顺序为 onLoadonEnableonDisable。 其中 onLoad 仅会执行一次,由于插件可能会被加载或卸载,故 onEnableonDisable 可能会被执行多次。

特殊地,可以在 onLoad 中注册一个 PostStartupExtension (runAfterStartup) 钩子,runAfterStartup 中的代码将会在 mirai-console 加载完毕后执行 (此时所有插件已加载且机器人自动登录完成),按照正常的插件生命周期,执行顺序一般为 onLoadonEnablerunAfterStartuponDisable

(钩子是编程时常用的名词,一般指作为触发器参数的 lambda)

  • onLoad 主要用于注册公共服务的,例如权限管理
  • onEnable 初始化操作 (如指令注册、数据初始化、事件监听器)
  • runAfterStartup 适合用于开启功能,比如说订阅推送启动 (onEnable 中自动登录还未执行,无法获取到已登录机器人实例,所以不适合开启推送服务)

重写 onLoad/onEnable/onDisable 和注册 PostStartupExtension 钩子的方法的例子如下。

// kotlin
override fun PluginComponentStorage.onLoad() {
    // Plugin load logic
    // do something you want.
    runAfterStartup {
        // do something when console post startup.
    }
}
override fun onEnable() {
    // Plugin enable logic
}
override fun onDisable() {
    // Plugin disable logic
}
// java
@Override
public void onLoad(PluginComponentStorage pcs) {
    // Plugin load logic
    // do something you want.
    pcs.runAfterStartup(() -> {
        // do something when console post startup.
        return Unit.INSTANCE;
    });
}
@Override
public void onEnable() {
    // Plugin enable logic
}
@Override
public void onDisable() {
    // Plugin disable logic
}

完成

至此,你已经学会如何新建项目了。接下来,你好,Mirai。

开发入门篇 /02/ Hello Mirai

注意事项

如果你的项目是用 IDEA 插件生成的,有时候会出现 kotlin 版本获取错误(其实是正确的,只是源里没有),导致类似 1.7.20 was not found 之类的错误,这种情况下请到 build.gradle(.kts) 文件将 1.7.20 改为 1.7.10