diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/lang/IntlString.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/lang/IntlString.java new file mode 100644 index 000000000..fada15f15 --- /dev/null +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/lang/IntlString.java @@ -0,0 +1,232 @@ +package mineplex.core.common.lang; + +import java.text.Format; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class IntlString +{ + + public static IntlString[] toIntl(String... strings) + { + IntlString[] intl = new IntlString[strings.length]; + + for (int i = 0; i < strings.length; i++) { + final String string = strings[i]; + intl[i] = new IntlString("") + { + public String tr(Locale locale) + { + return string; + } + }; + } + + return intl; + } + + /** + * An empty {@link IntlString}. + */ + public static final IntlString EMPTY = toIntl("")[0]; + + private final Argument key; + private final List> arguments = new ArrayList<>(); + + public IntlString(String key, ChatColor... styles) + { + this.key = new Argument<>(key, styles); + } + + IntlString(String key, String style) + { + this.key = new Argument<>(key, style); + } + + private IntlString arg(Argument argument) + { + IntlString result = new IntlString(getKey().getArgument(), getKey().getStyle()); + result.arguments.addAll(getArguments()); + result.arguments.add(argument); + + return result; + } + + public Argument getKey() + { + return key; + } + + public List> getArguments() + { + return Collections.unmodifiableList(arguments); + } + + public IntlString arg(Object value, ChatColor... styles) + { + return arg(new Argument<>(value, styles)); + } + + public IntlString arg(Object value, String style) + { + return arg(new Argument<>(value, style)); + } + + public String tr() + { + return tr(Locale.getDefault()); + } + + public String tr(Entity entity) + { + if (entity instanceof Player) + return tr((Player) entity); + else + return tr(); + } + + public String tr(Player player) + { + return tr(Lang.getPlayerLocale(player)); + } + + public String tr(Locale locale) + { + if (locale == null) + locale = Locale.getDefault(); + + String formatString = Lang.get(getKey().getArgument(), locale); + + if (getKey().getArgument().equals("stats.achievements.disabled.requires.0.players")) + { + int x = 8; + } + + if (getArguments().isEmpty()) + return getKey().getStyle() + formatString; + else + { + MessageFormat format = new MessageFormat(formatString, locale); + + Format[] formats = format.getFormatsByArgumentIndex(); + Object[] argArray = new Object[getArguments().size()]; + for (int i = 0; i < formats.length; i++) + { + argArray[i] = getArguments().get(i); + if (argArray[i] instanceof IntlString) + argArray[i] = ((IntlString) argArray[i]).tr(locale); + + if (formats[i] != null) + { + argArray[i] = formats[i].format(argArray[i]); + format.setFormatByArgumentIndex(i, null); + } + + String style = getArguments().get(i).getStyle(); + if (!style.isEmpty()) + argArray[i] = style + argArray[i] + ChatColor.RESET; + + argArray[i] = argArray[i] + getKey().getStyle(); + } + + return getKey().getStyle() + format.format(argArray, new StringBuffer(), null).toString(); + } + } + + @Override + public boolean equals(Object o) + { + if (!(o instanceof IntlString)) + return false; + + IntlString s = (IntlString) o; + + return getKey().equals(s.getKey()) && getArguments().equals(s.getArguments()); + } + + @Override + public int hashCode() + { + return toString().hashCode(); + } + + @Override + public String toString() + { + return toEnglishString(); + } + + public String toEnglishString() + { + return tr(Locale.ENGLISH); + } + + private static class Argument + { + private final T argument; + private final String style; + + public Argument(T value, ChatColor... styles) + { + this.argument = value; + + String s = ""; + ChatColor color = null; + for (ChatColor style : styles) + { + if (style.isColor()) + color = style; + else if (style.isFormat()) + s += style; + } + + this.style = ChatColor.getLastColors((color == null ? "" : color) + s); + } + + public Argument(T value, String style) + { + this.argument = value; + this.style = style == null ? "" : ChatColor.getLastColors(style); + } + + public T getArgument() + { + return argument; + } + + public String getStyle() + { + return style; + } + + @Override + public boolean equals(Object o) + { + if (!(o instanceof Argument)) + return false; + + Argument p = (Argument) o; + + return getArgument().equals(p.getArgument()) && getStyle().equals(p.getStyle()); + } + + @Override + public int hashCode() + { + return toString().hashCode(); + } + + @Override + public String toString() + { + return getStyle() + getArgument(); + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/lang/Lang.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/lang/Lang.java new file mode 100644 index 000000000..b91fe232a --- /dev/null +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/lang/Lang.java @@ -0,0 +1,154 @@ +package mineplex.core.common.lang; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import mineplex.core.common.util.F; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public final class Lang +{ + public static interface PlayerLocaleFunction + { + public Locale getLocaleOfPlayer(Player player); + } + + + private static PlayerLocaleFunction _playerLocaleFunction = null; + private static final Map _localeResourceBundles = Collections.synchronizedMap(new HashMap()); + + + public Lang() + { + init(); + } + + + private void init() + { + System.out.println(F.main("i18n","Attempting to initialize resource bundles...")); + + try + { + // Locales over which we should iterate and load. + for (Locale loc : new Locale[] { + Locale.ENGLISH, + Locale.GERMAN + }) + { + ResourceBundle bundle = ResourceBundle.getBundle("mineplex.core.common.lang.MineplexBundle", loc); + _localeResourceBundles.put(loc, bundle); + System.out.println("Loaded " + loc.toString() + "..."); + } + } + catch (MissingResourceException e) + { + System.err.println("AN ERROR OCCURED WHILE ATTEMPTING TO LOAD RESOURCE LOCALES"); + // For now at least, crash the runtime. + throw new RuntimeException(e); + } + } + + public static PlayerLocaleFunction getPlayerLocaleFunction() + { + return _playerLocaleFunction; + } + + public static void setPlayerLocaleFunction(PlayerLocaleFunction playerLocaleFunction) + { + _playerLocaleFunction = playerLocaleFunction; + } + + public static Locale getPlayerLocale(Player player) + { + if (getPlayerLocaleFunction() == null) + return Locale.getDefault(); + else + return getPlayerLocaleFunction().getLocaleOfPlayer(player); + } + + public static ResourceBundle getResourceBundle(Locale locale) + { + synchronized (_localeResourceBundles) + { + if (_localeResourceBundles.containsKey(locale)) + return _localeResourceBundles.get(locale); + else + { + return _localeResourceBundles.get(Locale.ENGLISH); + } + } + } + + public static ResourceBundle getBestResourceBundle(Locale locale) + { + ResourceBundle bundle = getResourceBundle(locale); + + if (bundle == null && !locale.equals(Locale.getDefault())) + bundle = getResourceBundle(Locale.getDefault()); + + if (bundle == null && !locale.equals(Locale.ENGLISH)) + bundle = getResourceBundle(Locale.ENGLISH); + + return bundle; + } + + /** + * Shorthand method for obtaining and translating a key. + */ + public static String tr(String key, Entity entity, Object... args) + { + IntlString string = key(key); + + for (Object a : args) + string.arg(a); + + return string.tr(entity); + } + + public static String get(String key) + { + return get(key, (Locale) null); + } + + public static String get(String key, Locale locale) + { + if (key == null) + return null; + else if (key.isEmpty()) + return ""; + else + { + if (locale == null) + locale = Locale.getDefault(); + + ResourceBundle bundle = getBestResourceBundle(locale); + if (bundle == null) + return null; + + return bundle.getString(key); + } + } + + public static String get(String key, Player player) + { + return get(key, getPlayerLocale(player)); + } + + public static IntlString key(String key, ChatColor... styles) + { + return new IntlString(key, styles); + } + + public static IntlString key(String key, String style) + { + return new IntlString(key, style); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java b/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java index d5097e318..99e3cc185 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/notifier/NotificationManager.java @@ -60,18 +60,18 @@ public class NotificationManager extends MiniPlugin if (rank == Rank.ALL) { - UtilPlayer.message(player, C.cWhite + "50% Off Sale! " + " Purchase " + C.cAqua + C.Bold + "Ultra Rank" + C.cWhite + " for $15"); + UtilPlayer.message(player, C.cWhite + " 50% Off Sale! " + " Purchase " + C.cAqua + C.Bold + "Ultra Rank" + C.cWhite + " for $15"); } else if (rank == Rank.ULTRA) { - UtilPlayer.message(player, C.cWhite + "50% Off Sale! " + " Upgrade to " + C.cPurple + C.Bold + "Hero Rank" + C.cWhite + " for $15!"); + UtilPlayer.message(player, C.cWhite + " 50% Off Sale! " + " Upgrade to " + C.cPurple + C.Bold + "Hero Rank" + C.cWhite + " for $15!"); } else if (rank == Rank.HERO) { - UtilPlayer.message(player, C.cWhite + "50% Off Sale! " + "Upgrade to " + C.cGreen + C.Bold + "Legend Rank" + C.cWhite + " for $15!"); + UtilPlayer.message(player, C.cWhite + " 50% Off Sale! " + "Upgrade to " + C.cGreen + C.Bold + "Legend Rank" + C.cWhite + " for $15!"); } - UtilPlayer.message(player, C.cWhite + " Visit " + F.link("www.mineplex.com/shop") + " for 50% Off Ranks!"); + UtilPlayer.message(player, C.cWhite + " Visit " + F.link("www.mineplex.com/shop") + C.cWhite + " for 50% Off Ranks!"); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferencesPage.java b/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferencesPage.java index 8007a3aef..1fb8c4d0d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferencesPage.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/preferences/ui/PreferencesPage.java @@ -165,7 +165,19 @@ public class PreferencesPage extends ShopPageBase