简介
本文档页面适用于Paper和Velocity项目。
自Minecraft 1.7以来,游戏使用组件来表示要显示给客户端的文本。组件相比纯文本字符串提供了许多好处,下面将列举这些好处。 Paper和Velocity原生实现了Adventure API,以在任何可能的地方添加组件支持。
为什么你应该使用组件
以前,文本是一个线性结构,只能使用像§c和§k这样令人困惑的符号来控制文本的基本颜色和样式。
组件是一个树状结构,可以从其父组件继承样式和颜色。
组件有几种类型,它们不仅仅是显示原始文本,比如根据键将文本翻译成客户端的语言,或向玩家显示客户端特定的按键绑定。
所有这些组件类型都支持更多的样式选项,如任何RGB颜色、交互事件(点击和悬停)。其他组件类型和这些样式选项在传统字符串格式中表现不佳或缺失。
使用
现在组件是Paper和Velocity表示文本的支持方式。它们用于几乎所有显示给客户端的文本方面。文本如物品名称、说明文字、Boss栏、团队前缀和后缀、自定义名称等在各自的API中都支持组件。
Mojang已经声明
将来会移除客户端对带有§的传统格式的支持。
在Paper API中,有许多处理这种传统格式的已弃用方法和类型。这是为了表明有更好的组件替代方案可用,应该在未来迁移到这些方案。
创建组件
组件可以作为对象进行交互。每种类型都有不同的接口以及所有类型的构建器。这些对象是不可变的,所以在构建更复杂的组件时,建议使用构建器来避免每次更改都创建新的Component实例。
// 这是构建组件的次优方式
// 因为每次更改都会创建一个新组件
final Component component = Component.text("Hello")
.color(TextColor.color(0x13f832))
.append(Component.text(" world!", NamedTextColor.GREEN));
/* 这是使用构建器创建相同组件的最佳方式。
另外请注意,Adventure组件设计为使用静态方法导入
以使代码不那么冗长 */
final Component component = text()
.content("Hello").color(color(0x13f832))
.append(text(" world!", GREEN))
.build();
关于Paper和Velocity使用的Adventure组件API的完整文档,请查看 Adventure文档。
MiniMessage
Paper和Velocity包含MiniMessage库,这是组件的字符串表示。如果你更喜欢使用字符串而不是对象,MiniMessage比传统字符串格式要好得多。它可以利用树状结构来继承样式,并且可以表示更复杂的组件类型,而传统格式则不能。
final Component component = MiniMessage.miniMessage().deserialize(
"<#438df2><b>这是父组件;它的样式会应用到所有子组件。\n<u><!b>这是第一个子组件," +
"它在父组件之后渲染</!b></u><key:key.inventory></b></#438df2>"
);
// 如果上面的语法对你来说太冗长,创建一个辅助方法!
public final class Components {
public static Component mm(String miniMessageString) { // mm,是MiniMessage的缩写
return MiniMessage.miniMessage().deserialize(miniMessageString);
}
}
// ...
import static io.papermc.docs.util.Components.mm; // 替换为你自己的包
final Component component = mm("<blue>你好 <red>世界!");
我们建议将这种格式用于面向用户的输入,如命令或配置值。
MiniMessage是Adventure的一部分,你可以在Adventure的文档中找到它的文档。
MiniMessage有一个网页查看器,这对于构建更复杂的组件并实时查看结果很有用。
JSON格式
组件可以从标准JSON格式序列化和反序列化。这种格式在原版中用于各种接受组件参数的命令,如/tellraw。下面是这种格式的一个简单示例。
{
"text": "这是父组件;它的样式会应用到所有子组件。\n",
"color": "#438df2",
"bold": true,
"extra": [
{
"text": "这是第一个子组件,它在父组件之后渲染",
"underlined": true,
// 这只为这个组件覆盖父组件的"bold"值
"bold": false
},
{
// 这是一个按键绑定组件,它将显示客户端该动作的按键绑定
"keybind": "key.inventory"
}
]
}
JSON格式在Minecraft Wiki上有完整的文档。
有一些在线工具可以使生成这种格式变得更容易,如JSON Text Generator。
序列化器
Paper和Velocity捆绑了不同的序列化器,用于在Component和其他形式的序列化文本之间转换。
GsonComponentSerializer
在Component和JSON格式的字符串之间转换,提供直接处理Gson的JsonElement的便捷方法。
这种转换是无损的,是不需要用户经常编辑的组件的首选序列化形式。
MiniMessage
在Component和MiniMessage格式的字符串之间转换。这种转换是无损的,是需要用户编辑的组件的首选序列化形式。你还可以向序列化器添加大量自定义设置,这在这里有文档说明。
PlainTextComponentSerializer
将Component序列化为纯文本字符串。这是非常有损的,因为所有样式信息以及大多数其他类型的组件都会丢失信息。可能会对TranslatableComponent进行特殊处理,将其序列化为默认语言,但通常除了某些情况(如记录到文本文件)外不应使用。
LegacyComponentSerializer
不建议使用这个,因为传统格式可能在将来被移除。
在Component和传统字符串格式之间转换。
这种转换是非常有损的,因为组件类型和事件在传统字符串表示中没有对应形式。
在迁移过程中将传统文本转换为MiniMessage格式是一个更有用的用例。
final String legacyString = ChatColor.RED + "这是一个传统的" + ChatColor.GOLD + "字符串";
// 通过两个序列化器运行传统字符串以转换legacy -> MiniMessage
final String miniMessageString = MiniMessage.miniMessage().serialize(
LegacyComponentSerializer.legacySection().deserialize(legacyString)
);
有2个内置的传统序列化器,一个处理§符号,另一个处理&符号。它们分别通过LegacyComponentSerializer#legacySection()和LegacyComponentSerializer#legacyAmpersand()提供自己的实例。