创建占位符标记

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

创建占位符解析器

有两种方法可以创建 PlaceholderParser

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

  • 直接实现这个接口。

備註

PlaceholderParsers索引类型。如果你直接实现了这个接口的话,切记解析器的ID应当在插件的命名空间内,使用``[pluginid]:[placeholderid]``的格式。ID也必须要是唯一的。

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

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

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

这是 Sponge 指定的最低限度。

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

小訣竅

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

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

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

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

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(Text.EMPTY);
    })
    .build();

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

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

public class PlayerLocationPlaceholder implements PlaceholderParser {

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

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

    @Override
    public Text parse(PlaceholderText placeholderText) {
        placeholderText.getAssociatedReceiver()
            .filter(x -> x instanceof Player)
            .map(player -> ((Player) player).getLocation())
            .map(location -> Text.of("World: ", location.getExtent().getName(), " - ", location.getPosition()))
            .orElse(Text.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 Text parse(PlaceholderContext placeholderContext) {
        if (placeholderContext.getArgumentString().filter(x -> x.equalsIgnoreCase("UTC")).isPresent()) {
            return Text.of(OffsetDateTime.now(ZoneOffset.UTC).format(FORMATTER));
        }
        return Text.of(OffsetDateTime.now().format(FORMATTER));
    }

}

注册你的占位符解析器

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

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

PlaceholderParser parser = ...;

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