Adds possibility for message customization and translation #5
This commit is contained in:
@ -6,6 +6,7 @@ import net.knarcraft.blacksmith.command.BlackSmithConfigTabCompleter;
|
||||
import net.knarcraft.blacksmith.command.BlackSmithEditCommand;
|
||||
import net.knarcraft.blacksmith.command.BlackSmithEditTabCompleter;
|
||||
import net.knarcraft.blacksmith.config.GlobalSettings;
|
||||
import net.knarcraft.blacksmith.formatting.Translator;
|
||||
import net.knarcraft.blacksmith.listener.NPCClickListener;
|
||||
import net.knarcraft.blacksmith.listener.PlayerListener;
|
||||
import net.knarcraft.blacksmith.manager.EconomyManager;
|
||||
@ -70,6 +71,8 @@ public class BlacksmithPlugin extends JavaPlugin {
|
||||
config = new GlobalSettings(this);
|
||||
config.load();
|
||||
|
||||
Translator.loadLanguages("en");
|
||||
|
||||
//Set up Vault integration
|
||||
if (!setUpVault()) {
|
||||
return;
|
||||
|
@ -5,8 +5,9 @@ import net.knarcraft.blacksmith.config.GlobalSetting;
|
||||
import net.knarcraft.blacksmith.config.GlobalSettings;
|
||||
import net.knarcraft.blacksmith.config.NPCSetting;
|
||||
import net.knarcraft.blacksmith.config.SettingValueType;
|
||||
import net.knarcraft.blacksmith.manager.ItemType;
|
||||
import net.knarcraft.blacksmith.manager.Message;
|
||||
import net.knarcraft.blacksmith.formatting.ItemType;
|
||||
import net.knarcraft.blacksmith.formatting.TranslatableMessage;
|
||||
import net.knarcraft.blacksmith.formatting.Translator;
|
||||
import net.knarcraft.blacksmith.util.InputParsingHelper;
|
||||
import net.knarcraft.blacksmith.util.TypeValidationHelper;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
@ -18,8 +19,8 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.MessageFormatter.displayErrorMessage;
|
||||
import static net.knarcraft.blacksmith.util.MessageFormatter.displaySuccessMessage;
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.displayErrorMessage;
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.displaySuccessMessage;
|
||||
|
||||
/**
|
||||
* The command used for changing global configuration options
|
||||
@ -41,9 +42,8 @@ public class BlackSmithConfigCommand implements CommandExecutor {
|
||||
|
||||
//Changing reforge-able items' default isn't recommended
|
||||
if (commandName.equalsIgnoreCase(NPCSetting.REFORGE_ABLE_ITEMS.getCommandName())) {
|
||||
displayErrorMessage(sender, "Changing reforge-able items globally will make every new " +
|
||||
"blacksmith unable to reforge anything not in the list, unless it's changed for the " +
|
||||
"individual NPC. If you really want to change this, change it manually.");
|
||||
displayErrorMessage(sender,
|
||||
Translator.getTranslatedMessage(TranslatableMessage.DEFAULT_REFORGE_ABLE_ITEMS_UNCHANGEABLE));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -82,9 +82,10 @@ public class BlackSmithConfigCommand implements CommandExecutor {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
displaySuccessMessage(sender, Message.getCurrentValueMessage(correctCommandName, rawValue));
|
||||
displaySuccessMessage(sender, TranslatableMessage.getCurrentValueMessage(correctCommandName, rawValue));
|
||||
if (printRawValue) {
|
||||
sender.sendMessage("Raw value: " + rawValue.replace(ChatColor.COLOR_CHAR, '&'));
|
||||
sender.sendMessage(TranslatableMessage.getRawValueMessage(
|
||||
rawValue.replace(ChatColor.COLOR_CHAR, '&')));
|
||||
}
|
||||
return true;
|
||||
} else if (args.length == 2 && isSpecialCase(commandName)) {
|
||||
@ -100,11 +101,11 @@ public class BlackSmithConfigCommand implements CommandExecutor {
|
||||
String newValue = args[1];
|
||||
if (detectedGlobalSetting != null) {
|
||||
settings.changeValue(detectedGlobalSetting, newValue);
|
||||
displaySuccessMessage(sender, Message.getValueChangedMessage(detectedGlobalSetting.getCommandName(), newValue));
|
||||
displaySuccessMessage(sender, TranslatableMessage.getValueChangedMessage(detectedGlobalSetting.getCommandName(), newValue));
|
||||
return true;
|
||||
} else if (detectedNPCSetting != null) {
|
||||
settings.changeValue(detectedNPCSetting, newValue);
|
||||
displaySuccessMessage(sender, Message.getValueChangedMessage(detectedNPCSetting.getNodeName(), newValue));
|
||||
displaySuccessMessage(sender, TranslatableMessage.getValueChangedMessage(detectedNPCSetting.getNodeName(), newValue));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -132,7 +133,7 @@ public class BlackSmithConfigCommand implements CommandExecutor {
|
||||
} else {
|
||||
currentValue = String.valueOf(settings.getPricePerDurabilityPoint(material));
|
||||
}
|
||||
displaySuccessMessage(sender, Message.getItemCurrentValueMessage(setting.getCommandName(), ItemType.MATERIAL,
|
||||
displaySuccessMessage(sender, TranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(), ItemType.MATERIAL,
|
||||
material.name(), currentValue));
|
||||
return true;
|
||||
} else if (setting == GlobalSetting.ENCHANTMENT_COST) {
|
||||
@ -140,7 +141,7 @@ public class BlackSmithConfigCommand implements CommandExecutor {
|
||||
if (enchantment == null) {
|
||||
return false;
|
||||
}
|
||||
displaySuccessMessage(sender, Message.getItemCurrentValueMessage(setting.getCommandName(), ItemType.ENCHANTMENT,
|
||||
displaySuccessMessage(sender, TranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(), ItemType.ENCHANTMENT,
|
||||
enchantment.toString(), String.valueOf(settings.getEnchantmentCost(enchantment))));
|
||||
return true;
|
||||
} else {
|
||||
@ -204,7 +205,7 @@ public class BlackSmithConfigCommand implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
displaySuccessMessage(sender, Message.getItemValueChangedMessage(detectedGlobalSetting.getCommandName(),
|
||||
displaySuccessMessage(sender, TranslatableMessage.getItemValueChangedMessage(detectedGlobalSetting.getCommandName(),
|
||||
itemType, itemChanged, newValue));
|
||||
return true;
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ public class BlackSmithConfigTabCompleter implements TabCompleter {
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
if (args.length == 1) {
|
||||
if (!sender.hasPermission("blacksmith.admin")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if (!sender.hasPermission("blacksmith.admin")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
List<String> availableCommands = new ArrayList<>();
|
||||
availableCommands.add("reload");
|
||||
for (NPCSetting setting : NPCSetting.values()) {
|
||||
|
@ -3,9 +3,10 @@ package net.knarcraft.blacksmith.command;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.knarcraft.blacksmith.config.NPCSetting;
|
||||
import net.knarcraft.blacksmith.manager.Message;
|
||||
import net.knarcraft.blacksmith.formatting.StringFormatter;
|
||||
import net.knarcraft.blacksmith.formatting.TranslatableMessage;
|
||||
import net.knarcraft.blacksmith.formatting.Translator;
|
||||
import net.knarcraft.blacksmith.trait.BlacksmithTrait;
|
||||
import net.knarcraft.blacksmith.util.MessageFormatter;
|
||||
import net.knarcraft.blacksmith.util.TypeValidationHelper;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
@ -13,7 +14,7 @@ import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.MessageFormatter.displaySuccessMessage;
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.displaySuccessMessage;
|
||||
|
||||
/**
|
||||
* The main command used for blacksmith editing
|
||||
@ -25,7 +26,8 @@ public class BlackSmithEditCommand implements CommandExecutor {
|
||||
@NotNull String[] args) {
|
||||
NPC npc = CitizensAPI.getDefaultNPCSelector().getSelected(sender);
|
||||
if (npc == null || !npc.hasTrait(BlacksmithTrait.class)) {
|
||||
MessageFormatter.displayErrorMessage(sender, "You must select an NPC before running this command");
|
||||
StringFormatter.displayErrorMessage(sender,
|
||||
Translator.getTranslatedMessage(TranslatableMessage.NO_NPC_SELECTED));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -59,18 +61,20 @@ public class BlackSmithEditCommand implements CommandExecutor {
|
||||
if (newValue == null) {
|
||||
//Display the current value of the setting
|
||||
String rawValue = String.valueOf(blacksmithTrait.getSettings().getRawValue(npcSetting));
|
||||
displaySuccessMessage(sender, Message.getCurrentValueMessage(npcSetting.getCommandName(), rawValue));
|
||||
displaySuccessMessage(sender, TranslatableMessage.getCurrentValueMessage(npcSetting.getCommandName(), rawValue));
|
||||
if (npcSetting.getPath().startsWith("defaults.messages")) {
|
||||
sender.sendMessage("Raw value: " + rawValue.replace(ChatColor.COLOR_CHAR, '&'));
|
||||
sender.sendMessage(TranslatableMessage.getRawValueMessage(
|
||||
rawValue.replace(ChatColor.COLOR_CHAR, '&')));
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
boolean isValidType = TypeValidationHelper.isValid(npcSetting.getValueType(), newValue, sender);
|
||||
if (isValidType) {
|
||||
//Change the setting
|
||||
blacksmithTrait.getSettings().changeSetting(npcSetting,
|
||||
ChatColor.translateAlternateColorCodes('&', newValue));
|
||||
displaySuccessMessage(sender, Message.getValueChangedMessage(npcSetting.getNodeName(), newValue));
|
||||
Object nullCheckedValue = newValue.equalsIgnoreCase("null") ? null :
|
||||
ChatColor.translateAlternateColorCodes('&', newValue);
|
||||
blacksmithTrait.getSettings().changeSetting(npcSetting, nullCheckedValue);
|
||||
displaySuccessMessage(sender, TranslatableMessage.getValueChangedMessage(npcSetting.getNodeName(), newValue));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -21,15 +21,16 @@ public class BlackSmithEditTabCompleter implements TabCompleter {
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
if (!sender.hasPermission("blacksmith.edit")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<String> npcSettings = new ArrayList<>();
|
||||
for (NPCSetting setting : NPCSetting.values()) {
|
||||
npcSettings.add(setting.getCommandName());
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
if (!sender.hasPermission("blacksmith.edit")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return TabCompletionHelper.filterMatchingContains(npcSettings, args[0]);
|
||||
} else {
|
||||
if (npcSettings.contains(args[0]) && args.length <= 2) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.knarcraft.blacksmith.command;
|
||||
|
||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
import net.knarcraft.blacksmith.formatting.TranslatableMessage;
|
||||
import net.knarcraft.blacksmith.formatting.Translator;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@ -10,7 +12,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.MessageFormatter.displaySuccessMessage;
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.displaySuccessMessage;
|
||||
|
||||
/**
|
||||
* The command for re-loading the plugin
|
||||
@ -21,7 +23,7 @@ public class ReloadCommand implements TabExecutor {
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] args) {
|
||||
BlacksmithPlugin.getInstance().reload();
|
||||
displaySuccessMessage(sender, "Blacksmith config reloaded!");
|
||||
displaySuccessMessage(sender, Translator.getTranslatedMessage(TranslatableMessage.PLUGIN_RELOADED));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,11 +62,9 @@ public class NPCSettings {
|
||||
* @param newValue <p>The new value of the setting</p>
|
||||
*/
|
||||
public void changeSetting(NPCSetting setting, Object newValue) {
|
||||
currentValues.put(setting, newValue);
|
||||
if (setting == NPCSetting.REFORGE_ABLE_ITEMS) {
|
||||
currentValues.put(setting, newValue);
|
||||
updateReforgeAbleItems();
|
||||
} else {
|
||||
currentValues.put(setting, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,13 +336,13 @@ public class NPCSettings {
|
||||
String[] list = string.split(",");
|
||||
List<String> replaced = new ArrayList<>(list.length);
|
||||
for (String item : list) {
|
||||
replaced.add(SmithPreset.replacePlaceholder(item));
|
||||
replaced.add(SmithPreset.replacePreset(item));
|
||||
}
|
||||
return String.join(",", replaced);
|
||||
} else if (value instanceof String[] stringList) {
|
||||
List<String> replaced = new ArrayList<>(stringList.length);
|
||||
for (String item : stringList) {
|
||||
replaced.add(SmithPreset.replacePlaceholder(item));
|
||||
replaced.add(SmithPreset.replacePreset(item));
|
||||
}
|
||||
return replaced.toArray();
|
||||
} else {
|
||||
|
@ -36,19 +36,19 @@ public enum SmithPreset {
|
||||
RANGED_SMITH;
|
||||
|
||||
/**
|
||||
* Replaces the given string if it's a smith type placeholder
|
||||
* Replaces the given string if it's a smith type preset
|
||||
*
|
||||
* @param possiblePlaceholder <p>The string that might be a placeholder</p>
|
||||
* @return <p>The string, possibly with the placeholder replaced</p>
|
||||
* @param possiblePreset <p>The string that might be a preset</p>
|
||||
* @return <p>The string, possibly with the preset replaced</p>
|
||||
*/
|
||||
public static String replacePlaceholder(String possiblePlaceholder) {
|
||||
public static String replacePreset(String possiblePreset) {
|
||||
for (SmithPreset smithPreset : SmithPreset.values()) {
|
||||
if (possiblePlaceholder.replace('-', '_').equalsIgnoreCase("preset:" +
|
||||
if (possiblePreset.replace('-', '_').equalsIgnoreCase("preset:" +
|
||||
smithPreset.name())) {
|
||||
return String.join(",", smithPreset.getMaterialNames());
|
||||
}
|
||||
}
|
||||
return possiblePlaceholder;
|
||||
return possiblePreset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,23 @@
|
||||
package net.knarcraft.blacksmith.formatting;
|
||||
|
||||
/**
|
||||
* An enum representing all item types used in messages
|
||||
*/
|
||||
public enum ItemType {
|
||||
|
||||
ENCHANTMENT,
|
||||
MATERIAL;
|
||||
|
||||
/**
|
||||
* Gets the name of this item type
|
||||
*
|
||||
* @return <p>The name of this item type</p>
|
||||
*/
|
||||
public String getItemTypeName() {
|
||||
return switch (this) {
|
||||
case MATERIAL -> Translator.getTranslatedMessage(TranslatableMessage.ITEM_TYPE_MATERIAL);
|
||||
case ENCHANTMENT -> Translator.getTranslatedMessage(TranslatableMessage.ITEM_TYPE_ENCHANTMENT);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.blacksmith.util;
|
||||
package net.knarcraft.blacksmith.formatting;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
@ -6,14 +6,17 @@ import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A message formatter to ensure uniform colors and format of chat messages
|
||||
* A formatter for formatting displayed messages
|
||||
*/
|
||||
public final class MessageFormatter {
|
||||
public final class StringFormatter {
|
||||
|
||||
private final static String pluginName = BlacksmithPlugin.getInstance().getDescription().getName();
|
||||
|
||||
private MessageFormatter() {
|
||||
private StringFormatter() {
|
||||
|
||||
}
|
||||
|
||||
@ -69,4 +72,47 @@ public final class MessageFormatter {
|
||||
return ChatColor.translateAlternateColorCodes('&', input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package net.knarcraft.blacksmith.formatting;
|
||||
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.replacePlaceholders;
|
||||
|
||||
/**
|
||||
* An enum containing all translatable global messages
|
||||
*
|
||||
* <p>This does not include NPC messages as they are configurable per-npc, and can be translated by changing the
|
||||
* default message values in the main config file.</p>
|
||||
*/
|
||||
public enum TranslatableMessage {
|
||||
|
||||
VALUE_CHANGED,
|
||||
VALUE_FOR_ITEM_CHANGED,
|
||||
CURRENT_VALUE,
|
||||
CURRENT_VALUE_FOR_ITEM,
|
||||
ITEM_TYPE_ENCHANTMENT,
|
||||
ITEM_TYPE_MATERIAL,
|
||||
RAW_VALUE,
|
||||
NO_NPC_SELECTED,
|
||||
DEFAULT_REFORGE_ABLE_ITEMS_UNCHANGEABLE,
|
||||
INPUT_STRING_LIST_REQUIRED,
|
||||
INPUT_PERCENTAGE_REQUIRED,
|
||||
INPUT_STRING_REQUIRED,
|
||||
INPUT_POSITIVE_DOUBLE_REQUIRED,
|
||||
INPUT_POSITIVE_INTEGER_REQUIRED,
|
||||
PERMISSION_DENIED,
|
||||
PLUGIN_RELOADED;
|
||||
|
||||
/**
|
||||
* Gets the message to display when displaying the raw value of messages
|
||||
*
|
||||
* @param rawValue <p>The raw value to display</p>
|
||||
* @return <p>The message to display</p>
|
||||
*/
|
||||
public static String getRawValueMessage(String rawValue) {
|
||||
return StringFormatter.replacePlaceholder(Translator.getTranslatedMessage(TranslatableMessage.RAW_VALUE),
|
||||
"{rawValue}", rawValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a value has been changed
|
||||
*
|
||||
* @param setting <p>The setting whose value has been changed</p>
|
||||
* @param newValue <p>The new value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getValueChangedMessage(String setting, String newValue) {
|
||||
return replacePlaceholders(Translator.getTranslatedMessage(TranslatableMessage.VALUE_CHANGED),
|
||||
new String[]{"{setting}", "{newValue}"}, new String[]{setting, newValue});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a value has been changed for an item
|
||||
*
|
||||
* @param setting <p>The setting whose value has been changed</p>
|
||||
* @param itemType <p>The type of item changed ("material" or "enchantment")</p>
|
||||
* @param item <p>The item the setting was changed for (a material or an enchantment name)</p>
|
||||
* @param newValue <p>The new value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getItemValueChangedMessage(String setting, ItemType itemType, String item, String newValue) {
|
||||
return replacePlaceholders(Translator.getTranslatedMessage(TranslatableMessage.VALUE_FOR_ITEM_CHANGED),
|
||||
new String[]{"{setting}", "{itemType}", "{item}", "{newValue}"},
|
||||
new String[]{setting, itemType.getItemTypeName(), item, newValue});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when displaying a setting's current value
|
||||
*
|
||||
* @param setting <p>The setting whose value is shown</p>
|
||||
* @param currentValue <p>The current value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getCurrentValueMessage(String setting, String currentValue) {
|
||||
return replacePlaceholders(Translator.getTranslatedMessage(TranslatableMessage.CURRENT_VALUE),
|
||||
new String[]{"{setting}", "{currentValue}"}, new String[]{setting, currentValue});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when displaying a setting's current value for an item
|
||||
*
|
||||
* @param setting <p>The setting whose value is shown</p>
|
||||
* @param itemType <p>The type of item shown ("material" or "enchantment")</p>
|
||||
* @param item <p>The item the setting is shown for (a material or an enchantment name)</p>
|
||||
* @param currentValue <p>The current value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getItemCurrentValueMessage(String setting, ItemType itemType, String item, String currentValue) {
|
||||
return replacePlaceholders(Translator.getTranslatedMessage(TranslatableMessage.CURRENT_VALUE_FOR_ITEM),
|
||||
new String[]{"{setting}", "{itemType}", "{item}", "{currentValue}"},
|
||||
new String[]{setting, itemType.getItemTypeName(), item, currentValue});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package net.knarcraft.blacksmith.formatting;
|
||||
|
||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
import net.knarcraft.blacksmith.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<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) {
|
||||
BlacksmithPlugin.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) {
|
||||
BlacksmithPlugin instance = BlacksmithPlugin.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 <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;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package net.knarcraft.blacksmith.listener;
|
||||
|
||||
import net.knarcraft.blacksmith.formatting.StringFormatter;
|
||||
import net.knarcraft.blacksmith.formatting.TranslatableMessage;
|
||||
import net.knarcraft.blacksmith.formatting.Translator;
|
||||
import net.knarcraft.blacksmith.trait.BlacksmithTrait;
|
||||
import net.knarcraft.blacksmith.util.MessageFormatter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -24,7 +26,8 @@ public class NPCClickListener implements Listener {
|
||||
|
||||
//Permission check
|
||||
if (!player.hasPermission("blacksmith.use")) {
|
||||
MessageFormatter.displayErrorMessage(player, "You lack the necessary permission");
|
||||
StringFormatter.displayErrorMessage(player,
|
||||
Translator.getTranslatedMessage(TranslatableMessage.PERMISSION_DENIED));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
package net.knarcraft.blacksmith.manager;
|
||||
|
||||
/**
|
||||
* An enum representing all item types used in messages
|
||||
*/
|
||||
public enum ItemType {
|
||||
|
||||
ENCHANTMENT("enchantment"),
|
||||
MATERIAL("material");
|
||||
|
||||
private final String itemTypeName;
|
||||
|
||||
/**
|
||||
* Instantiates an item type
|
||||
*
|
||||
* @param itemTypeName <p>The name shown in messages</p>
|
||||
*/
|
||||
ItemType(String itemTypeName) {
|
||||
this.itemTypeName = itemTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this item type
|
||||
*
|
||||
* @return <p>The name of this item type</p>
|
||||
*/
|
||||
public String getItemTypeName() {
|
||||
return this.itemTypeName;
|
||||
}
|
||||
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
package net.knarcraft.blacksmith.manager;
|
||||
|
||||
public enum Message {
|
||||
|
||||
VALUE_CHANGED("&7{setting} set to &6{newValue}"),
|
||||
VALUE_FOR_ITEM_CHANGED("&7{setting} for {itemType} {item} set to &6{newValue}"),
|
||||
CURRENT_VALUE("&7Current value of {setting}:&r {currentValue}"),
|
||||
CURRENT_VALUE_FOR_ITEM("&7Current value of {setting} for {itemType} {item}:&r {currentValue}");
|
||||
|
||||
private final String messageString;
|
||||
|
||||
/**
|
||||
* Instantiates a new message
|
||||
*
|
||||
* @param messageString <p>The string value of this message</p>
|
||||
*/
|
||||
Message(String messageString) {
|
||||
this.messageString = messageString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a value has been changed
|
||||
*
|
||||
* @param setting <p>The setting whose value has been changed</p>
|
||||
* @param newValue <p>The new value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getValueChangedMessage(String setting, String newValue) {
|
||||
return replacePlaceholders(VALUE_CHANGED.messageString, new String[]{"{setting}", "{newValue}"},
|
||||
new String[]{setting, newValue});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when a value has been changed for an item
|
||||
*
|
||||
* @param setting <p>The setting whose value has been changed</p>
|
||||
* @param itemType <p>The type of item changed ("material" or "enchantment")</p>
|
||||
* @param item <p>The item the setting was changed for (a material or an enchantment name)</p>
|
||||
* @param newValue <p>The new value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getItemValueChangedMessage(String setting, ItemType itemType, String item, String newValue) {
|
||||
return replacePlaceholders(VALUE_FOR_ITEM_CHANGED.messageString, new String[]{"{setting}", "{itemType}",
|
||||
"{item}", "{newValue}"}, new String[]{setting, itemType.getItemTypeName(), item, newValue});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when displaying a setting's current value
|
||||
*
|
||||
* @param setting <p>The setting whose value is shown</p>
|
||||
* @param currentValue <p>The current value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getCurrentValueMessage(String setting, String currentValue) {
|
||||
return replacePlaceholders(CURRENT_VALUE.messageString, new String[]{"{setting}", "{currentValue}"},
|
||||
new String[]{setting, currentValue});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when displaying a setting's current value for an item
|
||||
*
|
||||
* @param setting <p>The setting whose value is shown</p>
|
||||
* @param itemType <p>The type of item shown ("material" or "enchantment")</p>
|
||||
* @param item <p>The item the setting is shown for (a material or an enchantment name)</p>
|
||||
* @param currentValue <p>The current value of the setting</p>
|
||||
* @return <p>The string to display to a user</p>
|
||||
*/
|
||||
public static String getItemCurrentValueMessage(String setting, ItemType itemType, String item, String currentValue) {
|
||||
return replacePlaceholders(CURRENT_VALUE_FOR_ITEM.messageString, new String[]{"{setting}", "{itemType}",
|
||||
"{item}", "{currentValue}"}, new String[]{setting, itemType.getItemTypeName(), item, currentValue});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*/
|
||||
private 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>
|
||||
*/
|
||||
private 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;
|
||||
}
|
||||
|
||||
}
|
@ -22,7 +22,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.MessageFormatter.sendNPCMessage;
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.sendNPCMessage;
|
||||
|
||||
/**
|
||||
* The class representing the Blacksmith NPC trait
|
||||
|
@ -20,7 +20,7 @@ import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.MessageFormatter.sendNPCMessage;
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.sendNPCMessage;
|
||||
|
||||
/**
|
||||
* A representation of the session between a player and a blacksmith
|
||||
|
32
src/main/java/net/knarcraft/blacksmith/util/FileHelper.java
Normal file
32
src/main/java/net/knarcraft/blacksmith/util/FileHelper.java
Normal file
@ -0,0 +1,32 @@
|
||||
package net.knarcraft.blacksmith.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 <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,9 +1,11 @@
|
||||
package net.knarcraft.blacksmith.util;
|
||||
|
||||
import net.knarcraft.blacksmith.config.SettingValueType;
|
||||
import net.knarcraft.blacksmith.formatting.TranslatableMessage;
|
||||
import net.knarcraft.blacksmith.formatting.Translator;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import static net.knarcraft.blacksmith.util.MessageFormatter.displayErrorMessage;
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.displayErrorMessage;
|
||||
|
||||
/**
|
||||
* A helper class for validating a value's type
|
||||
@ -49,7 +51,7 @@ public final class TypeValidationHelper {
|
||||
private static boolean isStringList(Object value, CommandSender sender) {
|
||||
boolean isStringList = value instanceof String[] || value instanceof String;
|
||||
if (!isStringList && sender != null) {
|
||||
displayErrorMessage(sender, "A string list is required!");
|
||||
displayErrorMessage(sender, Translator.getTranslatedMessage(TranslatableMessage.INPUT_STRING_LIST_REQUIRED));
|
||||
}
|
||||
return isStringList;
|
||||
}
|
||||
@ -67,7 +69,7 @@ public final class TypeValidationHelper {
|
||||
return intValue > 0 && intValue <= 100;
|
||||
} catch (NumberFormatException | NullPointerException exception) {
|
||||
if (sender != null) {
|
||||
displayErrorMessage(sender, "You specified a value which isn't between 0 and 100!");
|
||||
displayErrorMessage(sender, Translator.getTranslatedMessage(TranslatableMessage.INPUT_PERCENTAGE_REQUIRED));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -83,7 +85,7 @@ public final class TypeValidationHelper {
|
||||
private static boolean isNonEmptyString(Object value, CommandSender sender) {
|
||||
boolean isString = value instanceof String string && !string.strip().isEmpty();
|
||||
if (!isString && sender != null) {
|
||||
displayErrorMessage(sender, "A non-empty string is required!");
|
||||
displayErrorMessage(sender, Translator.getTranslatedMessage(TranslatableMessage.INPUT_STRING_REQUIRED));
|
||||
}
|
||||
return isString;
|
||||
}
|
||||
@ -100,7 +102,8 @@ public final class TypeValidationHelper {
|
||||
return ConfigHelper.asDouble(value) > 0.0;
|
||||
} catch (NumberFormatException | NullPointerException exception) {
|
||||
if (sender != null) {
|
||||
displayErrorMessage(sender, "You specified a value which isn't a positive double!");
|
||||
displayErrorMessage(sender,
|
||||
Translator.getTranslatedMessage(TranslatableMessage.INPUT_POSITIVE_DOUBLE_REQUIRED));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -118,7 +121,8 @@ public final class TypeValidationHelper {
|
||||
return ConfigHelper.asInt(value) > 0;
|
||||
} catch (NumberFormatException | NullPointerException exception) {
|
||||
if (sender != null) {
|
||||
displayErrorMessage(sender, "You specified a value which isn't a positive integer!");
|
||||
displayErrorMessage(sender,
|
||||
Translator.getTranslatedMessage(TranslatableMessage.INPUT_POSITIVE_INTEGER_REQUIRED));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user