From f3ea35fd93bed2d4c6581f2bcfa59f2bd9227681 Mon Sep 17 00:00:00 2001 From: Shiewk Date: Fri, 17 Apr 2026 15:24:23 +0200 Subject: [PATCH] Add option for custom translation file --- .../smoderation/paper/SModerationPaper.java | 6 +- .../paper/translation/TranslatorManager.java | 59 ++++++++++++++++++- src/main/resources/default-config.yml | 8 +++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java b/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java index c64e4a8..9d23ded 100644 --- a/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java +++ b/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java @@ -74,7 +74,11 @@ public final class SModerationPaper extends JavaPlugin { LOGGER.info("Folia: {}", SchedulerUtil.isFolia ? "yes" : "no"); PLUGIN = this; LOGGER.info("Loading translations"); - translatorManager.load(); + if (config().getBoolean("custom-messages", false)) { + translatorManager.loadCustomMessages(getDataPath().resolve("messages.json")); + } else { + translatorManager.load(); + } updateConfig(); this.punishmentManager = new PunishmentManager(getDataPath().resolve("punishments.v2")); diff --git a/src/main/java/de/shiewk/smoderation/paper/translation/TranslatorManager.java b/src/main/java/de/shiewk/smoderation/paper/translation/TranslatorManager.java index 9170427..18f6d4c 100644 --- a/src/main/java/de/shiewk/smoderation/paper/translation/TranslatorManager.java +++ b/src/main/java/de/shiewk/smoderation/paper/translation/TranslatorManager.java @@ -1,17 +1,20 @@ package de.shiewk.smoderation.paper.translation; +import com.google.gson.FormattingStyle; import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonWriter; import de.shiewk.smoderation.paper.SModerationPaper; import net.kyori.adventure.key.Key; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.translation.MiniMessageTranslationStore; import net.kyori.adventure.translation.GlobalTranslator; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.util.Locale; import java.util.Map; @@ -45,4 +48,54 @@ public class TranslatorManager { } GlobalTranslator.translator().addSource(translationStore); } + + public void loadCustomMessages(Path customPath) { + try { + if (Files.notExists(customPath)) { + Files.createDirectories(customPath.getParent()); + Files.write(customPath, "{}".getBytes(), StandardOpenOption.CREATE); + } + + Map predefinedMap; + try (InputStream stream = SModerationPaper.class.getClassLoader().getResourceAsStream(resourcePath + "en_us.json")) { + if (stream == null) { + SModerationPaper.LOGGER.warn("English (US) predefined translations not found or not accessible"); + predefinedMap = Map.of(); + } else { + predefinedMap = SModerationPaper.gson.fromJson(new InputStreamReader(stream), new TypeToken<>(){}); + } + } + + Map translationMap; + try (InputStream stream = Files.newInputStream(customPath)) { + translationMap = SModerationPaper.gson.fromJson(new InputStreamReader(stream), new TypeToken<>(){}); + } + + boolean updated = false; + for (Map.Entry entry : predefinedMap.entrySet()) { + if (!translationMap.containsKey(entry.getKey())) { + translationMap.put(entry.getKey(), entry.getValue()); + updated = true; + } + } + + if (updated) { + SModerationPaper.LOGGER.warn("Updating {} custom translations", translationMap.size()); + try (OutputStream stream = Files.newOutputStream(customPath, StandardOpenOption.TRUNCATE_EXISTING); + OutputStreamWriter writer = new OutputStreamWriter(stream); + JsonWriter jsonWriter = new JsonWriter(writer)) { + jsonWriter.setFormattingStyle(FormattingStyle.PRETTY); + SModerationPaper.gson.toJson(translationMap, translationMap.getClass(), jsonWriter); + } + SModerationPaper.LOGGER.info("Update successful"); + } + + translationStore.registerAll(Locale.forLanguageTag("en-US"), translationMap); + SModerationPaper.LOGGER.info("Registered {} custom translations", translationMap.size()); + + } catch (IOException e) { + SModerationPaper.LOGGER.warn("Failed to load custom translations", e); + } + GlobalTranslator.translator().addSource(translationStore); + } } diff --git a/src/main/resources/default-config.yml b/src/main/resources/default-config.yml index f998b76..4951705 100644 --- a/src/main/resources/default-config.yml +++ b/src/main/resources/default-config.yml @@ -31,6 +31,14 @@ colors: secondary: '#fc9e07' detail: '#ababab' +# Allows you to customize translation files. +# - At 'false', the plugin's predefined localization is used +# and available for multiple languages: +# https://github.com/Shiewk/SModeration/tree/main/src/main/resources/smoderation/translations +# - At 'true', a JSON localization file will be created in the plugin directory. +# Only the contained strings will be used and localization will be disabled. +custom-messages: false + # A list of commands which will be captured and broadcast # to players which have SocialSpy enabled (/socialspy). socialspy-commands: