diff --git a/build.gradle b/build.gradle index ec505af..eb7b7f8 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'com.playerblocklife' -version = '1.0.1-1.20.4' +version = '2.0.0-1.20.4' sourceCompatibility = 17 targetCompatibility = 17 diff --git a/gradle.properties b/gradle.properties index a452c6d..a2b78e4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,5 +5,5 @@ org.gradle.caching=true org.gradle.daemon=true # ???? -pluginVersion=1.0.1-1.20.4 +pluginVersion=2.0.0-1.20.4 mcVersion=1.20.4 \ No newline at end of file diff --git a/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java b/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java index 81f2340..b84712e 100644 --- a/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java +++ b/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java @@ -78,7 +78,7 @@ public class CheckLifeBlocksCommand implements CommandExecutor { player.sendMessage("§7方块位置:"); for (int i = 0; i < blocks.size(); i++) { Location loc = blocks.get(i); - String worldName = loc.getWorld() != null ? loc.getWorld().getName() : "未知世界"); + String worldName = loc.getWorld() != null ? loc.getWorld().getName() : "未知世界"; String locationMsg = msgManager.getMessage("game.block.location_item", "&7- {world} ({x}, {y}, {z})"); locationMsg = locationMsg.replace("{world}", worldName) diff --git a/src/main/java/com/playerblocklife/MessageManager.java b/src/main/java/com/playerblocklife/MessageManager.java new file mode 100644 index 0000000..36f6558 --- /dev/null +++ b/src/main/java/com/playerblocklife/MessageManager.java @@ -0,0 +1,183 @@ +package com.playerblocklife; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +public class MessageManager { + private final PlayerBlockLife plugin; + private FileConfiguration messageConfig; + private File messageFile; + private final Map messageCache = new HashMap<>(); + + public MessageManager(PlayerBlockLife plugin) { + this.plugin = plugin; + this.messageFile = new File(plugin.getDataFolder(), "messages.yml"); + } + + /** + * 加载消息配置 + */ + public void loadMessages() { + ConfigManager config = plugin.getConfigManager(); + + // 检查是否使用外部消息文件 + if (config.useExternalMessageFile()) { + String fileName = config.getExternalMessageFileName(); + this.messageFile = new File(plugin.getDataFolder(), fileName); + + // 确保配置文件夹存在 + if (!plugin.getDataFolder().exists()) { + plugin.getDataFolder().mkdirs(); + } + + // 如果消息文件不存在,从JAR中复制默认配置 + if (!messageFile.exists()) { + plugin.saveResource(fileName, false); + plugin.logInfo("创建默认消息配置文件: " + fileName); + } + + // 加载消息配置 + reloadMessages(); + } else { + // 使用config.yml中的消息 + plugin.logInfo("使用config.yml中的消息配置"); + messageConfig = null; + messageCache.clear(); + } + } + + /** + * 重新加载消息配置 + */ + public void reloadMessages() { + ConfigManager config = plugin.getConfigManager(); + + if (!config.useExternalMessageFile()) { + return; + } + + try { + messageConfig = YamlConfiguration.loadConfiguration(messageFile); + + // 加载默认消息作为后备 + InputStream defaultStream = plugin.getResource(messageFile.getName()); + if (defaultStream != null) { + YamlConfiguration defaultConfig = YamlConfiguration.loadConfiguration( + new InputStreamReader(defaultStream, StandardCharsets.UTF_8)); + messageConfig.setDefaults(defaultConfig); + } + + // 清空缓存 + messageCache.clear(); + + plugin.logInfo("消息配置已加载: " + messageFile.getName()); + } catch (Exception e) { + plugin.logError("加载消息配置文件失败", e); + } + } + + /** + * 获取消息 + */ + public String getMessage(String path, String defaultValue) { + ConfigManager config = plugin.getConfigManager(); + + // 检查缓存 + String cacheKey = path + "|" + defaultValue; + if (messageCache.containsKey(cacheKey)) { + return messageCache.get(cacheKey); + } + + String message; + + if (config.useExternalMessageFile() && messageConfig != null) { + // 从外部消息文件获取 + message = messageConfig.getString(path, defaultValue); + if (message == null) { + message = defaultValue; + } + } else { + // 从config.yml获取或使用默认值 + message = config.getMessage(path, defaultValue); + } + + // 替换颜色代码 + if (message != null) { + message = message.replace("&", "§"); + } + + // 缓存结果 + messageCache.put(cacheKey, message); + + return message; + } + + /** + * 获取格式化消息(替换变量) + */ + public String getFormattedMessage(String path, String defaultValue, Map variables) { + String message = getMessage(path, defaultValue); + + if (message != null && variables != null) { + for (Map.Entry entry : variables.entrySet()) { + message = message.replace("{" + entry.getKey() + "}", entry.getValue()); + } + } + + return message; + } + + /** + * 获取控制台消息 + */ + public String getConsoleMessage(String path, String defaultValue) { + String message = getMessage("console." + path, defaultValue); + // 移除颜色代码(控制台不需要) + if (message != null) { + message = message.replace("§", "&"); + } + return message; + } + + /** + * 获取游戏内消息 + */ + public String getGameMessage(String path, String defaultValue) { + return getMessage("game." + path, defaultValue); + } + + /** + * 获取命令消息 + */ + public String getCommandMessage(String command, String path, String defaultValue) { + return getMessage("commands." + command + "." + path, defaultValue); + } + + /** + * 获取广播消息 + */ + public String getBroadcastMessage(String path, String defaultValue) { + return getMessage("broadcast." + path, defaultValue); + } + + /** + * 检查消息文件是否存在 + */ + public boolean hasExternalMessageFile() { + return messageFile.exists(); + } + + /** + * 获取消息文件路径 + */ + public String getMessageFilePath() { + return messageFile.getAbsolutePath(); + } +} \ No newline at end of file diff --git a/src/main/java/com/playerblocklife/PlayerJoinListener.java b/src/main/java/com/playerblocklife/PlayerJoinListener.java index 815e09a..2cc0131 100644 --- a/src/main/java/com/playerblocklife/PlayerJoinListener.java +++ b/src/main/java/com/playerblocklife/PlayerJoinListener.java @@ -113,9 +113,10 @@ public class PlayerJoinListener implements Listener { String message = plugin.getMessageManager().getMessage("console.blocks_generated", "&a[PlayerBlockLife] 已为玩家 {player} 生成 {amount} 个生命方块"); message = message.replace("{player}", player.getName()) - .replace("{amount}", String.valueOf(blockAmount)) - .replace("&", "§"); - plugin.getLogger().info(message); + .replace("{amount}", String.valueOf(blockAmount)); + // 移除颜色代码用于日志 + String logMessage = message.replace("&", ""); + plugin.getLogger().info(logMessage); // 发送给玩家 String playerMsg = plugin.getMessageManager().getMessage("game.block.placed", @@ -127,9 +128,10 @@ public class PlayerJoinListener implements Listener { // 生成失败 String failureMsg = plugin.getMessageManager().getMessage("console.error_generating_blocks", "&c[PlayerBlockLife] 为玩家 {player} 生成生命方块时失败"); - failureMsg = failureMsg.replace("{player}", player.getName()) - .replace("&", "§"); - plugin.getLogger().warning(failureMsg); + failureMsg = failureMsg.replace("{player}", player.getName()); + // 移除颜色代码用于日志 + String logFailureMsg = failureMsg.replace("&", ""); + plugin.getLogger().warning(logFailureMsg); // 根据配置处理失败 String onFailure = config.getOnFailureAction(); @@ -150,10 +152,13 @@ public class PlayerJoinListener implements Listener { String errorMsg = plugin.getMessageManager().getMessage("console.error_generating_blocks", "&c[PlayerBlockLife] 为玩家 {player} 生成生命方块时出错: {error}"); - errorMsg = errorMsg.replace("{player}", player.getName()) - .replace("{error}", e.getMessage()) - .replace("&", "§"); - plugin.getLogger().severe(errorMsg); + if (errorMsg != null) { + String errorDetail = e.getMessage() != null ? e.getMessage() : "未知错误"; + errorMsg = errorMsg.replace("{player}", player.getName()) + .replace("{error}", errorDetail) + .replace("&", "§"); + plugin.getLogger().severe(errorMsg); + } } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f2e901c..073d273 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: PlayerBlockLife -version: 1.0.1-1.20.4 +version: 2.0.0-1.20.4 main: com.playerblocklife.PlayerBlockLife api-version: 1.20 author: xiaobai