Appearance
插件开发
Bngeuit 的插件系统支持热加载,插件 JAR 放入 plugins/ 目录即自动加载。
生命周期
onLoad() # 插件被加载(Bngeuit.api() 尚未就绪)
↓
onEnable() # 插件被启用(Bngeuit 静态方法可用)
↓
onActive() # 机器人上线(两种接入模式统一触发一次,见下)
↓
... 运行中 ...
↓
onDisable() # 插件被卸载(清理资源)onActive() 是「机器人已就绪、可以收发消息」的统一时机,每次启动最多触发一次,两种接入方式等价:
- WebSocket —— 全部分片均收到网关真实 READY 后
- Webhook —— 回调服务启动完成后
相比监听 ReadyEvent(WebSocket 网关专属事件:每分片各触发一次,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.classGradle 构建
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。
