一只工具库,封装 Bukkit BungeeCord 以及其他计划中的 Minecraft 服务端 API
目的:
- 一套使用 Java 二次封装的 Bukkit API
- 更友好的 API 形式:链式调用和流(Stream)
- 详尽的文档与 Javadocs 帮助用户理解和使用代码
- 尽可能低的耦合度
- 尽可能小的最终包体积
目录:
- 这是什么?
- 快速开始
- 使用说明
- 示例
- 模块
- 计划
- 文档
- 贡献(PR、Issue 与其他形式的贡献)
- 行为准则
- 开源许可
- 关于开源
目前 Alkaid Lib 发布在 https://repository.alkaidmc.com
需要通过 Maven 或 Gradle 添加自定义仓库再添加对应模块依赖:
Maven
<repository>
<id>alkaidmc-repository-releases</id>
<name>AlkaidMC Repository</name>
<url>https://repository.alkaidmc.com/releases</url>
</repository>
<repository>
<id>alkaidmc-repository-snapshots</id>
<name>AlkaidMC Repository</name>
<url>https://repository.alkaidmc.com/snapshots</url>
</repository>
Gradle
maven { url "https://repository.alkaidmc.com/releases" }
maven { url "https://repository.alkaidmc.com/snapshots" }
Gradle Kotlin
maven { url = uri("https://repository.alkaidmc.com/releases") }
maven { url = uri("https://repository.alkaidmc.com/snapshots") }
编译:使用 Gradle 进行构造
# clone from our repository.
$ git clone https://github.com/hanbings/alkaid
# source dir.
$ cd alkaid
# complie and package with gradle build.
$ gradle build
来点简单的事件监听
使用 Alkaid 提供的链式 API,可以省去原先使用 Bukkit API 定义监听器所需的继承再重写的繁杂步骤。
new AlkaidEvent(plugin).simple()
// 监听的事件
.event(PlayerJoinEvent.class)
// 事件处理器
.listener(event -> {
event.getPlayer().sendMessage("欢迎");
})
// 事件优先级
.priority(EventPriority.HIGHEST)
// 忽略取消标志位
.ignore(false)
// 将事件注册到 Bukkit 事件系统
.register();
事件段落
事件段落由头部事件 - 主逻辑事件处理器 - 尾部事件组成。
监听到头部事件后才会执行事件处理器,最后由尾部事件挂起监听器,直到监听到下一个头部事件重新开始段落。
new AlkaidEvent(plugin).section()
.event(PlayerBedEnterEvent.class)
.listener(event -> {
event.getPlayer().sendMessage("晚安");
})
// 分别处理每一个实体 也就是说每一个实体对应一个段落
// 开启后段落只接受继承 PlayerEvent 或 EntityEvent 的事件
.entity(true)
// 过滤不符合条件的事件
.filter(event -> event.getPlayer().isSleeping())
// 监听到此事件时开始监听
.commence(PlayerBedEnterEvent.class)
// 监听到此事件时停止监听
.interrupt(PlayerBedLeaveEvent.class)
.ignore(true)
.priority(EventPriority.HIGHEST)
.register();
注册指令
new AlkaidCommand(plugin).simple()
.command("alkaid")
.description("须臾曈昽开晓晴 烂银一色摇光晶")
.permission("alkaid.permission")
.usage("/alkaid")
.aliases(List.of("alias"))
.executor((sender, command, label, args) -> {
sender.sendMessage("你好!");
return true;
})
.tab((sender, command, alias, args) -> List.of("你好"))
.register();
注册任务
new AlkaidTask(plugin).simple()
.run(() -> System.out.println("快和我一起歌唱 好孩子才不怕悲伤"))
.delay(20)
.period(20)
.async(true)
.register();
创建一本书
new AlkaidInventory(plugin).book()
.title("这是一本书")
.author("这是一本书的作者")
.write("这是往书里写了一句话")
.write(2, "这是往第三页写了一句话")
// 生成书的 ItemStack
.written();
创建自定义箱子界面
// 创建物品
ItemStack book = new ItemStack(Material.BOOK);
ItemStack glass = new ItemStack(Material.BLUE_STAINED_GLASS_PANE);
// 创建对物品的动作处理
CustomInventory.ItemStackAction action = new CustomInventory.ItemStackAction()
.click(e -> this.getLogger().info("别戳啦!"))
.left(e -> this.getLogger().info("喵喵"))
.right(e -> this.getLogger().info("喵喵"))
.drag(e -> this.getLogger().info("不要!"))
.update(e -> this.getLogger().info("刷新!"));
@SuppressWarnings("all")
Inventory inventory = new AlkaidInventory(this).gui()
.title("Alkaid Custom Inventory")
.rows(3)
// 更新周期
.interval(2000)
// 使用图形结构布局
.structure(
List.of(
"#########",
"####A####",
"#########"
),
Map.of(
'#', new CustomInventory.ItemStackRegister(glass, action),
'A', new CustomInventory.ItemStackRegister(book, action)
)
)
// 打开 Inventory 触发
.open(e -> ((Player) e.getPlayer()).playSound(e.getPlayer().getLocation(), "minecraft:block.note_block.pling", 1, 1))
// 关闭 Inventory 触发
.close(e -> ((Player) e.getPlayer()).playSound(e.getPlayer().getLocation(), "minecraft:block.note_block.pling", 1, 1))
.click(e -> {
if (e.getClickedInventory() == null) return;
if (e.getClickedInventory().getHolder() instanceof Player) return;
e.setCancelled(true);
})
.drag(e -> e.setCancelled(true))
.update((custom, inv , registries) -> {
return registries;
})
.inventory();
物品堆构造器
new AlkaidInventory(plugin).item()
// 从现有的 ItemStack ItemMeta 或 Material 创建一个新的 ItemStackBuilder
.of(Material.DIAMOND_SWORD)
.of(new ItemStack(Material.DIAMOND_SWORD))
// 可堆叠物品堆叠数量
.amount(1)
// 附魔效果
.enchantment(Enchantment.DAMAGE_ALL, 1)
// 标记位
.flag(ItemFlag.HIDE_ENCHANTS)
// 名称
.display("小蛋糕")
// 添加 lore 或 多行 lore
.lore("这是一个小蛋糕")
.lore("吃掉小蛋糕", "吃掉吃掉")
// 本地化键
.localized("alkaid.inventory.cake")
// custom model data
.model(1)
// 设置物品的 unbreakable 标签是否为 true.
.unbreakable(false)
.item();
Json 文本生成
new AlkaidMessage(plugin).text()
.append(it -> it.text("Hello")
.yellow()
.bold()
.underlined()
.hover(hover -> hover.text("一眼翻译,鉴定为:再见")))
// full ver: ... hover.text().text("一眼翻译,鉴定为:再见") ...
.red(", ")
.text("World", "#E682A0", Format.BOLD)
.components();
生成效果
{
"extra": [{
"bold": true,
"underlined": true,
"color": "yellow",
"hoverEvent": {
"action": "show_text",
"contents": [{
"extra": [{
"text": "一眼翻译,鉴定为:再见"
}],
"text": ""
}]
},
"extra": [{
"text": "Hello"
}],
"text": ""
}, {
"color": "red",
"text": ", "
}, {
"bold": true,
"color": "#E682A0",
"text": "World"
}],
"text": ""
}
辅助反射
new AlkaidCommon().reflection()
// 设置类 / 字符串类路径
.clazz(AlkaidCommon.class)
// 指定类加载器
.loader(this.getClass().getClassLoader())
// 是否初始化类
.initialize(true)
// 设置方法名
.method("test")
// 设置执行方法实例
.instance(null)
// 设置方法参数
.args(null)
// 自定义异常
.exception(Throwable::printStackTrace)
// 设置执行结果处理器
.result(System.out::println)
// 执行
.call();
文件监控
new AlkaidCommon().filewatchdog()
.path(Paths.get("alkaid.txt"))
// 监听变化的频率
.delay(1000)
// 状态变更时触发
.create(f -> System.out.println("创建"))
.modify(f -> System.out.println("修改"))
.delete(f -> System.out.println("删除"))
// 自定义异常处理
.exception(e -> System.out.println("异常"))
.watch();
模块 | 描述 | Bukkit 支持 | Bungee Cord 支持 | 不依赖于 Bukkit / Bungee Cord |
---|---|---|---|---|
alkaid-bukkit | Bukkit API 流式封装 | ✔️ | ❌ | ❌ |
alkaid-bungeecord | Bungee Cord 流式封装 | ❌ | ✔️ | ❌ |
alkaid-common | 服务端无关工具类 如反射 sha256 | ✔️ | ✔️ | ✔️ |
alkaid-inventory | 物品和物品容器封装 | ✔️ | ❌ | ❌ |
alkaid-log | 控制台 Logger 封装 包括色彩 | ✔️ | ✔️ | ✔️ |
alkaid-message | 表达信息类封装 | ✔️ | ⭕️ | ❌ |
alkaid-metadata | 处理 NBT 和 Region 原始数据 | ✔️ | ❌ | ❌ |
alkaid-mongodb | 对于 MongoDB 数据库的封装 | ✔️ | ✔️ | ✔️ |
alkaid-organism | 提供生物 AI 框架 | ✔️ | ❌ | ❌ |
alkaid-redis | 对于 Redis 中间件的封装 | ✔️ | ✔️ | ✔️ |
alkaid-world | 维度、群系与方块 | ✔️ | ❌ | ❌ |
通过计划列表可以知道我们正在进行什么工作以及计划进行什么工作。
同样的,欢迎 PR 为龙龙添加功能,但最好事先与我们讨论一下,避免重复实现。
如果希望我们实现某些功能可以通过 Issue 告诉我们,关于 Issue / PR 有一些要求,请往下阅读。
详细文档在 Github Pages 中展示,它们的源文件在这个仓库的 docs
目录中。
什么是贡献?
贡献是协助或参与我们开发的过程,包括但不限于向我们报告漏洞、请求合理的新功能和提交代码。
对于 Issue / PR 以及其他可能的一些贡献我们有一些特殊的要求,还请仔细看一看,感谢支持 w
我们正在编写行为准则...
本项目使用 Apache License, Version 2.0 许可协议进行开源。
本项目是非盈利性项目。
依据协议,本项目允许遵守协议的前提下基于本项目开发的项目进行商用,但需要注意的是,本项目中的图片(包括 Readme.md 文件中所展示的吉祥物狼龙摇光和可能出现的其他图片)不属于开源的范围
它们属于开发者 寒冰 hanbings 个人所有,是寒冰的崽子,请在复制、修改本项目时移除它们。
版权警告:吉祥物狼龙摇光图片中所使用 Alkaid 字样字体为商业需授权字体 Snap ITC
开源是一种精神。
开源运动所坚持的原则:
- 坚持开放与共享,鼓励最大化的参与与协作。
- 尊重作者权益,保证软件程序完整的同时,鼓励修改的自由以及衍生创新。
- 保持独立性和中立性。
与来自五湖四海的开发者共同讨论技术问题,解决技术难题,促进应用的发展是开源的本质目的。
众人拾柴火焰高,开源需要依靠大家的努力,请自觉遵守开源协议,弘扬开源精神,共建开源社区!