警告: 此文档不保证始终有效,因为有时我可能会重构 KookBC,导致文档提到的类、方法等元素不可用,如果出现这种情况,请联系我。
此文档旨在教您如何将 KookBC 嵌入您的项目,以便于与 Kook 交互。
我们假设您的项目使用 Maven 作为构建工具。
- 一个待嵌入 KookBC 的项目
- 对 Maven 中央仓库,以及 JitPack 连接通畅的网络
首先,请在您的 pom.xml 里添加 JitPack 作为仓库。如果您之前已经添加过,请跳过此步。
然后,在您的 pom.xml 里添加 KookBC 作为依赖项。
格式如下:
<dependency>
<groupId>com.github.SNWCreations</groupId>
<artifactId>KookBC</artifactId>
<version>0.37.0</version>
<scope>compile</scope>
</dependency>
- 注意: 本文可能不会随着 KookBC 的更新而修改
version
项,请自行将其替换为您需要的版本。
之后,刷新您的项目,等待 KookBC 从 JitPack 下载。
失败了?没关系,那很正常,对于一个从未在 JitPack 编译过的工件,第一次请求总是失败的。
如果这个情况出现了,请去您的本地 Maven 仓库将 com\github\SNWCreations\KookBC\<version>
(自行替换 <version>
为使用的版本) 文件夹删除,然后等待几分钟,再次刷新您的项目,应该就可以了。
如果 JitPack 构建出错,请联系我。
我们遇见过使用 snw.kookbc.LaunchMain
或 snw.kookbc.Main
类启动 KookBC 的情况,但是那是不推荐的。
你可以参考 snw.kookbc.Main
类的代码,以了解 KookBC 的正常启动流程。
- 请不要尝试阅读
snw.kookbc.LaunchMain
类以了解 KookBC 的启动流程!那是为了配合 Mixin 支持而编写的。那其中并没有启动的逻辑。
请直接使用 KBCClient
类。
有两个类是很重要的:
snw.kookbc.impl.CoreImpl
(实现了snw.jkook.Core
)snw.kookbc.impl.KBCClient
(表示一个 KookBC 实例)
首先,你需要构造一个 CoreImpl
的实例。
它有两个构造方法:
CoreImpl()
CoreImpl(org.slf4j.Logger)
一般情况下,我们推荐前者,因为前者默认使用 org.slf4j.helpers.NOPLogger
作为 Logger 。NOPLogger
使日志不会输出。
后者也是可以用的,您只是需要传入一个 org.slf4j.Logger
的实例。
构造之后请务必用这个实例调用 snw.jkook.JKook#setCore(Core)
方法,以保证需要通过 JKook Class 访问 Core
的方法能正常运行。
现在,您有了一个 CoreImpl
的实例。
但这只是第一步。真正重要的是 KBCClient
。
让我们看 KBCClient
的构造方法。
public class KBCClient {
public KBCClient(
snw.kookbc.impl.CoreImpl core,
snw.jkook.config.ConfigurationSection config,
java.io.File pluginsFolder,
String token
) {
// Actual logic here
}
}
由此可见,您需要一个 CoreImpl
实例,一个 ConfigurationSection
实例,和一个 File
实例。
解释一下这四者的作用:
core
: 用于 KookBC 实例的操作。在此项目中,通过调用JKook.getCore()
(高版本还有Plugin#getCore
) 得到的就是这个。config
: 即此客户端的配置数据。一般是kbc.yml
加载后的结果。(kbc.yml
使用YamlConfiguration
类的方法加载)pluginsFolder
: 即存放插件的 文件夹,可以为null
,为null
时,KookBC 将不会尝试从任何地方加载插件。token
: Bot Token
按照这个方法,您应该得到了一个 KBCClient
的实例。
现在就是启动了。
请看 KBCClient#start
方法。
public class KBCClient {
public void start() {
// Actual logic here
}
}
没有需要的参数,直接调用吧。
请注意,此方法可能会抛出 RuntimeException
,请注意捕获并处理。
此方法返回后,意味着您的 Kook Bot 已经启动,可以开始用 JKook API 进行操作了。
只需要调用 KBCClient#shutdown
方法即可。
但请注意,此方法可能会抛出 RuntimeException
,请注意捕获并处理。
首先,在嵌入 KookBC 的环境中,请不要直接通过 new
关键字使用 snw.jkook.plugin.BasePlugin
及其子类。
- 为什么?
BasePlugin
在构造时会检查加载其类的类加载器是否是snw.jkook.plugin.MarkedClassLoader
的子类 (在过去的 API 版本中比较的是snw.jkook.plugin.PluginLoader
),如果不是,会抛出异常。
怎么办?
你可以参考 snw.kookbc.impl.plugin.InternalPlugin
,编写一个始终被启用的,除了能返回一个 PluginDescription
以外什么都不能做的 Plugin
。
然后直接 new
这个占位符插件,用来调用需要 Plugin
实例的方法。
这个方法是最推荐的。
此节介绍 KBCClient
类内的部分方法。
此方法会启动控制台并一直循环监听用户输入,会阻塞当前线程。
除非此方法执行过程中出现错误,否则此方法永远不会返回。
注意! 此方法返回不代表当前客户端终止。 若要等待客户端结束运行,使用 KBCClient#waitUntilShutdown 方法。
此方法使当前线程阻塞,直到当前客户端实例终止。
此方法会从 pluginsFolder 加载插件。
您可以重写此方法,只需要把您所加载的插件通过 plugins.add(Plugin)
添加就可以了。
此方法获取绑定到此客户端实例的 CoreImpl
实例。
此方法会启动网络模块。
您可以重写此方法,如果您对于 Kook 连接有自己的处理方法。
如果要覆盖此方法,请同时覆盖 KBCClient#shutdownNetwork
方法,以便于您可以关闭您自己的网络相关模块。
此方法会向当前客户端实例注册一些内部命令,如 /help
,/plugins
,/stop
,以及注册一些可以比由插件注册的事件监听器更优先运行的事件监听器。
此方法会被 KBCClient#registerInternal
方法调用,用于向当前客户端注册 /help
命令的实现。
如果你需要禁用默认的 /help
的实现,请用空方法体覆盖此方法。
此方法会被 KBCClient#registerInternal
方法调用,用于向当前客户端注册 /stop
命令的实现。
如果你需要禁用默认的 /stop
的实现,请用空方法体覆盖此方法。
此方法会被方法调用,用于向当前客户端实例注册 /plugins
命令的实现。
如果你需要禁用默认的 /plugins
实现,请用空方法体覆盖此方法。
哦,这是一个有趣的想法!
但是在你这样做之前,让我们先告诉你一些有关这个的坑...
你是 "Minecraft Development" IDEA 插件的用户吗?
如果是,请注意!由这个插件生成的 Maven Bukkit 项目 (包括但不限于 Bukkit, Spigot) 所使用的 Maven Shade 插件是 3.2.4 。
而这个版本在 Shade KookBC 时会出现 "类版本不受支持" (Unsupported class version) 的问题,应该先升级插件。
经过测试,3.3.0 版本是正常的。
另外,在 Shade KookBC 时,你需要 Relocate 两个包:
- Google GSON (com.google.gson)
- SnakeYAML (org.yaml.snakeyaml)
为什么?
这两个包是很容易与 Bukkit 服务端冲突的,因为 Bukkit 项目也在使用它们。
怎么做?
像下面这样配置你的 Maven Shade 插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>shade</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>your.package.here.com.google.gson</shadedPattern>
</relocation>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>your.package.here.org.yaml.snakeyaml</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
其他的配置项按你自己的需求配置即可,但 relocations
标签以及指定的两个包的 relocation
必不可少。
shadedPattern
的内容随意,并不一定要按我们提供的写,这只是模板,但内容不可以与原本的 pattern
相同。
- 诸如
snw.myproject.include.com.google.gson
的字符串作为shadedPattern
是可以的。