<<<<<<< HEAD
1.LangUtil 是什么?
LangUtil 是一个 Minecraft 1.12.2 Bukkit / Spigot 多语言管理插件。
它的作用不是替代业务插件,而是给其他插件提供统一的语言 API:
- 每个插件维护自己的语言文件
- 玩家可以切换自己的语言
- 不同玩家可以看到不同语言
- 修改语言文件后可以不重启服务器直接重载
- 支持物品名称、物品 lore、普通消息、占位符和颜色代码
简单理解:
LangUtil = 公共语言管理器
其他插件 = 自己提供 lang 文件
玩家 = 自己选择 zh_CN / en_US 等语言
2.目录结构
LangUtil 自己的数据
玩家语言选择会保存到:
plugins/LangUtil/player-language.yml
格式示例:
player-language:
550e8400-e29b-41d4-a716-446655440000: zh_CN
其他插件的语言文件
其他插件必须把语言文件放在自己的插件目录下:
plugins/OtherPlugin/lang/zh_CN.yml
plugins/OtherPlugin/lang/en_US.yml
注意:
语言文件不是放在 LangUtil 的 lang 目录
语言文件是放在调用 register 的插件自己的 lang 目录
3.其他插件如何注册?
其他插件需要依赖 LangUtil。
plugin.yml
depend:
- LangUtil
插件入口
import com.io.yaohun.langutil.LangUtil;
import org.bukkit.plugin.java.JavaPlugin;
public final class OtherPlugin extends JavaPlugin {
@Override
public void onEnable() {
LangUtil.register(this);
}
}
当执行:
LangUtil.register(this);
LangUtil 会读取:
plugins/OtherPlugin/lang/*.yml
4.语言文件怎么写?
zh_CN.yml
message:
reload: "&a语言文件已重载"
no-permission: "&c你没有权限使用该命令。"
item:
flame-sword:
name: "&c烈焰长剑"
lore:
- "&7伤害: &c{damage}"
- "&7品质: &6{quality}"
- ""
- "&e右键释放火焰"
en_US.yml
message:
reload: "&aLanguage files reloaded"
no-permission: "&cYou do not have permission."
item:
flame-sword:
name: "&cFlame Sword"
lore:
- "&7Damage: &c{damage}"
- "&7Quality: &6{quality}"
- ""
- "&eRight-click to release fire"
文件名就是语言 ID:
zh_CN.yml → zh_CN
en_US.yml → en_US
5.玩家命令
查看可用语言
/lang
玩家会看到当前已经加载的语言 ID。
切换语言
/lang zh_CN
/lang en_US
切换后会按玩家 UUID 保存。
玩家退出服务器再进入,仍然保持上次选择。
重载语言文件
/lang reload
修改语言文件后,不需要重启服务器,执行该命令即可重新读取所有已注册插件的语言文件。
控制台也可以执行:
lang reload
6.权限节点
langutil.use # 允许玩家使用 /lang 查看和切换语言
langutil.reload # 允许使用 /lang reload
推荐配置:
普通玩家: langutil.use
管理员: langutil.use + langutil.reload
7.API 调用
获取普通消息
String message = LangUtil.get(player, this, "message.reload");
发送普通消息
LangUtil.send(player, this, "message.reload");
发送消息并播放音效
LangUtil.send(player, this, "message.reload", Sound.LEVEL_UP);
使用占位符
Map<String, String> placeholders = new HashMap<String, String>();
placeholders.put("damage", "12");
placeholders.put("quality", "史诗");
String name = LangUtil.get(player, this, "item.flame-sword.name", placeholders);
语言文件:
item:
flame-sword:
name: "&c烈焰长剑"
结果:
烈焰长剑
8.物品 name 和 lore 怎么做?
物品 name 是字符串,可以用:
LangUtil.get(player, this, "item.flame-sword.name", placeholders);
物品 lore 是 List,可以用:
LangUtil.getList(player, this, "item.flame-sword.lore", placeholders);
完整示例:
Map<String, String> placeholders = new HashMap<String, String>();
placeholders.put("damage", "12");
placeholders.put("quality", "史诗");
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(LangUtil.get(player, this, "item.flame-sword.name", placeholders));
meta.setLore(LangUtil.getList(player, this, "item.flame-sword.lore", placeholders));
item.setItemMeta(meta);
9.推荐封装方式
为了让业务代码更短,其他插件可以自己封装一个 Lang 工具类。
public final class Lang {
private static JavaPlugin plugin;
private Lang() {
}
public static void init(JavaPlugin javaPlugin) {
plugin = javaPlugin;
LangUtil.register(javaPlugin);
}
public static void send(CommandSender sender, String path) {
LangUtil.send(sender, plugin, path);
}
public static String get(CommandSender sender, String path) {
return LangUtil.get(sender, plugin, path);
}
public static List<String> getList(CommandSender sender, String path) {
return LangUtil.getList(sender, plugin, path);
}
}
插件启动时:
Lang.init(this);
业务代码:
Lang.send(player, "message.reload");
10.重载机制说明
LangUtil 不会每次发送消息都读取本地 YAML。
语言文件读取时机:
插件启动 register 时
/lang reload 时
再次调用 register 时
平时调用:
LangUtil.get(...)
LangUtil.getList(...)
LangUtil.send(...)
都是从内存缓存读取。
这样可以避免每次发消息都读磁盘,降低主线程压力。
11.异常与回退规则
玩家没有选择语言
默认使用:
zh_CN
玩家选择的语言文件不存在
回退:
zh_CN
zh_CN 也不存在
返回 path 原文:
LangUtil.get(player, this, "message.not-found");
返回:
message.not-found
lore 不存在
返回单行 List:
- item.xxx.lore
YAML 格式错误
控制台会输出:
插件名
语言文件名
错误原因
不会因为单个语言文件错误导致服务器关闭。
12.实战使用流程
第一步:安装 LangUtil
把插件放入服务器:
plugins/LangUtil-1.2.0.jar
启动服务器。
第二步:业务插件依赖 LangUtil
depend:
- LangUtil
第三步:业务插件注册语言文件
LangUtil.register(this);
第四步:创建语言文件
plugins/OtherPlugin/lang/zh_CN.yml
plugins/OtherPlugin/lang/en_US.yml
第五步:玩家切换语言
/lang zh_CN
/lang en_US
第六步:业务插件发送消息
LangUtil.send(player, this, "message.reload");
第七步:修改语言后重载
/lang reload
13.注意事项
- 推荐始终使用带
JavaPlugin plugin参数的 API。 - 不推荐使用
LangUtil.get(String path),因为它无法稳定判断读取哪个插件的语言。 - 其他插件必须先调用
LangUtil.register(this),否则读取不到自己的语言文件。 - 语言文件必须放在调用注册方法的插件自己的
lang目录。 - 物品 lore 必须用 YAML List 格式编写。
- 修改语言文件后必须执行
/lang reload才会进入缓存。 =======
LangUtil
12c7b3f43c6113b170b9e83dedf75650d51b9040
Description
Languages
Java
100%