I don't know if it's useful, but since 1.6 you can get a player's game language with Code:java public String getLanguage(Player p){Object ep = getMethod("getHandle", p.getClass()).invoke(p, (Object[]) null);Field f = ep.getClass().getDeclaredField("locale");f.setAccessible(true);String language = (String) f.get(ep);return language;}private Method getMethod(String name, Class<?> clazz) {for (Method m : clazz.getDeclaredMethods()) {if (m.getName().equals(name))return m;}return null;} Imports: java.lang.reflect.*; org.bukkit.entity.*; Before 1.6 you could get it with Code:java ((CraftPlayer) p).getHandle().getLocale(); Hope it helps you
Garris0n I implemented something like this in my System, I created a class that reads a string from the language config and sends it in the language of the player's minecraft^^ And, if you buy Google Translate Characters for their API you could use Google Translate to translate it, because it is soooooooooooooo good *irony off*
You can get notified about the client changing its locale setting if you use ProtocolLib here, and intercept packet 204 (client settings) from the client. The client's locale is the first string in the packet. That way your plugin can dynamically switch its locale as needed without the need to poll for the player's current locale.
Actually, if you're willing to take the time to do this, you can access Google's translate API for free using some neat "tricks" http://rupeshpatel.wordpress.com/2012/06/23/usage-of-google-translator-api-for-free/ (needs to be rewritten in java) It would actually be really cool if someone made a cross-language chat system with this!
bobacadodl except Google translate doesn't always translate perfectly as there are different adaptations of each language (learned that in Spanish class, thought I was saying one thing, teacher intepreted it as something completely different ). Also. That won't work for every Minecraft language, such as pirate speak (which virtually nobody uses :3).
chasechocolate bobacadodl Arrr! I love playing in pirate language! Pirate's 100% right when speakin' xD
I done enum with all languages, but it needs more work. Code: package com.stirante.Chat; import org.bukkit.entity.Player; import java.lang.reflect.*; public enum Language { AUSTRALIAN_ENGLISH("Australian English", "en_AU"), AFRIKAANS("Afrikaans", "af_ZA"), ARABIC("العربية", "ar_SA"), BULGARIAN("Български", "bg_BG"), CATALAN("Català", "ca_ES"), CZECH("Čeština", "cs_CZ"), CYMRAEG("Cymraeg", "cy_GB"), //??? DANISH("Dansk", "da_DK"), GERMAN("Deutsch", "de_DE"), GREEK("Ελληνικά", "el_GR"), CANADIAN_ENGLISH("Canadian English", "en_CA"), ENGLISH("English", "en_GB"), PIRATE_SPEAK("Pirate Speak", "en_PT"), //ARRRR! ESPERANTO("Esperanto", "eo_EO"), ARGENTINEAN_SPANISH("Español Argentino", "es_AR"), //these spanish languages still needs correct name, but i don't know how to name them SPANISH("Español", "es_ES"), MEXICO_SPANISH("Español México", "es_MX"), URUGUAY_SPANISH("Español Uruguay", "es_UY"), VENEZUELA_SPANISH("Español Venezuela", "es_VE"), ESTONIAN("Eesti", "et_EE"), EUSKARA("Euskara", "eu_ES"), //??? ENGLISH1("زبان انگلیسی", "fa_IR"), //I translated this text and it was just 'English', even code inside was en_US FINNISH("Suomi", "fi_FI"), TAGALOG("Tagalog", "fil_PH"), //??? FRENCH_CA("Français", "fr_CA"), //I think CA is from canada or something like that FRENCH("Français", "fr_FR"), GAEILGE("Gaeilge", "ga_IE"), //??? GALICIAN("Galego", "gl_ES"), HEBREW("עברית", "he_IL"), ENGLISH2("अंग्रेज़ी", "hi_IN"), //another weird english CROATIAN("Hrvatski", "hr_HR"), HUNGARIAN("Magyar", "hu_HU"), ARMENIAN("Հայերեն", "hy_AM"), BAHASA_INDONESIA("Bahasa Indonesia", "id_ID"), ICELANDIC("Íslenska", "is_IS"), ITALIAN("Italiano", "it_IT"), JAPANESE("日本語", "ja_JP"), GEORGIAN("ქართული", "ka_GE"), KOREAN("한국어", "ko_KR"), KERNEWEK("Kernewek", "kw_GB"), //??? ENGLISH3("अंग्रेज़ी", "ky_KG"), //another weird english LINGUA_LATINA("Lingua latina", "la_LA"), //??? LETZEBUERGESCH("Lëtzebuergesch", "lb_LU"), //google translate don't know what is this :o LITHUANIAN("Lietuvių", "lt_LT"), LATVIAN("Latviešu", "lv_LV"), MALAY_NZ("Bahasa Melayu", "mi_NZ"), //??? MALAY_MY("Bahasa Melayu", "ms_MY"), //??? MALTI("Malti", "mt_MT"), NORWEGIAN("Norsk", "nb_NO"), DUTCH("Nederlands", "nl_NL"), NORWEGIAN_NYNORSK("Norsk nynorsk", "nn_NO"), //??? NORWEGIAN1("Norsk", "no_NO"), //??? OCCITAN("Occitan", "oc_FR"), //??? PORTUGUESE_BR("Português", "pt_BR"), PORTUGUESE_PT("Português", "pt_PT"), QUENYA("Quenya", "qya_AA"), //??? ROMANIAN("Română", "ro_RO"), RUSSIAN("Русский", "ru_RU"), ENGLISH4("Angličtina", "sk_SK"), //another weird english, i think it's slovak SLOVENIAN("Slovenščina", "sl_SI"), SERBIAN("Српски", "sr_SP"), SWEDISH("Svenska", "sv_SE"), THAI("ภาษาไทย", "th_TH"), tlhIngan_Hol("tlhIngan Hol", "tlh_AA"), //??? TURKISH("Türkçe", "tr_TR"), UKRAINIAN("Українська", "uk_UA"), VIETNAMESE("Tiếng Việt", "vi_VI"), SIMPLIFIED_CHINESE("简体中文", "zh_CN"), TRADITIONAL_CHINESE("繁體中文", "zh_TW"), POLISH("Polski", "pl_PL"); private String name; private String code; Language(String name, String code) { this.name = name; this.code = code; } public String getName() { return name; } public String getCode() { return code; } public static Language getLanguage(Player p) { try { Object ep = getMethod("getHandle", p.getClass()).invoke(p, (Object[]) null); Field f = ep.getClass().getDeclaredField("locale"); f.setAccessible(true); String language = (String) f.get(ep); return getByCode(language); } catch (Throwable t) { t.printStackTrace(); return null; } } private static Method getMethod(String name, Class<?> clazz) { for (Method m : clazz.getDeclaredMethods()) { if (m.getName().equals(name)) return m; } return null; } public static Language getByCode(String code) { for (Language l : values()) { if (l.getCode().equalsIgnoreCase(code)) return l; } return null; } }
Used a combination of stirante and sheigutn code in order to make my Localizer for my plugin MyZ. Here's my Localizer enum: Code:java /****/package myz.Utilities; import java.lang.reflect.Field;import org.bukkit.entity.Player; /*** @author Jordan**/public enum Localizer { // English variants have been merged for sake of simplicity. AUSTRALIAN_ENGLISH("Australian English", "en_CA"/*"en_AU"*/), AFRIKAANS("Afrikaans", "af_ZA"), ARABIC("العربية", "ar_SA"), BULGARIAN( "Български", "bg_BG"), CATALAN("Català", "ca_ES"), CZECH("Čeština", "cs_CZ"), CYMRAEG("Cymraeg", "cy_GB"), DANISH("Dansk", "da_DK"), GERMAN("Deutsch", "de_DE"), GREEK("Ελληνικά", "el_GR"), CANADIAN_ENGLISH("Canadian English", "en_CA"), ENGLISH( "English", "en_CA"/*"en_GB"*/), PIRATE_SPEAK("Pirate Speak", "en_PT"), ESPERANTO("Esperanto", "eo_EO"), ARGENTINEAN_SPANISH( "Español Argentino", "es_AR"), SPANISH("Español", "es_ES"), MEXICO_SPANISH("Español México", "es_MX"), URUGUAY_SPANISH( "Español Uruguay", "es_UY"), VENEZUELA_SPANISH("Español Venezuela", "es_VE"), ESTONIAN("Eesti", "et_EE"), EUSKARA("Euskara", "eu_ES"), ENGLISH1("زبان انگلیسی", "en_CA"/*"fa_IR"*/), FINNISH("Suomi", "fi_FI"), TAGALOG("Tagalog", "fil_PH"), FRENCH_CA( "Français", "fr_CA"), FRENCH("Français", "fr_FR"), GAEILGE("Gaeilge", "ga_IE"), GALICIAN("Galego", "gl_ES"), HEBREW("עברית", "he_IL"), ENGLISH2("अंग्रेज़ी", "en_CA"/*"hi_IN"*/), CROATIAN("Hrvatski", "hr_HR"), HUNGARIAN("Magyar", "hu_HU"), ARMENIAN( "Հայերեն", "hy_AM"), BAHASA_INDONESIA("Bahasa Indonesia", "id_ID"), ICELANDIC("Íslenska", "is_IS"), ITALIAN("Italiano", "it_IT"), JAPANESE( "日本語", "ja_JP"), GEORGIAN("ქართული", "ka_GE"), KOREAN("한국어", "ko_KR"), KERNEWEK("Kernewek", "kw_GB"), ENGLISH3("अंग्रेज़ी", "en_CA"/*"ky_KG"*/), LINGUA_LATINA("Lingua latina", "la_LA"), LETZEBUERGESCH("Lëtzebuergesch", "lb_LU"), LITHUANIAN( "Lietuvių", "lt_LT"), LATVIAN("Latviešu", "lv_LV"), MALAY_NZ("Bahasa Melayu", "mi_NZ"), MALAY_MY("Bahasa Melayu", "ms_MY"), MALTI( "Malti", "mt_MT"), NORWEGIAN("Norsk", "nb_NO"), DUTCH("Nederlands", "nl_NL"), NORWEGIAN_NYNORSK("Norsk nynorsk", "nn_NO"), NORWEGIAN1( "Norsk", "no_NO"), OCCITAN("Occitan", "oc_FR"), PORTUGUESE_BR("Português", "pt_BR"), PORTUGUESE_PT("Português", "pt_PT"), QUENYA( "Quenya", "qya_AA"), ROMANIAN("Română", "ro_RO"), RUSSIAN("Русский", "ru_RU"), ENGLISH4("Angličtina", "en_CA"/*"sk_SK"*/), SLOVENIAN( "Slovenščina", "sl_SI"), SERBIAN("Српски", "sr_SP"), SWEDISH("Svenska", "sv_SE"), THAI("ภาษาไทย", "th_TH"), tlhIngan_Hol( "tlhIngan Hol", "tlh_AA"), TURKISH("Türkçe", "tr_TR"), UKRAINIAN("Українська", "uk_UA"), VIETNAMESE("Tiếng Việt", "vi_VI"), SIMPLIFIED_CHINESE( "简体中文", "zh_CN"), TRADITIONAL_CHINESE("繁體中文", "zh_TW"), POLISH("Polski", "pl_PL"); private String name; private String code; private Localizer(String name, String code) { this.name = name; this.code = code; } public String getName() { return name; } public String getCode() { return code; } private static Field field; public static Localizer getLocale(Player inPlayer) { try { Object nms = NMS.castToNMS(inPlayer); if (field == null) { field = nms.getClass().getDeclaredField("locale"); field.setAccessible(true); } Localizer code = getByCode((String) field.get(nms)); return code; } catch (Exception exc) { exc.printStackTrace(); return getByCode("en_CA"); } } public static Localizer getByCode(String code) { for (Localizer l : values()) { if (l.getCode().equalsIgnoreCase(code)) return l; } return Localizer.ENGLISH; }} Version independent with use of my NMS class (not provided but on GitHub). I just find the locale of the player and snag the string out of the right YAML file saved by the following where localizable is a HashMap for easy retrieval of FileConfigurations. Code:java private void loadLocalizable() { File folder = new File(getDataFolder() + File.separator + "locales"); if (!folder.exists()) { folder.mkdir(); } for (Localizer locale : Localizer.values()) { File localeable = new File(getDataFolder() + File.separator + "locales" + File.separator + locale.getCode() + ".yml"); if (!localeable.exists()) { try { localeable.createNewFile(); } catch (IOException e) { getLogger().warning("Unable to create locale " + locale.getCode()); e.printStackTrace(); } } localizable.put(locale.getCode(), YamlConfiguration.loadConfiguration(localeable)); } } May be a little dirty but it works great and I never would have thought of it on my own. Glad I happened across this thread!
Perhaps we could take a peak into the minecraft source code and look at how they do it, and steal their codez :3