文本模板

TextTemplate 是一个简单方便的方法来存储具有可变元素的消息。例如,您可能会发现自己希望为首次加入服务器的玩家,创建一个可配置的消息。利用 TextTemplate ,我们很容易实现:

假设我们要创建一个玩家加入消息,其中玩家的名字将是天蓝色和粗体,服务器的名称将是红色和粗体,而其他文本是黄色和斜体。我们可以使用以下代码创建对应的文本模板:

import static org.spongepowered.api.text.TextTemplate.*;
import org.spongepowered.api.text.TextTemplate;
import org.spongepowered.api.text.format.TextColor;
import org.spongepowered.api.text.format.TextStyle;

TextTemplate template = of(
    TextColors.YELLOW, TextStyles.ITALIC, "Welcome to ",
    arg("server").color(TextColors.RED).style(TextStyles.BOLD), " ",
    arg("player").color(TextColors.AQUA).style(TextStyles.BOLD), "!"
);

你可以使用 TextTemplate#apply() 方法获取此文本模板的结果。 apply() 方法接受一个 Map<String, TextElement> 参数,其中键是参数的名称,值是你想要替换的内容对应的 TextElement

注解

除非一个参数在创建时通过 Arg.optional() 指定为“可选”,否则提供给 apply() 方法的 Map<String, TextElement> 将在缺少参数时抛出一个 TextTemplateArgumentException 。参数也可以在创建时使用 Arg.defaultValue() 指定一个默认值。

注解

虽然参数可以具有与其相关联的文本格式,但是可以通过通过 apply() 方法向参数映射提供具有自定义格式的 Text 对象来覆盖以解决问题。

TextTemplate ,和 Text 类似,其对象本身可以为 Configurate 所序列化。下面的代码展示了如何将 TextTemplate 保存到配置文件。我们还将在此添加一个可配置项,以便用户定义其服务器的名称。

小技巧

如想要学习更多关于如何使用 Configurate 处理插件的配置文件,请参阅 插件配置 中的内容。

import ninja.leaping.configurate.ConfigurationNode;
import com.google.common.reflect.TypeToken;

ConfigurationNode node = loader.load();
node.getNode("serverName").setValue("My Sponge Server");
node.getNode("mytemplate").setValue(TypeToken.of(TextTemplate.class), template);
loader.save(node);

这将会产生以下输出:

serverName="My Sponge Server"
mytemplate {
    arguments {
        player {
            optional=false
        }
        server {
            optional=false
        }
    }
    content {
        color=yellow
        extra=[
            "Welcome to ",
            {
                bold=true
                color=red
                text="{server}"
            },
            " ",
            {
                bold=true
                color=aqua
                text="{player}"
            },
            "!"
        ]
        italic=true
        text=""
    }
    options {
        closeArg="}"
        openArg="{"
    }
}

你可以通过下面的代码从配置文件中加载并生成一个 TextTemplate

TextTemplate template = node.getNode("mytemplate").getValue(TypeToken.of(TextTemplate.class));

一旦你对新的 TextTemplate 的布局感到满意,让我们继续使用下面的代码使得一个玩家第一次加入服务器发送我们想要的信息:

小技巧

如想要了解更多关于插件中如何处理事件的内容,请参阅 事件 中的内容。

import com.google.common.collect.ImmutableMap;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.network.ClientConnectionEvent;
import org.spongepowered.api.text.Text;
import java.time.Instant;
import java.util.Optional;

@Listener
public void onJoin(ClientConnectionEvent.Join event) {
    Player player = event.getTargetEntity();
    Instant firstPlayed = player.firstPlayed().get();
    Instant lastPlayed = player.lastPlayed().get();
    if (firstPlayed.equals(lastPlayed)) {
        // Player has not been to this server before
        // First we will get the server name from our configuration file
        String serverName = node.getNode("serverName").getString();
        // Next we will send the template to the server,
        // using the "server" and "player" template parameters
        Text message = this.template.apply(ImmutableMap.of(
                "server", Text.of(serverName), "player", Text.of(player.getName())
        )).build();
        event.setMessage(message);
    }
}