diff --git a/nicko-core/pom.xml b/nicko-core/pom.xml index 69dcfdb..53ac089 100644 --- a/nicko-core/pom.xml +++ b/nicko-core/pom.xml @@ -96,7 +96,7 @@ com.github.seeseemelk MockBukkit-v1.19 - 2.143.0 + 2.29.0 test diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/nicko-core/src/main/java/net/artelnatif/nicko/NickoBukkit.java index 4ace6c5..6d9e4fe 100644 --- a/nicko-core/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/nicko-core/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -9,7 +9,8 @@ import net.artelnatif.nicko.config.NickoConfiguration; import net.artelnatif.nicko.event.PlayerJoinListener; import net.artelnatif.nicko.event.PlayerQuitListener; import net.artelnatif.nicko.gui.items.main.ExitDoorItem; -import net.artelnatif.nicko.i18n.LocaleManager; +import net.artelnatif.nicko.i18n.Locale; +import net.artelnatif.nicko.i18n.LocaleFileManager; import net.artelnatif.nicko.impl.Internals; import net.artelnatif.nicko.impl.InternalsProvider; import net.artelnatif.nicko.mojang.MojangAPI; @@ -34,7 +35,7 @@ public class NickoBukkit extends JavaPlugin { private NickoConfiguration config; private MojangAPI mojangAPI; private PlayerDataStore dataStore; - private LocaleManager localeManager; + private LocaleFileManager localeFileManager; public NickoBukkit() { this.unitTesting = false; } @@ -70,7 +71,7 @@ public class NickoBukkit extends JavaPlugin { dataStore.getStorage().setError(false); } - if (config.isBungeecordEnabled()) { + if (config.isBungeecordSupport()) { getServer().getMessenger().unregisterIncomingPluginChannel(this); getServer().getMessenger().unregisterOutgoingPluginChannel(this); } @@ -103,9 +104,14 @@ public class NickoBukkit extends JavaPlugin { saveDefaultConfig(); config = new NickoConfiguration(this); - localeManager = new LocaleManager(this); - localeManager.findFallbackLocale(); - localeManager.installCustomLanguageFile(); + localeFileManager = new LocaleFileManager(); + if (config.isCustomLocale()) { + if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) { + getLogger().info("Successfully dumped English locale to lang.yml!"); + } else { + getLogger().warning("Failed to dump English locale to lang.yml! Custom Locale usage will be disabled."); + } + } final PluginCommand command = getCommand("nicko"); if (command != null) { @@ -131,7 +137,7 @@ public class NickoBukkit extends JavaPlugin { final ServerUtils serverUtils = new ServerUtils(this); serverUtils.checkSpigotBungeeCordHook(); - if (config.isBungeecordEnabled()) { + if (config.isBungeecordSupport()) { if (serverUtils.checkBungeeCordHook()) { getLogger().info("Enabling BungeeCord support..."); getServer().getMessenger().registerIncomingPluginChannel(this, NickoBungee.NICKO_PLUGIN_CHANNEL_UPDATE, new PluginMessageHandler()); @@ -154,8 +160,8 @@ public class NickoBukkit extends JavaPlugin { public PlayerDataStore getDataStore() { return dataStore; } - public LocaleManager getLocaleManager() { - return localeManager; + public LocaleFileManager getLocaleFileManager() { + return localeFileManager; } public boolean isUnitTesting() { diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java b/nicko-core/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java index 480e44a..2e1897f 100644 --- a/nicko-core/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java +++ b/nicko-core/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java @@ -62,7 +62,7 @@ public class AnvilManager { if (!actionResult.isError()) { player.sendMessage(I18N.translate(player, I18NDict.Event.DISGUISE_SUCCESS)); } else { - player.sendMessage(I18N.translate(player, I18NDict.Event.DISGUISE_FAIL, I18N.translateFlat(player, actionResult.getErrorMessage()))); + player.sendMessage(I18N.translate(player, I18NDict.Event.DISGUISE_FAIL, I18N.translateWithoutPrefix(player, actionResult.getErrorMessage()))); } return AnvilGUI.Response.close(); } @@ -83,7 +83,7 @@ public class AnvilManager { if (!actionResult.isError()) { player.sendMessage(I18N.translate(player, I18NDict.Event.DISGUISE_SUCCESS)); } else { - player.sendMessage(I18N.translate(player, I18NDict.Event.DISGUISE_FAIL, I18N.translateFlat(player, actionResult.getErrorMessage()))); + player.sendMessage(I18N.translate(player, I18NDict.Event.DISGUISE_FAIL, I18N.translateWithoutPrefix(player, actionResult.getErrorMessage()))); } return AnvilGUI.Response.close(); } diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/config/NickoConfiguration.java b/nicko-core/src/main/java/net/artelnatif/nicko/config/NickoConfiguration.java index b51badf..9a75ec7 100644 --- a/nicko-core/src/main/java/net/artelnatif/nicko/config/NickoConfiguration.java +++ b/nicko-core/src/main/java/net/artelnatif/nicko/config/NickoConfiguration.java @@ -7,7 +7,6 @@ import org.bukkit.configuration.file.FileConfiguration; public class NickoConfiguration { private final NickoBukkit nicko; private String prefix; - private String fallbackLocale; private Boolean bungeecordSupport; private Boolean localStorage; @@ -19,13 +18,22 @@ public class NickoConfiguration { this.nicko = nicko; } + //............. + // SECTION ACCESSORS + //............. + public ConfigurationSection getBungeecordSection() { return getConfig().getConfigurationSection("bungeecord"); } - public ConfigurationSection getStorageSection() { return getConfig().getConfigurationSection("storage"); } + // Unused for now + public ConfigurationSection getRedisSection() { return getBungeecordSection().getConfigurationSection("redis"); } public ConfigurationSection getLocaleSection() { return getConfig().getConfigurationSection("locale"); } - public ConfigurationSection getRedisSection() { return getBungeecordSection().getConfigurationSection("redis"); } + public ConfigurationSection getStorageSection() { return getConfig().getConfigurationSection("storage"); } + + //............. + // GLOBAL + //............. public String getPrefix() { if (prefix == null) { @@ -34,33 +42,11 @@ public class NickoConfiguration { return prefix; } - public void setPrefix(String prefix) { - this.prefix = prefix; - } + //............. + // BUNGEECORD + //............. - public String getFallbackLocale() { - if (fallbackLocale == null) { - return fallbackLocale = getLocaleSection().getString("fallback"); - } - return fallbackLocale; - } - - public void setFallbackLocale(String fallbackLocale) { - this.fallbackLocale = fallbackLocale; - } - - public boolean isCustomLocaleEnabled() { - if (customLocale == null) { - return customLocale = getStorageSection().getBoolean("local"); - } - return customLocale; - } - - public void setCustomLocaleEnabled(Boolean localStorage) { - this.localStorage = localStorage; - } - - public boolean isBungeecordEnabled() { + public boolean isBungeecordSupport() { if (bungeecordSupport == null) { return bungeecordSupport = getBungeecordSection().getBoolean("enabled"); } @@ -71,6 +57,25 @@ public class NickoConfiguration { this.bungeecordSupport = bungeecordSupport; } + //............. + // LOCALE + //............. + + public boolean isCustomLocale() { + if (customLocale == null) { + return customLocale = getLocaleSection().getBoolean("use_custom_locale"); + } + return customLocale; + } + + public void setCustomLocale(boolean customLocale) { + this.customLocale = customLocale; + } + + //............. + // STORAGE + //............. + public boolean isLocalStorage() { if (localStorage == null) { return localStorage = getStorageSection().getBoolean("local"); @@ -78,7 +83,7 @@ public class NickoConfiguration { return localStorage; } - public void setLocalStorage(Boolean localStorage) { + public void setLocalStorage(boolean localStorage) { this.localStorage = localStorage; } diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/i18n/I18N.java b/nicko-core/src/main/java/net/artelnatif/nicko/i18n/I18N.java index d425e4b..98d473f 100644 --- a/nicko-core/src/main/java/net/artelnatif/nicko/i18n/I18N.java +++ b/nicko-core/src/main/java/net/artelnatif/nicko/i18n/I18N.java @@ -2,35 +2,28 @@ package net.artelnatif.nicko.i18n; import net.artelnatif.nicko.NickoBukkit; import net.artelnatif.nicko.disguise.NickoProfile; -import org.apache.commons.lang3.LocaleUtils; import org.bukkit.entity.Player; +import org.yaml.snakeyaml.Yaml; import java.text.MessageFormat; +import java.util.HashMap; import java.util.Optional; -import java.util.ResourceBundle; public class I18N { private final static MessageFormat formatter = new MessageFormat(""); + private static final Yaml yaml = new Yaml(); private static Locale getLocale(Player player) { final NickoBukkit instance = NickoBukkit.getInstance(); try { final Optional profile = instance.getDataStore().getData(player.getUniqueId()); - if (profile.isEmpty()) { - return Locale.ENGLISH; - } else { - return profile.get().getLocale(); - } + return profile.isEmpty() ? Locale.FALLBACK_LOCALE : profile.get().getLocale(); } catch (IllegalArgumentException exception) { - instance.getLogger().severe("Invalid locale provided by " + player.getName() + ", defaulting to " + LocaleManager.getFallback().getCode() + "."); - return LocaleManager.getFallback(); + instance.getLogger().severe("Invalid locale provided by " + player.getName() + ", defaulting to " + Locale.FALLBACK_LOCALE.getCode() + "."); + return Locale.FALLBACK_LOCALE; } } - private static ResourceBundle getBundle(java.util.Locale locale) { - return ResourceBundle.getBundle("locale", locale); - } - public static String translate(Player player, I18NDict key, Object... arguments) { final NickoBukkit instance = NickoBukkit.getInstance(); final String translation = findTranslation(player, key); @@ -43,7 +36,7 @@ public class I18N { } } - public static String translateFlat(Player player, I18NDict key, Object... arguments) { + public static String translateWithoutPrefix(Player player, I18NDict key, Object... arguments) { final String translation = findTranslation(player, key); try { formatter.applyPattern(translation); @@ -53,15 +46,15 @@ public class I18N { } } - private static String findTranslation(Player player, I18NDict key) { final NickoBukkit instance = NickoBukkit.getInstance(); final Locale locale = getLocale(player); String translation; if (locale == Locale.CUSTOM) { - translation = instance.getLocaleManager().getCustomLanguageFile().getProperty(key.key(), key.key()); + translation = instance.getLocaleFileManager().getFromFile(key.key()); } else { - translation = getBundle(LocaleUtils.toLocale(locale.getCode())).getString(key.key()); + final HashMap values = yaml.load(I18N.class.getResourceAsStream(locale.getCode() + ".yml")); + translation = values.getOrDefault(key.key(), key.key()); } return translation; diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/i18n/Locale.java b/nicko-core/src/main/java/net/artelnatif/nicko/i18n/Locale.java index ce3b81e..1aeeee9 100644 --- a/nicko-core/src/main/java/net/artelnatif/nicko/i18n/Locale.java +++ b/nicko-core/src/main/java/net/artelnatif/nicko/i18n/Locale.java @@ -1,14 +1,13 @@ package net.artelnatif.nicko.i18n; import java.io.Serializable; -import java.util.HashMap; public enum Locale implements Serializable { ENGLISH("en", "English"), FRENCH("fr", "Français"), CUSTOM("custom", "Server Custom"); - private static HashMap locales; + public static final Locale FALLBACK_LOCALE = ENGLISH; private final String code; private transient final String name; @@ -18,21 +17,6 @@ public enum Locale implements Serializable { this.name = name; } - public static HashMap getLocales() { - if (locales == null) { - return locales = new HashMap<>() {{ - for (Locale value : Locale.values()) { - put(value.getCode(), value); - } - }}; - } - return locales; - } - - public static Locale fromCode(String code) { - return getLocales().getOrDefault(code, LocaleManager.getFallback()); - } - public String getCode() { return code; } diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java b/nicko-core/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java new file mode 100644 index 0000000..12330bb --- /dev/null +++ b/nicko-core/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java @@ -0,0 +1,46 @@ +package net.artelnatif.nicko.i18n; + +import net.artelnatif.nicko.NickoBukkit; +import org.yaml.snakeyaml.Yaml; + +import java.io.*; +import java.util.HashMap; + +public class LocaleFileManager { + private final Yaml yaml = new Yaml(); + private final File folder = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/"); + private final File file = new File(folder, "lang.yml"); + + private HashMap data = new HashMap<>(); + + public boolean loadValues() { + if (!file.exists()) return false; + try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file))) { + data = yaml.load(inputStream); + return true; + } catch (IOException e) { + return false; + } + } + + public String getFromFile(String key) { + if (!file.exists() || data.isEmpty()) return key; + return data.get(key); + } + + public boolean dumpFromLocale(Locale locale) { + if (locale == Locale.CUSTOM) return true; + if (file.exists()) return true; + final HashMap values = yaml.load(this.getClass().getResourceAsStream(locale.getCode() + ".yml")); + try { + if (file.createNewFile()) { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) { + yaml.dump(values, writer); + } + } + return true; + } catch (IOException e) { + return false; + } + } +} diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/utils/ServerUtils.java b/nicko-core/src/main/java/net/artelnatif/nicko/utils/ServerUtils.java index 30de3cc..835ed6e 100644 --- a/nicko-core/src/main/java/net/artelnatif/nicko/utils/ServerUtils.java +++ b/nicko-core/src/main/java/net/artelnatif/nicko/utils/ServerUtils.java @@ -14,7 +14,7 @@ public class ServerUtils { public void checkSpigotBungeeCordHook() { final Server server = instance.getServer(); final YamlConfiguration config = server.spigot().getConfig(); - if (config.getConfigurationSection("settings").getBoolean("bungeecord") && instance.getNickoConfig().isBungeecordEnabled()) { + if (config.getConfigurationSection("settings").getBoolean("bungeecord") && instance.getNickoConfig().isBungeecordSupport()) { instance.getLogger().severe("Hummm. Your server is hooked to BungeeCord, but it seems"); instance.getLogger().severe("that BungeeCord support is not enabled inside Nicko."); instance.getLogger().severe("If this is intentional, you can safely ignore this message."); diff --git a/nicko-core/src/main/resources/config.yml b/nicko-core/src/main/resources/config.yml index 667cc30..0cf53ab 100644 --- a/nicko-core/src/main/resources/config.yml +++ b/nicko-core/src/main/resources/config.yml @@ -14,13 +14,9 @@ bungeecord: # Localisation: locale: - # By default, Nicko tries to get the locale from the player's preferences. - # If that fails, the locale fallback is the one provided by this option. - # Accepted values: fr (French), en (English), custom (Custom language file). - fallback: "en" - # Nicko will copy the English locale as "custom.yml" + # Nicko will copy the English locale as "lang.yml" # and will use the translations in that file when "Server Custom" - # is selected as the player's locale/default locale. + # is selected as the player's locale. use_custom_locale: false diff --git a/nicko-core/src/main/resources/en.yml b/nicko-core/src/main/resources/en.yml index 1066e42..22b55dd 100644 --- a/nicko-core/src/main/resources/en.yml +++ b/nicko-core/src/main/resources/en.yml @@ -1,15 +1,21 @@ -event.previous_skin_applied.success=§aYour previous active disguise has been applied back. -event.previous_skin_applied.fail=§cFailed to apply your previous disguise back. §7§o({0}) -event.disguise.success=§aDisguise applied! -event.disguise.fail=§cUnable to apply your disguise. §7§o({0}) -event.undisguise.success=§aDisguise removed. -event.undisguise.fail=§cUnable to remove your disguise. It will be set back to default on your next login. Sorry! -event.undisguise.notactive=§cYou do not have an active disguise. -error.player_offline=§c{0} §fis offline, please try again. -error.generic=Unknown error -error.couldnt_get_name_from_mojang=Failed to get username from Mojang -error.couldnt_get_skin_from_mojang=Failed to get skin from Mojang -error.couldnt_get_skin_from_cache=Failed to get skin from cache -error.invalid_username=§cThe specified username is not a valid Minecraft username. -admin.custom_language_reload_success=§aReloaded custom language file. -admin.custom_language_reload_fail=§cFailed to reload the custom language file! \ No newline at end of file +admin: + custom_language_reload_fail: "§cFailed to reload the custom language file!" + custom_language_reload_success: "§aReloaded custom language file." +error: + couldnt_get_name_from_mojang: "Failed to get username from Mojang" + couldnt_get_skin_from_cache: "Failed to get skin from cache" + couldnt_get_skin_from_mojang: "Failed to get skin from Mojang" + generic: "Unknown error" + invalid_username: "§cThe specified username is not a valid Minecraft username." + player_offline: "§c{0} §fis offline, please try again." +event: + disguise: + fail: "§cUnable to apply your disguise. §7§o({0})" + success: "§aDisguise applied!" + previous_skin_applied: + fail: "§cFailed to apply your previous disguise back. §7§o({0})" + success: "§aYour previous active disguise has been applied back." + undisguise: + fail: "§cUnable to remove your disguise. It will be set back to default on your next login. Sorry!" + notactive: "§cYou do not have an active disguise." + success: "§aDisguise removed." \ No newline at end of file diff --git a/nicko-core/src/main/resources/fr.yml b/nicko-core/src/main/resources/fr.yml index 32ef934..e200af4 100644 --- a/nicko-core/src/main/resources/fr.yml +++ b/nicko-core/src/main/resources/fr.yml @@ -1,15 +1,21 @@ -event.previous_skin_applied.success=§aVotre précédent déguisement a été réappliqué. -event.previous_skin_applied.fail=§cImpossible d'appliquer votre déguisement précédent. §7§o({0}) -event.disguise.success=§aDéguisement appliqué ! -event.disguise.fail=§cImpossible d'appliquer votre déguisement. §7§o({0}) -event.undisguise.success=§aDéguisement retiré. -event.undisguise.fail=§cImpossible de retier votre déguisement. Il sera remis par défaut à votre prochaine reconnexion. Désolé ! -event.undisguise.notactive=§cVous n'avez pas de déguisement. -error.player_offline=§c{0} §fest hors-ligne, veuillez réessayer. -error.generic=Erreur inconnue -error.couldnt_get_name_from_mojang=Impossible de récupérer le nom d'utilisateur depuis Mojang -error.couldnt_get_skin_from_mojang=Impossible de récupérer le skin depuis Mojang -error.couldnt_get_skin_from_cache=Impossible de récupérer le skin depuis le cache -error.invalid_username=§cLe pseudo spécifié n'est pas un pseudo Minecraft valide. -admin.custom_language_reload_success=§aFichier de langue rechargé. -admin.custom_language_reload_fail=§cImpossible de recharger le fichier de langue ! \ No newline at end of file +admin: + custom_language_reload_fail: "§cImpossible de recharger le fichier de langue !" + custom_language_reload_success: "§aFichier de langue rechargé." +error: + couldnt_get_name_from_mojang: "Impossible de récupérer le nom d'utilisateur depuis Mojang" + couldnt_get_skin_from_cache: "Impossible de récupérer le skin depuis le cache" + couldnt_get_skin_from_mojang: "Impossible de récupérer le skin depuis Mojang" + generic: "Erreur inconnue" + invalid_username: "§cLe pseudo spécifié n'est pas un pseudo Minecraft valide." + player_offline: "§c{0} §fest hors-ligne, veuillez réessayer." +event: + disguise: + fail: "§cImpossible d'appliquer votre déguisement. §7§o({0})" + success: "§aDéguisement appliqué !" + previous_skin_applied: + fail: "§cImpossible d'appliquer votre déguisement précédent. §7§o({0})" + success: "§aVotre précédent déguisement a été réappliqué." + undisguise: + fail: "§cImpossible de retier votre déguisement. Il sera remis par défaut à votre prochaine reconnexion. Désolé !" + notactive: "§cVous n'avez pas de déguisement." + success: "§aDéguisement retiré." \ No newline at end of file diff --git a/nicko-core/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java b/nicko-core/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java index 756f13b..f78dbce 100644 --- a/nicko-core/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java +++ b/nicko-core/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java @@ -31,7 +31,7 @@ public class SQLStorageTest { @DisplayName("Create SQL Tables") public void testSQLTables() { - final PlayerMock playerMock = server.addPlayer("Aro"); + final PlayerMock playerMock = server.addPlayer(); final Optional data = plugin.getDataStore().getData(playerMock.getUniqueId()); Assertions.assertTrue(data.isPresent()); Assertions.assertNull(data.get().getSkin());