Skip to content

消息外部化 (i18n)

ArcartXSuite 1.1.0 起提供 消息外部化框架,让模块的所有用户可见文本从硬编码迁移到可编辑的 messages.yml。服主可自定义措辞、翻译为其他语言,无需改动代码。

核心组件

组件位置职责
MessageProviderapi.message加载 messages.yml,提供 get(key, args...) 取值
AbstractAXSModule#messagesFileName()api声明消息文件名,基类自动导出+加载
AbstractAXSModule#messages()api获取已加载的 MessageProvider

工作原理

模块 jar 内 messages.yml
   │ (构建期 ProtectYamlResourcesTask 加密)

arcartx/internal/protected/<base64>.axb
   │ (onEnable 时 context.exportConfigResource 解密导出)

data/<moduleId>/messages.yml  ← 用户可编辑
   │ (MessageProvider.load 读取)

messages().get("key", args)  ← 代码中使用

消息文件与 config.yml 走同一套加密/导出管线。

接入步骤

1. 创建默认消息文件

在模块 src/main/resources/messages.yml

yaml
# 支持 & 颜色码和 {0} {1} 占位符
prefix: "&3◆ &6ArcartXSuite &7| &r"
no-permission: "&c你没有权限执行这个命令。"
toggle:
  enabled: "&a功能已开启。"
  disabled: "&e功能已关闭。"
status:
  mode: "&7当前模式: &f{0}"

嵌套键用点号路径访问:status.mode"当前模式: {0}"

2. 模块声明消息文件

java
@Override
protected String messagesFileName() {
    return "messages.yml";
}

3. 注入到命令/服务

messages()startService() 之前已就绪,可直接传给命令:

java
@Override
protected Map<String, TabExecutor> commandBindings() {
    return Map.of("mycommand", new MyCommand(messages()));
}

4. 替换硬编码文本

java
// 改造前
player.sendMessage(PREFIX + ChatColor.RED + "你没有权限执行这个命令。");

// 改造后
player.sendMessage(messages.get("prefix") + messages.get("no-permission"));

带占位符:

java
// messages.yml:  status.mode: "&7当前模式: &f{0}"
player.sendMessage(messages.get("status.mode", modeName));

API 速查

方法说明
get(key)取消息;键不存在时返回键名本身(便于发现遗漏)
get(key, args...)取消息并替换 {0} {1} ... 占位符;null 参数替换为空串
has(key)判断键是否存在
size()已加载消息条数

get 自动翻译 & 颜色码为 §

迁移现状

消息外部化采用渐进式迁移:基础设施已就绪,各模块逐步接入。

模块状态
pickup✅ 已迁移(玩家命令范例)
onlinerewards✅ 已迁移(管理+玩家命令范例)
loginview✅ 已迁移(管理命令,service 消息已在 config 定制)
combateffect✅ 已迁移(非基类模块手动集成范例)
announcer✅ 已迁移(广播+字幕管理命令)
eventpacket✅ 已迁移(信号触发+清理管理命令)
title✅ 已迁移
prop✅ 已迁移(基类模块管理命令范例)
questgps✅ 已迁移(基类模块双命令范例,包含玩家/管理命令)
map✅ 已迁移(基类模块双命令范例,包含玩家/管理命令)
chat✅ 已迁移(基类模块,三模式多指令集成范例)
market✅ 已迁移(基类模块双命令范例,包含玩家/管理命令)
rgb⚪ 无需迁移(纯 PlaceholderAPI 渲染,无命令消息)
qqbot✅ 已迁移(基类模块双命令范例,包含玩家/管理命令)
conversation✅ 已迁移(基类模块,NPC/动画交互命令范例)
warehouse✅ 已迁移(基类模块双命令,支持二级密码与银行接口外部化)
tab✅ 已迁移(基类模块,支持复杂虚拟快照管理与翻页命令外部化)
regions✅ 已迁移(基类模块,支持选区、世界规则及标志指令外部化)
essentials✅ 已迁移(基类模块自承载 ModuleCommandHandler 巨型指令集全部外部化)
其余模块🎉 100% 迁移完毕

非基类模块:少数模块(如 combateffect)直接 implements AXSModule 而非继承 AbstractAXSModule,无法用 messages()。它们需在 onEnable 手动 context.exportResource("messages.yml", file, false) + new MessageProvider(...).load(),自行实现 msg() 辅助方法。

分层原则:命令层的框架性文本(权限/用法/状态标签/help)外部化到 messages.yml;业务结果消息(如 OperationResult.message())和已在 config.yml 定制的文本(如签到完成语、loginviewmessages.locked() 锁定提示)保持原状。迁移前先检查该模块是否已有 config.yml 内的 messages 节——若有则无需重复外部化。

注意事项

  • 键命名:用 kebab-case + 点号分层(如 toggle.enabled
  • 前缀复用:把 prefix 也放进 messages.yml,连品牌前缀都可定制
  • reload 生效:用户编辑 data/<moduleId>/messages.yml/axs reload <module> 即可
  • 新增字段无需迁移声明messages.yml 不是配置,不走 ConfigDiagnosticEngine,新增键直接在 jar 默认文件补充即可

基于 GPL-3.0 许可发布