diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index fd4d8a4..6b4f663 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -59,11 +59,6 @@ import java.util.Objects; import java.util.UUID; import java.util.logging.Level; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getErrorColor; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSuccessColor; - /** * The main Books Without Borders class */ @@ -77,6 +72,26 @@ public class BooksWithoutBorders extends JavaPlugin { private static BooksWithoutBorders booksWithoutBorders; private static BookshelfHandler bookshelfHandler; private static StringFormatter stringFormatter; + private static BooksWithoutBordersConfig booksWithoutBordersConfig; + + /** + * Logs a message to the console + * + * @param level
The log level to use
+ * @param messageThe message to log
+ */ + public static void log(@NotNull Level level, @NotNull String message) { + getInstance().getLogger().log(level, message); + } + + /** + * Gets the configuration for BwB + * + * @returnThe BwB configuration
+ */ + public static BooksWithoutBordersConfig getConfiguration() { + return booksWithoutBordersConfig; + } /** * Gets the string formatter @@ -178,7 +193,7 @@ public class BooksWithoutBorders extends JavaPlugin { booksWithoutBorders = this; playerBooksList = new HashMap<>(); playerLetterIndex = new HashMap<>(); - BooksWithoutBordersConfig.initialize(this, translator); + booksWithoutBordersConfig = new BooksWithoutBordersConfig(this, translator); @Nullable ListTrue if necessary folders exist
*/ private boolean testFileSaving() { - File fileTest = new File(getBookFolder()); - File encryptedFileTest = new File(getBookFolder() + "Encrypted" + getSlash()); + File fileTest = new File(getConfiguration().getBookFolder()); + File encryptedFileTest = new File(getConfiguration().getEncryptedBookPath()); if (!fileTest.exists()) { try { if (!fileTest.mkdir()) { @@ -345,7 +360,7 @@ public class BooksWithoutBorders extends JavaPlugin { * @param messageThe message to send
*/ public static void sendSuccessMessage(@NotNull CommandSender sender, @NotNull String message) { - sender.sendMessage(getSuccessColor() + message); + sender.sendMessage(getConfiguration().getSuccessColor() + message); } /** @@ -355,7 +370,7 @@ public class BooksWithoutBorders extends JavaPlugin { * @param messageThe message to send
*/ public static void sendErrorMessage(@NotNull CommandSender sender, @NotNull String message) { - sender.sendMessage(getErrorColor() + message); + sender.sendMessage(getConfiguration().getErrorColor() + message); } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java index 3c6b345..116e7ce 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java @@ -6,7 +6,7 @@ import net.knarcraft.bookswithoutborders.config.BwBCommand; import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.Translatable; -import net.knarcraft.bookswithoutborders.utility.EconomyHelper; +import net.knarcraft.bookswithoutborders.manager.EconomyManager; import net.knarcraft.knarlib.formatting.StringFormatter; import org.bukkit.Material; import org.bukkit.command.Command; @@ -57,20 +57,27 @@ public class CommandBooksWithoutBorders implements TabExecutor { */ @NotNull private String getBookPrice() { - if (!BooksWithoutBordersConfig.booksHavePrice()) { + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + + if (!config.booksHavePrice()) { return ""; } StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter(); - Material bookPriceType = BooksWithoutBordersConfig.getBookPriceType(); - double bookPriceQuantity = BooksWithoutBordersConfig.getBookPriceQuantity(); + Material bookPriceType = config.getBookPriceType(); + double bookPriceQuantity = config.getBookPriceQuantity(); if (bookPriceType != Material.AIR) { return stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_BOOK_PRICE_ITEM, List.of("{quantity}", "{type}"), List.of(String.valueOf((int) bookPriceQuantity), bookPriceType.toString())); } else { - return stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_BOOK_PRICE_ECO, - "{price}", EconomyHelper.getEconomy().format(bookPriceQuantity)); + EconomyManager economyManager = BooksWithoutBorders.getConfiguration().getEconomyManager(); + if (economyManager.getEconomy() == null) { + return BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.ERROR_VAULT_COST_BUT_UNAVAILABLE); + } else { + return stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_BOOK_PRICE_ECO, + "{price}", economyManager.getEconomy().format(bookPriceQuantity)); + } } } @@ -114,7 +121,7 @@ public class CommandBooksWithoutBorders implements TabExecutor { private String showCommandInfo(@NotNull String command, @NotNull CommandSender sender) { PluginCommand pluginCommand = BooksWithoutBorders.getInstance().getCommand(command); if (pluginCommand == null) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, StringFormatter.replacePlaceholder( + BooksWithoutBorders.log(Level.SEVERE, StringFormatter.replacePlaceholder( StaticMessage.COMMAND_NOT_REGISTERED.toString(), "{command}", command)); return ""; } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java index b977ee5..d88c8e7 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java @@ -5,7 +5,6 @@ import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.utility.BookHelper; -import net.knarcraft.bookswithoutborders.utility.EconomyHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeHelper; import net.knarcraft.knarlib.formatting.StringFormatter; @@ -74,8 +73,10 @@ public class CommandCopy implements TabExecutor { * @returnTrue if the copying was successful
*/ private boolean performCopy(int copies, @NotNull Player player, @NotNull ItemStack heldBook) { + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + //Make sure the player owns the book if authorOnlyCopy is enabled - if (BooksWithoutBordersConfig.getAuthorOnlyCopy() && + if (config.getAuthorOnlyCopy() && !player.hasPermission(Permission.BYPASS_AUTHOR_ONLY_COPY.toString())) { if (BookHelper.isNotAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta()))) { return false; @@ -83,7 +84,7 @@ public class CommandCopy implements TabExecutor { } BookMeta bookMeta = (BookMeta) heldBook.getItemMeta(); - if (BooksWithoutBordersConfig.changeGenerationOnCopy() && bookMeta != null) { + if (config.changeGenerationOnCopy() && bookMeta != null) { return copyNextGenerationBook(bookMeta, player, copies); } else { //Make sure the player can pay for the copying @@ -105,9 +106,10 @@ public class CommandCopy implements TabExecutor { * @returnTrue if the payment failed
*/ private boolean paymentUnSuccessful(@NotNull Player player, int copies) { - return BooksWithoutBordersConfig.booksHavePrice() && + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + return (config.booksHavePrice() && !player.hasPermission(Permission.BYPASS_BOOK_PRICE.toString()) && - EconomyHelper.cannotPayForBookPrinting(player, copies); + config.getEconomyManager().cannotPayForBookPrinting(player, copies)); } /** diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java index a9ad969..a74cf57 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java @@ -2,9 +2,12 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.Permission; +import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.utility.BookHelper; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; +import net.knarcraft.knarlib.formatting.StringFormatter; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -17,39 +20,42 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash; - /** * Command executor for the decrypt command */ public class CommandDecrypt implements TabExecutor { @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] arguments) { + StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter(); + if (!(sender instanceof Player player)) { BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!"); return false; } if (InventoryHelper.notHoldingOneWrittenBookCheck(player, - "You must be holding a written book to decrypt it!", - "You cannot decrypt two books at once!")) { + stringFormatter.replacePlaceholder(Translatable.ERROR_NOT_HOLDING_WRITTEN_BOOK, "{action}", + stringFormatter.getUnFormattedColoredMessage(Translatable.ACTION_DECRYPT)), + stringFormatter.replacePlaceholder(Translatable.ERROR_ONLY_ONE_BOOK, "{action}", + stringFormatter.getUnFormattedColoredMessage(Translatable.ACTION_DECRYPT)))) { return false; } ItemStack heldItem = InventoryHelper.getHeldBook(player, true); BookMeta bookMetadata = (BookMeta) heldItem.getItemMeta(); if (bookMetadata == null) { - BooksWithoutBorders.sendErrorMessage(player, "Your book seems to be corrupt!"); + stringFormatter.displayErrorMessage(sender, Translatable.ERROR_METADATA_MISSING); return false; } - //Warning: admin decrypt only allows decrypting files created by the same player. Not sure if intended - if (args.length == 0 && BooksWithoutBordersConfig.getAdminDecrypt() && player.hasPermission("bookswithoutborders.admin")) { - String path = getBookFolder() + "Encrypted" + getSlash(); + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); - File encryptedDirectory = new File(path); + //Warning: admin decrypt only allows decrypting files created by the same player. Not sure if intended + if (arguments.length == 0 && config.getAdminDecrypt() && player.hasPermission(Permission.ADMIN.toString())) { + + File encryptedDirectory = new File(config.getEncryptedBookPath()); String[] encryptedFiles = encryptedDirectory.list(); if (encryptedFiles == null) { BooksWithoutBorders.sendErrorMessage(player, "Could not find any encrypted files!"); @@ -79,12 +85,12 @@ public class CommandDecrypt implements TabExecutor { BooksWithoutBorders.sendErrorMessage(player, "No matching encrypted book found!"); return false; } - } else if (args.length == 0) { + } else if (arguments.length == 0) { BooksWithoutBorders.sendErrorMessage(player, "No decryption password given!"); return false; } - String key = EncryptionHelper.getNumberKeyFromStringKey(args[0]); + String key = EncryptionHelper.getNumberKeyFromStringKey(arguments[0]); //Decrypt the book ItemStack book = EncryptionHelper.loadEncryptedBook(player, key, true); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java index 18bdbb4..5939829 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java @@ -121,25 +121,26 @@ public class CommandEncrypt implements TabExecutor { int argumentsCount = args.length; ListThe sender of the command
*/ private void clearItemPrice(@NotNull CommandSender sender) { - BooksWithoutBordersConfig.setBookPriceType(null); - BooksWithoutBordersConfig.setBookPriceQuantity(0); + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + config.setBookPriceType(null); + config.setBookPriceQuantity(0); booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Item type name"); - booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", BooksWithoutBordersConfig.getBookPriceQuantity()); + booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", config.getBookPriceQuantity()); booksWithoutBorders.saveConfig(); BooksWithoutBorders.sendSuccessMessage(sender, "Price to create books removed!"); @@ -98,10 +100,11 @@ public class CommandSetBookPrice implements TabExecutor { return false; } - BooksWithoutBordersConfig.setBookPriceType(heldItem.getType()); - BooksWithoutBordersConfig.setBookPriceQuantity(price); - String newPriceType = BooksWithoutBordersConfig.getBookPriceType().toString(); - double newPriceQuantity = BooksWithoutBordersConfig.getBookPriceQuantity(); + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + config.setBookPriceType(heldItem.getType()); + config.setBookPriceQuantity(price); + String newPriceType = config.getBookPriceType().toString(); + double newPriceQuantity = config.getBookPriceQuantity(); booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", newPriceType); booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity); booksWithoutBorders.saveConfig(); @@ -119,19 +122,21 @@ public class CommandSetBookPrice implements TabExecutor { * @returnTrue if the price was changed successfully
*/ private boolean setEconomyPrice(@NotNull CommandSender sender, double price) { - if (EconomyHelper.setupEconomy()) { - BooksWithoutBordersConfig.setBookPriceQuantity(price); - BooksWithoutBordersConfig.setBookPriceType(Material.AIR); - double newPriceQuantity = BooksWithoutBordersConfig.getBookPriceQuantity(); + EconomyManager economyManager = BooksWithoutBorders.getConfiguration().getEconomyManager(); + if (economyManager.getEconomy() != null) { + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + config.setBookPriceQuantity(price); + config.setBookPriceType(Material.AIR); + double newPriceQuantity = config.getBookPriceQuantity(); booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Economy"); booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity); booksWithoutBorders.saveConfig(); BooksWithoutBorders.sendSuccessMessage(sender, "Book creation price set to " + - EconomyHelper.getEconomy().format(newPriceQuantity) + "!"); + economyManager.getEconomy().format(newPriceQuantity) + "!"); return true; } else { - BooksWithoutBorders.sendErrorMessage(sender, "BooksWithoutBorders failed to hook into Vault! Book price not set!"); + BooksWithoutBorders.sendErrorMessage(sender, StaticMessage.EXCEPTION_VAULT_NOT_AVAILABLE.toString()); return false; } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookshelfData.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookshelfData.java index 4ee893c..a1db0aa 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookshelfData.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookshelfData.java @@ -1,7 +1,6 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.container.Bookshelf; import net.knarcraft.bookswithoutborders.handler.BookshelfHandler; import net.knarcraft.knarlib.util.TabCompletionHelper; @@ -77,7 +76,7 @@ public class CommandSetBookshelfData implements TabExecutor { BooksWithoutBorders.sendErrorMessage(commandSender, "You must name the bookshelf before " + "assigning lore!"); } else { - ListThe books without borders object used for getting required data
*/ - public static void initialize(@NotNull BooksWithoutBorders booksWithoutBorders, @NotNull Translator translator) { + public BooksWithoutBordersConfig(@NotNull BooksWithoutBorders booksWithoutBorders, @NotNull Translator translator) { if (isInitialized) { throw new IllegalArgumentException("Settings class initialized twice. This should not happen!"); } - BooksWithoutBordersConfig.translator = translator; + this.translator = translator; isInitialized = true; bookFolder = booksWithoutBorders.getDataFolder().getAbsolutePath() + getSlash() + "Books" + getSlash(); loadConfig(); } + /** + * Gets the economy manager + * + * @returnThe economy manager
+ */ + @NotNull + public EconomyManager getEconomyManager() { + return this.economyManager; + } + /** * Gets the folder used for storing books * * @returnThe folder used for storing books
*/ - public static String getBookFolder() { - return bookFolder; + public String getBookFolder() { + return this.bookFolder; } /** @@ -75,8 +86,8 @@ public class BooksWithoutBordersConfig { * * @returnThe color to use for error messages
*/ - public static ChatColor getErrorColor() { - return errorColor; + public ChatColor getErrorColor() { + return this.errorColor; } /** @@ -84,8 +95,8 @@ public class BooksWithoutBordersConfig { * * @returnThe color to use for success messages
*/ - public static ChatColor getSuccessColor() { - return successColor; + public ChatColor getSuccessColor() { + return this.successColor; } /** @@ -93,8 +104,8 @@ public class BooksWithoutBordersConfig { * * @returnThe color used to color commands
*/ - public static ChatColor getCommandColor() { - return commandColor; + public ChatColor getCommandColor() { + return this.commandColor; } /** @@ -102,8 +113,8 @@ public class BooksWithoutBordersConfig { * * @returnThe slash to use for file separators
*/ - public static String getSlash() { - return SLASH; + public String getSlash() { + return this.SLASH; } /** @@ -111,8 +122,8 @@ public class BooksWithoutBordersConfig { * * @returnWhether only the book author can copy it
*/ - public static boolean getAuthorOnlyCopy() { - return authorOnlyCopy; + public boolean getAuthorOnlyCopy() { + return this.authorOnlyCopy; } /** @@ -120,8 +131,8 @@ public class BooksWithoutBordersConfig { * * @returnWhether only the book author can unsign it
*/ - public static boolean getAuthorOnlyUnsign() { - return authorOnlyUnsign; + public boolean getAuthorOnlyUnsign() { + return this.authorOnlyUnsign; } /** @@ -129,8 +140,8 @@ public class BooksWithoutBordersConfig { * * @returnWhether a player can only save their own books
*/ - public static boolean getAuthorOnlySave() { - return authorOnlySave; + public boolean getAuthorOnlySave() { + return this.authorOnlySave; } /** @@ -138,8 +149,8 @@ public class BooksWithoutBordersConfig { * * @returnTrue if players can peek at the contained books
*/ - public static boolean getEnableBookshelfPeeking() { - return enableBookshelfPeeking; + public boolean getEnableBookshelfPeeking() { + return this.enableBookshelfPeeking; } /** @@ -147,8 +158,8 @@ public class BooksWithoutBordersConfig { * * @returnWhether to use YML for saving books
*/ - public static boolean getUseYml() { - return useYml; + public boolean getUseYml() { + return this.useYml; } /** @@ -156,8 +167,8 @@ public class BooksWithoutBordersConfig { * * @returnWhether admins can bypass the encryption password
*/ - public static boolean getAdminDecrypt() { - return adminDecrypt; + public boolean getAdminDecrypt() { + return this.adminDecrypt; } /** @@ -165,8 +176,8 @@ public class BooksWithoutBordersConfig { * * @param newQuantityThe new quantity necessary for payment
*/ - public static void setBookPriceQuantity(double newQuantity) { - bookPriceQuantity = newQuantity; + public void setBookPriceQuantity(double newQuantity) { + this.bookPriceQuantity = newQuantity; } /** @@ -174,8 +185,8 @@ public class BooksWithoutBordersConfig { * * @returnThe quantity necessary for payment
*/ - public static double getBookPriceQuantity() { - return bookPriceQuantity; + public double getBookPriceQuantity() { + return this.bookPriceQuantity; } /** @@ -186,8 +197,8 @@ public class BooksWithoutBordersConfig { * * @param newTypeThe new item type to use for book pricing
*/ - public static void setBookPriceType(Material newType) { - bookPriceType = newType; + public void setBookPriceType(Material newType) { + this.bookPriceType = newType; } /** @@ -198,8 +209,8 @@ public class BooksWithoutBordersConfig { * * @returnThe item type used for book pricing
*/ - public static Material getBookPriceType() { - return bookPriceType; + public Material getBookPriceType() { + return this.bookPriceType; } /** @@ -207,8 +218,8 @@ public class BooksWithoutBordersConfig { * * @returnThe welcome message to show new players
*/ - public static String getWelcomeMessage() { - return welcomeMessage; + public String getWelcomeMessage() { + return this.welcomeMessage; } /** @@ -216,8 +227,8 @@ public class BooksWithoutBordersConfig { * * @returnThe book duplicate limit
*/ - public static int getBookDuplicateLimit() { - return bookDuplicateLimit; + public int getBookDuplicateLimit() { + return this.bookDuplicateLimit; } /** @@ -225,8 +236,8 @@ public class BooksWithoutBordersConfig { * * @returnTrue if books should change their generation
*/ - public static boolean changeGenerationOnCopy() { - return changeGenerationOnCopy; + public boolean changeGenerationOnCopy() { + return this.changeGenerationOnCopy; } /** @@ -234,8 +245,8 @@ public class BooksWithoutBordersConfig { * * @returnThe separator between title and author
*/ - public static String getTitleAuthorSeparator() { - return titleAuthorSeparator; + public String getTitleAuthorSeparator() { + return this.titleAuthorSeparator; } /** @@ -243,8 +254,8 @@ public class BooksWithoutBordersConfig { * * @returnThe separator used to denote lore newline
*/ - public static String getLoreSeparator() { - return loreSeparator; + public String getLoreSeparator() { + return this.loreSeparator; } /** @@ -252,8 +263,8 @@ public class BooksWithoutBordersConfig { * * @returnWhether all books should be formatted
*/ - public static boolean formatBooks() { - return formatBooks; + public boolean formatBooks() { + return this.formatBooks; } /** @@ -261,8 +272,8 @@ public class BooksWithoutBordersConfig { * * @returnThe books to give new players
*/ - public static ListTrue if players need to pay for printing books
*/ - public static boolean booksHavePrice() { - return (bookPriceType != null && bookPriceQuantity > 0); + public boolean booksHavePrice() { + return (this.bookPriceType != null && this.bookPriceQuantity > 0); + } + + /** + * Gets the path used to store encrypted books + * + * @returnThe encrypted book path
+ */ + @NotNull + public String getEncryptedBookPath() { + return getBookFolder() + "Encrypted" + getSlash(); } /** * Saves the config */ - public static void saveConfigValues() { + public void saveConfigValues() { Logger logger = BooksWithoutBorders.getInstance().getLogger(); Configuration config = BooksWithoutBorders.getInstance().getConfig(); - config.set(ConfigOption.USE_YAML.getConfigNode(), useYml); - config.set(ConfigOption.MAX_DUPLICATES.getConfigNode(), bookDuplicateLimit); - config.set(ConfigOption.TITLE_AUTHOR_SEPARATOR.getConfigNode(), titleAuthorSeparator); - config.set(ConfigOption.LORE_LINE_SEPARATOR.getConfigNode(), loreSeparator); - config.set(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode(), firstBooks); - config.set(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(), welcomeMessage); - config.set(ConfigOption.FORMAT_AFTER_SIGNING.getConfigNode(), formatBooks); - config.set(ConfigOption.ENABLE_BOOKSHELF_PEEKING.getConfigNode(), enableBookshelfPeeking); + config.set(ConfigOption.USE_YAML.getConfigNode(), this.useYml); + config.set(ConfigOption.MAX_DUPLICATES.getConfigNode(), this.bookDuplicateLimit); + config.set(ConfigOption.TITLE_AUTHOR_SEPARATOR.getConfigNode(), this.titleAuthorSeparator); + config.set(ConfigOption.LORE_LINE_SEPARATOR.getConfigNode(), this.loreSeparator); + config.set(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode(), this.firstBooks); + config.set(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(), this.welcomeMessage); + config.set(ConfigOption.FORMAT_AFTER_SIGNING.getConfigNode(), this.formatBooks); + config.set(ConfigOption.ENABLE_BOOKSHELF_PEEKING.getConfigNode(), this.enableBookshelfPeeking); String itemTypeNode = ConfigOption.PRICE_ITEM_TYPE.getConfigNode(); - if (bookPriceType != null) { - if (bookPriceType != Material.AIR) { - config.set(itemTypeNode, bookPriceType.toString()); + if (this.bookPriceType != null) { + if (this.bookPriceType != Material.AIR) { + config.set(itemTypeNode, this.bookPriceType.toString()); } else { config.set(itemTypeNode, "Economy"); } @@ -300,12 +321,12 @@ public class BooksWithoutBordersConfig { config.set(itemTypeNode, "Item type name"); } - config.set(ConfigOption.PRICE_QUANTITY.getConfigNode(), bookPriceQuantity); - config.set(ConfigOption.ADMIN_AUTO_DECRYPT.getConfigNode(), adminDecrypt); - config.set(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(), authorOnlyCopy); - config.set(ConfigOption.AUTHOR_ONLY_UNSIGN.getConfigNode(), authorOnlyUnsign); - config.set(ConfigOption.AUTHOR_ONLY_SAVE.getConfigNode(), authorOnlySave); - config.set(ConfigOption.CHANGE_GENERATION_ON_COPY.getConfigNode(), changeGenerationOnCopy); + config.set(ConfigOption.PRICE_QUANTITY.getConfigNode(), this.bookPriceQuantity); + config.set(ConfigOption.ADMIN_AUTO_DECRYPT.getConfigNode(), this.adminDecrypt); + config.set(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(), this.authorOnlyCopy); + config.set(ConfigOption.AUTHOR_ONLY_UNSIGN.getConfigNode(), this.authorOnlyUnsign); + config.set(ConfigOption.AUTHOR_ONLY_SAVE.getConfigNode(), this.authorOnlySave); + config.set(ConfigOption.CHANGE_GENERATION_ON_COPY.getConfigNode(), this.changeGenerationOnCopy); //Handles old book and quill settings if (config.contains("Options.Require_book_and_quill_to_create_book")) { @@ -313,10 +334,10 @@ public class BooksWithoutBordersConfig { "\"Require_book_and_quill_to_create_book\"\nUpdating to \"Price_to_create_book\" settings"); if (config.getBoolean("Options.Require_book_and_quill_to_create_book")) { - bookPriceType = Material.WRITABLE_BOOK; - bookPriceQuantity = 1; - config.set("Options.Price_to_create_book.Item_type", bookPriceType.toString()); - config.set("Options.Price_to_create_book.Required_quantity", bookPriceQuantity); + this.bookPriceType = Material.WRITABLE_BOOK; + this.bookPriceQuantity = 1; + config.set("Options.Price_to_create_book.Item_type", this.bookPriceType.toString()); + config.set("Options.Price_to_create_book.Required_quantity", this.bookPriceQuantity); } config.set("Options.Require_book_and_quill_to_create_book", null); } @@ -328,53 +349,54 @@ public class BooksWithoutBordersConfig { * * @returnTrue if the config was loaded successfully
*/ - public static boolean loadConfig() { + public boolean loadConfig() { Logger logger = BooksWithoutBorders.getInstance().getLogger(); BooksWithoutBorders.getInstance().reloadConfig(); Configuration config = BooksWithoutBorders.getInstance().getConfig(); try { - useYml = getBoolean(config, ConfigOption.USE_YAML); - bookDuplicateLimit = config.getInt(ConfigOption.MAX_DUPLICATES.getConfigNode(), + this.useYml = getBoolean(config, ConfigOption.USE_YAML); + this.bookDuplicateLimit = config.getInt(ConfigOption.MAX_DUPLICATES.getConfigNode(), (Integer) ConfigOption.MAX_DUPLICATES.getDefaultValue()); - titleAuthorSeparator = getString(config, ConfigOption.TITLE_AUTHOR_SEPARATOR); - loreSeparator = getString(config, ConfigOption.LORE_LINE_SEPARATOR); - adminDecrypt = getBoolean(config, ConfigOption.ADMIN_AUTO_DECRYPT); - authorOnlyCopy = getBoolean(config, ConfigOption.AUTHOR_ONLY_COPY); - authorOnlyUnsign = getBoolean(config, ConfigOption.AUTHOR_ONLY_UNSIGN); - authorOnlySave = getBoolean(config, ConfigOption.AUTHOR_ONLY_SAVE); - firstBooks = config.getStringList(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode()); - welcomeMessage = getString(config, ConfigOption.MESSAGE_FOR_NEW_PLAYERS); - formatBooks = getBoolean(config, ConfigOption.FORMAT_AFTER_SIGNING); - changeGenerationOnCopy = getBoolean(config, ConfigOption.CHANGE_GENERATION_ON_COPY); - enableBookshelfPeeking = getBoolean(config, ConfigOption.ENABLE_BOOKSHELF_PEEKING); + this.titleAuthorSeparator = getString(config, ConfigOption.TITLE_AUTHOR_SEPARATOR); + this.loreSeparator = getString(config, ConfigOption.LORE_LINE_SEPARATOR); + this.adminDecrypt = getBoolean(config, ConfigOption.ADMIN_AUTO_DECRYPT); + this.authorOnlyCopy = getBoolean(config, ConfigOption.AUTHOR_ONLY_COPY); + this.authorOnlyUnsign = getBoolean(config, ConfigOption.AUTHOR_ONLY_UNSIGN); + this.authorOnlySave = getBoolean(config, ConfigOption.AUTHOR_ONLY_SAVE); + this.firstBooks = config.getStringList(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode()); + this.welcomeMessage = getString(config, ConfigOption.MESSAGE_FOR_NEW_PLAYERS); + this.formatBooks = getBoolean(config, ConfigOption.FORMAT_AFTER_SIGNING); + this.changeGenerationOnCopy = getBoolean(config, ConfigOption.CHANGE_GENERATION_ON_COPY); + this.enableBookshelfPeeking = getBoolean(config, ConfigOption.ENABLE_BOOKSHELF_PEEKING); String language = config.getString("language", "en"); - translator.loadLanguages(BooksWithoutBorders.getInstance().getDataFolder(), "en", language); + this.translator.loadLanguages(BooksWithoutBorders.getInstance().getDataFolder(), "en", language); //Convert string into material + this.economyManager = new EconomyManager(); String paymentMaterial = getString(config, ConfigOption.PRICE_ITEM_TYPE); if (paymentMaterial.equalsIgnoreCase("Economy")) { - if (EconomyHelper.setupEconomy()) { - bookPriceType = Material.AIR; + if (this.economyManager.getEconomy() == null) { + logger.log(Level.SEVERE, StaticMessage.EXCEPTION_VAULT_NOT_AVAILABLE.toString()); + this.bookPriceType = null; } else { - logger.log(Level.SEVERE, "BooksWithoutBorders failed to hook into Vault! Book price not set!"); - bookPriceType = null; + this.bookPriceType = Material.AIR; } } else if (!paymentMaterial.trim().isEmpty()) { Material material = Material.matchMaterial(paymentMaterial); if (material != null) { - bookPriceType = material; + this.bookPriceType = material; } } - bookPriceQuantity = config.getDouble(ConfigOption.PRICE_QUANTITY.getConfigNode(), + this.bookPriceQuantity = config.getDouble(ConfigOption.PRICE_QUANTITY.getConfigNode(), (Double) ConfigOption.PRICE_QUANTITY.getDefaultValue()); //Make sure titleAuthorSeparator is a valid value - titleAuthorSeparator = cleanString(titleAuthorSeparator); - if (titleAuthorSeparator.length() != 1) { + this.titleAuthorSeparator = cleanString(this.titleAuthorSeparator); + if (this.titleAuthorSeparator.length() != 1) { logger.log(Level.SEVERE, "Title-Author_Separator is set to an invalid value!\n" + "Reverting to default value of \",\""); - titleAuthorSeparator = ","; - config.set("Options.Title-Author_Separator", titleAuthorSeparator); + this.titleAuthorSeparator = ","; + config.set("Options.Title-Author_Separator", this.titleAuthorSeparator); } } catch (Exception e) { logger.log(Level.SEVERE, "Warning! Config.yml failed to load!\n" + diff --git a/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java b/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java index c811db6..49f3a48 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java @@ -9,7 +9,9 @@ public enum StaticMessage { BOOK_SAVING_FAILED("Saving failed! Aborting..."), BOOK_FOLDER_CREATE_FAILED("Unable to create necessary folders"), - COMMAND_NOT_REGISTERED("Command {command} has not been registered!"); + COMMAND_NOT_REGISTERED("Command {command} has not been registered!"), + EXCEPTION_VAULT_NOT_AVAILABLE("BooksWithoutBorders failed to hook into Vault! Book price not set!"), + ; private final @NotNull String messageString; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java b/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java index 7960b36..552b1b0 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java @@ -73,6 +73,11 @@ public enum Translatable implements TranslatableMessage { */ ERROR_INVENTORY_FULL, + /** + * The error displayed when trying to do a Vault transaction while Vault is unavailable + */ + ERROR_VAULT_COST_BUT_UNAVAILABLE, + /** * The header displayed before printing all commands */ @@ -103,6 +108,11 @@ public enum Translatable implements TranslatableMessage { */ NEUTRAL_COMMANDS_COMMAND_PERMISSION, + /** + * The translation of unknown author for a book + */ + NEUTRAL_UNKNOWN_AUTHOR, + /** * The translation of the copy action */ @@ -112,6 +122,11 @@ public enum Translatable implements TranslatableMessage { * The translation of the clear action */ ACTION_CLEAR, + + /** + * The translation of the decrypt action + */ + ACTION_DECRYPT, ; @Override diff --git a/src/main/java/net/knarcraft/bookswithoutborders/encryption/AES.java b/src/main/java/net/knarcraft/bookswithoutborders/encryption/AES.java index e96ca74..a38a78c 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/encryption/AES.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/encryption/AES.java @@ -73,7 +73,7 @@ public class AES { try { aes.init(mode, secretKeySpec, ivParameterSpec); } catch (InvalidKeyException | InvalidAlgorithmParameterException exception) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES input given!"); + BooksWithoutBorders.log(Level.SEVERE, "Invalid AES input given!"); return null; } //Perform encryption/decryption and output result @@ -81,7 +81,7 @@ public class AES { byte[] output = aes.doFinal(getInputBytes(input, encrypt)); return createResult(output, encrypt); } catch (IllegalBlockSizeException | BadPaddingException exception) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES block size or padding"); + BooksWithoutBorders.log(Level.SEVERE, "Invalid AES block size or padding"); return null; } } @@ -140,7 +140,7 @@ public class AES { try { aes = Cipher.getInstance("AES/CBC/PKCS5Padding"); } catch (NoSuchAlgorithmException | NoSuchPaddingException exception) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES algorithm or padding"); + BooksWithoutBorders.log(Level.SEVERE, "Invalid AES algorithm or padding"); return null; } return aes; @@ -159,14 +159,14 @@ public class AES { try { keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); } catch (NoSuchAlgorithmException exception) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES algorithm"); + BooksWithoutBorders.log(Level.SEVERE, "Invalid AES algorithm"); return null; } SecretKey tmp; try { tmp = keyFactory.generateSecret(spec); } catch (InvalidKeySpecException exception) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Invalid AES key specification"); + BooksWithoutBorders.log(Level.SEVERE, "Invalid AES key specification"); return null; } return new SecretKeySpec(tmp.getEncoded(), "AES"); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java b/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java index 8fa76cd..744d128 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.gui; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.utility.BookFileHelper; import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ClickEvent; @@ -28,8 +28,8 @@ public class AuthorBookIndex extends BookIndex { public static void printBooks(@NotNull CommandSender sender, boolean listPublic, @NotNull String command, int page, @NotNull String authorName) { ListAn economy instance, or null if it's not initialized
*/ - @NotNull - public static Economy getEconomy() { + @Nullable + public Economy getEconomy() { return economy; } - /** - * Tries to set up economy - * - * @returnTrue if economy is set up and enabled
- */ - public static boolean setupEconomy() { - if (economy != null) { - return true; - } - - Server server = BooksWithoutBorders.getInstance().getServer(); - Plugin plugin = server.getPluginManager().getPlugin("Vault"); - ServicesManager servicesManager = server.getServicesManager(); - - if (plugin != null) { - RegisteredServiceProviderThe number of copies the player is trying to print
* @returnTrue if the player cannot pay for the printing of the books
*/ - public static boolean cannotPayForBookPrinting(@NotNull Player player, int numCopies) { + public boolean cannotPayForBookPrinting(@NotNull Player player, int numCopies) { + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); //BookPriceQuantity: How many items are required to pay for each book //BookPriceType: Which item is used to pay for the books. AIR = use economy - Material bookCurrency = BooksWithoutBordersConfig.getBookPriceType(); - double cost = BooksWithoutBordersConfig.getBookPriceQuantity() * numCopies; + Material bookCurrency = config.getBookPriceType(); + double cost = config.getBookPriceQuantity() * numCopies; int itemCost = (int) cost; if (bookCurrency == Material.AIR) { - return !EconomyHelper.payForBookPrintingEconomy(player, cost, numCopies); + return !payForBookPrintingEconomy(player, cost, numCopies); } else { if (bookCurrency == Material.WRITABLE_BOOK) { //Writable books are treated as a special case to prevent WIP books from being used @@ -102,7 +97,7 @@ public final class EconomyHelper { * @param itemCostThe number of writable books to pay
* @returnTrue if the payment was successful
*/ - private static boolean takeWritableBookPayment(@NotNull Player player, int itemCost) { + private boolean takeWritableBookPayment(@NotNull Player player, int itemCost) { ListThe items to count
* @returnThe total number of items
*/ - private static int countItems(@NotNull ListThe empty books in the player's inventory
*/ @NotNull - private static ListThe number of books the player is printing
* @returnTrue if the player had the money and it has been withdrawn
*/ - private static boolean payForBookPrintingEconomy(@NotNull Player player, double cost, int numCopies) { + private boolean payForBookPrintingEconomy(@NotNull Player player, double cost, int numCopies) { + if (economy == null) { + BooksWithoutBorders.getStringFormatter().displayErrorMessage(player, Translatable.ERROR_VAULT_COST_BUT_UNAVAILABLE); + return false; + } + if ((economy.getBalance(player) - cost) >= 0) { economy.withdrawPlayer(player, cost); BooksWithoutBorders.sendSuccessMessage(player, economy.format(cost) + " withdrawn to create " + @@ -191,12 +191,12 @@ public final class EconomyHelper { * @param playerThe player which needs to pay
* @param itemCostThe number of items to pay
*/ - private static void payForBookPrintingItem(@NotNull Player player, int itemCost) { + private void payForBookPrintingItem(@NotNull Player player, int itemCost) { PlayerInventory playerInventory = player.getInventory(); int clearedAmount = 0; while (clearedAmount < itemCost) { - int firstItemIndex = playerInventory.first(BooksWithoutBordersConfig.getBookPriceType()); + int firstItemIndex = playerInventory.first(BooksWithoutBorders.getConfiguration().getBookPriceType()); ItemStack firstItem = playerInventory.getItem(firstItemIndex); if (Objects.requireNonNull(firstItem).getAmount() <= itemCost - clearedAmount) { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/state/EncryptionStyle.java b/src/main/java/net/knarcraft/bookswithoutborders/state/EncryptionStyle.java index f0bd495..7a942e7 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/state/EncryptionStyle.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/state/EncryptionStyle.java @@ -12,6 +12,11 @@ public enum EncryptionStyle { private final String name; + /** + * Instantiates a new encryption style + * + * @param nameThe human-readable encryption style name
+ */ EncryptionStyle(@NotNull String name) { this.name = name; } @@ -32,4 +37,10 @@ public enum EncryptionStyle { return SUBSTITUTION; } + @Override + @NotNull + public String toString() { + return this.name; + } + } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java index 9a5f177..deba501 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.utility; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.state.BookDirectory; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; @@ -16,8 +16,6 @@ import java.util.Map; import java.util.Objects; import java.util.regex.Pattern; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder; - /** * Helper class for dealing with files */ @@ -33,7 +31,7 @@ public final class BookFileHelper { * @returnTrue if the number is a book index
*/ public static boolean isBookListIndex(@NotNull String possibleIndex) { - File bookDirectory = new File(getBookFolder().replaceAll("[\\\\/]$", "")); + File bookDirectory = new File(BooksWithoutBorders.getConfiguration().getBookFolder().replaceAll("[\\\\/]$", "")); try { //Tests if a load list number has been supplied @@ -150,14 +148,12 @@ public final class BookFileHelper { continue; } String fileName = foundFile.getName(); - String separator = BooksWithoutBordersConfig.getTitleAuthorSeparator(); + String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); if (fileName.contains(separator)) { //Convert the UUID into a username if necessary - String[] data = fileName.split(separator); - String extension = data[1].substring(data[1].length() - 4); - String userName = data[1].substring(0, data[1].length() - 4); - data[1] = BookHelper.authorFromUUID(userName) + extension; - fileList.add(String.join(separator, data)); + String userName = getBookAuthorFromPath(fileName); + String title = getBookTitleFromPath(fileName); + fileList.add(title + separator + BookHelper.authorFromUUID(userName)); } else { fileList.add(fileName); } @@ -187,4 +183,68 @@ public final class BookFileHelper { return foundDuplicates; } + /** + * Gets a book's title given the book's path + * + * @param pathThe path of the book
+ * @returnThe book title
+ */ + @NotNull + public static String getBookTitleFromPath(@NotNull String path) { + String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); + String stripped = stripExtensionFromPath(path); + if (stripped.contains(separator)) { + return stripped.split(separator)[0]; + } else { + return stripped; + } + } + + /** + * Gets a book's author given the book's path + * + * @param pathThe path of the book
+ * @returnThe author name
+ */ + @NotNull + public static String getBookAuthorFromPath(@NotNull String path) { + String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); + String stripped = stripExtensionFromPath(path); + if (stripped.contains(separator)) { + return stripped.split(separator)[1]; + } else { + return BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR); + } + } + + /** + * Strips the extension from the given path + * + * @param pathThe path to strip the extension from
+ * @returnThe input with the extension stripped
+ */ + @NotNull + public static String stripExtensionFromPath(@NotNull String path) { + if (path.contains(".")) { + return path.substring(0, path.lastIndexOf(".")); + } else { + return path; + } + } + + /** + * Gets the extension from the given path + * + * @param pathThe path to get the extension from
+ * @returnThe extension of the input
+ */ + @NotNull + public static String getExtensionFromPath(@NotNull String path) { + if (path.contains(".")) { + return path.substring((path.length() - path.lastIndexOf(".")) + 1); + } else { + return ""; + } + } + } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java index b116c75..425ecb8 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java @@ -2,6 +2,7 @@ package net.knarcraft.bookswithoutborders.utility; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.state.BookDirectory; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @@ -14,7 +15,6 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.UUID; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash; import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName; /** @@ -35,7 +35,7 @@ public final class BookHelper { @NotNull public static String authorFromUUID(@NotNull String author) { try { - UUID authorID = UUID.fromString(author); + UUID authorID = UUID.fromString(BookFormatter.stripColor(author)); Player player = Bukkit.getPlayer(authorID); if (player != null) { author = player.getName(); @@ -70,12 +70,13 @@ public final class BookHelper { */ @Nullable public static String getBookDirectoryPathString(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) { + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); String folder = null; - String bookFolder = BooksWithoutBordersConfig.getBookFolder(); + String bookFolder = config.getBookFolder(); if (bookDirectory == BookDirectory.PUBLIC) { folder = bookFolder; } else if (bookDirectory == BookDirectory.PLAYER && sender instanceof Player player) { - folder = bookFolder + player.getUniqueId() + getSlash(); + folder = bookFolder + player.getUniqueId() + config.getSlash(); } return folder; } @@ -87,7 +88,7 @@ public final class BookHelper { */ public static void increaseGeneration(@NotNull ItemStack bookItem) { BookMeta bookMeta = (BookMeta) bookItem.getItemMeta(); - if (BooksWithoutBordersConfig.changeGenerationOnCopy() && bookMeta != null) { + if (BooksWithoutBorders.getConfiguration().changeGenerationOnCopy() && bookMeta != null) { bookMeta.setGeneration(BookHelper.getNextGeneration(bookMeta.getGeneration())); bookItem.setItemMeta(bookMeta); } @@ -124,7 +125,7 @@ public final class BookHelper { */ @NotNull public static String getBookFile(@NotNull BookMeta book, @NotNull Player player, boolean isPublic) throws IllegalArgumentException { - String titleAuthorSeparator = BooksWithoutBordersConfig.getTitleAuthorSeparator(); + String titleAuthorSeparator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); String bookName; if (book.hasTitle()) { bookName = book.getTitle(); @@ -144,7 +145,7 @@ public final class BookHelper { } else { authorName = book.getAuthor(); if (authorName == null) { - authorName = "Unknown"; + authorName = BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR); } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java index 39af228..ffcf563 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java @@ -68,18 +68,21 @@ public final class BookLoader { } catch (NumberFormatException ignored) { } + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + //Get the full path of the book to load File file = getFullPath(sender, fileName, bookDirectory, directory); if (file == null) { //Try converting the username to UUID - String titleAuthorSeparator = BooksWithoutBordersConfig.getTitleAuthorSeparator(); - String[] data = fileName.split(titleAuthorSeparator); - String extension = data[1].substring(data[1].length() - 4); - String userName = data[1].substring(0, data[1].length() - 4); + String separator = config.getTitleAuthorSeparator(); + String userName = BookFileHelper.getBookAuthorFromPath(fileName); + String title = BookFileHelper.getBookTitleFromPath(fileName); + String extension = BookFileHelper.getExtensionFromPath(fileName); + Player player = Bukkit.getPlayer(userName); if (player != null) { - data[1] = player.getUniqueId() + extension; - file = getFullPath(sender, String.join(titleAuthorSeparator, data), bookDirectory, directory); + userName = userName.replace(BookFormatter.stripColor(userName), player.getUniqueId().toString()); + file = getFullPath(sender, title + separator + userName + extension, bookDirectory, directory); if (file == null) { BooksWithoutBorders.sendErrorMessage(sender, "Incorrect file name!"); return null; @@ -90,10 +93,10 @@ public final class BookLoader { } //Make sure the player can pay for the book - if (BooksWithoutBordersConfig.booksHavePrice() && + if (config.booksHavePrice() && !sender.hasPermission("bookswithoutborders.bypassBookPrice") && (bookDirectory == BookDirectory.PUBLIC || bookDirectory == BookDirectory.PLAYER) && - EconomyHelper.cannotPayForBookPrinting((Player) sender, numCopies)) { + config.getEconomyManager().cannotPayForBookPrinting((Player) sender, numCopies)) { return null; } @@ -149,11 +152,11 @@ public final class BookLoader { @Nullable private static File getFullPath(@NotNull CommandSender sender, @NotNull String fileName, @NotNull BookDirectory bookDirectory, @NotNull String directory) { + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); File file; - String slash = BooksWithoutBordersConfig.getSlash(); - String bookFolder = BooksWithoutBordersConfig.getBookFolder(); + String slash = config.getSlash(); if (bookDirectory == BookDirectory.ENCRYPTED) { - file = BookFileHelper.getBookFile(bookFolder + "Encrypted" + slash + directory + slash + fileName); + file = BookFileHelper.getBookFile(config.getEncryptedBookPath() + directory + slash + fileName); } else { file = BookFileHelper.getBookFile(BookHelper.getBookDirectoryPathString(bookDirectory, sender) + fileName); } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookToFromTextHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookToFromTextHelper.java index ac74c5c..d63dbd7 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookToFromTextHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookToFromTextHelper.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.utility; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.knarlib.util.FileHelper; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -122,7 +122,8 @@ public final class BookToFromTextHelper { bookMetadata.setGeneration(BookMeta.Generation.valueOf(bookYml.getString("Generation", "ORIGINAL"))); bookMetadata.setTitle(bookYml.getString("Title", "Untitled")); - bookMetadata.setAuthor(authorFromUUID(bookYml.getString("Author", "Unknown"))); + bookMetadata.setAuthor(authorFromUUID(bookYml.getString("Author", + BooksWithoutBorders.getStringFormatter().getUnFormattedColoredMessage(Translatable.NEUTRAL_UNKNOWN_AUTHOR)))); bookMetadata.setPages(bookYml.getStringList("Pages")); bookMetadata.setLore(bookYml.getStringList("Lore")); } catch (IllegalArgumentException e) { @@ -141,21 +142,9 @@ public final class BookToFromTextHelper { */ @Nullable private static BookMeta bookFromTXT(@NotNull String fileName, @NotNull File file, @NotNull BookMeta bookMetadata) { - String author; - String title; - String titleAuthorSeparator = BooksWithoutBordersConfig.getTitleAuthorSeparator(); - - //Remove .txt extension - fileName = fileName.substring(0, fileName.length() - 4); //Get title and author from the file name - if (fileName.contains(titleAuthorSeparator)) { - String[] titleAuthor = fileName.split(titleAuthorSeparator); - title = titleAuthor[0]; - author = titleAuthor[1]; - } else { - author = "Unknown"; - title = fileName; - } + String title = BookFileHelper.getBookTitleFromPath(fileName); + String author = BookFileHelper.getBookAuthorFromPath(fileName); //Replace underscores with spaces title = fixName(title, true); @@ -165,11 +154,11 @@ public final class BookToFromTextHelper { try { rawPages = readTextFile(file); if (rawPages == null) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Text file's first line was null"); + BooksWithoutBorders.log(Level.SEVERE, "Text file's first line was null"); return null; } } catch (IOException exception) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to read text file"); + BooksWithoutBorders.log(Level.SEVERE, "Unable to read text file"); return null; } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java index b1c88fc..6f152ba 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java @@ -20,8 +20,6 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getBookFolder; -import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash; import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString; import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName; @@ -211,7 +209,7 @@ public final class EncryptionHelper { public static ItemStack loadEncryptedBook(@NotNull Player player, @NotNull String key, boolean deleteEncryptedFile) { ItemStack heldBook = InventoryHelper.getHeldBook(player, true); BookMeta bookMetadata = (BookMeta) heldBook.getItemMeta(); - String path = getBookFolder() + "Encrypted" + getSlash(); + String path = BooksWithoutBorders.getConfiguration().getEncryptedBookPath(); if (bookMetadata == null) { return null; @@ -266,17 +264,18 @@ public final class EncryptionHelper { @Nullable private static BookMeta saveEncryptedBookForGroup(@NotNull Player player, @NotNull BookMeta bookMetadata, @NotNull String groupName) { - String path = getBookFolder() + "Encrypted" + getSlash() + cleanString(groupName) + getSlash(); + BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + String path = config.getEncryptedBookPath() + cleanString(groupName) + config.getSlash(); File dirTest = new File(path); //Creates group dir if (!dirTest.exists()) { try { if (!dirTest.mkdir()) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to create encryption group folder!"); + BooksWithoutBorders.log(Level.SEVERE, "Unable to create encryption group folder!"); return null; } } catch (Exception exception) { - BooksWithoutBorders.getInstance().getLogger().log(Level.SEVERE, "Unable to save group encrypted book"); + BooksWithoutBorders.log(Level.SEVERE, "Unable to save group encrypted book"); return null; } } @@ -294,7 +293,7 @@ public final class EncryptionHelper { bookMetadata.setLore(newLore); //Save file - File file = (BooksWithoutBordersConfig.getUseYml()) ? new File(path + fileName + ".yml") : + File file = (BooksWithoutBorders.getConfiguration().getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt"); if (!file.isFile()) { try { @@ -318,13 +317,13 @@ public final class EncryptionHelper { */ @NotNull private static Boolean saveEncryptedBook(@NotNull Player player, @NotNull BookMeta bookMetaData, @NotNull String key) { - String path = getBookFolder() + "Encrypted" + getSlash(); + String path = BooksWithoutBorders.getConfiguration().getEncryptedBookPath(); String fileName = "[" + key + "]" + BookHelper.getBookFile(bookMetaData, player, true); fileName = fixName(cleanString(fileName), false); //cancels saving if file is already encrypted - File file = (BooksWithoutBordersConfig.getUseYml()) ? new File(path + fileName + ".yml") : + File file = (BooksWithoutBorders.getConfiguration().getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt"); if (file.isFile()) { return true; diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml index e048f05..13b69c1 100644 --- a/src/main/resources/strings.yml +++ b/src/main/resources/strings.yml @@ -14,6 +14,7 @@ en: ERROR_BOOK_COPIED_TOO_FAR: "You cannot copy this book any further. You must have the original or a direct copy." ERROR_INVENTORY_FULL: "You need an available slot in your inventory." ERROR_METADATA_MISSING: "Unable to get metadata for the held book!" + ERROR_VAULT_COST_BUT_UNAVAILABLE: "The cost was set to economy, but Vault is unavailable!" NEUTRAL_COMMANDS_HEADER: | &e[] denote optional parameters <> denote required parameters @@ -26,5 +27,7 @@ en: NEUTRAL_COMMANDS_COMMAND: "\n \n&e{usage}: &a{description}" NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED: "None" NEUTRAL_COMMANDS_COMMAND_PERMISSION: " &7{{permission}}" + NEUTRAL_UNKNOWN_AUTHOR: "Unknown" ACTION_COPY: "copy" - ACTION_CLEAR: "clear" \ No newline at end of file + ACTION_CLEAR: "clear" + ACTION_DECRYPT: "decrypt" \ No newline at end of file