diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index aa3b712..18c244c 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -26,8 +26,8 @@ import net.knarcraft.bookswithoutborders.command.CommandSetGeneration; import net.knarcraft.bookswithoutborders.command.CommandSetLore; import net.knarcraft.bookswithoutborders.command.CommandSetTitle; import net.knarcraft.bookswithoutborders.command.CommandUnSign; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBCommand; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.container.MigrationRequest; @@ -79,7 +79,7 @@ public class BooksWithoutBorders extends JavaPlugin { private Map> playerLetterIndex; private BookshelfHandler bookshelfHandler; private StringFormatter stringFormatter; - private BooksWithoutBordersConfig booksWithoutBordersConfig; + private BwBConfig booksWithoutBordersConfig; private final Queue migrationQueue = new LinkedList<>(); /** @@ -97,7 +97,7 @@ public class BooksWithoutBorders extends JavaPlugin { * * @return

The BwB configuration

*/ - public static BooksWithoutBordersConfig getConfiguration() { + public static BwBConfig getConfiguration() { return getInstance().booksWithoutBordersConfig; } @@ -215,7 +215,7 @@ public class BooksWithoutBorders extends JavaPlugin { booksWithoutBorders = this; playerBooksList = new HashMap<>(); playerLetterIndex = new HashMap<>(); - booksWithoutBordersConfig = new BooksWithoutBordersConfig(this, translator); + booksWithoutBordersConfig = new BwBConfig(this, translator); @Nullable List files = BookFileHelper.listFiles(this.getServer().getConsoleSender(), true); if (files != null) { publicBooksList = files; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java index 27a6a4f..ba50243 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java @@ -1,13 +1,14 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBCommand; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.manager.EconomyManager; import net.knarcraft.knarlib.formatting.StringFormatter; +import net.knarcraft.knarlib.util.TabCompletionHelper; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -16,7 +17,7 @@ import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.logging.Level; @@ -25,13 +26,32 @@ import java.util.logging.Level; */ public class CommandBooksWithoutBorders implements TabExecutor { + private static final List commandNames = Arrays.stream(BwBCommand.values()).map(BwBCommand::toString).toList(); + @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] arguments) { StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter(); - String header = stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_HEADER, - List.of("{bookPrice}", "{commands}"), List.of(getBookPrice(), getCommands(sender))); - sender.sendMessage(header); + + String commands; + String commandExplanation; + + if (arguments.length == 1) { + BwBCommand bwbCommand = BwBCommand.fromString(arguments[0]); + if (bwbCommand != null) { + commands = getCommandInfo(bwbCommand, sender, false); + commandExplanation = getCommandExplanation(false); + } else { + stringFormatter.displayErrorMessage(sender, Translatable.ERROR_UNKNOWN_COMMAND); + return false; + } + } else { + commands = getCommands(sender); + commandExplanation = getCommandExplanation(true); + } + stringFormatter.displaySuccessMessage(sender, stringFormatter.replacePlaceholders( + Translatable.NEUTRAL_COMMANDS_HEADER, List.of("{bookPrice}", "{commands}", "{commandExplanation}"), + List.of(getBookPrice(), commands, commandExplanation))); return true; } @@ -57,7 +77,7 @@ public class CommandBooksWithoutBorders implements TabExecutor { */ @NotNull private String getBookPrice() { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); if (!config.booksHavePrice()) { return ""; @@ -91,7 +111,7 @@ public class CommandBooksWithoutBorders implements TabExecutor { StringBuilder builder = new StringBuilder(); for (BwBCommand command : BwBCommand.values()) { if (!command.requiresPlayer()) { - builder.append(showCommandInfo(command.toString(), sender)); + builder.append(getCommandInfo(command, sender, true)); } } return builder.toString(); @@ -106,7 +126,7 @@ public class CommandBooksWithoutBorders implements TabExecutor { private String showPlayerCommands(@NotNull CommandSender sender) { StringBuilder builder = new StringBuilder(); for (BwBCommand command : BwBCommand.values()) { - builder.append(showCommandInfo(command.toString(), sender)); + builder.append(getCommandInfo(command, sender, true)); } return builder.toString(); } @@ -114,29 +134,44 @@ public class CommandBooksWithoutBorders implements TabExecutor { /** * Shows information about the given command * - * @param command

The command to get information about

- * @param sender

The sender asking to see command info

+ * @param bwBCommand

The command to get information about

+ * @param sender

The sender asking to see command info

+ * @param summary

Whether to only show a summary, vs. showing all available info

*/ @NotNull - private String showCommandInfo(@NotNull String command, @NotNull CommandSender sender) { - PluginCommand pluginCommand = BooksWithoutBorders.getInstance().getCommand(command); + private String getCommandInfo(@NotNull BwBCommand bwBCommand, @NotNull CommandSender sender, boolean summary) { + PluginCommand pluginCommand = BooksWithoutBorders.getInstance().getCommand(bwBCommand.toString()); if (pluginCommand == null) { BooksWithoutBorders.log(Level.SEVERE, StringFormatter.replacePlaceholder( - StaticMessage.COMMAND_NOT_REGISTERED.toString(), "{command}", command)); + StaticMessage.COMMAND_NOT_REGISTERED.toString(), "{command}", bwBCommand.toString())); return ""; } + // Don't show info if the user is missing required permissions String permission = pluginCommand.getPermission(); if (permission != null && !sender.hasPermission(permission)) { return ""; } StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter(); - String commandDescription = stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND, - List.of("{usage}", "{description}"), List.of(pluginCommand.getUsage().replace("", - pluginCommand.getName()), pluginCommand.getDescription())); + String description; + String aliases = ""; + String commandUsage; - if (sender.hasPermission(Permission.ADMIN.toString())) { + if (summary) { + commandUsage = "/" + pluginCommand.getName(); + description = bwBCommand.getSummary(); + } else { + commandUsage = pluginCommand.getUsage().replace("", pluginCommand.getName()); + description = pluginCommand.getDescription(); + aliases = stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_ALIASES, "{aliases}", + String.join(",", pluginCommand.getAliases())); + } + + String commandDescription = stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND, + List.of("{usage}", "{description}", "{aliases}"), List.of(commandUsage, description, aliases)); + + if (!summary && sender.hasPermission(Permission.ADMIN.toString())) { if (permission == null) { permission = stringFormatter.getUnFormattedColoredMessage(Translatable.NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED); } @@ -145,10 +180,34 @@ public class CommandBooksWithoutBorders implements TabExecutor { return commandDescription; } + /** + * Gets an explanation of what the differently colored command description parts are all about + * + * @param summary

Whether to give explanation of the summary or the full info

+ * @return

The command explanation

+ */ + @NotNull + private String getCommandExplanation(boolean summary) { + StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter(); + if (summary) { + return stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND, + List.of("{usage}", "{description}", "{aliases}"), List.of("Command", "Usage summary", "")); + } else { + return stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND, + List.of("{usage}", "{description}", "{aliases}"), List.of("Command and arguments", "Full description", + stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_ALIASES, "{aliases}", "Alias list"))) + + stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_COMMAND_PERMISSION, "{permission}", "Required permission"); + } + } + @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] arguments) { - return new ArrayList<>(); + if (arguments.length == 1) { + return TabCompletionHelper.filterMatchingStartsWith(commandNames, arguments[0]); + } else { + return List.of(); + } } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandClear.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandClear.java index 1a66de7..1c65b8a 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandClear.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandClear.java @@ -10,6 +10,7 @@ import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.WritableBookMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,16 +42,24 @@ public class CommandClear implements TabExecutor { //Clear the player's held book ItemStack heldBook = InventoryHelper.getHeldBook(player, false); - BookMeta bookMeta = (BookMeta) heldBook.getItemMeta(); - if (bookMeta == null) { - stringFormatter.displayErrorMessage(sender, Translatable.ERROR_METADATA_MISSING); - return false; + + WritableBookMeta newMetadata = (BookMeta) BooksWithoutBorders.getItemFactory().getItemMeta(heldBook.getType()); + if (newMetadata != null) { + // Create new blank metadata to clear everything + heldBook.setItemMeta(newMetadata); + } else { + // Fallback to cleaning existing metadata + BookMeta bookMeta = (BookMeta) heldBook.getItemMeta(); + if (bookMeta == null) { + stringFormatter.displayErrorMessage(sender, Translatable.ERROR_METADATA_MISSING); + return false; + } + bookMeta.setPages(""); + bookMeta.setAuthor(null); + bookMeta.setGeneration(null); + bookMeta.setTitle(null); + heldBook.setItemMeta(bookMeta); } - bookMeta.setPages(""); - bookMeta.setAuthor(null); - bookMeta.setGeneration(null); - bookMeta.setTitle(null); - heldBook.setItemMeta(bookMeta); stringFormatter.displaySuccessMessage(sender, Translatable.SUCCESS_CLEARED); return true; } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java index d88c8e7..adf6b22 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.utility.BookHelper; @@ -73,7 +73,7 @@ public class CommandCopy implements TabExecutor { * @return

True if the copying was successful

*/ private boolean performCopy(int copies, @NotNull Player player, @NotNull ItemStack heldBook) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); //Make sure the player owns the book if authorOnlyCopy is enabled if (config.getAuthorOnlyCopy() && @@ -106,7 +106,7 @@ public class CommandCopy implements TabExecutor { * @return

True if the payment failed

*/ private boolean paymentUnSuccessful(@NotNull Player player, int copies) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); return (config.booksHavePrice() && !player.hasPermission(Permission.BYPASS_BOOK_PRICE.toString()) && config.getEconomyManager().cannotPayForBookPrinting(player, copies)); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java index 2361cef..2b9312a 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.Translatable; @@ -82,7 +82,7 @@ public class CommandSave implements TabExecutor { return; } - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); //Only allow saving of own books if enabled if (config.getAuthorOnlySave() && !saveToPublicFolder && diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookPrice.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookPrice.java index df9acc5..1d0c0c8 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookPrice.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookPrice.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.manager.EconomyManager; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; @@ -71,7 +71,7 @@ public class CommandSetBookPrice implements TabExecutor { * @param sender

The sender of the command

*/ private void clearItemPrice(@NotNull CommandSender sender) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); config.setBookPriceType(null); config.setBookPriceQuantity(0); booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Item type name"); @@ -100,7 +100,7 @@ public class CommandSetBookPrice implements TabExecutor { return false; } - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); config.setBookPriceType(heldItem.getType()); config.setBookPriceQuantity(price); String newPriceType = config.getBookPriceType().toString(); @@ -124,7 +124,7 @@ public class CommandSetBookPrice implements TabExecutor { private boolean setEconomyPrice(@NotNull CommandSender sender, double price) { EconomyManager economyManager = BooksWithoutBorders.getConfiguration().getEconomyManager(); if (economyManager.getEconomy() != null) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); config.setBookPriceQuantity(price); config.setBookPriceType(Material.AIR); double newPriceQuantity = config.getBookPriceQuantity(); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/config/BwBCommand.java b/src/main/java/net/knarcraft/bookswithoutborders/config/BwBCommand.java index 67c5348..b0098ca 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/config/BwBCommand.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/config/BwBCommand.java @@ -1,127 +1,13 @@ package net.knarcraft.bookswithoutborders.config; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * A representation of a BwB command */ public enum BwBCommand { - /** - * The help command - */ - BOOKS_WITHOUT_BORDERS("booksWithoutBorders", false), - - /** - * Clears the contents of a book - */ - CLEAR_BOOK("clearBook", true), - - /** - * Copies the held book - */ - COPY_BOOK("copyBook", true), - - /** - * Decrypts the held encrypted book - */ - DECRYPT_BOOK("decryptBook", true), - - /** - * Deletes a book from a player's private collection - */ - DELETE_BOOK("deleteBook", true), - - /** - * Deletes a book from the public collection - */ - DELETE_PUBLIC_BOOK("deletePublicBook", false), - - /** - * Encrypts the held book - */ - ENCRYPT_BOOK("encryptBook", true), - - /** - * Executes formatting codes in the held book - */ - FORMAT_BOOK("formatBook", true), - - /** - * Gives a book from a player's private collection to another player - */ - GIVE_BOOK("giveBook", true), - - /** - * Gives a book from the public collection to a player - */ - GIVE_PUBLIC_BOOK("givePublicBook", false), - - /** - * Encrypts a book for specific group - */ - GROUP_ENCRYPT_BOOK("groupEncryptBook", true), - - /** - * Loads a book from a player's private collection - */ - LOAD_BOOK("loadBook", true), - - /** - * Loads a book from the public collection - */ - LOAD_PUBLIC_BOOK("loadPublicBook", true), - - /** - * Reloads the plugin's configuration and the book lists - */ - RELOAD("reload", false), - - /** - * Saves a book to a player's private collection - */ - SAVE_BOOK("saveBook", true), - - /** - * Saves a book to the public collection - */ - SAVE_PUBLIC_BOOK("savePublicBook", true), - - /** - * Sets the author of the held book - */ - SET_BOOK_AUTHOR("setBookAuthor", true), - - /** - * Sets the generation of the held book - */ - SET_BOOK_GENERATION("setBookGeneration", true), - - /** - * Sets the price of copying, loading and giving books - */ - SET_BOOK_PRICE("setBookPrice", false), - - /** - * Sets the name/lore for the chiseled bookshelf in front of the player, displayed when peeking the bookshelf - */ - SET_BOOKSHELF_DATA("setBookshelfData", true), - - /** - * Sets the lore of the held book/item - */ - SET_LORE("setLore", true), - - /** - * Sets the book title of the held signed book, or the display name of the held item - */ - SET_TITLE("setTitle", true), - - /** - * Un-signs the held signed book - */ - UNSIGN_BOOK("unsignBook", true), - /** * Adds a title page, blank page or chapter page to the held book * @@ -132,31 +18,149 @@ public enum BwBCommand { * If both an index and text is given, and a signed or unsigned book is provided, a custom chapter page depending on * the text will be added to the specified index.

*/ - ADD_TITLE_PAGE("addBookTitlePage", true), + ADD_TITLE_PAGE("addBookTitlePage", true, "Add held book title/chapter page"), + + /** + * The help command + */ + BOOKS_WITHOUT_BORDERS("booksWithoutBorders", false, "Help command"), + + /** + * Clears the contents of a book + */ + CLEAR_BOOK("clearBook", true, "Clear held book"), + + /** + * Copies the held book + */ + COPY_BOOK("copyBook", true, "Copy held book"), + + /** + * Decrypts the held encrypted book + */ + DECRYPT_BOOK("decryptBook", true, "Decrypt the held book"), + + /** + * Deletes a book from a player's private collection + */ + DELETE_BOOK("deleteBook", true, "Delete saved book"), /** * Deletes a page from the held book */ - DELETE_PAGE("deleteBookPage", true), + DELETE_PAGE("deleteBookPage", true, "Delete one page of held book"), + + /** + * Deletes a book from the public collection + */ + DELETE_PUBLIC_BOOK("deletePublicBook", false, "Delete saved public book"), + + /** + * Encrypts the held book + */ + ENCRYPT_BOOK("encryptBook", true, "Encrypt the held book"), + + /** + * Executes formatting codes in the held book + */ + FORMAT_BOOK("formatBook", true, "Format the held book"), + + /** + * Gives a book from a player's private collection to another player + */ + GIVE_BOOK("giveBook", true, "Give saved book"), + + /** + * Gives a book from the public collection to a player + */ + GIVE_PUBLIC_BOOK("givePublicBook", false, "Give saved public book"), + + /** + * Encrypts a book for specific group + */ + GROUP_ENCRYPT_BOOK("groupEncryptBook", true, "Group encrypt the held book"), + + /** + * Loads a book from a player's private collection + */ + LOAD_BOOK("loadBook", true, "Load saved book"), + + /** + * Loads a book from the public collection + */ + LOAD_PUBLIC_BOOK("loadPublicBook", true, "Load saved public book"), /** * Migrates all books, fixing any problems with their names, and converts txt books to yml */ - MIGRATE("migrateBooks", true), + MIGRATE("migrateBooks", true, "Migrate old books"), + + /** + * Reloads the plugin's configuration and the book lists + */ + RELOAD("reload", false, "Reload BwB"), + + /** + * Saves a book to a player's private collection + */ + SAVE_BOOK("saveBook", true, "Save held book"), + + /** + * Saves a book to the public collection + */ + SAVE_PUBLIC_BOOK("savePublicBook", true, "Publicly save held book"), + + /** + * Sets the author of the held book + */ + SET_BOOK_AUTHOR("setBookAuthor", true, "Set held book author"), + + /** + * Sets the generation of the held book + */ + SET_BOOK_GENERATION("setBookGeneration", true, "Set held book generation"), + + /** + * Sets the price of copying, loading and giving books + */ + SET_BOOK_PRICE("setBookPrice", false, "Set book creation price"), + + /** + * Sets the name/lore for the chiseled bookshelf in front of the player, displayed when peeking the bookshelf + */ + SET_BOOKSHELF_DATA("setBookshelfData", true, "Set targeted bookshelf data"), + + /** + * Sets the lore of the held book/item + */ + SET_LORE("setLore", true, "Set held item lore"), + + /** + * Sets the book title of the held signed book, or the display name of the held item + */ + SET_TITLE("setTitle", true, "Set held item title"), + + /** + * Un-signs the held signed book + */ + UNSIGN_BOOK("unsignBook", true, "Unsign held book"), ; private final @NotNull String commandName; private final boolean requiresPlayer; + private final @NotNull String summary; /** * Instantiates a new command * * @param commandName

The name of the command

* @param requiresPlayer

Whether the command requires to be run by a player

+ * @param summary

A short summary of the command's usage

*/ - BwBCommand(@NotNull String commandName, boolean requiresPlayer) { + BwBCommand(@NotNull String commandName, boolean requiresPlayer, @NotNull String summary) { this.commandName = commandName; this.requiresPlayer = requiresPlayer; + this.summary = summary; } /** @@ -168,6 +172,16 @@ public enum BwBCommand { return this.requiresPlayer; } + /** + * Gets a summary of this command + * + * @return

A summary of this command

+ */ + @NotNull + public String getSummary() { + return this.summary; + } + /** * Return name instead of enum when displayed as a string * @@ -179,4 +193,20 @@ public enum BwBCommand { return this.commandName; } + /** + * Gets the command specified by the given string + * + * @param input

The input denoting a command

+ * @return

The command, or null if not matched

+ */ + @Nullable + public static BwBCommand fromString(@NotNull String input) { + for (BwBCommand command : BwBCommand.values()) { + if (command.commandName.equalsIgnoreCase(input)) { + return command; + } + } + return null; + } + } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/config/BooksWithoutBordersConfig.java b/src/main/java/net/knarcraft/bookswithoutborders/config/BwBConfig.java similarity index 98% rename from src/main/java/net/knarcraft/bookswithoutborders/config/BooksWithoutBordersConfig.java rename to src/main/java/net/knarcraft/bookswithoutborders/config/BwBConfig.java index 9e22961..17e5711 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/config/BooksWithoutBordersConfig.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/config/BwBConfig.java @@ -19,7 +19,7 @@ import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.clea /** * A config class that keeps track of all config values */ -public class BooksWithoutBordersConfig { +public class BwBConfig { private final ChatColor errorColor = ChatColor.RED; private final ChatColor successColor = ChatColor.GREEN; @@ -51,7 +51,7 @@ public class BooksWithoutBordersConfig { * * @param booksWithoutBorders

The books without borders object used for getting required data

*/ - public BooksWithoutBordersConfig(@NotNull BooksWithoutBorders booksWithoutBorders, @NotNull Translator translator) { + public BwBConfig(@NotNull BooksWithoutBorders booksWithoutBorders, @NotNull Translator translator) { if (isInitialized) { throw new IllegalArgumentException("Settings class initialized twice. This should not happen!"); } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java b/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java index 30eacfe..400bcfd 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/config/Translatable.java @@ -278,6 +278,11 @@ public enum Translatable implements TranslatableMessage { */ ERROR_SAVE_DUPLICATE_UNNAMED, + /** + * The error displayed when specifying a command, but the command is unknown + */ + ERROR_UNKNOWN_COMMAND, + /** * The header displayed before printing all commands */ @@ -308,6 +313,11 @@ public enum Translatable implements TranslatableMessage { */ NEUTRAL_COMMANDS_COMMAND_PERMISSION, + /** + * The format used when printing aliases + */ + NEUTRAL_COMMANDS_ALIASES, + /** * The translation of unknown author for a book */ diff --git a/src/main/java/net/knarcraft/bookswithoutborders/encryption/Magic.java b/src/main/java/net/knarcraft/bookswithoutborders/encryption/Magic.java index b865fc1..613d606 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/encryption/Magic.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/encryption/Magic.java @@ -1,6 +1,5 @@ package net.knarcraft.bookswithoutborders.encryption; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -11,12 +10,12 @@ public class Magic implements Encryptor { @Override public @Nullable String encryptText(@NotNull String input) { - return "§k" + BookFormatter.stripColor(input.replace("§", "")); + return "§k" + input.replace("§", "&"); } @Override public @Nullable String decryptText(@NotNull String input) { - return null; + return input.replace("§k", "").replace("&", "§"); } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/BookshelfListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/BookshelfListener.java index 07b337a..2e66272 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/listener/BookshelfListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/BookshelfListener.java @@ -5,6 +5,8 @@ import net.knarcraft.bookswithoutborders.container.Bookshelf; import net.knarcraft.bookswithoutborders.handler.BookshelfHandler; import net.knarcraft.bookswithoutborders.utility.BookHelper; import net.knarcraft.bookswithoutborders.utility.IntegerToRomanConverter; +import net.knarcraft.knarlib.property.ColorConversion; +import net.knarcraft.knarlib.util.ColorHelper; import net.md_5.bungee.api.ChatColor; import org.bukkit.Location; import org.bukkit.Material; @@ -88,10 +90,12 @@ public class BookshelfListener implements Listener { Bookshelf bookshelf = BooksWithoutBorders.getBookshelfHandler().getFromLocation(location); if (bookshelf != null) { - builder.append(ChatColor.of("#FF5700")).append("Books in ").append(bookshelf.getTitle()) - .append(":").append(ChatColor.RESET); + builder.append(ChatColor.of("#FF5700")).append("Books in ").append( + ColorHelper.translateColorCodes(bookshelf.getTitle(), ColorConversion.RGB)).append( + ChatColor.RESET).append(ChatColor.of("#FF5700")).append(":"); for (String lore : bookshelf.getLore()) { - builder.append("\n ").append(ChatColor.LIGHT_PURPLE).append(lore); + builder.append("\n ").append(ChatColor.LIGHT_PURPLE).append( + ColorHelper.translateColorCodes(lore, ColorConversion.RGB)).append(ChatColor.RESET); } } else { builder.append(ChatColor.of("#FF5700")).append("Books in shelf:").append(ChatColor.RESET); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/PlayerEventListener.java index 835bf02..36b19ee 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/PlayerEventListener.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.listener; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.utility.BookLoader; import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import org.bukkit.entity.Player; @@ -24,7 +24,7 @@ public class PlayerEventListener implements Listener { @EventHandler public void onPlayerJoin(@NotNull PlayerJoinEvent event) { Player player = event.getPlayer(); - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); //If a book directory exists with this player's name, move it to this player's UUID String bookFolder = config.getBookFolder(); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java index 9462642..43c66cb 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.listener; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.encryption.EncryptionStyle; import net.knarcraft.bookswithoutborders.state.BookDirectory; @@ -250,7 +250,7 @@ public class SignEventListener implements Listener { */ private void decryptBook(@NotNull BookMeta oldBook, @NotNull Player player, @NotNull ItemStack heldItem, @NotNull EquipmentSlot hand) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); ItemStack newBook; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/manager/EconomyManager.java b/src/main/java/net/knarcraft/bookswithoutborders/manager/EconomyManager.java index 5a539c4..fd90421 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/manager/EconomyManager.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/manager/EconomyManager.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.manager; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; +import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.Translatable; import net.milkbowl.vault.economy.Economy; import org.bukkit.Material; @@ -63,7 +63,7 @@ public class EconomyManager { * @return

True if the player cannot pay for the printing of the books

*/ public boolean cannotPayForBookPrinting(@NotNull Player player, int numCopies) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig 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 = config.getBookPriceType(); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java index 0f76ca9..0da4650 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.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.BwBConfig; import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.state.BookDirectory; import org.bukkit.Bukkit; @@ -106,7 +106,7 @@ public final class BookHelper { */ @Nullable public static String getBookDirectoryPathString(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); String folder = null; String bookFolder = config.getBookFolder(); if (bookDirectory == BookDirectory.PUBLIC) { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java index 3e5988d..cf89dab 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.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.BwBConfig; import net.knarcraft.bookswithoutborders.state.BookDirectory; import org.bukkit.Material; import org.bukkit.command.CommandSender; @@ -85,7 +85,7 @@ public final class BookLoader { } catch (NumberFormatException ignored) { } - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); //Get the full path of the book to load File file = getFullPath(sender, fileName, bookDirectory, directory); @@ -158,7 +158,7 @@ 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(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); File file = null; String slash = config.getSlash(); if (bookDirectory == BookDirectory.ENCRYPTED) { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java index 747005e..59da41a 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.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.BwBConfig; import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.encryption.AES; import net.knarcraft.bookswithoutborders.encryption.AESConfiguration; @@ -427,7 +427,7 @@ public final class EncryptionHelper { @Nullable private static BookMeta saveEncryptedBookForGroup(@NotNull Player player, @NotNull BookMeta bookMetadata, @NotNull String groupName) { - BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); + BwBConfig config = BooksWithoutBorders.getConfiguration(); String path = config.getEncryptedBookPath() + cleanString(groupName) + config.getSlash(); File dirTest = new File(path); //Creates group dir diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 979c918..7171952 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -10,156 +10,227 @@ website: https://www.spigotmc.org/resources/books-without-borders-updated.96069/ dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders commands: bookswithoutborders: - description: Lists Books Without Borders's commands and uses. + description: Lists Books Without Borders' commands and uses, or shows a detailed description of a specific command. aliases: - bwb - usage: / + usage: / [commandName] decryptbook: - description: Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt held book + description: | + Decrypts the book you are holding. "key" is required and MUST be IDENTICAL to the key used to encrypt held book. + Use the method with no arguments if you want to (and are allowed to) utilize admin decryption. + There is no decryption method option, as that's stored in the encrypted file, or it's not relevant for decryption. aliases: - bwbdecrypt - usage: / + usage: / [key] permission: bookswithoutborders.decrypt formatbook: - description: Replaces color/formatting codes in a written book with formatted text + description: | + Replaces color and formatting codes (#000000, &a, &4, &n, &#ffffff) in a written book with formatted text. + Note that while formatting an unsigned book can be useful for fixing whitespace, like centering text, but + RGB colors look really strange for some reason. Once the book is signed, the colors display as intended. aliases: - bwbformat usage: / permission: bookswithoutborders.format givebook: - description: Gives the selected player a book from your personal directory + description: | + Gives the selected player a book from the books you have saved to your personal collection. + Any costs for creating the book will be payed by you, the sender. + If used with no arguments, a list of all books will be shown. aliases: - bwbgive usage: / [# of copies (num)] [signed (true/false)] permission: bookswithoutborders.give givepublicbook: - description: Same as givebook, but uses books from the public directory + description: | + Gives the selected player a book from the public book collection. + Any costs for creating the book will be payed by you, the sender. + If used with no arguments, a list of all books will be shown. aliases: - bwbgivep - usage: / [# of copies (num)] [signed (true/false)] + usage: / [# of copies (num)] [signed (true/false)] permission: bookswithoutborders.givepublic groupencryptbook: - description: Encrypts book so that only players with the bookswithoutborders.decrypt. permission may decrypt the book by holding and left clicking the book + description: | + Encrypts book so that only players with the bookswithoutborders.decrypt. permission may decrypt the + book by holding and interacting with the book in their hand. The key isn't necessary for decryption, it's only + used for properly scrambling the book's contents. aliases: - bwbgencrypt usage: / [encryption style] permission: bookswithoutborders.groupencrypt deletebook: - description: Deletes the specified file in the player's directory + description: | + Deletes the specified book from your personal collection. + If used with no arguments, a list of all books will be shown. aliases: - bwbdelete usage: / permission: bookswithoutborders.delete deletepublicbook: - description: Same as deletebook, but deletes files in the public directory + description: | + Deletes the specified book from your public collection. + If used with no arguments, a list of all books will be shown. aliases: - bwbdeletep usage: / permission: bookswithoutborders.admin copybook: - description: Copies the book the player is holding + description: | + Copies your held book the specified amount times. + If you specify 1 as the number of copies, one book will be added to the stack of book you are copying aliases: - bwbcopy usage: / <# of copies> permission: bookswithoutborders.copy clearbook: - description: Removes all text from the book the player is holding + description: Removes all text and metadata from the unsigned book you are holding aliases: - bwbclear usage: / permission: bookswithoutborders.clear unsignbook: - description: Un-signs the book the player is holding + description: Un-signs your held signed book aliases: - bwbunsign usage: / permission: bookswithoutborders.unsign encryptbook: - description: Encrypts the book the player is holding. "key" is required and can be any phrase or number excluding spaces. "style" is not required. Possible values are "DNA" or "" + description: | + Encrypts the book the player is holding. "key" is required and can be any phrase or number excluding spaces. + "style" is not required. Possible values are "dna", "substitution", "aes", "onetimepad" and "magic". + If real encryption is enabled, possible methods are restricted. aliases: - bwbencrypt usage: / [encryption style] permission: bookswithoutborders.encrypt setbookgeneration: - description: Sets the generation of the held book + description: Sets the generation of your held book aliases: - bwbgeneration usage: / permission: bookswithoutborders.setgeneration setbookprice: - description: Sets the per-book-price to create a book via commands. If "Item", the item in the player's hand in the amount of [quantity] will be the price. If "Eco", a Vault based economy will be used for price. If neither or are specified, the current price to create books will be removed. + description: | + Sets the per-book-price to create a book via commands. If "Item", the item in the player's hand in the amount + of [quantity] will be the price. + If "Eco", a Vault based economy will be used for price. + If neither or are specified, the current price to create books will be removed. aliases: - bwbprice usage: / permission: bookswithoutborders.setbookprice setlore: - description: Sets the lore of the item the player is holding. Insert the lore_line_separator character to force a new line ("~" by default) + description: | + Sets the lore of your held item. Insert the lore_line_separator character to force a new line ("~" by default). + The separator can be used several times to split into different lore lines. + Color and formatting codes (#000000, &a, &4, &n, &#ffffff) are supported. aliases: - bwblore usage: / permission: bookswithoutborders.setlore savepublicbook: - description: Same as savebook, but saves files in the public directory + description: | + Saves your held book to the public book collection. + If true is specified, a book of the same name by the same author will be overwritten by the new book. aliases: - bwbsavep usage: / [overwrite (true/false)] permission: bookswithoutborders.savepublic savebook: - description: Saves the book the player is holding to a text file in a private directory. If true is specified, a book of the same name by the same author will be overwritten by the new book + description: | + Saves your held book to your personal book collection. + If true is specified, a book of the same name by the same author will be overwritten by the new book. aliases: - bwbsave usage: / [overwrite (true/false)] permission: bookswithoutborders.save setbookauthor: - description: Sets the author of the book the player is holding + description: | + Sets the author of the book you are holding. + Note that certain configuration options will lock some actions to the author, so it is possible to lock your + access to your own books. Be careful. aliases: - bwbauthor usage: / permission: bookswithoutborders.setauthor settitle: - description: Sets the title of the book/item the player is holding + description: | + Sets the title of the book/item you are holding + Note that this behaves differently for signed books compared to other items. + For signed books, the book's actual name in the book's metadata is changed, and that name is limited to 32 characters. + For other items, the display name is set, which has no relevant limit. + Color and formatting codes (#000000, &a, &4, &n, &#ffffff) are supported. aliases: - bwbtitle usage: / permission: bookswithoutborders.settitle loadbook: - description: Creates a book from the specified file and gives it to the player. If no file is specified, a list of available files is returned. If true is specified, the book will be signed, if false it will be unsigned + description: | + Gives you the book with the given identifier stored in your private collection. + If used with no arguments, a list of all books will be shown. + If signed is set to true, the book will be signed, if false it will be unsigned. + The number of copies can be specified to get more than one book, but the signed argument can be used without + also specifying the number of copies. aliases: - bwbload usage: /<command> <file name or number> [# of copies] [signed (true/false)] permission: bookswithoutborders.load loadpublicbook: - description: Same as loadbook, but views files in the public directory + description: | + Gives you the book with the given identifier stored in the public collection. + If used with no arguments, a list of all books will be shown. + If signed is set to true, the book will be signed, if false it will be unsigned. + The number of copies can be specified to get more than one book, but the signed argument can be used without + also specifying the number of copies. aliases: - bwbloadp usage: /<command> <file name or number> [# of copies] [signed (true/false)] permission: bookswithoutborders.loadpublic reload: - description: Reloads BwB's configuration file + description: Reloads BwB's configuration file, translations the list of available books aliases: - bwbreload usage: /<command> permission: bookswithoutborders.reload setBookshelfData: - description: Sets custom data for a chiseled bookshelf used when peeking at the bookshelf + description: | + Sets custom data for a chiseled bookshelf used when peeking at the bookshelf + Specifying delete will remove any data set by this command earlier. Breaking the bookshelf will also remove data. + Specifying name will set the name of the bookshelf, displayed when using the peeking functionality. + Specifying the lore will set the lore of the bookshelf, displayed when using the peeking functionality. Use the + lore line separator (default "~") for specifying multiple lore lines. + Color and formatting codes (#000000, &a, &4, &n, &#ffffff) are supported. aliases: - bwbshelfdata usage: /<command> <delete/name/lore> <text> [more text] permission: bookswithoutborders.editbookshelf addBookTitlePage: - description: Adds a blank page, title page or chapter page depending on input and whether the book is signed + description: | + Adds a blank page, title page or chapter page depending on input and whether the book is signed + If no input is given, and a signed book is provided, a title page will be added to the beginning of the book. + If an index is given, and a signed book is provided, a title page will be added to the specified index. + If no input is given, and an unsigned book is provided, an error will be displayed. + If an index is given, but no text, and a signed book is provided, a blank page is added to the specified index. + If both an index and text is given, and a signed or unsigned book is provided, a custom chapter page depending on + the text will be added to the specified index.</p> aliases: - bwbtitlepage usage: /<command> [page index] [title~description] permission: bookswithoutborders.addtitlepage deleteBookPage: - description: Deletes one page from a book + description: Deletes the specified page from the held book aliases: - bwbdeletepage usage: /<command> <page> permission: bookswithoutborders.deletepage migrateBooks: - description: Migrates all txt books to yml, and fixes any incorrect filenames + description: | + Migrates all books. + All txt files will be converted to yml. + All books will be re-saved, fixing any incorrect file-names, a changed title-author separator and files using + underscores "_" instead of spaces. + Books encrypted using real encryption will have their decrypted contents show up in the file system. aliases: - bwbmigrate usage: /<command> diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml index 6798332..3a702ba 100644 --- a/src/main/resources/strings.yml +++ b/src/main/resources/strings.yml @@ -64,18 +64,19 @@ en: ERROR_SAVE_OVERWRITE_REQUIRED: "Use &e{command}&r to overwrite!" ERROR_SAVE_DUPLICATE_NAMED: "Book is already saved!" ERROR_SAVE_DUPLICATE_UNNAMED: "Maximum amount of {fileName} duplicates reached!" + ERROR_UNKNOWN_COMMAND: "Invalid command specified" NEUTRAL_COMMANDS_HEADER: | - &e[] denote optional parameters - <> denote required parameters - {} denote required permission - In some cases, commands with required parameters can be called with no parameters + &nBooks without Borders help page&r + &e[] = optional, <> = required (see each description for exceptions) {bookPrice}&eCommands: + {commandExplanation}&r {commands} NEUTRAL_COMMANDS_BOOK_PRICE_ECO: "\n&c[{price} is required to create a book]" NEUTRAL_COMMANDS_BOOK_PRICE_ITEM: "&c[{quantity} {type} (s) are required to create a book]\n" - NEUTRAL_COMMANDS_COMMAND: "\n \n&e{usage}: &a{description}" + NEUTRAL_COMMANDS_COMMAND: "\n&e{usage}{aliases}: &a{description}" NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED: "None" NEUTRAL_COMMANDS_COMMAND_PERMISSION: " &7{{permission}}" + NEUTRAL_COMMANDS_ALIASES: " &f(&b{aliases}&f)" NEUTRAL_UNKNOWN_AUTHOR: "Unknown" NEUTRAL_UNKNOWN_TITLE: "Untitled" NEUTRAL_TITLE_PAGE_TITLE_AUTHOR_FORMAT: "{title}{separator}By: {author}" diff --git a/src/test/java/net/knarcraft/bookswithoutborders/encryption/MagicTest.java b/src/test/java/net/knarcraft/bookswithoutborders/encryption/MagicTest.java new file mode 100644 index 0000000..51965e3 --- /dev/null +++ b/src/test/java/net/knarcraft/bookswithoutborders/encryption/MagicTest.java @@ -0,0 +1,23 @@ +package net.knarcraft.bookswithoutborders.encryption; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; + +public class MagicTest { + + @Test + public void magicEncryptionDecryptionTest() { + String plaintext = "Super secret text!"; + Magic magic = new Magic(); + String cipherText = magic.encryptText(plaintext); + assertNotNull(cipherText); + assertNotEquals(plaintext, cipherText); + String decrypted = magic.decryptText(cipherText); + assertNotNull(decrypted); + assertEquals(plaintext, decrypted); + } + +}