diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index 0b74ede..1cdcb52 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -13,6 +13,9 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import net.knarcraft.bookswithoutborders.command.CommandDecrypt; +import net.knarcraft.bookswithoutborders.command.CommandGive; +import net.knarcraft.bookswithoutborders.command.GiveTabCompleter; import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.bookswithoutborders.utility.FileHelper; @@ -24,6 +27,7 @@ import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -39,25 +43,27 @@ import org.bukkit.plugin.java.JavaPlugin; public class BooksWithoutBorders extends JavaPlugin { protected static int bookDuplicateLimit; //The separating string between the book title and the book author - protected static String titleAuthorSeparator; + public static String titleAuthorSeparator; protected static String loreSep; - protected static final String SLASH = System.getProperty("file.separator"); + public static final String SLASH = System.getProperty("file.separator"); protected static List firstBooks; protected static String welcomeMessage; protected static List existingPlayers; protected static Economy eco; protected static Material bookPriceType = null; protected static double bookPriceQuantity; - protected static boolean authorOnlyCopy, useYml, adminDecrypt; + protected static boolean authorOnlyCopy; + protected static boolean useYml; + public static boolean adminDecrypt; protected static ItemFactory iF; - protected static Map> loadList; - protected static BooksWithoutBorders bwb; + public static Map> loadList; + public static BooksWithoutBorders bwb; protected static BooksWithoutBordersListener bL; protected static ConsoleCommandSender consoleSender; - protected static String bookFolder; - protected static ChatColor errorColor = ChatColor.RED; + public static String bookFolder; + public static ChatColor errorColor = ChatColor.RED; protected static ChatColor successColor = ChatColor.GREEN; - protected static ChatColor commandColor = ChatColor.YELLOW; + public static ChatColor commandColor = ChatColor.YELLOW; @Override public void onEnable() { @@ -73,6 +79,13 @@ public class BooksWithoutBorders extends JavaPlugin { } else { this.getPluginLoader().disablePlugin(this); } + + PluginCommand giveCommand = this.getCommand("give"); + if (giveCommand != null) { + giveCommand.setExecutor(new CommandGive(this)); + giveCommand.setTabCompleter(new GiveTabCompleter(this)); + } + this.getCommand("decrypt").setExecutor(new CommandDecrypt(this)); } protected boolean init() { @@ -288,7 +301,7 @@ public class BooksWithoutBorders extends JavaPlugin { if ((command.getName().equalsIgnoreCase("BooksWithoutBorders") || command.getName().equalsIgnoreCase("bwb"))) { if (args.length == 0 && sender instanceof Player) { - //lists commands + //Lists all commands sender.sendMessage(commandColor + "Use: /bwb [Command]"); sender.sendMessage(commandColor + "[] denote parameters"); @@ -552,8 +565,8 @@ public class BooksWithoutBorders extends JavaPlugin { String pluginCommand = args[0].toLowerCase(); switch (pluginCommand) { - case "give": - return commandGive(player, args); + /*case "give": + return commandGive(player, args);*/ case "delete": return commandDelete(player, args); case "unsign": @@ -562,105 +575,8 @@ public class BooksWithoutBorders extends JavaPlugin { return commandCopy(player, args); case "encrypt": return commandEncrypt(player, args); - } - - if (args[0].equalsIgnoreCase("groupEncrypt")) { - if (!sender.hasPermission("bookswithoutborders.groupencrypt")) { - sendErrorMessage(sender, " You don't have permission to use this command!"); - return false; - } - - if (!(((Player) sender).getItemInHand().getType() == Material.WRITTEN_BOOK)) { - sendErrorMessage(sender, "You must be holding a written book to encrypt it!"); - return false; - } - - if (args.length < 3) { - sendErrorMessage(sender, "You must specify a key to encrypt a book!"); - return false; - } - if (args.length > 4) { - sendErrorMessage(sender, "Too many command options specified!"); - return false; - } - - if (!((BookMeta) ((Player) sender).getItemInHand().getItemMeta()).hasPages()) { - sendErrorMessage(sender, "Book must have contents to encrypt!"); - return false; - } - - if (((Player) sender).getItemInHand().getItemMeta().hasLore() - && ((Player) sender).getItemInHand().getItemMeta().getLore().get(0).contains(" encrypted]")) { - sendErrorMessage(sender, "Book is already group encrypted!"); - return false; - } - - ItemStack eBook; - - if (args.length == 4) { - eBook = encryptBook((Player) sender, true, args[2], EncryptionStyle.getFromString(args[3]), args[1]); - } else { - eBook = encryptBook((Player) sender, true, args[2], EncryptionStyle.SUBSTITUTION, args[1]); - } - - if (eBook != null) { - ((Player) sender).setItemInHand(eBook); - return true; - } else - return false; - } - - if (args[0].equalsIgnoreCase("decrypt")) { - if (!sender.hasPermission("bookswithoutborders.decrypt")) { - sendErrorMessage(sender, " You don't have permission to use this command!"); - return false; - } - - if (!(((Player) sender).getItemInHand().getType() == Material.WRITTEN_BOOK)) { - sendErrorMessage(sender, "You must be holding a written book to decrypt it!"); - return false; - } - - if (args.length == 1 && adminDecrypt && sender.hasPermission("bookswithoutborders.admin") && sender instanceof Player) { - String path = bookFolder + "Encrypted" + SLASH; - String fname = (!((BookMeta) ((Player) sender).getItemInHand().getItemMeta()).hasTitle()) ? "Untitled," + sender.getName() : - ((BookMeta) ((Player) sender).getItemInHand().getItemMeta()).getTitle() + titleAuthorSeparator + ((BookMeta) ((Player) sender).getItemInHand().getItemMeta()).getAuthor(); - File eDir = new File(path); - - String key = ""; - for (int i = 0; i < eDir.list().length; i++) { - if (eDir.list()[i].contains(fname)) { - key = eDir.list()[i].substring(eDir.list()[i].indexOf("[") + 1, eDir.list()[i].indexOf("]")); - break; - } - } - - if (!key.equalsIgnoreCase("")) { - ItemStack book = eLoad(((Player) sender), key, false); - if (book != null) { - ((Player) sender).setItemInHand(book); - sendSuccessMessage(sender, "Book auto-decrypted!"); - return true; - } else - return false; - } else { - sendErrorMessage(sender, "No matching encrypted book found!"); - return false; - } - } else if (args.length == 1) { - sendErrorMessage(sender, "No decryption password given!"); - return false; - } - - String key = EncryptionHelper.getNumberKeyFromStringKey(args[1]); - - ItemStack book = eLoad(((Player) sender), key, true); - if (book != null) { - ((Player) sender).setItemInHand(book); - sendSuccessMessage(sender, "Book decrypted!"); - return true; - } else - return false; + case "groupEncrypt": + return commandGroupEncrypt(player, args); } if (args[0].equalsIgnoreCase("setTitle")) { @@ -937,13 +853,83 @@ public class BooksWithoutBorders extends JavaPlugin { return false; } - protected boolean commandEncrypt(Player player, String[] args) { + /** + * Executes the group encrypt command + * + * @param player

The player which sent the command

+ * @param args

The arguments given

+ * @return

True if the command was executed successfully

+ */ + private boolean commandGroupEncrypt(Player player, String[] args) { + if (!player.hasPermission("bookswithoutborders.groupencrypt")) { + sendErrorMessage(player, " You don't have permission to use this command!"); + return false; + } + + if (InventoryHelper.notHoldingOneWrittenBookCheck(player, + "You must be holding a written book to encrypt it!", + "You cannot encrypt two books at once!")) { + return false; + } + + if (args.length < 3) { + sendErrorMessage(player, "You must specify a key to encrypt a book!"); + return false; + } + if (args.length > 4) { + sendErrorMessage(player, "Too many command options specified!"); + return false; + } + + ItemStack heldBook = InventoryHelper.getHeldBook(player); + BookMeta bookMetadata = (BookMeta) heldBook.getItemMeta(); + + if (bookMetadata == null) { + sendErrorMessage(player, "Your book seems to be corrupt!"); + return false; + } + + if (!bookMetadata.hasPages()) { + sendErrorMessage(player, "Book must have contents to encrypt!"); + return false; + } + + List lore = bookMetadata.getLore(); + if (bookMetadata.hasLore() && lore != null && lore.get(0).contains(" encrypted]")) { + sendErrorMessage(player, "Book is already group encrypted!"); + return false; + } + + ItemStack eBook; + + if (args.length == 4) { + eBook = encryptBook(player, true, args[2], EncryptionStyle.getFromString(args[3]), args[1]); + } else { + eBook = encryptBook(player, true, args[2], EncryptionStyle.SUBSTITUTION, args[1]); + } + + if (eBook != null) { + InventoryHelper.setHeldBook(player, eBook); + return true; + } else { + return false; + } + } + + /** + * Executes the encrypt command + * + * @param player

The player which sent the command

+ * @param args

The arguments given

+ * @return

True if the command was executed successfully

+ */ + private boolean commandEncrypt(Player player, String[] args) { if (!player.hasPermission("bookswithoutborders.encrypt")) { sendErrorMessage(player, " You don't have permission to use this command!"); return false; } - if (InventoryHelper.notHoldingOneBookCheck(player, "You must be holding a written book to encrypt it!", + if (InventoryHelper.notHoldingOneWrittenBookCheck(player, "You must be holding a written book to encrypt it!", "You cannot encrypt two books at once!")) { return false; } @@ -986,13 +972,13 @@ public class BooksWithoutBorders extends JavaPlugin { * @param args

The arguments given

* @return

True if the command was executed successfully

*/ - protected boolean commandCopy(Player player, String[] args) { + private boolean commandCopy(Player player, String[] args) { if (!player.hasPermission("bookswithoutborders.copy")) { sendErrorMessage(player, " You don't have permission to use this command!"); return false; } - if (InventoryHelper.notHoldingOneBookCheck(player, "You must be holding a written book to copy it!", + if (InventoryHelper.notHoldingOneWrittenBookCheck(player, "You must be holding a written book to copy it!", "You cannot copy two books at once!")) { return false; } @@ -1038,19 +1024,19 @@ public class BooksWithoutBorders extends JavaPlugin { * @param player

The player which executed the command

* @return

True if the command was executed successfully

*/ - protected boolean commandUnSign(Player player) { + private boolean commandUnSign(Player player) { if (!player.hasPermission("bookswithoutborders.unsign")) { sendErrorMessage(player, " You don't have permission to use this command!"); return false; } - if (InventoryHelper.notHoldingOneBookCheck(player, "You must be holding a written book to un-sign it!", + if (InventoryHelper.notHoldingOneWrittenBookCheck(player, "You must be holding a written book to un-sign it!", "You cannot un-sign two books at once. Please un-equip one of the books you're holding!")) { return false; } //Find which hand the player is using to hold the book. If holding one in each, throw an error - BookHoldingState holdingState = InventoryHelper.getHoldingBookState(player); + BookHoldingState holdingState = InventoryHelper.getHoldingSignedBookState(player); unSignHeldBook(player, holdingState == BookHoldingState.MAIN_HAND); return true; } @@ -1062,7 +1048,7 @@ public class BooksWithoutBorders extends JavaPlugin { * @param args

The arguments given

* @return

True if the command was executed successfully

*/ - protected boolean commandDelete(Player player, String[] args) { + private boolean commandDelete(Player player, String[] args) { if (!player.hasPermission("bookswithoutborders.delete")) { sendErrorMessage(player, " You don't have permission to use this command!"); return false; @@ -1099,7 +1085,7 @@ public class BooksWithoutBorders extends JavaPlugin { * @param args

The arguments given

* @return

True if the command was executed successfully

*/ - protected boolean commandGive(Player player, String[] args) { + private boolean commandGive(Player player, String[] args) { if (!player.hasPermission("bookswithoutborders.give")) { sendErrorMessage(player, " You don't have permission to use this command!"); return false; @@ -1162,7 +1148,7 @@ public class BooksWithoutBorders extends JavaPlugin { } } - protected String cleanString(String fname) { + public String cleanString(String fname) { //removes illegal characters if (fname.contains("/")) { fname = fname.replace("/", ""); @@ -1384,11 +1370,11 @@ public class BooksWithoutBorders extends JavaPlugin { } - protected ItemStack loadBook(CommandSender sender, String fname, String isSigned, String dir) { + public ItemStack loadBook(CommandSender sender, String fname, String isSigned, String dir) { return loadBook(sender, fname, isSigned, dir, 1); } - protected ItemStack loadBook(CommandSender sender, String fname, String isSigned, String dir, int numCopies) { + public ItemStack loadBook(CommandSender sender, String fname, String isSigned, String dir, int numCopies) { //checks if player is using list number to load for (int x = 0; x < fname.length(); x++) { if (!Character.isDigit(fname.charAt(x))) { @@ -1560,7 +1546,7 @@ public class BooksWithoutBorders extends JavaPlugin { return book; } - protected ItemStack eLoad(Player player, String key, boolean deleteEncryptedFile) { + public ItemStack eLoad(Player player, String key, boolean deleteEncryptedFile) { BookMeta book = (BookMeta) player.getItemInHand().getItemMeta(); String path = bookFolder + "Encrypted" + SLASH; @@ -1588,7 +1574,10 @@ public class BooksWithoutBorders extends JavaPlugin { if (deleteEncryptedFile) { try { - file.delete(); + if (!file.delete()) { + sendErrorMessage(consoleSender, "Book encryption data failed to delete upon decryption!"); + sendErrorMessage(consoleSender, "File location:" + file.getPath()); + } } catch (Exception e) { sendErrorMessage(consoleSender, "Book encryption data failed to delete upon decryption!"); sendErrorMessage(consoleSender, "File location:" + file.getPath()); @@ -1609,7 +1598,7 @@ public class BooksWithoutBorders extends JavaPlugin { * @param silent

Whether to just return the list without printing it

* @return

A list of available files

*/ - protected List listFiles(CommandSender sender, Boolean listPublic, boolean silent) { + public List listFiles(CommandSender sender, Boolean listPublic, boolean silent) { File file; if (listPublic) { file = new File(bookFolder); @@ -1682,7 +1671,7 @@ public class BooksWithoutBorders extends JavaPlugin { //Remove empty pages List newPages = cleanList(encryptedPages); - ItemStack encryptedBook = createEncryptedBook(book, newPages, mainHand, player, newMetadata); + ItemStack encryptedBook = createEncryptedBook(book, newPages, player, newMetadata); sendSuccessMessage(player, "Book encrypted!"); return encryptedBook; @@ -1693,12 +1682,11 @@ public class BooksWithoutBorders extends JavaPlugin { * * @param book

The book to encrypt

* @param newPages

The new encrypted pages

- * @param mainHand

Whether the book is held in the player's main hand or off hand

* @param player

The player encrypting the book

* @param newMetadata

The new metadata of the book

* @return

An encrypted version of the book

*/ - private ItemStack createEncryptedBook(BookMeta book, List newPages, boolean mainHand, Player player, BookMeta newMetadata) { + private ItemStack createEncryptedBook(BookMeta book, List newPages, Player player, BookMeta newMetadata) { //Create the encrypted book ItemStack encryptedBook = new ItemStack(Material.WRITTEN_BOOK); book.setPages(newPages); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java new file mode 100644 index 0000000..c2469a9 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandBooksWithoutBorders.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandBooksWithoutBorders implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java new file mode 100644 index 0000000..4541598 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandCopy.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandCopy implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java new file mode 100644 index 0000000..db3b7b7 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java @@ -0,0 +1,99 @@ +package net.knarcraft.bookswithoutborders.command; + +import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; +import net.knarcraft.bookswithoutborders.utility.InventoryHelper; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; + +import java.io.File; + +public class CommandDecrypt implements CommandExecutor { + + private final BooksWithoutBorders booksWithoutBorders; + + public CommandDecrypt(BooksWithoutBorders booksWithoutBorders) { + this.booksWithoutBorders = booksWithoutBorders; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!"); + return false; + } + + if (!InventoryHelper.notHoldingOneWrittenBookCheck(player, + "You must be holding a written book to decrypt it!", + "You cannot decrypt two books at once!")) { + return false; + } + + ItemStack heldItem = InventoryHelper.getHeldBook(player); + BookMeta bookMetadata = (BookMeta) heldItem.getItemMeta(); + if (bookMetadata == null) { + BooksWithoutBorders.sendErrorMessage(player, "Your book seems to be corrupt!"); + return false; + } + + //Warning: admin decrypt only allows decrypting files created by the same player. Not sure if intended + if (args.length == 0 && BooksWithoutBorders.adminDecrypt && player.hasPermission("bookswithoutborders.admin")) { + String path = BooksWithoutBorders.bookFolder + "Encrypted" + BooksWithoutBorders.SLASH; + String fileName; + if (bookMetadata.hasTitle()) { + fileName = bookMetadata.getTitle() + BooksWithoutBorders.titleAuthorSeparator + bookMetadata.getAuthor(); + } else { + fileName = "Untitled," + player.getName(); + } + + File encryptedDirectory = new File(path); + String[] encryptedFiles = encryptedDirectory.list(); + if (encryptedFiles == null) { + return false; + } + + //Get the "encryption key" from the filename + String key = ""; + for (String encryptedFile : encryptedFiles) { + if (encryptedFile.contains(fileName)) { + key = encryptedFile.substring(encryptedFile.indexOf("[") + 1, encryptedFile.indexOf("]")); + break; + } + } + + if (!key.equalsIgnoreCase("")) { + //Decrypt the book + ItemStack book = booksWithoutBorders.eLoad(player, key, false); + if (book != null) { + InventoryHelper.setHeldBook(player, book); + BooksWithoutBorders.sendSuccessMessage(player, "Book auto-decrypted!"); + return true; + } else { + return false; + } + } else { + BooksWithoutBorders.sendErrorMessage(player, "No matching encrypted book found!"); + return false; + } + } else if (args.length == 0) { + BooksWithoutBorders.sendErrorMessage(player, "No decryption password given!"); + return false; + } + + String key = EncryptionHelper.getNumberKeyFromStringKey(args[0]); + + //Decrypt the book + ItemStack book = booksWithoutBorders.eLoad(player, key, true); + if (book != null) { + InventoryHelper.setHeldBook(player, book); + BooksWithoutBorders.sendSuccessMessage(player, "Book decrypted!"); + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java new file mode 100644 index 0000000..ca09485 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandDelete implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDeletePublic.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDeletePublic.java new file mode 100644 index 0000000..c544a66 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDeletePublic.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandDeletePublic implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java new file mode 100644 index 0000000..1b8fb99 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandEncrypt implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGive.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGive.java new file mode 100644 index 0000000..d158156 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGive.java @@ -0,0 +1,100 @@ +package net.knarcraft.bookswithoutborders.command; + +import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class CommandGive implements CommandExecutor { + + private final BooksWithoutBorders booksWithoutBorders; + + public CommandGive(BooksWithoutBorders booksWithoutBorders) { + this.booksWithoutBorders = booksWithoutBorders; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!"); + return false; + } + + if (args.length == 1 || args.length > 4) { + BooksWithoutBorders.sendErrorMessage(player, "Incorrect number of arguments for this command!"); + return false; + } + + if (args.length == 0) { + BooksWithoutBorders.loadList.put(player.getName(), booksWithoutBorders.listFiles(player, false, false)); + return true; + } + + String bookIdentifier = args[0]; + String receivingPlayerName = args[1]; + + String copies = null; + String isSigned = null; + String copiesOrIsSigned = null; + if (args.length == 4) { + copies = args[2]; + isSigned = args[3]; + } else if (args.length == 3) { + copiesOrIsSigned = args[2]; + } + + + for (int x = 0; x < bookIdentifier.length(); x++) { + if (!Character.isDigit(bookIdentifier.charAt(x))) { + break; + } + if (x == bookIdentifier.length() - 1) { + BooksWithoutBorders.loadList.put(player.getName(), booksWithoutBorders.listFiles(player, false, true)); + } + } + + ItemStack newBook; + Player receivingPlayer = booksWithoutBorders.getServer().getPlayer(receivingPlayerName); + if (receivingPlayer == null) { + BooksWithoutBorders.sendErrorMessage(player, "Player not found!"); + return false; + } + + if (receivingPlayer.getInventory().firstEmpty() == -1) { + BooksWithoutBorders.sendErrorMessage(player, "Receiving player must have space in their inventory to receive books!"); + return false; + } + + //bwb give [bookname] [player] [numCopies] [issigned] + try { + + if (isSigned != null && copies != null) { + newBook = booksWithoutBorders.loadBook(player, booksWithoutBorders.cleanString(bookIdentifier), isSigned, "player", Integer.parseInt(copies)); + } else if (copiesOrIsSigned != null) { + if (copiesOrIsSigned.equalsIgnoreCase("true") || copiesOrIsSigned.equalsIgnoreCase("false")) { + newBook = booksWithoutBorders.loadBook(player, booksWithoutBorders.cleanString(bookIdentifier), copiesOrIsSigned, "player"); + } else { + newBook = booksWithoutBorders.loadBook(player, booksWithoutBorders.cleanString(bookIdentifier), "true", "player", Integer.parseInt(copiesOrIsSigned)); + } + } else { + newBook = booksWithoutBorders.loadBook(player, booksWithoutBorders.cleanString(bookIdentifier), "true", "player"); + } + + if (newBook != null) { + receivingPlayer.getInventory().addItem(newBook); + BooksWithoutBorders.sendSuccessMessage(player, "Book sent!"); + BooksWithoutBorders.sendSuccessMessage(receivingPlayer, "Book received!"); + return true; + } else { + BooksWithoutBorders.sendErrorMessage(player, "Book failed to load!"); + return false; + } + } catch (NumberFormatException e) { + BooksWithoutBorders.sendErrorMessage(player, "Invalid number of book copies specified!"); + return false; + } + } + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGivePublic.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGivePublic.java new file mode 100644 index 0000000..09cb6f8 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGivePublic.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandGivePublic implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGroupEncrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGroupEncrypt.java new file mode 100644 index 0000000..b0d37f6 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGroupEncrypt.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandGroupEncrypt implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoad.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoad.java new file mode 100644 index 0000000..6d01062 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoad.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandLoad implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoadPublic.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoadPublic.java new file mode 100644 index 0000000..6f754de --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoadPublic.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandLoadPublic implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java new file mode 100644 index 0000000..feea6ab --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandSave implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSavePublic.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSavePublic.java new file mode 100644 index 0000000..b2d6dfd --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSavePublic.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandSavePublic implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookPrice.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookPrice.java new file mode 100644 index 0000000..077fc9a --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSetBookPrice.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandSetBookPrice implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandUnsign.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandUnsign.java new file mode 100644 index 0000000..983a67e --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandUnsign.java @@ -0,0 +1,12 @@ +package net.knarcraft.bookswithoutborders.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandUnsign implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/GiveTabCompleter.java b/src/main/java/net/knarcraft/bookswithoutborders/command/GiveTabCompleter.java new file mode 100644 index 0000000..818ee4c --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/GiveTabCompleter.java @@ -0,0 +1,75 @@ +package net.knarcraft.bookswithoutborders.command; + +import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import org.bukkit.Server; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class GiveTabCompleter implements TabCompleter { + + BooksWithoutBorders booksWithoutBorders; + + public GiveTabCompleter(BooksWithoutBorders booksWithoutBorders) { + this.booksWithoutBorders = booksWithoutBorders; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + Server server = booksWithoutBorders.getServer(); + List playerNames = new ArrayList<>(); + for (Player player : server.getOnlinePlayers()) { + playerNames.add(player.getName()); + } + List booleans = new ArrayList<>(); + booleans.add("true"); + booleans.add("false"); + List numbers = new ArrayList<>(); + numbers.add("1"); + numbers.add("2"); + numbers.add("3"); + numbers.add("4"); + numbers.add("5"); + List boolAndNumbers = new ArrayList<>(); + boolAndNumbers.addAll(booleans); + boolAndNumbers.addAll(numbers); + + int argumentCount = args.length; + + if (argumentCount > 2) { + //Don't continue with autocompletion if the recipient is invalid + if (server.getPlayer(args[1]) == null) { + return null; + } + } + + BooksWithoutBorders.sendErrorMessage(sender, Arrays.toString(args)); + BooksWithoutBorders.sendErrorMessage(sender, String.valueOf(argumentCount)); + + if (argumentCount == 1) { + //Return list of books + return BooksWithoutBorders.loadList.put(sender.getName(), booksWithoutBorders.listFiles(sender, false, true)); + } else if (argumentCount == 2) { + //Return online players + return playerNames; + } else if (argumentCount == 3) { + //Number of copies + return boolAndNumbers; + } else if (argumentCount == 4) { + //Signed + try { + Integer.parseInt(args[2]); + return booleans; + } catch (NumberFormatException e) { + return null; + } + } + return null; + } + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java index 789cb50..8975b00 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java @@ -7,6 +7,9 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; +/** + * The inventory helper mainly helps with getting and setting books + */ public class InventoryHelper { /** @@ -29,7 +32,7 @@ public class InventoryHelper { public static ItemStack getHeldBook(Player player, boolean signedBook) { BookHoldingState holdingState; if (signedBook) { - holdingState = getHoldingBookState(player); + holdingState = getHoldingSignedBookState(player); } else { holdingState = getHoldingUnsignedBookState(player); } @@ -51,20 +54,49 @@ public class InventoryHelper { * @param newBook

The new book the player should hold

*/ public static void setHeldBook(Player player, ItemStack newBook) { - BookHoldingState holdingState = getHoldingBookState(player); + BookHoldingState holdingState = getHoldingSignedBookState(player); replaceHeldItem(player, newBook, holdingState == BookHoldingState.MAIN_HAND); } /** - * Performs checks to validate that a player contains exactly one book + * Performs checks to validate that a player contains exactly one written * * @param player

The player to validate

* @param noBookMessage

The message to display if the player is not holding a book

* @param twoBooksMessage

The message to display if the player is holding one book in each hand

+ * @return

False if the player is holding exactly one written book

+ */ + public static boolean notHoldingOneWrittenBookCheck(Player player, String noBookMessage, String twoBooksMessage) { + return notHoldingOneBookCheck(player, noBookMessage, twoBooksMessage, true); + } + + /** + * Performs checks to validate that a player contains exactly one writable + * + * @param player

The player to validate

+ * @param noBookMessage

The message to display if the player is not holding a book

+ * @param twoBooksMessage

The message to display if the player is holding one book in each hand

+ * @return

False if the player is holding exactly one writable book

+ */ + public static boolean notHoldingOneWritableBookCheck(Player player, String noBookMessage, String twoBooksMessage) { + return notHoldingOneBookCheck(player, noBookMessage, twoBooksMessage, false); + } + + /** + * Performs checks to validate that a player contains exactly one book + * @param player

The player to validate

+ * @param noBookMessage

The message to display if the player is not holding a book

+ * @param twoBooksMessage

The message to display if the player is holding one book in each hand

+ * @param written

Whether to require a written/signed book as opposed to a writable/unsigned book

* @return

False if the player is holding exactly one book

*/ - public static boolean notHoldingOneBookCheck(Player player, String noBookMessage, String twoBooksMessage) { - BookHoldingState holdingState = getHoldingBookState(player); + private static boolean notHoldingOneBookCheck(Player player, String noBookMessage, String twoBooksMessage, boolean written) { + BookHoldingState holdingState; + if (written) { + holdingState = getHoldingSignedBookState(player); + } else { + holdingState = getHoldingUnsignedBookState(player); + } if (holdingState == BookHoldingState.NONE) { BooksWithoutBorders.sendErrorMessage(player, noBookMessage); @@ -89,7 +121,7 @@ public class InventoryHelper { public static boolean isHoldingBook(Player player, boolean signedBook) { BookHoldingState holdingState; if (signedBook) { - holdingState = getHoldingBookState(player); + holdingState = getHoldingSignedBookState(player); } else { holdingState = getHoldingUnsignedBookState(player); } @@ -103,7 +135,7 @@ public class InventoryHelper { * @param player

The player possibly holding a book

* @return

The state of the player's book holding

*/ - public static BookHoldingState getHoldingBookState(Player player) { + public static BookHoldingState getHoldingSignedBookState(Player player) { return getHoldingItemState(player, Material.WRITTEN_BOOK); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 60929cb..0e35061 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,18 +3,24 @@ version: '${project.version}' main: net.knarcraft.bookswithoutborders.BooksWithoutBorders api-version: 1.17 prefix: Books Without Borders -authors: [ EpicKnarvik97, AkiraAkiba ] +authors: [EpicKnarvik97, AkiraAkiba] description: A continuation of the original Books Without Borders -softdepend: - - Vault +softdepend: [Vault] website: ???? dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders commands: - BooksWithoutBorders: + bookswithoutborders: description: Lists Books Without Borders's commands and uses. - aliases: - - bwb - usage: / - Used to see Books Without Borders commands + aliases: [bwb] + usage: / + give: + description: Gives the held book to another player + usage: / [file name or number] [# of copies (num)] [signed (true/false)] + permission: bookswithoutborders.give + decrypt: + description: Encrypts the held book + usage: / + permission: bookswithoutborders.decrypt permissions: bookswithoutborders.admin: description: Grants all permissions