Files
LangUtil/README.md
2026-06-01 07:06:35 +08:00

460 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<<<<<<< HEAD
# 1.LangUtil 是什么?
LangUtil 是一个 Minecraft 1.12.2 Bukkit / Spigot 多语言管理插件。
它的作用不是替代业务插件,而是给其他插件提供统一的语言 API
- 每个插件维护自己的语言文件
- 玩家可以切换自己的语言
- 不同玩家可以看到不同语言
- 修改语言文件后可以不重启服务器直接重载
- 支持物品名称、物品 lore、普通消息、占位符和颜色代码
简单理解:
```yml
LangUtil = 公共语言管理器
其他插件 = 自己提供 lang 文件
玩家 = 自己选择 zh_CN / en_US 等语言
```
------
# 2.目录结构
## LangUtil 自己的数据
玩家语言选择会保存到:
```yml
plugins/LangUtil/player-language.yml
```
格式示例:
```yml
player-language:
550e8400-e29b-41d4-a716-446655440000: zh_CN
```
## 其他插件的语言文件
其他插件必须把语言文件放在自己的插件目录下:
```yml
plugins/OtherPlugin/lang/zh_CN.yml
plugins/OtherPlugin/lang/en_US.yml
```
注意:
```yml
语言文件不是放在 LangUtil 的 lang 目录
语言文件是放在调用 register 的插件自己的 lang 目录
```
------
# 3.其他插件如何注册?
其他插件需要依赖 LangUtil。
## plugin.yml
```yml
depend:
- LangUtil
```
## 插件入口
```java
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);
}
}
```
当执行:
```java
LangUtil.register(this);
```
LangUtil 会读取:
```yml
plugins/OtherPlugin/lang/*.yml
```
------
# 4.语言文件怎么写?
## zh_CN.yml
```yml
message:
reload: "&a语言文件已重载"
no-permission: "&c你没有权限使用该命令。"
item:
flame-sword:
name: "&c烈焰长剑"
lore:
- "&7伤害: &c{damage}"
- "&7品质: &6{quality}"
- ""
- "&e右键释放火焰"
```
## en_US.yml
```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
```yml
zh_CN.yml → zh_CN
en_US.yml → en_US
```
------
# 5.玩家命令
## 查看可用语言
```yml
/lang
```
玩家会看到当前已经加载的语言 ID。
## 切换语言
```yml
/lang zh_CN
/lang en_US
```
切换后会按玩家 UUID 保存。
玩家退出服务器再进入,仍然保持上次选择。
## 重载语言文件
```yml
/lang reload
```
修改语言文件后,不需要重启服务器,执行该命令即可重新读取所有已注册插件的语言文件。
控制台也可以执行:
```yml
lang reload
```
------
# 6.权限节点
```yml
langutil.use # 允许玩家使用 /lang 查看和切换语言
langutil.reload # 允许使用 /lang reload
```
推荐配置:
```yml
普通玩家: langutil.use
管理员: langutil.use + langutil.reload
```
------
# 7.API 调用
## 获取普通消息
```java
String message = LangUtil.get(player, this, "message.reload");
```
## 发送普通消息
```java
LangUtil.send(player, this, "message.reload");
```
## 发送消息并播放音效
```java
LangUtil.send(player, this, "message.reload", Sound.LEVEL_UP);
```
## 使用占位符
```java
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);
```
语言文件:
```yml
item:
flame-sword:
name: "&c烈焰长剑"
```
结果:
```yml
烈焰长剑
```
------
# 8.物品 name 和 lore 怎么做?
物品 name 是字符串,可以用:
```java
LangUtil.get(player, this, "item.flame-sword.name", placeholders);
```
物品 lore 是 List可以用
```java
LangUtil.getList(player, this, "item.flame-sword.lore", placeholders);
```
完整示例:
```java
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` 工具类。
```java
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);
}
}
```
插件启动时:
```java
Lang.init(this);
```
业务代码:
```java
Lang.send(player, "message.reload");
```
------
# 10.重载机制说明
LangUtil 不会每次发送消息都读取本地 YAML。
语言文件读取时机:
```yml
插件启动 register 时
/lang reload 时
再次调用 register 时
```
平时调用:
```java
LangUtil.get(...)
LangUtil.getList(...)
LangUtil.send(...)
```
都是从内存缓存读取。
这样可以避免每次发消息都读磁盘,降低主线程压力。
------
# 11.异常与回退规则
## 玩家没有选择语言
默认使用:
```yml
zh_CN
```
## 玩家选择的语言文件不存在
回退:
```yml
zh_CN
```
## zh_CN 也不存在
返回 path 原文:
```java
LangUtil.get(player, this, "message.not-found");
```
返回:
```yml
message.not-found
```
## lore 不存在
返回单行 List
```yml
- item.xxx.lore
```
## YAML 格式错误
控制台会输出:
```yml
插件名
语言文件名
错误原因
```
不会因为单个语言文件错误导致服务器关闭。
------
# 12.实战使用流程
## 第一步:安装 LangUtil
把插件放入服务器:
```yml
plugins/LangUtil-1.2.0.jar
```
启动服务器。
## 第二步:业务插件依赖 LangUtil
```yml
depend:
- LangUtil
```
## 第三步:业务插件注册语言文件
```java
LangUtil.register(this);
```
## 第四步:创建语言文件
```yml
plugins/OtherPlugin/lang/zh_CN.yml
plugins/OtherPlugin/lang/en_US.yml
```
## 第五步:玩家切换语言
```yml
/lang zh_CN
/lang en_US
```
## 第六步:业务插件发送消息
```java
LangUtil.send(player, this, "message.reload");
```
## 第七步:修改语言后重载
```yml
/lang reload
```
------
# 13.注意事项
- 推荐始终使用带 `JavaPlugin plugin` 参数的 API。
- 不推荐使用 `LangUtil.get(String path)`,因为它无法稳定判断读取哪个插件的语言。
- 其他插件必须先调用 `LangUtil.register(this)`,否则读取不到自己的语言文件。
- 语言文件必须放在调用注册方法的插件自己的 `lang` 目录。
- 物品 lore 必须用 YAML List 格式编写。
- 修改语言文件后必须执行 `/lang reload` 才会进入缓存。
=======
# LangUtil
>>>>>>> 12c7b3f43c6113b170b9e83dedf75650d51b9040