Last active
November 5, 2020 19:12
-
-
Save Braayy/6027148ab6f1289c4323410eff33776f to your computer and use it in GitHub Desktop.
A message provider with i18n for the bukkit plataform
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package braayy.lib.provider.impl; | |
import braayy.lib.provider.MessageProvider; | |
import org.bukkit.ChatColor; | |
import org.bukkit.command.CommandSender; | |
import org.bukkit.configuration.ConfigurationSection; | |
import org.bukkit.configuration.file.YamlConfiguration; | |
import org.bukkit.entity.Player; | |
import org.bukkit.plugin.Plugin; | |
import java.io.File; | |
import java.io.FileOutputStream; | |
import java.io.InputStream; | |
import java.util.*; | |
import java.util.jar.JarEntry; | |
import java.util.jar.JarFile; | |
import java.util.logging.Level; | |
public class DefaultMessageProvider implements MessageProvider { | |
private final Map<String, Map<String, String[]>> messageMap; | |
private String defaultLanguage; | |
public DefaultMessageProvider() { | |
this.messageMap = new HashMap<>(); | |
this.defaultLanguage = "en_us"; | |
} | |
@Override | |
public void enable(Plugin plugin) { | |
try { | |
long start = System.currentTimeMillis(); | |
File i18nFolder = new File(plugin.getDataFolder(), "i18n"); | |
if (!i18nFolder.exists()) { | |
if (!i18nFolder.mkdirs()) { | |
throw new IllegalStateException("Could not make i18n folder"); | |
} | |
this.saveDefaultLangFiles(i18nFolder); | |
} else { | |
this.loadLangFiles(i18nFolder); | |
} | |
long diff = System.currentTimeMillis() - start; | |
for (String lang : this.messageMap.keySet()) { | |
plugin.getLogger().info(lang + " locale was loaded"); | |
} | |
plugin.getLogger().info("Message service was enabled successfully " + diff + "ms"); | |
} catch (Exception ex) { | |
plugin.getLogger().log(Level.SEVERE, "Could not load messages.yml", ex); | |
} | |
} | |
@Override | |
public String[] get(String key, Object... args) { | |
return this.get(this.defaultLanguage, key, args); | |
} | |
@Override | |
public String[] get(String locale, String key, Object... args) { | |
if ((args.length & 1) != 0) { | |
throw new IllegalArgumentException("args length must be even"); | |
} | |
Map<String, String[]> localeMap = this.messageMap.get(locale); | |
Objects.requireNonNull(localeMap, locale + " locale was not found"); | |
String[] messageArray = localeMap.get(key); | |
Objects.requireNonNull(messageArray, key + " message was not found"); | |
String[] appliedArray = new String[messageArray.length]; | |
for (int i = 0 ; i < messageArray.length; i++) { | |
appliedArray[i] = applyParameters(messageArray[i], args); | |
} | |
return appliedArray; | |
} | |
@Override | |
public void sendMessage(CommandSender sender, String key, Object... args) { | |
String locale = (sender instanceof Player) ? ((Player) sender).getLocale() : this.defaultLanguage; | |
String[] messageArray = this.get(locale, key, args); | |
sender.sendMessage(messageArray); | |
} | |
@Override | |
public void setDefaultLanguage(String defaultLanguage) { | |
this.defaultLanguage = defaultLanguage; | |
} | |
private void loadLangFiles(File i18nFolder) { | |
File[] langFiles = i18nFolder.listFiles(); | |
if (langFiles == null) { | |
throw new IllegalStateException("Could not list i18n folder"); | |
} | |
for (File langFile : langFiles) { | |
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(langFile); | |
String lang = langFile.getName(); | |
lang = lang.substring(0, lang.length() - 4); | |
this.searchMessages(lang, yaml); | |
} | |
} | |
private void saveDefaultLangFiles(File i18nFolder) throws Exception { | |
File ownFile = new File(MessageProvider.class.getProtectionDomain().getCodeSource().getLocation().getPath()); | |
JarFile jarFile = new JarFile(ownFile); | |
Enumeration<JarEntry> enumeration = jarFile.entries(); | |
while (enumeration.hasMoreElements()) { | |
JarEntry entry = enumeration.nextElement(); | |
if (entry.getName().startsWith("i18n/") && !entry.isDirectory()) { | |
String fileName = entry.getName().substring(5); | |
File langFile = new File(i18nFolder, fileName); | |
FileOutputStream output = new FileOutputStream(langFile); | |
InputStream input = jarFile.getInputStream(entry); | |
byte[] buffer = new byte[2048]; | |
int read; | |
while ((read = input.read(buffer)) != -1) { | |
output.write(buffer, 0, read); | |
} | |
output.flush(); | |
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(langFile); | |
String lang = langFile.getName(); | |
lang = lang.substring(0, lang.length() - 4); | |
this.searchMessages(lang, yaml); | |
} | |
} | |
} | |
private void searchMessages(String locale, ConfigurationSection section) { | |
for (String key : section.getKeys(false)) { | |
String path = section.getCurrentPath() + '.' + key; | |
if (path.startsWith(".")) path = path.substring(1); | |
if (section.isConfigurationSection(key)) { | |
this.searchMessages(locale, section.getConfigurationSection(key)); | |
} else if (section.isString(key)) { | |
String message = ChatColor.translateAlternateColorCodes('&', section.getString(key)); | |
Map<String, String[]> localeMap = this.messageMap.getOrDefault(locale, new HashMap<>()); | |
localeMap.put(key, new String[] { message }); | |
this.messageMap.put(locale, localeMap); | |
} else if (section.isList(key)) { | |
List<String> messageList = section.getStringList(key); | |
messageList.replaceAll(string -> ChatColor.translateAlternateColorCodes('&', string)); | |
Map<String, String[]> localeMap = this.messageMap.getOrDefault(locale, new HashMap<>()); | |
localeMap.put(path, messageList.toArray(new String[0])); | |
this.messageMap.put(locale, localeMap); | |
} | |
} | |
} | |
private static String applyParameters(String string, Object... args) { | |
for (int i = 0; i < args.length; i += 2) { | |
String key = (String) args[i]; | |
String value = args[i + 1].toString(); | |
string = string.replace("{" + key + "}", value); | |
} | |
return string; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package braayy.lib.provider; | |
import org.bukkit.command.CommandSender; | |
import org.bukkit.plugin.Plugin; | |
public interface MessageProvider { | |
/** | |
* Configures the service | |
* @param plugin The plugin who is enabling this service | |
*/ | |
void enable(Plugin plugin); | |
/** | |
* @param key The key of the message | |
* @param args The arguments for the message | |
* @return The formatted message | |
*/ | |
String[] get(String key, Object... args); | |
/** | |
* @param locale The locale of the message | |
* @param key The key of the message | |
* @param args The arguments for the message | |
* @return The formatted message | |
*/ | |
String[] get(String locale, String key, Object... args); | |
/** | |
* @param sender The sender who will receive this message | |
* @param key The key of the message | |
* @param args The arguments for the message | |
*/ | |
void sendMessage(CommandSender sender, String key, Object... args); | |
/** | |
* @param defaultLanguage The default language | |
*/ | |
void setDefaultLanguage(String defaultLanguage); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment