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: / [# 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: / [# 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: /
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: / [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.
aliases:
- bwbtitlepage
usage: / [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: /
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: /
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);
+ }
+
+}