diff --git a/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java b/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java index c48fd66bc..15b31c36b 100644 --- a/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java +++ b/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java @@ -4,14 +4,25 @@ import com.gmail.nossr50.config.Config; import com.gmail.nossr50.mcMMO; import org.bukkit.ChatColor; +import java.io.IOException; +import java.io.Reader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.text.MessageFormat; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; import java.util.MissingResourceException; +import java.util.PropertyResourceBundle; import java.util.ResourceBundle; +import java.util.logging.Level; public final class LocaleLoader { private static final String BUNDLE_ROOT = "com.gmail.nossr50.locale.locale"; + private static Map bundleCache = new HashMap<>(); private static ResourceBundle bundle = null; + private static ResourceBundle filesystemBundle = null; private static ResourceBundle enBundle = null; private LocaleLoader() {}; @@ -32,25 +43,33 @@ public final class LocaleLoader { initialize(); } - try { - return getString(key, bundle, messageArguments); - } - catch (MissingResourceException ex) { - try { - return getString(key, enBundle, messageArguments); - } - catch (MissingResourceException ex2) { - if (!key.contains("Guides")) { - mcMMO.p.getLogger().warning("Could not find locale string: " + key); - } - - return '!' + key + '!'; - } - } + String rawMessage = bundleCache.computeIfAbsent(key, LocaleLoader::getRawString); + return formatString(rawMessage, messageArguments); } - private static String getString(String key, ResourceBundle bundle, Object... messageArguments) throws MissingResourceException { - return formatString(bundle.getString(key), messageArguments); + private static String getRawString(String key) { + if (filesystemBundle != null) { + try { + return filesystemBundle.getString(key); + } + catch (MissingResourceException ignored) {} + } + + try { + return bundle.getString(key); + } + catch (MissingResourceException ignored) {} + + try { + return enBundle.getString(key); + } + catch (MissingResourceException ignored) { + if (!key.contains("Guides")) { + mcMMO.p.getLogger().warning("Could not find locale string: " + key); + } + + return '!' + key + '!'; + } } public static String formatString(String string, Object... messageArguments) { @@ -85,6 +104,19 @@ public final class LocaleLoader { locale = new Locale(myLocale[0], myLocale[1]); } + if (locale == null) { + throw new IllegalStateException("Failed to parse locale string '" + Config.getInstance().getLocale() + "'"); + } + + Path localePath = Paths.get(mcMMO.getLocalesDirectory() + "locale_" + locale.toString() + ".properties"); + if (Files.exists(localePath) && Files.isRegularFile(localePath)) { + try (Reader localeReader = Files.newBufferedReader(localePath)) { + mcMMO.p.getLogger().log(Level.INFO, "Loading locale from {0}", localePath); + filesystemBundle = new PropertyResourceBundle(localeReader); + } catch (IOException e) { + mcMMO.p.getLogger().log(Level.WARNING, "Failed to load locale from " + localePath, e); + } + } bundle = ResourceBundle.getBundle(BUNDLE_ROOT, locale); enBundle = ResourceBundle.getBundle(BUNDLE_ROOT, Locale.US); } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 644ad1bce..9b39ecd60 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -79,6 +79,7 @@ public class mcMMO extends JavaPlugin { /* File Paths */ private static String mainDirectory; + private static String localesDirectory; private static String flatFileDirectory; private static String usersFile; private static String modDirectory; @@ -357,6 +358,10 @@ public class mcMMO extends JavaPlugin { return mainDirectory; } + public static String getLocalesDirectory() { + return localesDirectory; + } + public static String getFlatFileDirectory() { return flatFileDirectory; } @@ -432,6 +437,7 @@ public class mcMMO extends JavaPlugin { private void setupFilePaths() { mcmmo = getFile(); mainDirectory = getDataFolder().getPath() + File.separator; + localesDirectory = mainDirectory + "locales" + File.separator; flatFileDirectory = mainDirectory + "flatfile" + File.separator; usersFile = flatFileDirectory + "mcmmo.users"; modDirectory = mainDirectory + "mods" + File.separator; @@ -485,6 +491,8 @@ public class mcMMO extends JavaPlugin { File currentFlatfilePath = new File(flatFileDirectory); currentFlatfilePath.mkdirs(); + File localesDirectoryPath = new File(localesDirectory); + localesDirectoryPath.mkdirs(); } private void loadConfigFiles() {