diff --git a/README.md b/README.md index ec3075a..fe6aef6 100644 --- a/README.md +++ b/README.md @@ -39,71 +39,64 @@ Books without Borders has got your back! An in-game description of available commands is available through the /bwb command. -- /bookswithoutborders - Displays information about commands (and permissions if the user has bookswithoutborders.admin) -- /copybook <# of copies> - Copies the book the player is holding -- /decryptbook \ - Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used - to encrypt the held book -- /deletebook \ - Deletes the specified file in the player's directory -- /deletepublicbook \ - Same as deletebook, but deletes files in the public directory -- encryptbook \ \[encryption style] - 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 "" -- /formatbook - Formats the held written book (converts color and formatting codes to the corresponding formatted text) -- /givebook \ \ \[# of copies (num)] \[signed (true/false)] - Gives the selected player - a book from your personal directory -- /givepublicbook \ \ \[# of copies (num)] \[signed (true/false)] - Same as givebook, - but uses books from the public directory -- /loadbook \ \[# of copies] \[signed (true/false)] - 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 -- /loadpublicbook \ \[# of copies] \[signed (true/false)] - Same as loadbook, but views files in - the public directory -- /reload - Reloads BwB's configuration file -- /savebook \[overwrite (true/false)] - 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 -- /savepublicbook \[overwrite (true/false)] - Same as savebook, but saves files in the public directory -- /setbookauthor \ - Sets the author of the book the player is holding -- /setbookgeneration - Sets the generation of the held book (ORIGINAL, COPY_OF_ORIGINAL, COPY_OF_COPY, - TATTERED) -- /setbookprice \ \ - Sets the per-book price to create a book via commands. If "Item", the item in - the player's hand in the amount of \ will be the price. If "Eco", a Vault based economy will be used for - price. If neither \ nor \ are specified, the current price to create books will be removed. -- /setlore \ - Sets the lore of the item the player is holding. Insert the lore_line_separator character to - force a new line ("~" by default) -- /settitle \ - Sets the title of the book/item the player is holding -- /unsignbook - Un-signs the book the player is holding +| Command | Arguments | Description | +| --- | --- | --- | +| /bookswithoutborders | None | Displays information about commands (and permissions if the user has bookswithoutborders.admin) | +| /copybook | \<# of copies> | Copies the book the player is holding | +| /decryptbook | \<key> | Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt the held book | +| /deletebook | \<file name or number> | Deletes the specified file in the player's directory | +| /deletepublicbook | \<file name or number> | Same as deletebook, but deletes files in the public directory | +| encryptbook | \<key> \[encryption style] | 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 "" | +| /formatbook | None | Formats the held written book (converts color and formatting codes to the corresponding formatted text) | +| /givebook | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | Gives the selected player a book from your personal directory | +| /givepublicbook | \<file name or number> \<playername> \[# of copies (num)] \[signed (true/false)] | Same as givebook, but uses books from the public directory | +| /loadbook | \<file name or number> \[# of copies] \[signed (true/false)] | 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 | +| /loadpublicbook | \<file name or number> \[# of copies] \[signed (true/false)] | Same as loadbook, but views files in the public directory | +| /reload | None | Reloads BwB's configuration file | +| /savebook | \[overwrite (true/false)] | 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 | +| /savepublicbook | \[overwrite (true/false)] | Same as savebook, but saves files in the public directory | +| /setbookauthor | \<author> | Sets the author of the book the player is holding | +| /setbookgeneration | \<generation> | Sets the generation of the held book (ORIGINAL, COPY_OF_ORIGINAL, COPY_OF_COPY, TATTERED) | +| /setbookprice | \<item/eco> \<quantity> | 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 \<Item/Eco> nor \<quantity> are specified, the current price to create books will be removed. | +| /setlore | \<new lore> | Sets the lore of the item the player is holding. Insert the lore_line_separator character to force a new line ("~" by default) | +| /settitle | \<title> | Sets the title of the book/item the player is holding | +| /unsignbook | None | Un-signs the book the player is holding | +| /clearbook | None | Removes all text from the held un-signed book | ### Permissions: -- bookswithoutborders.* - Grants all permissions -- bookswithoutborders.admin - Grants all permissions -- bookswithoutborders.use - Allows player to use commands to save/load/delete in their personal directory -- bookswithoutborders.alterbooks - Allows player to change books' data such as lore/title/author/generation/formatting - and unsigning books -- bookswithoutborders.reload - Allows player to reload this plugin -- bookswithoutborders.format - Allows a player to format a book -- bookswithoutborders.save - Allows a player to save books to their personal directory -- bookswithoutborders.load - Allows player to load books from their personal directory -- bookswithoutborders.delete - Allows player to delete books from their personal directory -- bookswithoutborders.unsign - Allows player to un-sign books -- bookswithoutborders.copy - Allows player to copy books -- bookswithoutborders.loadpublic - Allows player to load from the public directory -- bookswithoutborders.savepublic - Allows player to save to the public directory -- bookswithoutborders.encrypt - Allows player to encrypt books -- bookswithoutborders.groupencrypt - Allows player to use group-based encryption -- bookswithoutborders.decrypt - Allows player to decrypt books -- bookswithoutborders.decrypt.agroup - Allows player to decrypt books group-encrypted for group "agroup" -- bookswithoutborders.signs - Allows player to create signs that give/encrypt/decrypt books -- bookswithoutborders.give - Allows player to give another player one of their privately saved books -- bookswithoutborders.givepublic - Allows a player to give another player a book from the public directory -- bookswithoutborders.settitle - Allows player to set the title of the currently held book -- bookswithoutborders.setauthor - Allows player to set the author of the currently held book -- bookswithoutborders.setlore - Allows player to set the lore of the currently held item -- bookswithoutborders.bypassauthoronlycopy - Allows player to ignore Author_Only_Copy config setting -- bookswithoutborders.bypassauthoronlyunsign - Allows player to ignore Author_Only_Unsign config setting -- bookswithoutborders.bypassauthoronlysave - Allows player to ignore Author_Only_Save config setting -- bookswithoutborders.bypassbookprice - Allows player to ignore Price_to_create_book config setting -- bookswithoutborders.setbookprice - Allows player to set the cost of creating a book -- bookswithoutborders.setgeneration - Allows player to change the generation of a book (Original, Copy, Copy of Copy) +| Node | Description | +| --- | --- | +| bookswithoutborders.* | Grants all permissions | +| bookswithoutborders.admin | Grants all permissions | +| bookswithoutborders.use | Allows player to use commands to save/load/delete in their personal directory | +| bookswithoutborders.alterbooks | Allows player to change books' data such as lore/title/author/generation/formatting and un-signing books | +| bookswithoutborders.reload | Allows player to reload this plugin | +| bookswithoutborders.format | Allows a player to format a book | +| bookswithoutborders.save | Allows a player to save books to their personal directory | +| bookswithoutborders.load | Allows player to load books from their personal directory | +| bookswithoutborders.delete | Allows player to delete books from their personal directory | +| bookswithoutborders.unsign | Allows player to un-sign books | +| bookswithoutborders.copy | Allows player to copy books | +| bookswithoutborders.loadpublic | Allows player to load from the public directory | +| bookswithoutborders.savepublic | Allows player to save to the public directory | +| bookswithoutborders.encrypt | Allows player to encrypt books | +| bookswithoutborders.groupencrypt | Allows player to use group-based encryption | +| bookswithoutborders.decrypt | Allows player to decrypt books | +| bookswithoutborders.decrypt.agroup | Allows player to decrypt books group-encrypted for group "agroup" | +| bookswithoutborders.signs | Allows player to create signs that give/encrypt/decrypt books | +| bookswithoutborders.give | Allows player to give another player one of their privately saved books | +| bookswithoutborders.givepublic | Allows a player to give another player a book from the public directory | +| bookswithoutborders.settitle | Allows player to set the title of the currently held book | +| bookswithoutborders.setauthor | Allows player to set the author of the currently held book | +| bookswithoutborders.setlore | Allows player to set the lore of the currently held item | +| bookswithoutborders.bypassauthoronlycopy | Allows player to ignore Author_Only_Copy config setting | +| bookswithoutborders.bypassauthoronlyunsign | Allows player to ignore Author_Only_Unsign config setting | +| bookswithoutborders.bypassauthoronlysave | Allows player to ignore Author_Only_Save config setting | +| bookswithoutborders.bypassbookprice | Allows player to ignore Price_to_create_book config setting | +| bookswithoutborders.setbookprice | Allows player to set the cost of creating a book | +| bookswithoutborders.setgeneration | Allows player to change the generation of a book (Original, Copy, Copy of Copy) | +| bookswithoutborders.clear | Allows player to clear the contents of the held writable book | ### Signs @@ -127,19 +120,19 @@ The **_decrypt_** sign must have **\[Decrypt]** on its second line. The third li ### Configuration options: -- Save_Books_in_Yaml_Format - Whether to use YAML for saved books instead of just storing them as text -- Max_Number_of_Duplicates - The maximum number of duplicates of a saved book allowed -- Author_Separator - The separator used to separate the book title and the book author -- Lore_line_separator - The separator used to denote a new line in the book/item lore -- Books_for_new_players - A list of books given to new players the first time they join the server -- Message_for_new_players - An optional message displayed to new players the first time they join the server -- Price_to_create_book.Item_type - The item type used as currency for copying books. Use "Economy" to use money instead - of items -- Price_to_create_book.Required_quantity - The quantity of currency required to pay for each book produced -- Admin_Auto_Decrypt - Whether any admin can decrypt any book regardless of the group it was encrypted for -- Author_Only_Copy - Whether to only allow the author of a book to create copies -- Author_Only_Unsign - Whether to only allow the author of a book to unsign it -- Author_Only_Save - Whether to only allow saving a player's own books with /savebook -- Format_Book_After_Signing - Whether to automatically format every book when it's signed -- Change_Generation_On_Copy - Whether to display "COPY" or "COPY_OF_COPY" instead of "ORIGINAL" when a book is copied. - This also uses the vanilla behavior where a copy of a copy or tattered book cannot be copied further. \ No newline at end of file +| Option | Description | +| --- | --- | +| Save_Books_in_Yaml_Format | Whether to use YAML for saved books instead of just storing them as text | +| Max_Number_of_Duplicates | The maximum number of duplicates of a saved book allowed | +| Author_Separator | The separator used to separate the book title and the book author | +| Lore_line_separator | The separator used to denote a new line in the book/item lore | +| Books_for_new_players | A list of books given to new players the first time they join the server | +| Message_for_new_players | An optional message displayed to new players the first time they join the server | +| Price_to_create_book.Item_type | The item type used as currency for copying books. Use "Economy" to use money instead of items | +| Price_to_create_book.Required_quantity | The quantity of currency required to pay for each book produced | +| Admin_Auto_Decrypt | Whether any admin can decrypt any book regardless of the group it was encrypted for | +| Author_Only_Copy | Whether to only allow the author of a book to create copies | +| Author_Only_Unsign | Whether to only allow the author of a book to unsign it | +| Author_Only_Save | Whether to only allow saving a player's own books with /savebook | +| Format_Book_After_Signing | Whether to automatically format every book when it's signed | +| Change_Generation_On_Copy | Whether to display "COPY" or "COPY_OF_COPY" instead of "ORIGINAL" when a book is copied. This also uses the vanilla behavior where a copy of a copy or tattered book cannot be copied further. | \ No newline at end of file diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index 7664859..8dd8c05 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -1,6 +1,7 @@ package net.knarcraft.bookswithoutborders; import net.knarcraft.bookswithoutborders.command.CommandBooksWithoutBorders; +import net.knarcraft.bookswithoutborders.command.CommandClear; import net.knarcraft.bookswithoutborders.command.CommandCopy; import net.knarcraft.bookswithoutborders.command.CommandDecrypt; import net.knarcraft.bookswithoutborders.command.CommandDelete; @@ -173,6 +174,7 @@ public class BooksWithoutBorders extends JavaPlugin { registerCommand("reload", new CommandReload()); registerCommand("formatBook", new CommandFormat()); registerCommand("setBookGeneration", new CommandSetGeneration()); + registerCommand("clearBook", new CommandClear()); } /** diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandClear.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandClear.java new file mode 100644 index 0000000..52d6902 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandClear.java @@ -0,0 +1,48 @@ +package net.knarcraft.bookswithoutborders.command; + +import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.utility.InventoryHelper; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Command executor for the clear command + */ +public class CommandClear implements TabExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + if (!(sender instanceof Player player)) { + BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!"); + return false; + } + + InventoryHelper.notHoldingOneWritableBookCheck(player, "You must be holding a writable book to copy it!", + "You cannot copy two books at once!"); + + //Clear the player's held book + ItemStack heldBook = InventoryHelper.getHeldBook(player, true); + BookMeta bookMeta = (BookMeta) heldBook; + bookMeta.setPages(""); + heldBook.setItemMeta(bookMeta); + return true; + } + + @Nullable + @Override + public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + return new ArrayList<>(); + } + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/EconomyHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/EconomyHelper.java index 9ce8567..e31ab3d 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/EconomyHelper.java @@ -103,7 +103,7 @@ public final class EconomyHelper { private static boolean takeWritableBookPayment(Player player, int itemCost) { List<ItemStack> books = getPlayersEmptyBooks(player); if (countItems(books) < itemCost) { - BooksWithoutBorders.sendErrorMessage(player, itemCost + " " + Material.WRITABLE_BOOK + + BooksWithoutBorders.sendErrorMessage(player, itemCost + " empty " + Material.WRITABLE_BOOK + "(s) are required for this command!"); return false; } else { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java index fd2bc1e..d4f6ff0 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java @@ -51,6 +51,31 @@ public final class InventoryHelper { } } + /** + * Performs checks to validate that a player contains exactly one unwritten book + * + * @param player <p>The player to validate</p> + * @param noBookMessage <p>The message to display if the player is not holding a book</p> + * @param twoBooksMessage <p>The message to display if the player is holding one book in each hand</p> + * @return <p>False if the player is holding exactly one book</p> + */ + public static boolean notHoldingOneWritableBookCheck(Player player, String noBookMessage, String twoBooksMessage) { + BookHoldingState holdingState = getBookHoldingState(player); + + if (holdingState == BookHoldingState.NONE || holdingState == BookHoldingState.SIGNED_BOTH_HANDS || + holdingState == BookHoldingState.SIGNED_MAIN_HAND || holdingState == BookHoldingState.SIGNED_OFF_HAND) { + BooksWithoutBorders.sendErrorMessage(player, noBookMessage); + return true; + } + + if (holdingState == BookHoldingState.UNSIGNED_BOTH_HANDS) { + BooksWithoutBorders.sendErrorMessage(player, twoBooksMessage); + return true; + } + + return false; + } + /** * Performs checks to validate that a player contains exactly one written book * diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index b89ce96..7927997 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -45,6 +45,10 @@ commands: description: Copies the book the player is holding usage: /<command> <# of copies> permission: bookswithoutborders.copy + clearbook: + description: Removes all text from the book the player is holding + usage: /<command> + permission: bookswithoutborders.clear unsignbook: description: Un-signs the book the player is holding usage: /<command> @@ -130,6 +134,7 @@ permissions: bookswithoutborders.alterbooks: description: Allows player to change books' data such as lore/title/author/generation/formatting and unsigning books children: + bookswithoutborders.clear: true bookswithoutborders.unsign: true bookswithoutborders.settitle: true bookswithoutborders.setauthor: true @@ -145,9 +150,11 @@ permissions: bookswithoutborders.delete: description: Allows player to delete books from their personal directory bookswithoutborders.unsign: - description: Allows player to use unsign command + description: Allows player to use the unsign command bookswithoutborders.copy: - description: Allows player to use copy command + description: Allows player to use the copy command + bookswithoutborders.clear: + description: Allows player to use the clear command bookswithoutborders.loadpublic: description: Allows player to load from the public directory bookswithoutborders.savepublic: