Backport Messages from BigDoors v2

- Backported the Messages system from BigDoors v2. This new system does not overwrite the default language file anymore (nor does it make it read-only). Instead, it reads as many translations from whatever file is selected and takes any missing translations from the translation file inside the jar (and lets the admin know that a translation is missing in the console). This makes the plugin a bit friendlier to use for people that cannot be bothered to read the disclaimer at the top of the file.
This commit is contained in:
Pim van der Loos 2020-05-20 13:12:25 +02:00
parent e093b18124
commit 7f09a34fdb
No known key found for this signature in database
GPG Key ID: C16F020ADAE6D5A8
9 changed files with 394 additions and 168 deletions

View File

@ -9,8 +9,9 @@ import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier; import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.ArmorTierName; import nl.pim16aap2.armoredElytra.util.ArmorTierName;
import nl.pim16aap2.armoredElytra.util.ConfigLoader; import nl.pim16aap2.armoredElytra.util.ConfigLoader;
import nl.pim16aap2.armoredElytra.util.Messages;
import nl.pim16aap2.armoredElytra.util.UpdateManager; import nl.pim16aap2.armoredElytra.util.UpdateManager;
import nl.pim16aap2.armoredElytra.util.messages.Message;
import nl.pim16aap2.armoredElytra.util.messages.Messages;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -21,9 +22,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.regex.Pattern;
// TODO: Figure out if the config really does read the list of enchantments accurately. A bug report with a customized config seemed to load the default settings... // TODO: Figure out if the config really does read the list of enchantments accurately. A bug report with a customized config seemed to load the default settings...
// TODO: Verify enchantments on startup. Remove them from the list if they're invalid. // TODO: Verify enchantments on startup. Remove them from the list if they're invalid.
@ -37,9 +36,6 @@ public class ArmoredElytra extends JavaPlugin implements Listener
private ConfigLoader config; private ConfigLoader config;
private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap<>(ArmorTier.class); private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap<>(ArmorTier.class);
private String elytraReceivedMessage;
private String usageDeniedMessage;
private String elytraLore;
private boolean upToDate; private boolean upToDate;
private boolean is1_9; private boolean is1_9;
private UpdateManager updateManager; private UpdateManager updateManager;
@ -112,35 +108,19 @@ public class ArmoredElytra extends JavaPlugin implements Listener
return messages; return messages;
} }
private final String getColorCodedStringFromConfig(final String configEntry)
{
return getMyMessages().getString(configEntry).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
}
private void readMessages() private void readMessages()
{ {
// Replace color codes by the corresponding colors.
usageDeniedMessage = getColorCodedStringFromConfig("MESSAGES.UsageDenied");
elytraReceivedMessage = getColorCodedStringFromConfig("MESSAGES.ElytraReceived");
elytraLore = getColorCodedStringFromConfig("MESSAGES.Lore");
armorTierNames.put(ArmorTier.NONE, new ArmorTierName("NONE", "NONE")); // Shouldn't be used. armorTierNames.put(ArmorTier.NONE, new ArmorTierName("NONE", "NONE")); // Shouldn't be used.
armorTierNames.put(ArmorTier.LEATHER, new ArmorTierName(getColorCodedStringFromConfig("TIER.Leather"), armorTierNames.put(ArmorTier.LEATHER, new ArmorTierName(messages.getString(Message.TIER_LEATHER),
getColorCodedStringFromConfig("TIER.SHORT.Leather"))); messages.getString(Message.TIER_SHORT_LEATHER)));
armorTierNames.put(ArmorTier.GOLD, new ArmorTierName(getColorCodedStringFromConfig("TIER.Gold"), armorTierNames.put(ArmorTier.GOLD, new ArmorTierName(messages.getString(Message.TIER_GOLD),
getColorCodedStringFromConfig("TIER.SHORT.Gold"))); messages.getString(Message.TIER_SHORT_GOLD)));
armorTierNames.put(ArmorTier.CHAIN, new ArmorTierName(getColorCodedStringFromConfig("TIER.Chain"), armorTierNames.put(ArmorTier.CHAIN, new ArmorTierName(messages.getString(Message.TIER_CHAIN),
getColorCodedStringFromConfig("TIER.SHORT.Chain"))); messages.getString(Message.TIER_SHORT_CHAIN)));
armorTierNames.put(ArmorTier.IRON, new ArmorTierName(getColorCodedStringFromConfig("TIER.Iron"), armorTierNames.put(ArmorTier.IRON, new ArmorTierName(messages.getString(Message.TIER_IRON),
getColorCodedStringFromConfig("TIER.SHORT.Iron"))); messages.getString(Message.TIER_SHORT_IRON)));
armorTierNames.put(ArmorTier.DIAMOND, new ArmorTierName(getColorCodedStringFromConfig("TIER.Diamond"), armorTierNames.put(ArmorTier.DIAMOND, new ArmorTierName(messages.getString(Message.TIER_DIAMOND),
getColorCodedStringFromConfig("TIER.SHORT.Diamond"))); messages.getString(Message.TIER_SHORT_DIAMOND)));
// Change the string to null if it says "NONE".
usageDeniedMessage = (Objects.equals(usageDeniedMessage, new String("NONE")) ? null : usageDeniedMessage);
elytraReceivedMessage = (Objects.equals(elytraReceivedMessage, new String("NONE")) ? null :
elytraReceivedMessage);
elytraLore = (Objects.equals(elytraLore, new String("NONE")) ? null : elytraLore);
} }
public boolean playerHasCraftPerm(Player player, ArmorTier armorTier) public boolean playerHasCraftPerm(Player player, ArmorTier armorTier)
@ -185,41 +165,41 @@ public class ArmoredElytra extends JavaPlugin implements Listener
messagePlayer(player, ChatColor.WHITE, str); messagePlayer(player, ChatColor.WHITE, str);
} }
private String getMessageWithTierNames(final Message message, final ArmorTier armorTier)
{
ArmorTierName tierName = armorTierNames.get(armorTier);
return getMyMessages().getString(message,
tierName.getLongName(),
tierName.getShortName());
}
// Send the usageDeniedMessage message to the player. // Send the usageDeniedMessage message to the player.
public void usageDeniedMessage(Player player, ArmorTier armorTier) public void usageDeniedMessage(Player player, ArmorTier armorTier)
{ {
if (usageDeniedMessage != null) final String message = getMessageWithTierNames(Message.MESSAGES_USAGEDENIED, armorTier);
{ if (!message.equals("NONE"))
final String message = fillInArmorTierInStringNoColor(usageDeniedMessage, armorTier);
messagePlayer(player, ChatColor.RED, message); messagePlayer(player, ChatColor.RED, message);
}
} }
// Send the elytraReceivedMessage message to the player. // Send the elytraReceivedMessage message to the player.
public void elytraReceivedMessage(Player player, ArmorTier armorTier) public void elytraReceivedMessage(Player player, ArmorTier armorTier)
{ {
if (elytraReceivedMessage != null) final String message = getMessageWithTierNames(Message.MESSAGES_ELYTRARECEIVED, armorTier);
{ if (!message.equals("NONE"))
final String message = fillInArmorTierInStringNoColor(elytraReceivedMessage, armorTier);
messagePlayer(player, ChatColor.GREEN, message); messagePlayer(player, ChatColor.GREEN, message);
}
} }
private static final Pattern ARMOR_TIER = Pattern.compile("%ARMOR_TIER%"); public void sendNoGivePermissionMessage(Player player, ArmorTier armorTier)
private static final Pattern ARMOR_TIER_SHORT = Pattern.compile("%ARMOR_TIER_SHORT%");
// Replace %ARMOR_TIER% by the name of that armor tier in a string, but strip %ARMOR_TIER% of its color.
public String fillInArmorTierInStringNoColor(String string, ArmorTier armorTier)
{ {
if (armorTier == null) final String message = getMessageWithTierNames(Message.MESSAGES_NOGIVEPERMISSION, armorTier);
{ messagePlayer(player, ChatColor.RED, message);
getLogger().log(Level.INFO, "ArmorTier was null! Failed to obtain proper string!"); }
return string;
} public String getElytraLore(ArmorTier armorTier)
final ArmorTierName tierName = armorTierNames.get(armorTier); {
return ARMOR_TIER_SHORT final String message = getMessageWithTierNames(Message.MESSAGES_LORE, armorTier);
.matcher(ARMOR_TIER.matcher(string).replaceAll(ChatColor.stripColor(tierName.getLongName()))) Bukkit.broadcastMessage(message);
.replaceAll(ChatColor.stripColor(tierName.getShortName())); return message.equals("NONE") ? null : message;
} }
// Print a string to the log. // Print a string to the log.
@ -258,11 +238,6 @@ public class ArmoredElytra extends JavaPlugin implements Listener
return instance; return instance;
} }
public String getElytraLore()
{
return elytraLore;
}
public String getArmoredElytraName(ArmorTier tier) public String getArmoredElytraName(ArmorTier tier)
{ {
if (tier == null) if (tier == null)

View File

@ -3,6 +3,7 @@ package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra; import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor; import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
import nl.pim16aap2.armoredElytra.util.ArmorTier; import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.messages.Message;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
@ -34,7 +35,7 @@ public class CommandHandler implements CommandExecutor
if (plugin.getConfigLoader().uninstallMode()) if (plugin.getConfigLoader().uninstallMode())
{ {
plugin.messagePlayer(player, plugin.getMyMessages().getString("MESSAGES.UninstallMode")); plugin.messagePlayer(player, plugin.getMyMessages().getString(Message.MESSAGES_UNINSTALLMODE));
return true; return true;
} }
@ -67,7 +68,8 @@ public class CommandHandler implements CommandExecutor
allowed = player.hasPermission("armoredelytra.give." + ArmorTier.getName(armorTier)); allowed = player.hasPermission("armoredelytra.give." + ArmorTier.getName(armorTier));
else else
{ {
plugin.messagePlayer(player, plugin.getMyMessages().getString("MESSAGES.UnsupportedTier")); plugin.messagePlayer(player, plugin.getMyMessages()
.getString(Message.MESSAGES_UNSUPPORTEDTIER));
return false; return false;
} }
@ -79,8 +81,7 @@ public class CommandHandler implements CommandExecutor
plugin.giveArmoredElytraToPlayer(receiver, newElytra); plugin.giveArmoredElytraToPlayer(receiver, newElytra);
} }
else else
plugin.messagePlayer(player, plugin.fillInArmorTierInStringNoColor( plugin.sendNoGivePermissionMessage(player, armorTier);
plugin.getMyMessages().getString("MESSAGES.NoGivePermission"), armorTier));
return true; return true;
} }
} }
@ -94,7 +95,7 @@ public class CommandHandler implements CommandExecutor
if (args.length == 2) if (args.length == 2)
{ {
ItemStack newElytra = null; ItemStack newElytra;
final String tier = args[1]; final String tier = args[1];
if (Bukkit.getPlayer(args[0]) != null) if (Bukkit.getPlayer(args[0]) != null)
{ {

View File

@ -11,6 +11,7 @@ import nl.pim16aap2.armoredElytra.util.AllowedToWearEnum;
import nl.pim16aap2.armoredElytra.util.ArmorTier; import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.Util; import nl.pim16aap2.armoredElytra.util.Util;
import nl.pim16aap2.armoredElytra.util.XMaterial; import nl.pim16aap2.armoredElytra.util.XMaterial;
import nl.pim16aap2.armoredElytra.util.messages.Message;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@ -525,7 +526,7 @@ public class EventHandlers implements Listener
case ALLOWED: case ALLOWED:
break; break;
case BROKEN: case BROKEN:
plugin.messagePlayer(e.getPlayer(), plugin.getMyMessages().getString("MESSAGES.RepairNeeded")); plugin.messagePlayer(e.getPlayer(), plugin.getMyMessages().getString(Message.MESSAGES_REPAIRNEEDED));
e.setCancelled(true); e.setCancelled(true);
break; break;
case NOPERMISSION: case NOPERMISSION:

View File

@ -3,6 +3,7 @@ package nl.pim16aap2.armoredElytra.nbtEditor;
import nl.pim16aap2.armoredElytra.ArmoredElytra; import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.util.ArmorTier; import nl.pim16aap2.armoredElytra.util.ArmorTier;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -145,10 +146,9 @@ public class NBTEditor
int armorToughness = ArmorTier.getToughness(armorTier); int armorToughness = ArmorTier.getToughness(armorTier);
itemmeta.setDisplayName(ArmoredElytra.getInstance().getArmoredElytraName(armorTier)); itemmeta.setDisplayName(ArmoredElytra.getInstance().getArmoredElytraName(armorTier));
if (ArmoredElytra.getInstance().getElytraLore() != null) final String message = ChatColor.stripColor(ArmoredElytra.getInstance().getElytraLore(armorTier));
itemmeta if (message != null)
.setLore(Arrays.asList(ArmoredElytra.getInstance().fillInArmorTierInStringNoColor( itemmeta.setLore(Arrays.asList(message));
ArmoredElytra.getInstance().getElytraLore(), armorTier)));
item.setItemMeta(itemmeta); item.setItemMeta(itemmeta);

View File

@ -1,97 +0,0 @@
package nl.pim16aap2.armoredElytra.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
public class Messages
{
private Map<String, String> messageMap = new HashMap<>();
private ArmoredElytra plugin;
private File textFile;
public Messages(ArmoredElytra plugin)
{
this.plugin = plugin;
textFile = new File(plugin.getDataFolder(), plugin.getConfigLoader().languageFile() + ".txt");
if (!textFile.exists())
{
plugin.myLogger(Level.WARNING, "Failed to load language file: \"" + textFile + "\": File not found! Using default file instead!");
textFile = new File(plugin.getDataFolder(), "en_US.txt");
}
readFile();
}
private void writeDefaultFile()
{
File defaultFile = new File(plugin.getDataFolder(), "en_US.txt");
if (!defaultFile.setWritable(true))
plugin.myLogger(Level.SEVERE, "Failed to make file \"" + defaultFile + "\" writable!");
// Load the default en_US from the resources.
plugin.saveResource("en_US.txt", true);
if (!defaultFile.setWritable(false))
{
plugin.myLogger(Level.WARNING, "Could not set default language file to read-only!");
plugin.myLogger(Level.WARNING, "This is not a big problem. Just remember not to edit the file!");
}
}
// Read locale file.
private void readFile()
{
writeDefaultFile();
try (BufferedReader br = new BufferedReader(new FileReader(textFile)))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
{
// Ignore comments.
if (sCurrentLine.startsWith("#") || sCurrentLine.isEmpty())
continue;
String key, value;
String[] parts = sCurrentLine.split("=", 2);
key = parts[0];
value = parts[1].replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
String[] newLineSplitter = value.split("\\\\n");
String values = newLineSplitter[0];
for (int idx = 1; idx < newLineSplitter.length; ++idx)
values += "\n" + newLineSplitter[idx];
messageMap.put(key, values);
}
br.close();
}
catch (FileNotFoundException e)
{
plugin.myLogger(Level.SEVERE, "Locale file \"" + textFile + "\" does not exist!");
}
catch (IOException e)
{
plugin.myLogger(Level.SEVERE, "Could not read locale file: \"" + textFile + "\"");
e.printStackTrace();
}
}
// Get a string from a key. Returns "null" if null.
public String getString(String key)
{
String value = messageMap.get(key);
if (value != null)
return value;
plugin.myLogger(Level.WARNING, "Failed to get the translation for key " + key);
return "Translation for key \"" + key + "\" not found! Contact server admin!";
}
}

View File

@ -0,0 +1,12 @@
package nl.pim16aap2.armoredElytra.util.messages;
/**
* Represents supported variables in localizable messages.
*
* @author Pim
*/
public interface IMessageVariable
{
String VAR_TIER_NAME = "%ARMOR_TIER%";
String VAR_TIER_NAME_SHORT = "%ARMOR_TIER_SHORT%";
}

View File

@ -0,0 +1,85 @@
package nl.pim16aap2.armoredElytra.util.messages;
/**
* Represents a localizable message.
*
* @author Pim
*/
public enum Message implements IMessageVariable
{
EMPTY(),
TIER_LEATHER(),
TIER_GOLD(),
TIER_CHAIN(),
TIER_IRON(),
TIER_DIAMOND(),
TIER_SHORT_LEATHER(),
TIER_SHORT_GOLD(),
TIER_SHORT_CHAIN(),
TIER_SHORT_IRON(),
TIER_SHORT_DIAMOND(),
MESSAGES_UNINSTALLMODE(),
MESSAGES_UNSUPPORTEDTIER(),
MESSAGES_REPAIRNEEDED(),
MESSAGES_LORE(VAR_TIER_NAME, VAR_TIER_NAME_SHORT),
MESSAGES_NOGIVEPERMISSION(VAR_TIER_NAME, VAR_TIER_NAME_SHORT),
MESSAGES_USAGEDENIED(VAR_TIER_NAME, VAR_TIER_NAME_SHORT),
MESSAGES_ELYTRARECEIVED(VAR_TIER_NAME, VAR_TIER_NAME_SHORT),
;
/**
* The list of names that can be used as variables in this message.
* <p>
* For example: "This door will move %BLOCKSTOMOVE% blocks." Would contain at least "%BLOCKSTOMOVE%".
*/
private final String[] variableNames;
/**
* Constructs a message.
*
* @param variableNames The names of the variables in the value that can be replaced.
*/
Message(final String... variableNames)
{
this.variableNames = variableNames;
}
/**
* Gets the name of the variable at the given position for the given message.
*
* @param msg The message for which to retrieve the variable name.
* @param idx The index of the variable name.
* @return The name of the variable at the given position of this message.
*/
public static String getVariableName(final Message msg, final int idx)
{
return msg.variableNames[idx];
}
/**
* Gets the names of the variables for the given message..
*
* @param msg The message for which to retrieve the variable names.
* @return The names of the variables of this message.
*/
public static String[] getVariableNames(final Message msg)
{
return msg.variableNames;
}
/**
* Gets the number of variables in this message that can be substituted.
*
* @param msg The message to retrieve the variable count for.
* @return The number of variables in this message that can be substituted.
*/
public static int getVariableCount(final Message msg)
{
return msg.variableNames.length;
}
}

View File

@ -0,0 +1,250 @@
package nl.pim16aap2.armoredElytra.util.messages;
import nl.pim16aap2.armoredElytra.ArmoredElytra;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.StandardCopyOption;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.logging.Level;
import java.util.regex.Pattern;
public class Messages
{
private static final String DEFAULTFILENAME = "en_US.txt";
/**
* The map of all messages.
* <p>
* Key: The {@link Message} enum entry.
* <p>
* Value: The translated message.
*/
private Map<Message, String> messageMap = new EnumMap<>(Message.class);
private final ArmoredElytra plugin;
private File textFile;
private static final Pattern matchDots = Pattern.compile("\\.");
private static final Pattern matchNewLines = Pattern.compile("\\\\n");
private static final Pattern matchColorCodes = Pattern.compile("&((?i)[0-9a-fk-or])");
public Messages(final ArmoredElytra plugin)
{
this.plugin = plugin;
textFile = new File(plugin.getDataFolder(), plugin.getConfigLoader().languageFile() + ".txt");
if (!textFile.exists())
{
plugin.myLogger(Level.WARNING, "Failed to load language file: \"" + textFile +
"\": File not found! Using default file instead!");
textFile = new File(plugin.getDataFolder(), DEFAULTFILENAME);
}
populateMessageMap();
}
private void writeDefaultFile()
{
File defaultFile = new File(plugin.getDataFolder(), DEFAULTFILENAME);
InputStream in = null;
try
{
URL url = getClass().getClassLoader().getResource(DEFAULTFILENAME);
if (url == null)
plugin.myLogger(Level.SEVERE, "Failed to read resources file from the jar! " +
"The default translation file cannot be generated! Please contact pim16aap2");
else
{
URLConnection connection = url.openConnection();
connection.setUseCaches(false);
in = connection.getInputStream();
java.nio.file.Files.copy(in, defaultFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
catch (Exception e)
{
plugin.myLogger(Level.SEVERE, "Failed to write default file to \"" + textFile + "\".");
e.printStackTrace();
}
finally
{
try
{
if (in != null)
in.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
/**
* Processes the contents of a file. Each valid line will be split up in the message key and the message value. It
* then
*
* @param br The {@link BufferedReader} that supplies the text.
* @param action The action to take for every message and value combination that is encountered.
* @throws IOException
*/
private void processFile(final BufferedReader br, final BiConsumer<Message, String> action)
throws IOException
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
{
// Ignore comments.
if (sCurrentLine.startsWith("#") || sCurrentLine.isEmpty())
continue;
String[] parts = sCurrentLine.split("=", 2);
try
{
final Message msg = Message.valueOf(matchDots.matcher(parts[0]).replaceAll("_").toUpperCase());
final String value = matchNewLines.matcher(matchColorCodes.matcher(parts[1]).replaceAll("\u00A7$1"))
.replaceAll("\n");
action.accept(msg, value);
}
catch (IllegalArgumentException e)
{
plugin.myLogger(Level.WARNING, "Failed to identify Message corresponding to key: \"" + parts[0] +
"\". Its value will be ignored!");
System.out.println(
"Trying to find enum value of: " + matchDots.matcher(parts[0]).replaceAll("_").toUpperCase());
}
}
}
/**
* Adds a message to the {@link #messageMap}.
*
* @param message The {@link Message}.
* @param value The value of the message.
*/
private void addMessage(final Message message, final String value)
{
messageMap.put(message, value);
}
/**
* Adds a message to the {@link #messageMap} if it isn't on the map already.
*
* @param message The {@link Message}.
* @param value The value of the message.
*/
private void addBackupMessage(final Message message, final String value)
{
if (messageMap.containsKey(message))
return;
plugin.myLogger(Level.WARNING,
"Could not find translation of key: \"" + message.name() + "\". Using default value instead!");
addMessage(message, value);
}
/**
* Reads the translations from the provided translations file.
* <p>
* Missing translations will use their default value.
*/
private void populateMessageMap()
{
try (BufferedReader br = new BufferedReader(new FileReader(textFile)))
{
processFile(br, this::addMessage);
}
catch (FileNotFoundException e)
{
plugin.myLogger(Level.SEVERE, "Locale file \"" + textFile + "\" does not exist!");
e.printStackTrace();
}
catch (IOException e)
{
plugin.myLogger(Level.SEVERE, "Could not read locale file! \"" + textFile + "\"");
e.printStackTrace();
}
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
Objects.requireNonNull(getClass().getClassLoader().getResource(DEFAULTFILENAME)).openStream())))
{
processFile(br, this::addBackupMessage);
}
catch (FileNotFoundException e)
{
plugin.myLogger(Level.SEVERE, "Failed to load internal locale file!");
e.printStackTrace();
}
catch (IOException e)
{
plugin.myLogger(Level.SEVERE, "Could not read internal locale file!");
e.printStackTrace();
}
for (final Message msg : Message.values())
if (!msg.equals(Message.EMPTY) && !messageMap.containsKey(msg))
{
plugin.myLogger(Level.WARNING, "Could not find translation of key: " + msg.name());
messageMap.put(msg, getFailureString(msg.name()));
}
}
/**
* Gets the default String to return in case a value could not be found for a given String.
*
* @param key The key that could not be resolved.
* @return The default String to return in case a value could not be found for a given String.
*/
private String getFailureString(final String key)
{
return "Translation for key \"" + key + "\" not found! Contact server admin!";
}
/**
* Gets the translated message of the provided {@link Message} and substitutes its variables for the provided
* values.
*
* @param msg The {@link Message} to translate.
* @param values The values to substitute for the variables in the message.
* @return The translated message of the provided {@link Message} and substitutes its variables for the provided
* values.
*/
public String getString(final Message msg, final String... values)
{
if (msg.equals(Message.EMPTY))
return "";
if (values.length != Message.getVariableCount(msg))
{
plugin.myLogger(Level.SEVERE,
"Expected " + Message.getVariableCount(msg) + " variables for key " + msg.name() +
" but only got " + values.length + ". This is a bug. Please contact pim16aap2!");
return getFailureString(msg.name());
}
String value = messageMap.get(msg);
if (value != null)
{
for (int idx = 0; idx != values.length; ++idx)
value = value.replaceAll(Message.getVariableName(msg, idx), values[idx]);
return value;
}
plugin.myLogger(Level.WARNING, "Failed to get the translation for key " + msg.name());
return getFailureString(msg.name());
}
}

View File

@ -1,5 +1,4 @@
# This file contains all the (partial) sentences used in this plugin. # This file contains all the (partial) sentences used in this plugin.
# If you want to modify anything, make sure to do so in a copy, as this file will be regenerated on startup!
# You can change which file will be used in the config.yml. # You can change which file will be used in the config.yml.
# The format is "key=value" (without quotation marks). You can modify the values, but not the keys. # The format is "key=value" (without quotation marks). You can modify the values, but not the keys.
# Order doesn't matter and you can use comments if you so desire. # Order doesn't matter and you can use comments if you so desire.
@ -25,4 +24,4 @@ MESSAGES.RepairNeeded=&cYou cannot equip this elytra! Please repair it in an anv
MESSAGES.Lore=Elytra with %ARMOR_TIER_SHORT% level protection. MESSAGES.Lore=Elytra with %ARMOR_TIER_SHORT% level protection.
MESSAGES.NoGivePermission=&cYou do not have the required permission node to give a(n) %ARMOR_TIER%s. MESSAGES.NoGivePermission=&cYou do not have the required permission node to give a(n) %ARMOR_TIER%s.
MESSAGES.UsageDenied=You do not have the required permissions to wear a(n) %ARMOR_TIER%! MESSAGES.UsageDenied=You do not have the required permissions to wear a(n) %ARMOR_TIER%!
MESSAGES.ElytraReceived=&2A(n) %ARMOR_TIER% has been bestowed upon you! MESSAGES.ElytraReceived=&2A(n) %ARMOR_TIER% has been bestowed upon you!