创建占位符标记

警告

这些文档是为 SpongeAPI 7 编写的,可能已经过时。 如果你觉得你可以帮助更新它们,请提交一个 PR!

Sponge 占位符 API 的核心是能够创建你自己的占位符标记,并让所有插件都能访问到它们。 想要要创建你自己的占位符,你必须创建一个实现了 PlaceholderParser 接口,且在正确的注册表中注册了的对象。

创建占位符解析器

有两种方法可以创建 PlaceholderParser

  • 使用 PlaceholderParser#builder(),提供您的 PluginContainer,命名空间内未使用的 ID,以及一个参数类型为``PlaceholderContext``、返回类型为 Component 的函数。

  • 直接实现这个接口。

PlaceholderParser 对象持有一个包含请求上下文的 PlaceholderContext 对象并且返回一个依赖于上下文的 ComponentPlaceholderContext 可能包含的信息有:

  • 一个相关的对象,例如一个 Player

  • 通常由模板引擎提供的参数字符串

这是 Sponge 指定的最低限度。

如果你的占位符因为上下文不足而无法提供文本,那么占位符应该返回一个空 Component 并且不要抛出异常。

小技巧

如果你期望拥有处理多个参数的能力,那请考虑指定分割参数字符串的方法。

记着告诉用户你的插件所需的参数字符串的格式。

示例:默认世界名称占位符解析器

这个 PlaceholderParser 尝试获取默认世界的名称,如果无法找到就返回空 Component。它使用了生成器来创建 ID 为 spongedocs:defaultworld 的解析器,假定插件 ID 为 spongedocs

import net.kyori.adventure.text.Component;

PluginContainer thisPlugin = ...;

PlaceholderParser parser = PlaceholderParser.builder()
    .plugin(this.thisPlugin)
    .id("defaultworld")
    .name("Default World Placeholder")
    .parser(placeholderContext -> {
        return Sponge.getServer()
            .getDefaultWorld()
            .map(x -> x.getWorldName())
            .orElse(Component.empty());
    })
    .build();

示例:玩家位置占位符解析器

这个 PlaceholderParser 尝试获取玩家在世界中的位置,如果没有 Player 作为关联对象,它将会返回空 Component,它直接实现了 PlaceholderParser 接口。

import net.kyori.adventure.text.TextComponent;

public class PlayerLocationPlaceholder implements PlaceholderParser {

    @Override
    public String getId() {
        return "spongedocs:location"
    }

    @Override
    public String getName() {
        return "Location Placeholder"
    }

    @Override
    public Component parse(PlaceholderContext placeholderContext) {
        placeholderContext.associatedObject()
            .filter(x -> x instanceof Player)
            .map(player -> ((Player) player).getLocation())
            .map(location -> TextComponent.ofChildren(
                Component.text("World: "),
                Component.text(location.getExtent().getName()),
                Component.text(" - "),
                Component.text(location.getPosition())))
            .orElse(Component.empty());
    }
}

示例:当前时间占位符解析器

这个 PlaceholderParser 返回了服务器本地时区的当前时间,如果提供了“UTC”作为参数字符串,它将会返回 UTC 时区的当前时间,它直接实现了 PlaceholderParser 接口。

public class CurrentTimePlaceholder implements PlaceholderParser {

    @Override
    public String getId() {
        return "spongedocs:currenttime";
    }

    @Override
    public String getName() {
        return "Current Time parser";
    }

    @Override
    public Component parse(PlaceholderContext placeholderContext) {
        if (placeholderContext.argumentString().filter(x -> x.equalsIgnoreCase("UTC")).isPresent()) {
            return Component.text(OffsetDateTime.now(ZoneOffset.UTC).format(FORMATTER));
        }
        return Component.text(OffsetDateTime.now().format(FORMATTER));
    }

}

注册你的占位符解析器

为了让你的解析器可以被其他插件轻松访问,它必须在注册表中注册。这需要通过监听 GameRegistryEvent.Register<PlaceholderParser> 事件并且使用 register 方法注册。

示例:注册一个占位符解析器

PlaceholderParser parser = ...;

@Listener
public void registerTokensEvent(GameRegistryEvent.Register<PlaceholderParser> event) {
    event.register(this.parser);
}