Skip to content

插件开发

Bngeuit 的插件系统支持热加载,插件 JAR 放入 plugins/ 目录即自动加载。

生命周期

onLoad()      # 插件被加载(Bngeuit.api() 尚未就绪)

onEnable()    # 插件被启用(Bngeuit 静态方法可用)

onActive()    # 机器人上线(两种接入模式统一触发一次,见下)

   ... 运行中 ...

onDisable()   # 插件被卸载(清理资源)

onActive() 是「机器人已就绪、可以收发消息」的统一时机,每次启动最多触发一次,两种接入方式等价:

  • WebSocket —— 全部分片均收到网关真实 READY 后
  • Webhook —— 回调服务启动完成后

相比监听 ReadyEventWebSocket 网关专属事件:每分片各触发一次,Webhook 模式不触发),在 onActive() 中做「机器人上线初始化」(如启动定时推送)无需关心接入模式与分片,也无需自行防重;断线重连(RESUME)不会重复触发。机器人上线后才热加载的插件,onEnable() 返回后会立即补调一次 onActive()

插件主类

所有插件继承 JavaPlugin,通过 Bngeuit 静态方法调用 API:

java
package com.example.myplugin;

import cn.org.bukkit.bngeuit.Bngeuit;
import cn.org.bukkit.bngeuit.plugin.JavaPlugin;
import cn.org.bukkit.bngeuit.event.SubscribeEvent;
import cn.org.bukkit.bngeuit.event.receive.GroupAtMessageEvent;
import cn.org.bukkit.bngeuit.event.receive.C2CMessageEvent;

public class MyPlugin extends JavaPlugin {

    @Override
    public void onLoad() {
        getLogger().info("插件加载中...");
    }

    @Override
    public void onEnable() {
        getLogger().info("插件已启用!");
    }

    @Override
    public void onActive() {
        // 机器人上线(WS 全部分片就绪 / Webhook 回调服务就绪),只触发一次
        getLogger().info("机器人已上线,启动定时任务...");
    }

    @Override
    public void onDisable() {
        getLogger().info("插件已卸载");
    }

    @SubscribeEvent
    public void onGroupAt(GroupAtMessageEvent e) {
        // 被动回复群文本
        Bngeuit.replyGroupText(
            e.getGroupOpenid(), e.getId(), 1,
            "你好," + e.getAuthor().username() + "!"
        );
    }

    @SubscribeEvent
    public void onC2C(C2CMessageEvent e) {
        // 回复私聊
        Bngeuit.replyC2CText(
            e.getAuthor().id(), e.getId(), 1,
            "收到你的私聊消息"
        );
    }
}

JavaPlugin 便捷方法

方法返回类型说明
getConfig()YamlConfig插件配置(若 JAR 内有 config.yml),未配置时为 null
getLogger()Logger插件专属 Logger(Plugin.<插件名>
getDataFolder()File数据文件夹 plugins/<插件名>/
getDescription()PluginDescription插件描述信息
getState()PluginState当前状态
getApi()BotApi获取 API(等价 Bngeuit.api()

项目结构

my-plugin/
├── libs/
│   └── Bngeuit.jar       # 核心 jar(本地依赖,见 Gradle 构建)
├── build.gradle.kts
└── src/
    └── main/
        └── resources/
        │   └── plugin.yml        # 必须
        └── java/
            └── com/example/myplugin/
                ├── MyPlugin.java  # 主类(继承 JavaPlugin)
                ├── MyListener.java # 事件处理器
                └── MyCommand.java  # 命令类

打包后的 JAR:

MyPlugin.jar
├── plugin.yml              # 插件元信息(必须)
├── config.yml              # 默认配置(可选)
└── com/example/myplugin/
    ├── MyPlugin.class
    ├── MyListener.class
    └── MyCommand.class

Gradle 构建

Bngeuit 未发布到任何 Maven 仓库,需要把核心 jar 下载到插件项目本地,再以本地文件方式引用。

kotlin
plugins {
    id("java")
}

repositories {
    mavenCentral()
}

dependencies {
    // 从发布页下载 Bngeuit.jar,放到本项目的 libs/ 目录
    compileOnly(files("libs/Bngeuit.jar"))
}

java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
}

为什么用 compileOnly

插件运行时,核心 jar 已由机器人进程(Bngeuit.jar)加载到父级 ClassLoader,插件不能也不应把核心类打包进自己的 jar。因此编译期用 compileOnly(只在编译时可见、不打包),打包插件时只包含插件自身的类。

插件配置 (config.yml)

如果 JAR 内包含 config.yml,Bngeuit 会在首次加载时自动复制到 plugins/<插件名>/config.yml。已有配置不会被覆盖。

java
// 读取
String groupId = getConfig().getString("group_openid");
int count = getConfig().getInt("max_count");

// 写入
getConfig().set("last_user", "xxx");
getConfig().save();

依赖排序

硬依赖(depend)

yaml
depend:
  - RequiredLib        # 必须存在,否则加载失败

软依赖(softdepend)

yaml
softdepend:
  - OptionalFeature    # 存在则先加载,不存在则跳过

注解自动扫描

插件 JAR 内的所有类会被 PluginManager 自动扫描,无需手动注册:

  • @SubscribeEvent → 自动注册到事件总线
  • @Command → 自动注册到命令管理器(命名空间 = 插件名小写,支持 插件名:命令 精确指定,见 @Command 注解

YamlConfig API

YamlConfig 是 Bngeuit 的 YAML 配置系统,支持链式路径访问、类型安全的 getter、默认值机制、嵌套节点遍历等功能。

基本使用

java
// 获取插件配置(自动加载 JAR 内的 config.yml)
YamlConfig config = getConfig();

// 读取配置值(支持点号路径访问嵌套配置)
String appId = config.getString("bot.appId");
int port = config.getInt("bot.port", 8080);  // 带默认值
boolean debug = config.getBoolean("bot.debug", false);

// 读取列表
List<String> groups = config.getStringList("bot.allowedGroups");

// 写入配置值
config.set("bot.debug", true);
config.save();  // 保存到文件

完整 API 请参考 Javadoc。