diff --git a/src/main/java/de/pixelmindmc/pixelchat/PixelChat.java b/src/main/java/de/pixelmindmc/pixelchat/PixelChat.java index ac60bdb..143dd46 100644 --- a/src/main/java/de/pixelmindmc/pixelchat/PixelChat.java +++ b/src/main/java/de/pixelmindmc/pixelchat/PixelChat.java @@ -121,6 +121,36 @@ private void loadConfigs() { } } + /** + * Reloads all plugin configurations and re-initializes dependent components + */ + public void reloadPlugin() { + getLoggingHelper().debug("Reloading plugin"); + + // Reload all configuration files + configHelper.loadConfig(); + configHelperPlayerStrikes.loadConfig(); + configHelperEmojiList.loadConfig(); + configHelperChatCodesList.loadConfig(); + configHelperLangCustom.loadConfig(); + configHelperLangGerman.loadConfig(); + configHelperLangEnglish.loadConfig(); + configHelperLangSpanish.loadConfig(); + configHelperLangFrench.loadConfig(); + configHelperLangDutch.loadConfig(); + configHelperLangSimplifiedChinese.loadConfig(); + configHelperLangTraditionalChinese.loadConfig(); + + // Update the log level from the reloaded config + loggingHelper.setLogLevel(getConfigHelper().getString(ConfigConstants.General.LOG_LEVEL)); + + // Re-initialize the API helper so new API key / endpoint / model values take effect + registerAPIHelper(); + + // Re-initialize the ChatGuard helper so it picks up the refreshed language config + registerChatGuardHelper(); + } + /** * Retrieves the plugin configuration * @@ -229,12 +259,14 @@ private void registerAPIHelper() { // Check if the Chatguard module is active if (!getConfigHelper().getBoolean(ConfigConstants.Modules.CHATGUARD)) { + apiHelper = null; return; } // Check if the config file exists and API key is either unset or still at its default value if (apiKey.isEmpty() || getConfigHelper().getFileExist() && Objects.equals(apiKey, "API-KEY")) { getLoggingHelper().warning(getConfigHelperLanguage().getString(LangConstants.Global.NO_API_KEY_SET)); + apiHelper = null; return; } diff --git a/src/main/java/de/pixelmindmc/pixelchat/commands/PixelChatCommand.java b/src/main/java/de/pixelmindmc/pixelchat/commands/PixelChatCommand.java index 362fbd5..819dfff 100644 --- a/src/main/java/de/pixelmindmc/pixelchat/commands/PixelChatCommand.java +++ b/src/main/java/de/pixelmindmc/pixelchat/commands/PixelChatCommand.java @@ -47,7 +47,6 @@ public class PixelChatCommand implements CommandExecutor { private final @NotNull LoggingHelper loggingHelper; private final @NotNull ConfigHelper configHelper; private final @NotNull ConfigHelper configHelperPlayerStrikes; - private final @NotNull ConfigHelper configHelperLanguage; /** * Constructs a PixelChatCommand object @@ -59,7 +58,6 @@ public PixelChatCommand(@NotNull PixelChat plugin) { this.loggingHelper = plugin.getLoggingHelper(); this.configHelper = plugin.getConfigHelper(); this.configHelperPlayerStrikes = plugin.getConfigHelperPlayerStrikes(); - this.configHelperLanguage = plugin.getConfigHelperLanguage(); } /** @@ -73,6 +71,8 @@ public PixelChatCommand(@NotNull PixelChat plugin) { */ @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) { + ConfigHelper configHelperLanguage = plugin.getConfigHelperLanguage(); + // Display usage information if no arguments are provided if (args.length == 0) { sender.sendMessage(LangConstants.PLUGIN_PREFIX + ChatColor.RED + configHelperLanguage.getString(LangConstants.Global.INVALID_SYNTAX) + " " + ChatColor.RESET + configHelperLanguage.getString(LangConstants.Global.INVALID_SYNTAX_USAGE) + label + " "); @@ -99,6 +99,8 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command * @param args The arguments */ private void handleVersionSubcommand(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) { + ConfigHelper configHelperLanguage = plugin.getConfigHelperLanguage(); + // Check if the player has the required permission if (!sender.hasPermission(PermissionConstants.Commands.VERSION) && sender.hasPermission(PermissionConstants.Commands.RELOAD) && !sender.hasPermission(PermissionConstants.Commands.VERSION) && !sender.hasPermission(PermissionConstants.Commands.VERSION)) { sender.sendMessage(ChatColor.RED + configHelperLanguage.getString(LangConstants.Global.NO_PERMISSION)); @@ -144,6 +146,8 @@ private void handleVersionSubcommand(@NotNull CommandSender sender, @NotNull Str * @param args The arguments */ private void handleReloadSubcommand(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) { + ConfigHelper configHelperLanguage = plugin.getConfigHelperLanguage(); + // Check if the player has the required permission if (!sender.hasPermission(PermissionConstants.Commands.RELOAD)) { sender.sendMessage(ChatColor.RED + configHelperLanguage.getString(LangConstants.Global.NO_PERMISSION)); @@ -158,14 +162,15 @@ private void handleReloadSubcommand(@NotNull CommandSender sender, @NotNull Stri return; } - // Reload the plugin configurations - configHelper.loadConfig(); - configHelperPlayerStrikes.loadConfig(); - configHelperLanguage.loadConfig(); + // Reload all plugin configurations and re-initialize dependent components + plugin.reloadPlugin(); // Debug logger message loggingHelper.debug("Configuration files successfully reloaded"); + // Re-resolve after reload in case the configured language changed + configHelperLanguage = plugin.getConfigHelperLanguage(); + // Send a message after successfully reloading the configurations sender.sendMessage(LangConstants.PLUGIN_PREFIX + ChatColor.GREEN + configHelperLanguage.getString(LangConstants.PixelChatCommand.RELOAD)); } diff --git a/src/main/java/de/pixelmindmc/pixelchat/listener/AsyncPlayerChatListener.java b/src/main/java/de/pixelmindmc/pixelchat/listener/AsyncPlayerChatListener.java index 01e2a5d..b86e557 100644 --- a/src/main/java/de/pixelmindmc/pixelchat/listener/AsyncPlayerChatListener.java +++ b/src/main/java/de/pixelmindmc/pixelchat/listener/AsyncPlayerChatListener.java @@ -45,7 +45,6 @@ public class AsyncPlayerChatListener implements Listener { private final @NotNull LoggingHelper loggingHelper; private final @NotNull ConfigHelper configHelper; private final @NotNull ChatGuardHelper chatGuardHelper; - private boolean chatGuardEnabled = false; private boolean emojiEnabled = false; private boolean chatCodesEnabled = false; @@ -66,13 +65,8 @@ public AsyncPlayerChatListener(@NotNull PixelChat plugin) { @NotNull ConfigHelper configHelperEmojiList = plugin.getConfigHelperEmojiList(); @NotNull ConfigHelper configHelperChatCodesList = plugin.getConfigHelperChatCodesList(); - // Chatguard module - if (plugin.getAPIHelper() != null) { - this.chatGuardEnabled = true; - } - // Initialize CarbonChat integration if available - if (chatGuardEnabled && configHelper.getBoolean(ConfigConstants.PluginSupport.CARBONCHAT) && setupCarbonChatIntegration()) { + if (plugin.getAPIHelper() != null && configHelper.getBoolean(ConfigConstants.PluginSupport.CARBONCHAT) && setupCarbonChatIntegration()) { carbonChatIntegration.registerCarbonChatListener(); } @@ -121,7 +115,7 @@ private void onAsyncPlayerChat(@NotNull AsyncPlayerChatEvent event) { boolean chatGuardMessageBlocked = false; // AI based chat guard module - if (chatGuardEnabled && carbonChatIntegration == null && !player.hasPermission(PermissionConstants.Moderation.BYPASS_CHAT_MODERATION)) { + if (plugin.getAPIHelper() != null && carbonChatIntegration == null && !player.hasPermission(PermissionConstants.Moderation.BYPASS_CHAT_MODERATION)) { chatGuardMessageBlocked = checkIfMessageShouldBeBlocked(event, message, player); } diff --git a/src/main/java/de/pixelmindmc/pixelchat/utils/APIHelper.java b/src/main/java/de/pixelmindmc/pixelchat/utils/APIHelper.java index 6c0d939..b39a328 100644 --- a/src/main/java/de/pixelmindmc/pixelchat/utils/APIHelper.java +++ b/src/main/java/de/pixelmindmc/pixelchat/utils/APIHelper.java @@ -45,11 +45,6 @@ public class APIHelper { private final @NotNull LoggingHelper loggingHelper; private final @NotNull ConfigHelper configHelper; - private final String aiModel; - private final String apiUrl; - private final String apiKey; - private final String sysPrompt; - /** * Constructs a APIHelper object * @@ -58,11 +53,6 @@ public class APIHelper { public APIHelper(@NotNull PixelChat plugin) { this.loggingHelper = plugin.getLoggingHelper(); this.configHelper = plugin.getConfigHelper(); - - this.apiUrl = configHelper.getString(ConfigConstants.API.ENDPOINT); - this.aiModel = configHelper.getString(ConfigConstants.API.MODEL); - this.apiKey = configHelper.getString(ConfigConstants.API.KEY); - this.sysPrompt = configHelper.getString(ConfigConstants.API.SYSTEM_PROMPT); } /** @@ -92,7 +82,7 @@ public APIHelper(@NotNull PixelChat plugin) { } catch (IOException e) { throw new MessageClassificationException("Failed to classify message due to an IO issue.", e); } catch (URISyntaxException e) { - throw new MessageClassificationException("Failed to classify message: invalid API endpoint URL '" + apiUrl + "'", e); + throw new MessageClassificationException("Failed to classify message: invalid API endpoint URL '" + configHelper.getString(ConfigConstants.API.ENDPOINT) + "'", e); } catch (Exception e) { throw new MessageClassificationException("Failed to classify message due to an unexpected error.", e); } @@ -106,11 +96,11 @@ public APIHelper(@NotNull PixelChat plugin) { * @throws URISyntaxException Thrown if the set API URL isn't valid */ private @NotNull HttpURLConnection createConnection() throws IOException, URISyntaxException { - URL url = new URI(apiUrl).toURL(); + URL url = new URI(configHelper.getString(ConfigConstants.API.ENDPOINT)).toURL(); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("Authorization", "Bearer " + apiKey); + connection.setRequestProperty("Authorization", "Bearer " + configHelper.getString(ConfigConstants.API.KEY)); connection.setDoOutput(true); return connection; @@ -124,7 +114,7 @@ public APIHelper(@NotNull PixelChat plugin) { * @throws IOException If any issue happens, an exception is thrown */ private void sendRequest(@NotNull HttpURLConnection connection, @NotNull String message) throws IOException { - Map json = Map.of("model", aiModel, "messages", new Map[]{Map.of("role", "system", APIConstants.General.CONTENT, sysPrompt + "Language: " + configHelper.getString(ConfigConstants.General.LANGUAGE)), Map.of("role", "user", APIConstants.General.CONTENT, message)}, "response_format", Map.of("type", "json_object")); + Map json = Map.of("model", configHelper.getString(ConfigConstants.API.MODEL), "messages", new Map[]{Map.of("role", "system", APIConstants.General.CONTENT, configHelper.getString(ConfigConstants.API.SYSTEM_PROMPT) + "Language: " + configHelper.getString(ConfigConstants.General.LANGUAGE)), Map.of("role", "user", APIConstants.General.CONTENT, message)}, "response_format", Map.of("type", "json_object")); String jsonInputString = new Gson().toJson(json); diff --git a/src/main/java/de/pixelmindmc/pixelchat/utils/ChatGuardHelper.java b/src/main/java/de/pixelmindmc/pixelchat/utils/ChatGuardHelper.java index f7eb4a2..354b4ce 100644 --- a/src/main/java/de/pixelmindmc/pixelchat/utils/ChatGuardHelper.java +++ b/src/main/java/de/pixelmindmc/pixelchat/utils/ChatGuardHelper.java @@ -39,7 +39,6 @@ public class ChatGuardHelper { private final @NotNull PixelChat plugin; private final @NotNull LoggingHelper loggingHelper; private final @NotNull ConfigHelper configHelper; - private final @NotNull ConfigHelper configHelperLanguage; /** * Constructs a ChatGuardHelper object @@ -48,7 +47,6 @@ public ChatGuardHelper(@NotNull PixelChat plugin) { this.plugin = plugin; this.loggingHelper = plugin.getLoggingHelper(); this.configHelper = plugin.getConfigHelper(); - this.configHelperLanguage = plugin.getConfigHelperLanguage(); } /** @@ -60,6 +58,7 @@ public ChatGuardHelper(@NotNull PixelChat plugin) { * @param blockOrCensor Whether the message should be blocked ({@code true}) or censored ({@code false}) */ public void notifyAndStrikePlayer(@NotNull Player player, @NotNull String userMessage, @NotNull MessageClassification classification, boolean blockOrCensor) { + ConfigHelper configHelperLanguage = plugin.getConfigHelperLanguage(); String chatGuardPrefix = (configHelper.getBoolean(ConfigConstants.ChatGuard.CustomPrefix.ENABLED) ? configHelper.getString(ConfigConstants.ChatGuard.CustomPrefix.FORMAT) + ChatColor.RESET + " " : LangConstants.PLUGIN_PREFIX); // Notify player if enabled @@ -113,6 +112,7 @@ public void runStrikeSystem(@NotNull UUID playerUUID, @NotNull String playerName // Debug logger message loggingHelper.debug("Run strike system on " + playerName); + ConfigHelper configHelperLanguage = plugin.getConfigHelperLanguage(); ConfigHelper configHelperPlayerStrikes = plugin.getConfigHelperPlayerStrikes(); String action = "NOTHING"; @@ -134,11 +134,11 @@ public void runStrikeSystem(@NotNull UUID playerUUID, @NotNull String playerName action = "KICK"; } else if (strikes >= strikesToTempBan && strikes < strikesToBan) { // Player has enough strikes to be temporarily banned - executeCommand(plugin.getConfigHelper().getString(ConfigConstants.ChatGuard.StrikeSystem.Commands.TEMP_BAN), playerName, configHelperLanguage.getString(LangConstants.ChatGuard.Player.BAN_TEMPORARY) + " " + reason); + executeCommand(configHelper.getString(ConfigConstants.ChatGuard.StrikeSystem.Commands.TEMP_BAN), playerName, configHelperLanguage.getString(LangConstants.ChatGuard.Player.BAN_TEMPORARY) + " " + reason); action = "TEMP-BAN"; } else if (strikes >= strikesToBan) { // Player has enough strikes to be permanently banned - executeCommand(plugin.getConfigHelper().getString(ConfigConstants.ChatGuard.StrikeSystem.Commands.BAN), playerName, configHelperLanguage.getString(LangConstants.ChatGuard.Player.BAN_PERMANENT) + " " + reason); + executeCommand(configHelper.getString(ConfigConstants.ChatGuard.StrikeSystem.Commands.BAN), playerName, configHelperLanguage.getString(LangConstants.ChatGuard.Player.BAN_PERMANENT) + " " + reason); action = "BAN"; }