Adds code to be able to translate plugin messages
This commit is contained in:
parent
483ffaec2b
commit
eb0e06f193
@ -10,6 +10,7 @@ import net.knarcraft.paidsigns.command.ReloadTabCommand;
|
||||
import net.knarcraft.paidsigns.command.RemoveConditionCommand;
|
||||
import net.knarcraft.paidsigns.command.RemoveConditionTabCompleter;
|
||||
import net.knarcraft.paidsigns.command.RemoveTabCommand;
|
||||
import net.knarcraft.paidsigns.formatting.Translator;
|
||||
import net.knarcraft.paidsigns.listener.BlockBreakListener;
|
||||
import net.knarcraft.paidsigns.listener.SignListener;
|
||||
import net.knarcraft.paidsigns.manager.EconomyManager;
|
||||
@ -33,6 +34,7 @@ public final class PaidSigns extends JavaPlugin {
|
||||
|
||||
private static PaidSigns paidSigns;
|
||||
private PaidSignManager signManager;
|
||||
private String language;
|
||||
private boolean ignoreCase;
|
||||
private boolean ignoreColor;
|
||||
private boolean enableRefunds;
|
||||
@ -58,9 +60,10 @@ public final class PaidSigns extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
setupVault();
|
||||
loadConfig();
|
||||
Translator.loadLanguages(language);
|
||||
signManager = new PaidSignManager(PaidSignManager.loadSigns());
|
||||
TrackedSignManager.loadTrackedSigns();
|
||||
loadConfig();
|
||||
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
pluginManager.registerEvents(new SignListener(), this);
|
||||
@ -79,6 +82,7 @@ public final class PaidSigns extends JavaPlugin {
|
||||
public void reload() {
|
||||
this.reloadConfig();
|
||||
loadConfig();
|
||||
Translator.loadLanguages(language);
|
||||
signManager = new PaidSignManager(PaidSignManager.loadSigns());
|
||||
TrackedSignManager.loadTrackedSigns();
|
||||
}
|
||||
@ -174,6 +178,7 @@ public final class PaidSigns extends JavaPlugin {
|
||||
ignoreColor = config.getBoolean("ignoreColor", false);
|
||||
enableRefunds = config.getBoolean("enableRefunds", true);
|
||||
refundPercentage = config.getInt("refundPercentage", 100);
|
||||
language = config.getString("language", "en");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,125 @@
|
||||
package net.knarcraft.paidsigns.formatting;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A formatter for formatting displayed messages
|
||||
*/
|
||||
public final class StringFormatter {
|
||||
|
||||
private StringFormatter() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the given boolean value
|
||||
*
|
||||
* @param booleanValue <p>The boolean value to translate</p>
|
||||
* @return <p>The translation of the boolean value</p>
|
||||
*/
|
||||
public static String translateBoolean(boolean booleanValue) {
|
||||
if (booleanValue) {
|
||||
return Translator.getTranslatedMessage(TranslatableMessage.BOOLEAN_TRUE);
|
||||
} else {
|
||||
return Translator.getTranslatedMessage(TranslatableMessage.BOOLEAN_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a placeholder in a string
|
||||
*
|
||||
* @param input <p>The input string to replace in</p>
|
||||
* @param placeholder <p>The placeholder to replace</p>
|
||||
* @param replacement <p>The replacement value</p>
|
||||
* @return <p>The input string with the placeholder replaced</p>
|
||||
*/
|
||||
public static String replacePlaceholder(String input, String placeholder, String replacement) {
|
||||
return input.replace(placeholder, replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces placeholders in a string
|
||||
*
|
||||
* @param input <p>The input string to replace in</p>
|
||||
* @param placeholders <p>The placeholders to replace</p>
|
||||
* @param replacements <p>The replacement values</p>
|
||||
* @return <p>The input string with placeholders replaced</p>
|
||||
*/
|
||||
public static String replacePlaceholders(String input, String[] placeholders, String[] replacements) {
|
||||
for (int i = 0; i < Math.min(placeholders.length, replacements.length); i++) {
|
||||
input = replacePlaceholder(input, placeholders[i], replacements[i]);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a translated and formatted info message
|
||||
*
|
||||
* @param translatableMessage <p>The translatable message to translate and format</p>
|
||||
* @return <p>The translated and formatted message</p>
|
||||
*/
|
||||
public static String getTranslatedInfoMessage(TranslatableMessage translatableMessage) {
|
||||
return formatInfoMessage(Translator.getTranslatedMessage(translatableMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a translated and formatted error message
|
||||
*
|
||||
* @param translatableMessage <p>The translatable message to translate and format</p>
|
||||
* @return <p>The translated and formatted message</p>
|
||||
*/
|
||||
public static String getTranslatedErrorMessage(TranslatableMessage translatableMessage) {
|
||||
return formatErrorMessage(Translator.getTranslatedMessage(translatableMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an information message by adding the prefix and text color
|
||||
*
|
||||
* @param message <p>The message to format</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
public static String formatInfoMessage(String message) {
|
||||
return ChatColor.DARK_GREEN + formatMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an error message by adding the prefix and text color
|
||||
*
|
||||
* @param message <p>The message to format</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
public static String formatErrorMessage(String message) {
|
||||
return ChatColor.DARK_RED + formatMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates all found color codes to formatting in a string
|
||||
*
|
||||
* @param message <p>The string to search for color codes</p>
|
||||
* @return <p>The message with color codes translated</p>
|
||||
*/
|
||||
public static String translateAllColorCodes(String message) {
|
||||
message = ChatColor.translateAlternateColorCodes('&', message);
|
||||
Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
while (matcher.find()) {
|
||||
message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group()));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a message by adding the prefix and text color
|
||||
*
|
||||
* @param message <p>The message to format</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
private static String formatMessage(String message) {
|
||||
return Translator.getTranslatedMessage(TranslatableMessage.PREFIX) + " " +
|
||||
ChatColor.RESET + message;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package net.knarcraft.paidsigns.formatting;
|
||||
|
||||
/**
|
||||
* An enum representing all translatable messages
|
||||
*/
|
||||
public enum TranslatableMessage {
|
||||
|
||||
/**
|
||||
* The prefix to display in messages
|
||||
*/
|
||||
PREFIX,
|
||||
|
||||
/**
|
||||
* The message to display when a paid sign is successfully added
|
||||
*/
|
||||
SUCCESS_ADDED_PAID_SIGN,
|
||||
|
||||
/**
|
||||
* The message to display when a paid sign condition is successfully added
|
||||
*/
|
||||
SUCCESS_ADDED_PAID_SIGN_CONDITION,
|
||||
|
||||
/**
|
||||
* The info text used to display information about a paid sign
|
||||
*/
|
||||
PAID_SIGN_INFO,
|
||||
|
||||
/**
|
||||
* The info text used to display information about a paid sign condition
|
||||
*/
|
||||
PAID_SIGN_CONDITION_INFO,
|
||||
|
||||
/**
|
||||
* The format used for displaying one of a paid sign's conditions
|
||||
*/
|
||||
PAID_SIGN_INFO_CONDITION_FORMAT,
|
||||
|
||||
/**
|
||||
* The message to display for a true boolean value
|
||||
*/
|
||||
BOOLEAN_TRUE,
|
||||
|
||||
/**
|
||||
* The message to display for a false boolean value
|
||||
*/
|
||||
BOOLEAN_FALSE,
|
||||
|
||||
/**
|
||||
* The error to display when a command argument contains an invalid number
|
||||
*/
|
||||
ERROR_INVALID_NUMBER,
|
||||
|
||||
/**
|
||||
* The error to display if a paid sign name duplicate is encountered
|
||||
*/
|
||||
ERROR_NAME_DUPLICATE,
|
||||
|
||||
/**
|
||||
* The error to display if a severe exception occurs
|
||||
*/
|
||||
ERROR_EXCEPTION_OCCURRED,
|
||||
|
||||
/**
|
||||
* The error to display if some input is invalid
|
||||
*/
|
||||
ERROR_INVALID_INPUT,
|
||||
|
||||
/**
|
||||
* The error to display if a specified paid sign is not found
|
||||
*/
|
||||
ERROR_PAID_SIGN_NOT_FOUND,
|
||||
|
||||
/**
|
||||
* The error to display if a paid sign condition is specified, but does not exist
|
||||
*/
|
||||
ERROR_NO_SUCH_CONDITION,
|
||||
|
||||
}
|
118
src/main/java/net/knarcraft/paidsigns/formatting/Translator.java
Normal file
118
src/main/java/net/knarcraft/paidsigns/formatting/Translator.java
Normal file
@ -0,0 +1,118 @@
|
||||
package net.knarcraft.paidsigns.formatting;
|
||||
|
||||
import net.knarcraft.paidsigns.PaidSigns;
|
||||
import net.knarcraft.paidsigns.utility.FileHelper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A tool to get strings translated to the correct language
|
||||
*/
|
||||
public final class Translator {
|
||||
|
||||
private static Map<TranslatableMessage, String> translatedMessages;
|
||||
private static Map<TranslatableMessage, String> backupTranslatedMessages;
|
||||
|
||||
private Translator() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the languages used by this translator
|
||||
*/
|
||||
public static void loadLanguages(String selectedLanguage) {
|
||||
backupTranslatedMessages = loadTranslatedMessages("en");
|
||||
translatedMessages = loadCustomTranslatedMessages(selectedLanguage);
|
||||
if (translatedMessages == null) {
|
||||
translatedMessages = loadTranslatedMessages(selectedLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a translated version of the given translatable message
|
||||
*
|
||||
* @param translatableMessage <p>The message to translate</p>
|
||||
* @return <p>The translated message</p>
|
||||
*/
|
||||
public static String getTranslatedMessage(TranslatableMessage translatableMessage) {
|
||||
if (translatedMessages == null) {
|
||||
return "Translated strings not loaded";
|
||||
}
|
||||
String translatedMessage;
|
||||
if (translatedMessages.containsKey(translatableMessage)) {
|
||||
translatedMessage = translatedMessages.get(translatableMessage);
|
||||
} else if (backupTranslatedMessages.containsKey(translatableMessage)) {
|
||||
translatedMessage = backupTranslatedMessages.get(translatableMessage);
|
||||
} else {
|
||||
translatedMessage = translatableMessage.toString();
|
||||
}
|
||||
return StringFormatter.translateAllColorCodes(translatedMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all translated messages for the given language
|
||||
*
|
||||
* @param language <p>The language chosen by the user</p>
|
||||
* @return <p>A mapping of all strings for the given language</p>
|
||||
*/
|
||||
public static Map<TranslatableMessage, String> loadTranslatedMessages(String language) {
|
||||
try {
|
||||
BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml");
|
||||
return loadTranslatableMessages(language, reader);
|
||||
} catch (FileNotFoundException e) {
|
||||
PaidSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to load translated messages");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load translated messages from a custom strings.yml file
|
||||
*
|
||||
* @param language <p>The selected language</p>
|
||||
* @return <p>The loaded translated strings, or null if no custom language file exists</p>
|
||||
*/
|
||||
public static Map<TranslatableMessage, String> loadCustomTranslatedMessages(String language) {
|
||||
File strings = new File(PaidSigns.getInstance().getDataFolder(), "strings.yml");
|
||||
if (!strings.exists()) {
|
||||
PaidSigns.getInstance().getLogger().log(Level.FINEST, "Strings file not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
PaidSigns.getInstance().getLogger().log(Level.WARNING, "Loading custom strings...");
|
||||
return loadTranslatableMessages(language, new BufferedReader(new InputStreamReader(new FileInputStream(strings))));
|
||||
} catch (FileNotFoundException e) {
|
||||
PaidSigns.getInstance().getLogger().log(Level.WARNING, "Unable to load custom messages");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads translatable messages from the given reader
|
||||
*
|
||||
* @param language <p>The selected language</p>
|
||||
* @param reader <p>The buffered reader to read from</p>
|
||||
* @return <p>The loaded translated strings</p>
|
||||
*/
|
||||
private static Map<TranslatableMessage, String> loadTranslatableMessages(String language, BufferedReader reader) {
|
||||
Map<TranslatableMessage, String> translatedMessages = new HashMap<>();
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(reader);
|
||||
|
||||
for (TranslatableMessage message : TranslatableMessage.values()) {
|
||||
String translated = configuration.getString(language + "." + message.toString());
|
||||
if (translated != null) {
|
||||
translatedMessages.put(message, translated);
|
||||
}
|
||||
}
|
||||
return translatedMessages;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package net.knarcraft.paidsigns.utility;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* A helper class for dealing with files
|
||||
*/
|
||||
public final class FileHelper {
|
||||
|
||||
private FileHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a buffered reader for
|
||||
*
|
||||
* @return <p>A buffered read for reading the file</p>
|
||||
* @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
|
||||
*/
|
||||
public static BufferedReader getBufferedReaderForInternalFile(String file) throws FileNotFoundException {
|
||||
InputStream inputStream = FileHelper.class.getResourceAsStream(file);
|
||||
if (inputStream == null) {
|
||||
throw new FileNotFoundException("Unable to read the given file");
|
||||
}
|
||||
return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
# The currently enabled language. More languages can be added to the language file
|
||||
language: en
|
||||
|
||||
# Whether to ignore the case (lowercase/uppercase) of the paid sign text. The option can be set on a per-sign basis, but
|
||||
# this value is used if not specified. The correct value depends on whether the plugin signs it should match are
|
||||
# case-sensitive or not.
|
||||
|
Loading…
Reference in New Issue
Block a user