正在载入

等待时间过长时请刷新页面

编写于

最近更新

高级字符串

Linlang 高级字符串用于在普通文本中组合 Minecraft 的颜色、文本样式、悬浮信息和点击行为。
一段最简单的高级字符串如下:

点击这里[@color=yellow;click.run="/rs help"]

点击这里 是显示文本,紧随其后的 [@...] 是这段文本的描述符。描述符可以为空或省略,此时文本按原版样式显示。

文本片段

一条高级字符串可以由任意数量的文本片段组成:

欢迎使用[@color=gray]琳琅[@gradient="#ff70c8,#70ddff";bold]![]

描述符只作用于它前方相邻的文本片段,不会向后继承。上例中:

  1. 欢迎使用 使用灰色。
  2. 琳琅 使用渐变色并加粗。
  3. 由空描述符 [] 明确标记为原版样式。

只有 [@ 开始的中括号内容会被识别为高级描述符。因此,[VIP][系统] 等普通文本不需要转义。

[] 是片段边界,不会显示在游戏中。如果确实需要显示 [@[],请转义左中括号:

\[@color=red]
\[]

反斜线本身使用 \\ 表示。

描述符

同一片段的多个描述符使用分号 ; 分隔。包含空格、分号或其他特殊字符的值应使用双引号 "" 包裹。

支持 Minecraft 颜色或更多色彩(十六进制颜色):

警告[@color=red]
自定义颜色[@color=#70ddff]

可用的文本样式包括:

重要[@bold]
说明[@italic]
链接[@underlined]
删除[@strikethrough]
随机字符[@obfuscated]

样式也可以显式设置为 false,例如 [@bold=false]

渐变与彩虹效果的写法如下:

琳琅[@gradient="#ff70c8,#70ddff"]
彩虹文本[@rainbow]

渐变至少需要两个颜色值,也可以按顺序提供更多颜色。运行时会按 Unicode 字符为文本计算颜色。

悬浮文本、插入文本和字体键分别使用:

查看说明[@hover="鼠标悬浮时显示的内容"]
玩家名称[@insertion="PlayerName"]
自定义字体[@font="minecraft:uniform"]

悬浮内容支持普通文本和 Minecraft 色彩( &§ 颜色代码),不能递归解析高级描述符。

点击行为包括:

执行命令[@click.run="/rs help"]
建议命令[@click.suggest="/rs "]
复制文本[@click.copy="需要复制的文本"]
打开网页[@click.url="https://jling.me"]

一个文本片段只能声明一个点击行为。语言文件中包含 click.runclick.url 时,应把该语言文件视为可信资源,不要把玩家输入直接作为高级文本使用。

Java 类型

LinText 是保存高级字符串源码的不可变对象:

import api.linlang.text.LinText;

LinText help = LinText.of(
        "点击查看帮助[@color=yellow;click.run=\"/rs help\"]"
);

消息服务可以直接接受高级字符串:

messenger.send(
        player,
        "点击查看帮助[@color=yellow;click.run=\"/rs help\"]"
);

语言文件

LangText 同样是一种文本来源,因此语言文件可以直接保存高级字符串:

public LangText success = LangText.of(
        "操作成功[@color=green]"
);
success: '操作成功[@color=green]'

发送时直接传入语言字段引用:

messenger.send(player, lang.success);

消息服务会在每次发送时解析 LangText,普通语言重载后不需要重新注册消息模板。

变量

高级字符串继续使用 {name} 形式的命名变量:

give-item: '{player} 获得了 {item}'
messenger.send(
        player,
        lang.giveItem,
        "player", player.getName(),
        "item", itemName
);

其中,要替换的变量类型决定替换方式:

  1. String 字符串、数字、布尔值和其他普通对象会被转义后作为普通文本插入。
  2. LinTextLangText 等会作为独立高级文本片段插入。

因此,将玩家名称作为普通字符串变量传入时,即使其中包含 [@click.run=...],也不会生成点击行为。需要让变量包含高级文本效果时,应显式创建 LinText

LinText itemName = LinText.of("钻石[@color=aqua]");
messenger.send(player, lang.giveItem, "item", itemName);

使用 {{ 可以输出普通左花括号。未提供值的变量会保持原样。

游戏内处理

聊天和动作栏使用组件发送,因此可以保留颜色、悬浮和点击行为。Bukkit 标题接口和控制台只接受旧式文本,运行时会保留可表示的颜色与样式,但点击和悬浮行为无法生效。

如果您的控制台输出了彩色文本的源代码,这不是 Linlang 的错误。

当描述符存在名称无效、引号未闭合、渐变颜色不足或同一片段声明多个点击行为等错误时,Linlang 会抛出 IllegalArgumentException 异常,并且在控制台中告知错误位置。

实现流程

flowchart LR
    Source["String、LinText 或 LangText"] --> Resolve["解析当前文本来源"]
    Resolve --> Args["安全绑定命名变量"]
    Args --> Prefix["按消息策略组合前缀"]
    Prefix --> Parse["解析文本片段与描述符"]
    Parse --> Render["转换为 Bukkit 文本组件"]
    Render --> Transport["由消息传输层投递"]

高级字符串本身只描述文本内容,不包含标题时长、消息通道、接收者或降级策略。这些信息属于消息服务,而不是文本描述符。

讨论

请登录账号