diff --git a/pom.xml b/pom.xml index ca25666..408bc6d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ A plugin for displaying citizens on the dynmap map - 17 + 16 UTF-8 @@ -24,8 +24,8 @@ maven-compiler-plugin 3.8.1 - 17 - 17 + ${java.version} + ${java.version} @@ -40,6 +40,20 @@ false + + + net.knarcraft:knarlib + + net/knarcraft/knarlib/** + + + + + *.MF + *.yml + + + @@ -136,6 +150,12 @@ 1.7.3 provided + + net.knarcraft + knarlib + 1.0-SNAPSHOT + compile + org.mcmonkey sentinel diff --git a/src/main/java/net/knarcraft/dynmapcitizens/DynmapCitizens.java b/src/main/java/net/knarcraft/dynmapcitizens/DynmapCitizens.java index 6cfee42..cac77f9 100644 --- a/src/main/java/net/knarcraft/dynmapcitizens/DynmapCitizens.java +++ b/src/main/java/net/knarcraft/dynmapcitizens/DynmapCitizens.java @@ -1,6 +1,6 @@ package net.knarcraft.dynmapcitizens; -import net.knarcraft.dynmapcitizens.formatting.Translator; +import net.knarcraft.dynmapcitizens.formatting.DynmapCitizensTranslatableMessage; import net.knarcraft.dynmapcitizens.handler.VaultHandler; import net.knarcraft.dynmapcitizens.handler.trait.BlacksmithHandler; import net.knarcraft.dynmapcitizens.handler.trait.CitizensTraitHandler; @@ -8,6 +8,9 @@ import net.knarcraft.dynmapcitizens.handler.trait.MinstrelHandler; import net.knarcraft.dynmapcitizens.handler.trait.SentinelHandler; import net.knarcraft.dynmapcitizens.handler.trait.quests.QuestsHandler; import net.knarcraft.dynmapcitizens.settings.GlobalSettings; +import net.knarcraft.knarlib.KnarLib; +import net.knarcraft.knarlib.formatting.TranslatableTimeUnit; +import net.knarcraft.knarlib.formatting.Translator; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.Plugin; @@ -31,6 +34,8 @@ public final class DynmapCitizens extends JavaPlugin { @Override public void onEnable() { DynmapCitizens.instance = this; + KnarLib.setPlugin(this); + //Initialize quest and dynmap APIs PluginManager pluginManager = Bukkit.getPluginManager(); Plugin dynmapPlugin = pluginManager.getPlugin("dynmap"); @@ -51,6 +56,8 @@ public final class DynmapCitizens extends JavaPlugin { this.globalSettings.load(configuration); //Load all messages + Translator.registerMessageCategory(TranslatableTimeUnit.UNIT_SECOND); + Translator.registerMessageCategory(DynmapCitizensTranslatableMessage.SENTINEL_DESCRIPTION); Translator.loadLanguages("en"); //Initialize all enabled traits diff --git a/src/main/java/net/knarcraft/dynmapcitizens/formatting/DynmapCitizensTranslatableMessage.java b/src/main/java/net/knarcraft/dynmapcitizens/formatting/DynmapCitizensTranslatableMessage.java new file mode 100644 index 0000000..4c50c6a --- /dev/null +++ b/src/main/java/net/knarcraft/dynmapcitizens/formatting/DynmapCitizensTranslatableMessage.java @@ -0,0 +1,35 @@ +package net.knarcraft.dynmapcitizens.formatting; + +import net.knarcraft.knarlib.formatting.TranslatableMessage; + +/** + * An enum describing all of DynmapCitizens' translatable messages + */ +public enum DynmapCitizensTranslatableMessage implements TranslatableMessage { + + SENTINEL_DESCRIPTION, + SENTINEL_DETAILS, + QUESTS_PLANNER_DESCRIPTION, + QUESTS_PLANNER_COOL_DOWN, + QUESTS_PLANNER_UNREPEATABLE, + QUESTS_PLANNER_FROM, + QUESTS_PLANNER_UNTIL, + QUEST_PLANNER_REPEAT, + QUESTS_REQUIREMENTS_FORMAT, + QUESTS_REQUIREMENTS_QUEST_POINTS, + QUESTS_REQUIREMENTS_EXP, + QUESTS_REQUIREMENTS_BLOCKED_BY_QUEST_FORMAT, + QUESTS_REQUIREMENTS_BLOCKED_BY_QUEST_ITEM, + QUESTS_REQUIREMENTS_REQUIRED_QUEST_FORMAT, + QUESTS_REQUIREMENTS_REQUIRED_QUEST_ITEM, + QUESTS_REQUIREMENTS_REQUIRED_ITEM_FORMAT, + QUESTS_REQUIREMENTS_REQUIRED_ITEM_ITEM, + QUESTS_REQUIREMENTS_MC_MMO_SKILL, + QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_FORMAT, + QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_ITEM; + + @Override + public TranslatableMessage[] getAllMessages() { + return DynmapCitizensTranslatableMessage.values(); + } +} diff --git a/src/main/java/net/knarcraft/dynmapcitizens/formatting/StringFormatter.java b/src/main/java/net/knarcraft/dynmapcitizens/formatting/StringFormatter.java deleted file mode 100644 index ce14013..0000000 --- a/src/main/java/net/knarcraft/dynmapcitizens/formatting/StringFormatter.java +++ /dev/null @@ -1,114 +0,0 @@ -package net.knarcraft.dynmapcitizens.formatting; - -import net.knarcraft.dynmapcitizens.DynmapCitizens; -import net.md_5.bungee.api.ChatColor; -import org.bukkit.command.CommandSender; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A formatter for formatting displayed messages - */ -public final class StringFormatter { - - private final static String pluginName = DynmapCitizens.getInstance().getDescription().getName(); - - private StringFormatter() { - - } - - /** - * Displays a message signifying a successful action - * - * @param sender

The command sender to display the message to

- * @param message

The translatable message to display

- */ - public static void displaySuccessMessage(CommandSender sender, TranslatableMessage message) { - sender.sendMessage(ChatColor.GREEN + getFormattedMessage(Translator.getTranslatedMessage(message))); - } - - /** - * Displays a message signifying a successful action - * - * @param sender

The command sender to display the message to

- * @param message

The raw message to display

- */ - public static void displaySuccessMessage(CommandSender sender, String message) { - sender.sendMessage(ChatColor.GREEN + getFormattedMessage(message)); - } - - /** - * Displays a message signifying an unsuccessful action - * - * @param sender

The command sender to display the message to

- * @param message

The translatable message to display

- */ - public static void displayErrorMessage(CommandSender sender, TranslatableMessage message) { - sender.sendMessage(ChatColor.DARK_RED + getFormattedMessage(Translator.getTranslatedMessage(message))); - } - - /** - * Gets the formatted version of any chat message - * - * @param message

The message to format

- * @return

The formatted message

- */ - private static String getFormattedMessage(String message) { - return "[" + pluginName + "] " + ChatColor.RESET + translateColors(message); - } - - /** - * Translates & color codes to proper colors - * - * @param input

The input string to translate colors for

- * @return

The input with color codes translated

- */ - private static String translateColors(String input) { - return ChatColor.translateAlternateColorCodes('&', input); - } - - /** - * Replaces a placeholder in a string - * - * @param input

The input string to replace in

- * @param placeholder

The placeholder to replace

- * @param replacement

The replacement value

- * @return

The input string with the placeholder replaced

- */ - public static String replacePlaceholder(String input, String placeholder, String replacement) { - return input.replace(placeholder, replacement); - } - - /** - * Replaces placeholders in a string - * - * @param input

The input string to replace in

- * @param placeholders

The placeholders to replace

- * @param replacements

The replacement values

- * @return

The input string with placeholders replaced

- */ - 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; - } - - /** - * Translates all found color codes to formatting in a string - * - * @param message

The string to search for color codes

- * @return

The message with color codes translated

- */ - 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; - } - -} diff --git a/src/main/java/net/knarcraft/dynmapcitizens/formatting/TranslatableMessage.java b/src/main/java/net/knarcraft/dynmapcitizens/formatting/TranslatableMessage.java deleted file mode 100644 index 46ebefe..0000000 --- a/src/main/java/net/knarcraft/dynmapcitizens/formatting/TranslatableMessage.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.knarcraft.dynmapcitizens.formatting; - -public enum TranslatableMessage { - - SENTINEL_DETAILS - -} diff --git a/src/main/java/net/knarcraft/dynmapcitizens/formatting/Translator.java b/src/main/java/net/knarcraft/dynmapcitizens/formatting/Translator.java deleted file mode 100644 index 85c3716..0000000 --- a/src/main/java/net/knarcraft/dynmapcitizens/formatting/Translator.java +++ /dev/null @@ -1,120 +0,0 @@ -package net.knarcraft.dynmapcitizens.formatting; - -import net.knarcraft.dynmapcitizens.DynmapCitizens; -import net.knarcraft.dynmapcitizens.util.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 translatedMessages; - private static Map 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

The message to translate

- * @return

The translated message

- */ - 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

The language chosen by the user

- * @return

A mapping of all strings for the given language

- */ - public static Map loadTranslatedMessages(String language) { - try { - BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml"); - return loadTranslatableMessages(language, reader); - } catch (FileNotFoundException e) { - DynmapCitizens.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

The selected language

- * @return

The loaded translated strings, or null if no custom language file exists

- */ - public static Map loadCustomTranslatedMessages(String language) { - DynmapCitizens instance = DynmapCitizens.getInstance(); - - File strings = new File(instance.getDataFolder(), "strings.yml"); - if (!strings.exists()) { - instance.getLogger().log(Level.FINEST, "Strings file not found"); - return null; - } - - try { - instance.getLogger().log(Level.INFO, "Loading custom strings..."); - return loadTranslatableMessages(language, new BufferedReader(new InputStreamReader(new FileInputStream(strings)))); - } catch (FileNotFoundException e) { - instance.getLogger().log(Level.WARNING, "Unable to load custom messages"); - return null; - } - } - - /** - * Loads translatable messages from the given reader - * - * @param language

The selected language

- * @param reader

The buffered reader to read from

- * @return

The loaded translated strings

- */ - private static Map loadTranslatableMessages(String language, BufferedReader reader) { - Map 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; - } - -} \ No newline at end of file diff --git a/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/quests/QuestPlannerInfoGenerator.java b/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/quests/QuestPlannerInfoGenerator.java index 3d6d6e5..4bb64f9 100644 --- a/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/quests/QuestPlannerInfoGenerator.java +++ b/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/quests/QuestPlannerInfoGenerator.java @@ -2,7 +2,11 @@ package net.knarcraft.dynmapcitizens.handler.trait.quests; import me.blackvein.quests.quests.IQuest; import me.blackvein.quests.quests.Planner; -import net.knarcraft.dynmapcitizens.util.TimeFormatter; +import net.knarcraft.knarlib.formatting.TimeFormatter; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; /** * A class to generate a string containing all information about a quest's planner info @@ -42,13 +46,13 @@ public class QuestPlannerInfoGenerator { //Quest only becomes available after the start date if (planner.hasStart()) { plannerInfo.append("
  • Quest available from "); - plannerInfo.append(TimeFormatter.formatTimestamp(planner.getStartInMillis())).append("
  • "); + plannerInfo.append(formatTimestamp(planner.getStartInMillis())).append(""); } //Quest is only available until the end date if (planner.hasEnd()) { plannerInfo.append("
  • Quest available until "); - plannerInfo.append(TimeFormatter.formatTimestamp(planner.getEndInMillis())).append("
  • "); + plannerInfo.append(formatTimestamp(planner.getEndInMillis())).append(""); } //Quest availability repeats @@ -61,4 +65,16 @@ public class QuestPlannerInfoGenerator { return plannerInfo.toString(); } + /** + * Gets a datetime string for the given timestamp + * + * @param timestamp

    A timestamp in milliseconds

    + * @return

    A datetime string

    + */ + private String formatTimestamp(long timestamp) { + DateFormat format = new SimpleDateFormat("dd MM yyyy HH:mm:ss"); + Date date = new Date(timestamp); + return format.format(date); + } + } diff --git a/src/main/java/net/knarcraft/dynmapcitizens/util/FileHelper.java b/src/main/java/net/knarcraft/dynmapcitizens/util/FileHelper.java deleted file mode 100644 index a5d13cc..0000000 --- a/src/main/java/net/knarcraft/dynmapcitizens/util/FileHelper.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.knarcraft.dynmapcitizens.util; - -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

    A buffered read for reading the file

    - * @throws FileNotFoundException

    If unable to get an input stream for the given file

    - */ - 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)); - } - -} diff --git a/src/main/java/net/knarcraft/dynmapcitizens/util/TimeFormatter.java b/src/main/java/net/knarcraft/dynmapcitizens/util/TimeFormatter.java deleted file mode 100644 index 30c0753..0000000 --- a/src/main/java/net/knarcraft/dynmapcitizens/util/TimeFormatter.java +++ /dev/null @@ -1,98 +0,0 @@ -package net.knarcraft.dynmapcitizens.util; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static net.knarcraft.dynmapcitizens.formatting.StringFormatter.replacePlaceholder; - -/** - * A helper class for time formatting - */ -public class TimeFormatter { - - /** - * Gets a datetime string for the given timestamp - * - * @param timestamp

    A timestamp in milliseconds

    - * @return

    A datetime string

    - */ - public static String formatTimestamp(long timestamp) { - DateFormat format = new SimpleDateFormat("dd MM yyyy HH:mm:ss"); - Date date = new Date(timestamp); - return format.format(date); - } - - /** - * Gets the string used for displaying this sign's duration - * - * @return

    The string used for displaying this sign's duration

    - */ - public static String getDurationString(long duration) { - if (duration == 0) { - return "immediately"; - } else { - double minute = 60; - double hour = minute * 60; - double day = hour * 24; - double week = day * 7; - double month = day * 30; - double year = day * 365; - double decade = year * 10; - - Map timeUnits = new HashMap<>(); - timeUnits.put(decade, new String[]{"decade", "decades"}); - timeUnits.put(year, new String[]{"year", "years"}); - timeUnits.put(month, new String[]{"month", "months"}); - timeUnits.put(week, new String[]{"week", "weeks"}); - timeUnits.put(day, new String[]{"day", "days"}); - timeUnits.put(hour, new String[]{"hour", "hours"}); - timeUnits.put(minute, new String[]{"minute", "minutes"}); - timeUnits.put(1D, new String[]{"second", "seconds"}); - - List sortedUnits = new ArrayList<>(timeUnits.keySet()); - Collections.sort(sortedUnits); - Collections.reverse(sortedUnits); - - for (Double unit : sortedUnits) { - if (duration / unit >= 1) { - double units = round(duration / unit); - return formatDurationString(units, timeUnits.get(unit)[units == 1 ? 0 : 1], - (units * 10) % 10 == 0); - } - } - return formatDurationString(duration, "seconds", false); - } - } - - /** - * Rounds a number to its last two digits - * - * @param number

    The number to round

    - * @return

    The rounded number

    - */ - private static double round(double number) { - return Math.round(number * 100.0) / 100.0; - } - - /** - * Formats a duration string - * - * @param duration

    The duration to display

    - * @param translatableMessage

    The time unit to display

    - * @param castToInt

    Whether to cast the duration to an int

    - * @return

    The formatted duration string

    - */ - private static String formatDurationString(double duration, String translatableMessage, boolean castToInt) { - String durationFormat = "{duration} {unit}"; - durationFormat = replacePlaceholder(durationFormat, "{unit}", translatableMessage); - return replacePlaceholder(durationFormat, "{duration}", castToInt ? String.valueOf((int) duration) : - String.valueOf(duration)); - } - -} diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml index 05aec0f..c2ba5f6 100644 --- a/src/main/resources/strings.yml +++ b/src/main/resources/strings.yml @@ -49,7 +49,24 @@ en: QUESTS_REQUIREMENTS_REQUIRED_QUEST_ITEM: "
  • {questName}
  • " QUESTS_REQUIREMENTS_REQUIRED_ITEM_FORMAT: "
  • Required items:
      {requiredItems}
  • " QUESTS_REQUIREMENTS_REQUIRED_ITEM_ITEM: "
  • {itemName}
  • " - QUESTS_REQUIREMENTS_MCMMO_SKILL: "
  • Requires mcMMO skill {skill} at level {level}
  • " + QUESTS_REQUIREMENTS_MC_MMO_SKILL: "
  • Requires mcMMO skill {skill} at level {level}
  • " QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_FORMAT: "
  • Required permissions:
      {permissions}
  • " QUESTS_REQUIREMENTS_REQUIRED_PERMISSION_ITEM: "
  • {permission}
  • " - \ No newline at end of file + DURATION_FORMAT: "in {time} {unit}" + UNIT_NOW: "imminently" + UNIT_SECOND: "second" + UNIT_SECONDS: "seconds" + UNIT_MINUTE: "minute" + UNIT_MINUTES: "minutes" + UNIT_HOUR: "hour" + UNIT_HOURS: "hours" + UNIT_DAY: "day" + UNIT_DAYS: "days" + UNIT_WEEK: "week" + UNIT_WEEKS: "weeks" + UNIT_MONTH: "month" + UNIT_MONTHS: "months" + UNIT_YEAR: "year" + UNIT_YEARS: "years" + UNIT_DECADE: "decade" + UNIT_DECADES: "decades" \ No newline at end of file