diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BookHoldingState.java b/src/main/java/net/knarcraft/bookswithoutborders/BookHoldingState.java deleted file mode 100644 index 0bdc4aa..0000000 --- a/src/main/java/net/knarcraft/bookswithoutborders/BookHoldingState.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.knarcraft.bookswithoutborders; - -/** - * This enum represents the possible states for players holding books - */ -public enum BookHoldingState { - - /** - * The player is holding one book in each hand - */ - BOTH_HANDS, - /** - * The player is holding one book in their main hand - */ - MAIN_HAND, - /** - * The player is holding one book in their off hand - */ - OFF_HAND, - /** - * The player is not holding any books - */ - NONE - -} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index de8b7e4..fa2c349 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -22,6 +22,8 @@ import net.knarcraft.bookswithoutborders.command.CommandSetBookPrice; import net.knarcraft.bookswithoutborders.command.CommandSetLore; import net.knarcraft.bookswithoutborders.command.CommandUnSign; import net.knarcraft.bookswithoutborders.command.GiveTabCompleter; +import net.knarcraft.bookswithoutborders.state.EncryptionStyle; +import net.knarcraft.bookswithoutborders.state.ItemSlot; import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.bookswithoutborders.utility.FileHelper; @@ -61,7 +63,7 @@ public class BooksWithoutBorders extends JavaPlugin { public static boolean authorOnlyCopy; protected static boolean useYml; public static boolean adminDecrypt; - protected static ItemFactory iF; + protected static ItemFactory itemFactory; public static Map> loadList; public static BooksWithoutBorders bwb; protected static BooksWithoutBordersListener bL; @@ -104,7 +106,7 @@ public class BooksWithoutBorders extends JavaPlugin { protected boolean init() { //initializes Item Factory try { - iF = this.getServer().getItemFactory(); + itemFactory = this.getServer().getItemFactory(); } catch (java.lang.NoSuchMethodError nsmE) { sendErrorMessage(consoleSender, "Warning! [BooksWithoutBorders] failed to initialize!"); sendErrorMessage(consoleSender, "Please confirm the correct version of [BooksWithoutBorders] is"); @@ -274,11 +276,11 @@ public class BooksWithoutBorders extends JavaPlugin { } else { try { BufferedReader br = new BufferedReader(new FileReader(fTest)); - String nullcheck = br.readLine(); + String nullCheck = br.readLine(); - while (nullcheck != null) { - existingPlayers.add(nullcheck); - nullcheck = br.readLine(); + while (nullCheck != null) { + existingPlayers.add(nullCheck); + nullCheck = br.readLine(); } br.close(); } catch (Exception e) { @@ -351,11 +353,11 @@ public class BooksWithoutBorders extends JavaPlugin { sendSuccessMessage(sender, "but saves files in the public directory"); } if (sender.hasPermission("bookswithoutborders.give")) { - sender.sendMessage("\n" + commandColor + "Give [file name or number] [playername] [# of copies] [true/false]:"); + sender.sendMessage("\n" + commandColor + "Give [file name or number] [player name] [# of copies] [true/false]:"); sendSuccessMessage(sender, "Gives the selected player a book from your personal directory"); } if (sender.hasPermission("bookswithoutborders.givepublic")) { - sender.sendMessage(commandColor + "givePublic [file name or number] [playername] [# of copies] [true/false]:"); + sender.sendMessage(commandColor + "givePublic [file name or number] [player name] [# of copies] [true/false]:"); sendSuccessMessage(sender, "Same as give, but uses books from the public directory"); } if (sender.hasPermission("bookswithoutborders.delete")) { @@ -370,7 +372,7 @@ public class BooksWithoutBorders extends JavaPlugin { } if (sender.hasPermission("bookswithoutborders.unsign")) - sender.sendMessage("\n" + commandColor + "Unsign: " + successColor + "Unsigns the book the player is holding"); + sender.sendMessage("\n" + commandColor + "Unsign: " + successColor + "Un-signs the book the player is holding"); if (sender.hasPermission("bookswithoutborders.copy")) sender.sendMessage("\n" + commandColor + "Copy [number of copies]: " + successColor + "Copies the book the player is holding"); @@ -399,7 +401,7 @@ public class BooksWithoutBorders extends JavaPlugin { } if (sender.hasPermission("bookswithoutborders.setbookprice")) sender.sendMessage("\n" + commandColor + "setBookPrice [Item/Eco] [quantity]: " + successColor + "Sets the per-book-price to create a book via commands." + - "\nIf [Item], the item in the player's hand in the amount of [quanity] will be the price.\nIf [Eco], a Vault based economy will be used for price." + + "\nIf [Item], the item in the player's hand in the amount of [quantity] will be the price.\nIf [Eco], a Vault based economy will be used for price." + "\nIf neither [Item/Eco] or [quantity] are specified the current price to create books will be removed."); return true; } @@ -410,7 +412,7 @@ public class BooksWithoutBorders extends JavaPlugin { sender.sendMessage(commandColor + "[] denote parameters"); sender.sendMessage(commandColor + "Commands:"); sender.sendMessage(commandColor + "\nReload:" + successColor + " Reloads BwB's config file"); - sender.sendMessage(commandColor + "givePublic [file name or number] [playername] [true/false]: " + successColor); + sender.sendMessage(commandColor + "givePublic [file name or number] [player name] [true/false]: " + successColor); sendSuccessMessage(sender, "Gives the selected player a book from the public directory"); sendSuccessMessage(sender, "If no file is specified, a list of available files is returned"); sender.sendMessage(commandColor + "deletePublic [file name or number]: " + successColor + "Deletes the specified"); @@ -446,12 +448,18 @@ public class BooksWithoutBorders extends JavaPlugin { return false; } - if (InventoryHelper.isHoldingBook(player, true) || - InventoryHelper.isHoldingBook(player, false)) { - if (args.length == 2) { - saveBook(player, args[1], true); + ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, false, false); + if (holdingSlot != ItemSlot.NONE) { + ItemStack holdingItem; + if (holdingSlot == ItemSlot.MAIN_HAND) { + holdingItem = player.getInventory().getItemInMainHand(); } else { - saveBook(player, "false", true); + holdingItem = player.getInventory().getItemInOffHand(); + } + if (args.length == 2) { + saveBook(player, holdingItem, args[1], true); + } else { + saveBook(player, holdingItem, "false", true); } return true; } else { @@ -466,11 +474,18 @@ public class BooksWithoutBorders extends JavaPlugin { return false; } - if (((Player) sender).getItemInHand().getType() == Material.WRITTEN_BOOK || ((Player) sender).getItemInHand().getType() == Material.WRITABLE_BOOK) { - if (args.length == 2) { - saveBook((Player) sender, args[1], false); + ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, false, false); + if (holdingSlot != ItemSlot.NONE) { + ItemStack holdingItem; + if (holdingSlot == ItemSlot.MAIN_HAND) { + holdingItem = player.getInventory().getItemInMainHand(); } else { - saveBook((Player) sender, "false", false); + holdingItem = player.getInventory().getItemInOffHand(); + } + if (args.length == 2) { + saveBook(player, holdingItem, args[1], false); + } else { + saveBook(player, holdingItem, "false", false); } return true; } else { @@ -686,7 +701,7 @@ public class BooksWithoutBorders extends JavaPlugin { sendErrorMessage(sender, "Receiving player must have space in their inventory to receive books!"); return false; } - //bwb give [bookname] [player] [numCopies] [issigned] + //bwb give [book name] [player] [numCopies] [is signed] try { if (args.length == 5) newBook = loadBook(sender, cleanString(args[1]), args[4], "public", Integer.parseInt(args[3])); @@ -749,48 +764,48 @@ public class BooksWithoutBorders extends JavaPlugin { return false; } - public String cleanString(String fname) { + public String cleanString(String fileName) { //removes illegal characters - if (fname.contains("/")) { - fname = fname.replace("/", ""); + if (fileName.contains("/")) { + fileName = fileName.replace("/", ""); } - if (fname.contains("\\")) { - fname = fname.replace("\\", ""); + if (fileName.contains("\\")) { + fileName = fileName.replace("\\", ""); } - if (fname.contains("*")) { - fname = fname.replace("*", ""); + if (fileName.contains("*")) { + fileName = fileName.replace("*", ""); } - if (fname.contains(":")) { - fname = fname.replace(":", ""); + if (fileName.contains(":")) { + fileName = fileName.replace(":", ""); } - if (fname.contains("|")) { - fname = fname.replace("|", ""); + if (fileName.contains("|")) { + fileName = fileName.replace("|", ""); } - if (fname.contains("<")) { - fname = fname.replace("<", ""); + if (fileName.contains("<")) { + fileName = fileName.replace("<", ""); } - if (fname.contains(">")) { - fname = fname.replace(">", ""); + if (fileName.contains(">")) { + fileName = fileName.replace(">", ""); } - if (fname.contains("?")) { - fname = fname.replace("?", ""); + if (fileName.contains("?")) { + fileName = fileName.replace("?", ""); } - if (fname.contains("\"")) { - fname = fname.replace("\"", ""); + if (fileName.contains("\"")) { + fileName = fileName.replace("\"", ""); } - return fname; + return fileName; } - protected String fixName(String fname, Boolean isLoad) { + protected String fixName(String fileName, Boolean isLoad) { if (isLoad) { - fname = fname.replace("_", " "); + fileName = fileName.replace("_", " "); } else { - fname = fname.replace(" ", "_"); + fileName = fileName.replace(" ", "_"); } - return fname; + return fileName; } - protected void bookToYml(String path, String fname, BookMeta book) throws IOException { + protected void bookToYml(String path, String fileName, BookMeta book) throws IOException { FileConfiguration bookYml = YamlConfiguration.loadConfiguration(new File(path, "blank")); if (book.hasTitle()) @@ -802,7 +817,7 @@ public class BooksWithoutBorders extends JavaPlugin { if (book.hasLore()) bookYml.set("Lore", book.getLore()); - bookYml.save(path + fname + ".yml"); + bookYml.save(path + fileName + ".yml"); } protected BookMeta bookFromYml(File file, BookMeta bDat) { @@ -825,8 +840,8 @@ public class BooksWithoutBorders extends JavaPlugin { return bDat; } - protected void bookToTXT(String path, String fname, BookMeta book) throws IOException { - FileWriter fw = new FileWriter(path + fname + ".txt"); + protected void bookToTXT(String path, String fileName, BookMeta book) throws IOException { + FileWriter fw = new FileWriter(path + fileName + ".txt"); PrintWriter pw = new PrintWriter(fw); List pages = book.getPages(); @@ -837,21 +852,21 @@ public class BooksWithoutBorders extends JavaPlugin { pw.close(); } - protected BookMeta bookFromTXT(String fname, File file, BookMeta bDat) { + protected BookMeta bookFromTXT(String fileName, File file, BookMeta bDat) { String author; String title; - if (fname.contains(titleAuthorSeparator)) { - author = fname.substring(fname.indexOf(titleAuthorSeparator) + 1, fname.length() - 4); - title = fname.substring(0, fname.indexOf(titleAuthorSeparator)); + if (fileName.contains(titleAuthorSeparator)) { + author = fileName.substring(fileName.indexOf(titleAuthorSeparator) + 1, fileName.length() - 4); + title = fileName.substring(0, fileName.indexOf(titleAuthorSeparator)); } else { author = "Unknown"; - title = fname.substring(0, fname.length() - 4); + title = fileName.substring(0, fileName.length() - 4); } title = fixName(title, true); List rawPages = new ArrayList<>(); - String nullcheck; + String nullCheck; try { FileReader fileReader = new FileReader(file); @@ -867,10 +882,10 @@ public class BooksWithoutBorders extends JavaPlugin { //If a book is being loaded its content need not be adjusted if (rawPages.get(0).equalsIgnoreCase("[Book]")) { rawPages.remove(0); - nullcheck = bufferedReader.readLine(); - while (nullcheck != null) { - rawPages.add(nullcheck); - nullcheck = bufferedReader.readLine(); + nullCheck = bufferedReader.readLine(); + while (nullCheck != null) { + rawPages.add(nullCheck); + nullCheck = bufferedReader.readLine(); } } else { //Adjusts content to page length @@ -894,46 +909,54 @@ public class BooksWithoutBorders extends JavaPlugin { return bDat; } - protected void saveBook(Player player, String dupe, Boolean pub) { + protected void saveBook(Player player, ItemStack heldBook, String dupe, Boolean saveToPublicFolder) { //Notice: Could be both a signed or unsigned book - BookMeta book = (BookMeta) player.getItemInHand().getItemMeta(); + BookMeta book = (BookMeta) heldBook.getItemMeta(); + if (book == null) { + sendErrorMessage(player, "Unable to get metadata for your held book!"); + return; + } + String path; - if (pub) { + if (saveToPublicFolder) { path = bookFolder; } else { path = bookFolder + cleanString(player.getName()) + SLASH; } - String fname; + String fileName; if (!book.hasTitle()) { - fname = "Untitled," + player.getName(); + fileName = "Untitled," + player.getName(); } else { - fname = book.getTitle() + titleAuthorSeparator + book.getAuthor(); + fileName = book.getTitle() + titleAuthorSeparator + book.getAuthor(); } - fname = cleanString(fname); - fname = fixName(fname, false); + fileName = cleanString(fileName); + fileName = fixName(fileName, false); int dupes = 0; //checks to see if the file name is already taken and adjusts it if so File file = new File(path); //if this is a private save, make sure the dir exists - if (!file.exists()) { - if (!file.mkdir()) { + if (!file.exists() && !file.mkdir()) { sendErrorMessage(player, "Saving Failed! If this continues to happen, consult server admin!"); return; - } } - if (file.listFiles().length > 0) { - File[] fl = file.listFiles(); - for (int x = 0; x < fl.length; x++) { + File[] foundFiles = file.listFiles(); + if (foundFiles == null) { + sendErrorMessage(player, "Saving Failed! If this continues to happen, consult server admin!"); + return; + } + + if (foundFiles.length > 0) { + for (int x = 0; x < foundFiles.length; x++) { if (dupes == 0) { - if (fl[x].getName().equalsIgnoreCase(fname)) { + if (foundFiles[x].getName().equalsIgnoreCase(fileName)) { dupes++; x = -1; } } else { - if (fl[x].getName().equalsIgnoreCase("(" + dupes + ")" + fname)) { + if (foundFiles[x].getName().equalsIgnoreCase("(" + dupes + ")" + fileName)) { dupes++; x = -1; } @@ -941,132 +964,93 @@ public class BooksWithoutBorders extends JavaPlugin { } } if (dupes > 0) { - if (!fname.contains("Untitled") && dupe.equalsIgnoreCase("false")) { + if (!fileName.contains("Untitled") && dupe.equalsIgnoreCase("false")) { sendErrorMessage(player, "Book is already saved!"); sendErrorMessage(player, "Use " + commandColor + "/bwb Save true " + errorColor + "to overwrite!"); return; } if (dupes > bookDuplicateLimit) { - sendErrorMessage(player, "Maximum amount of " + fname + " duplicates reached!"); + sendErrorMessage(player, "Maximum amount of " + fileName + " duplicates reached!"); sendErrorMessage(player, "Use " + commandColor + "/bwb Save true " + errorColor + "to overwrite!"); return; } - if (fname.contains("Untitled") && dupe.equalsIgnoreCase("false")) { - fname = "(" + dupes + ")" + fname; + if (fileName.contains("Untitled") && dupe.equalsIgnoreCase("false")) { + fileName = "(" + dupes + ")" + fileName; } } try { if (useYml) - bookToYml(path, fname, book); + bookToYml(path, fileName, book); else - bookToTXT(path, fname, book); + bookToTXT(path, fileName, book); - sendSuccessMessage(player, "Book Saved as \"" + fname + "\""); + sendSuccessMessage(player, "Book Saved as \"" + fileName + "\""); } catch (IOException e) { e.printStackTrace(); } } - public ItemStack loadBook(CommandSender sender, String fname, String isSigned, String dir) { - return loadBook(sender, fname, isSigned, dir, 1); + public ItemStack loadBook(CommandSender sender, String fileName, String isSigned, String dir) { + return loadBook(sender, fileName, isSigned, dir, 1); } - public ItemStack loadBook(CommandSender sender, String fname, String isSigned, String dir, int numCopies) { + public ItemStack loadBook(CommandSender sender, String fileName, 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))) { + for (int x = 0; x < fileName.length(); x++) { + if (!Character.isDigit(fileName.charAt(x))) { break; } - if (x == fname.length() - 1 && Character.isDigit(fname.charAt(x)) && loadList.containsKey(sender.getName())) { - if (Integer.parseInt(fname) <= loadList.get(sender.getName()).size()) { - fname = loadList.get(sender.getName()).get(Integer.parseInt(fname) - 1); + if (x == fileName.length() - 1 && Character.isDigit(fileName.charAt(x)) && loadList.containsKey(sender.getName())) { + if (Integer.parseInt(fileName) <= loadList.get(sender.getName()).size()) { + fileName = loadList.get(sender.getName()).get(Integer.parseInt(fileName) - 1); } } } File file; - NameCheck: - { - //Extension is already present - if (fname.lastIndexOf(".") != -1) { - if (fname.substring(fname.lastIndexOf(".")).equals(".yml") || fname.substring(fname.lastIndexOf(".")).equals(".txt")) { - if (dir.equalsIgnoreCase("public")) - file = new File(bookFolder + fname); - - else if (dir.equalsIgnoreCase("player")) - file = new File(bookFolder + cleanString(sender.getName()) + SLASH + fname); - - else if (!dir.equalsIgnoreCase("")) - file = new File(bookFolder + "Encrypted" + SLASH + dir + SLASH + fname); - - else - file = null; - - if (!file.isFile()) { - sendErrorMessage(sender, "Incorrect file name!"); - return null; - } - break NameCheck; - } - } - //No extension present - if (dir.equalsIgnoreCase("public")) - file = new File(bookFolder + fname + ".yml"); - - else if (dir.equalsIgnoreCase("player")) - file = new File(bookFolder + cleanString(sender.getName()) + SLASH + fname + ".yml"); - - else if (!dir.equalsIgnoreCase("")) - file = new File(bookFolder + "Encrypted" + SLASH + dir + SLASH + fname + ".yml"); - - else - file = null; - - if (!file.isFile()) { - if (dir.equalsIgnoreCase("public")) - file = new File(bookFolder + fname + ".txt"); - - else if (dir.equalsIgnoreCase("player")) - file = new File(bookFolder + cleanString(sender.getName()) + SLASH + fname + ".txt"); - - else if (!dir.equalsIgnoreCase("")) - file = new File(bookFolder + "Encrypted" + SLASH + dir + SLASH + fname + ".txt"); - - else - file = null; - - if (!file.isFile()) { - sendErrorMessage(sender, "Incorrect file name!"); - return null; - } - } + if (dir.equalsIgnoreCase("public")) { + file = FileHelper.getBookFile(bookFolder + fileName); + } else if (dir.equalsIgnoreCase("player")) { + file = FileHelper.getBookFile(bookFolder + cleanString(sender.getName()) + SLASH + fileName); + } else if (dir.trim().isEmpty()) { + file = FileHelper.getBookFile(bookFolder + "Encrypted" + SLASH + dir + SLASH + fileName); + } else { + file = null; + } + if (file == null || !file.isFile()) { + sendErrorMessage(sender, "Incorrect file name!"); + return null; } ItemStack book; - BookMeta bDat = (BookMeta) iF.getItemMeta(Material.WRITTEN_BOOK); + BookMeta bookMetadata = (BookMeta) itemFactory.getItemMeta(Material.WRITTEN_BOOK); if (isSigned.equalsIgnoreCase("true")) { book = new ItemStack(Material.WRITTEN_BOOK); } else { book = new ItemStack(Material.WRITABLE_BOOK); } - bookFromYml(file, bDat); - if (bDat == null) { + bookFromYml(file, bookMetadata); + if (bookMetadata == null) { sendErrorMessage(sender, "File was blank!!"); return null; } - if (!dir.equalsIgnoreCase("public") && !dir.equalsIgnoreCase("player") && !dir.equalsIgnoreCase("") && bDat.hasLore()) { - List newLore = new ArrayList<>(bDat.getLore()); - newLore.remove(0); - bDat.setLore(newLore); + if (!dir.equalsIgnoreCase("public") && !dir.equalsIgnoreCase("player") && + !dir.equalsIgnoreCase("") && bookMetadata.hasLore()) { + List oldLore = bookMetadata.getLore(); + if (oldLore != null) { + List newLore = new ArrayList<>(oldLore); + newLore.remove(0); + bookMetadata.setLore(newLore); + } } - book.setItemMeta(bDat); + book.setItemMeta(bookMetadata); book.setAmount(numCopies); if (booksHavePrice() && !sender.hasPermission("bookswithoutborders.bypassbookprice") && @@ -1081,21 +1065,21 @@ public class BooksWithoutBorders extends JavaPlugin { protected Boolean eSave(Player player, BookMeta book, String key) { String path = bookFolder + "Encrypted" + SLASH; - String fname = (!book.hasTitle()) ? "Untitled," + player.getName() : + String fileName = (!book.hasTitle()) ? "Untitled," + player.getName() : book.getTitle() + titleAuthorSeparator + book.getAuthor(); - fname = "[" + key + "]" + fname; - fname = cleanString(fname); - fname = fixName(fname, false); + fileName = "[" + key + "]" + fileName; + fileName = cleanString(fileName); + fileName = fixName(fileName, false); //cancels saving if file is already encrypted - File file = (useYml) ? new File(path + fname + ".yml") : new File(path + fname + ".txt"); + File file = (useYml) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt"); if (file.isFile()) { return true; } try { - bookToYml(path, fname, book); + bookToYml(path, fileName, book); } catch (IOException e) { e.printStackTrace(); sendErrorMessage(player, "Encryption failed!"); @@ -1104,7 +1088,7 @@ public class BooksWithoutBorders extends JavaPlugin { return true; } - protected BookMeta groupESave(Player player, BookMeta bookMetadata, String key, String groupName) { + protected BookMeta groupESave(Player player, BookMeta bookMetadata, String groupName) { String path = bookFolder + "Encrypted" + SLASH + cleanString(groupName) + SLASH; File dirTest = new File(path); //Creates group dir @@ -1120,24 +1104,27 @@ public class BooksWithoutBorders extends JavaPlugin { } } //Creates file - String fname = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : + String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() + titleAuthorSeparator + bookMetadata.getAuthor(); - fname = cleanString(fname); - fname = fixName(fname, false); + fileName = cleanString(fileName); + fileName = fixName(fileName, false); List nuLore = new ArrayList<>(); nuLore.add(ChatColor.GRAY + "[" + groupName + " encrypted]"); if (bookMetadata.hasLore()) { - nuLore.addAll(bookMetadata.getLore()); + List oldLore = bookMetadata.getLore(); + if (oldLore != null) { + nuLore.addAll(oldLore); + } } bookMetadata.setLore(nuLore); //Save file - File file = (useYml) ? new File(path + fname + ".yml") : new File(path + fname + ".txt"); + File file = (useYml) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt"); if (!file.isFile()) { try { - bookToYml(path, fname, bookMetadata); + bookToYml(path, fileName, bookMetadata); } catch (IOException e) { e.printStackTrace(); sendErrorMessage(player, "Group encrypted failed!"); @@ -1157,14 +1144,14 @@ public class BooksWithoutBorders extends JavaPlugin { return null; } - String fname = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() + titleAuthorSeparator + bookMetadata.getAuthor(); - fname = "[" + key + "]" + fname; - fname = cleanString(fname); - fname = fixName(fname, false); + String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() + titleAuthorSeparator + bookMetadata.getAuthor(); + fileName = "[" + key + "]" + fileName; + fileName = cleanString(fileName); + fileName = fixName(fileName, false); - File file = new File(path + fname + ".yml"); + File file = new File(path + fileName + ".yml"); if (!file.isFile()) { - file = new File(path + fname + ".txt"); + file = new File(path + fileName + ".txt"); if (!file.isFile()) { sendErrorMessage(player, "Incorrect decryption key!"); @@ -1322,7 +1309,7 @@ public class BooksWithoutBorders extends JavaPlugin { if (groupName.trim().isEmpty()) { wasSaved = eSave(player, book, integerKey); } else { - newMetadata = groupESave(player, book, integerKey, groupName); + newMetadata = groupESave(player, book, groupName); wasSaved = newMetadata != null; } if (wasSaved) { @@ -1397,7 +1384,7 @@ public class BooksWithoutBorders extends JavaPlugin { } /** - * Unsigns the player's currently held book + * Un-signs the player's currently held book * * @param player

The player holding the book

* @param mainHand

Whether the player is holding the book in its main hand or its off hand

diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java index 1a6b6c1..262d53a 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java @@ -4,6 +4,7 @@ import java.io.File; import java.util.List; import java.util.Objects; +import net.knarcraft.bookswithoutborders.state.EncryptionStyle; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.bookswithoutborders.utility.FileHelper; import org.bukkit.ChatColor; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java index db3b7b7..49c9c9d 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java @@ -12,6 +12,9 @@ import org.bukkit.inventory.meta.BookMeta; import java.io.File; +/** + * Command executor for the decrypt command + */ public class CommandDecrypt implements CommandExecutor { private final BooksWithoutBorders booksWithoutBorders; @@ -27,7 +30,7 @@ public class CommandDecrypt implements CommandExecutor { return false; } - if (!InventoryHelper.notHoldingOneWrittenBookCheck(player, + if (InventoryHelper.notHoldingOneWrittenBookCheck(player, "You must be holding a written book to decrypt it!", "You cannot decrypt two books at once!")) { return false; @@ -53,6 +56,7 @@ public class CommandDecrypt implements CommandExecutor { File encryptedDirectory = new File(path); String[] encryptedFiles = encryptedDirectory.list(); if (encryptedFiles == null) { + BooksWithoutBorders.sendErrorMessage(player, "Could not find any encrypted files!"); return false; } @@ -69,7 +73,7 @@ public class CommandDecrypt implements CommandExecutor { //Decrypt the book ItemStack book = booksWithoutBorders.eLoad(player, key, false); if (book != null) { - InventoryHelper.setHeldBook(player, book); + InventoryHelper.setHeldWrittenBook(player, book); BooksWithoutBorders.sendSuccessMessage(player, "Book auto-decrypted!"); return true; } else { @@ -89,10 +93,11 @@ public class CommandDecrypt implements CommandExecutor { //Decrypt the book ItemStack book = booksWithoutBorders.eLoad(player, key, true); if (book != null) { - InventoryHelper.setHeldBook(player, book); + InventoryHelper.setHeldWrittenBook(player, book); BooksWithoutBorders.sendSuccessMessage(player, "Book decrypted!"); return true; } else { + BooksWithoutBorders.sendErrorMessage(player, "Failed to decrypt book!"); return false; } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java index 4901483..f6a72ea 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandEncrypt.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.EncryptionStyle; +import net.knarcraft.bookswithoutborders.state.EncryptionStyle; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -60,7 +60,7 @@ public class CommandEncrypt implements CommandExecutor { } if (encryptedBook != null) { - InventoryHelper.setHeldBook(player, encryptedBook); + InventoryHelper.setHeldWrittenBook(player, encryptedBook); return true; } else { return false; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGroupEncrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGroupEncrypt.java index 0774424..bf9ebc5 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGroupEncrypt.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGroupEncrypt.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.EncryptionStyle; +import net.knarcraft.bookswithoutborders.state.EncryptionStyle; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -73,7 +73,7 @@ public class CommandGroupEncrypt implements CommandExecutor { } if (eBook != null) { - InventoryHelper.setHeldBook(player, eBook); + InventoryHelper.setHeldWrittenBook(player, eBook); return true; } else { return false; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandUnSign.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandUnSign.java index d77b3ee..766daf2 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandUnSign.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandUnSign.java @@ -1,13 +1,16 @@ package net.knarcraft.bookswithoutborders.command; -import net.knarcraft.bookswithoutborders.BookHoldingState; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.state.ItemSlot; 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; +/** + * Command executor for the un-sign command + */ public class CommandUnSign implements CommandExecutor { private final BooksWithoutBorders booksWithoutBorders; @@ -29,8 +32,8 @@ public class CommandUnSign implements CommandExecutor { } //Find which hand the player is using to hold the book. If holding one in each, throw an error - BookHoldingState holdingState = InventoryHelper.getHoldingSignedBookState(player); - booksWithoutBorders.unSignHeldBook(player, holdingState == BookHoldingState.MAIN_HAND); + ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, true, true); + booksWithoutBorders.unSignHeldBook(player, holdingSlot == ItemSlot.MAIN_HAND); return true; } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/state/BookHoldingState.java b/src/main/java/net/knarcraft/bookswithoutborders/state/BookHoldingState.java new file mode 100644 index 0000000..a30454b --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/state/BookHoldingState.java @@ -0,0 +1,53 @@ +package net.knarcraft.bookswithoutborders.state; + +/** + * This enum represents the possible states for players holding books + */ +public enum BookHoldingState { + + /** + * The player is holding one signed book in each hand + */ + SIGNED_BOTH_HANDS, + + /** + * The player is holding one unsigned book in each hand + */ + UNSIGNED_BOTH_HANDS, + + /** + * The player is holding one signed book in their main hand + */ + SIGNED_MAIN_HAND, + + /** + * The player is holding one unsigned book in their main hand + */ + UNSIGNED_MAIN_HAND, + + /** + * The player is holding one signed book in their off hand + */ + SIGNED_OFF_HAND, + + /** + * The player is holding one unsigned book in their off hand + */ + UNSIGNED_OFF_HAND, + + /** + * The player is holding one signed book in their main hand and one unsigned book in their off hand + */ + SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND, + + /** + * The player is holding one unsigned book in their main hand and one signed book in their off hand + */ + UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND, + + /** + * The player is not holding any books + */ + NONE + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/EncryptionStyle.java b/src/main/java/net/knarcraft/bookswithoutborders/state/EncryptionStyle.java similarity index 93% rename from src/main/java/net/knarcraft/bookswithoutborders/EncryptionStyle.java rename to src/main/java/net/knarcraft/bookswithoutborders/state/EncryptionStyle.java index 25d8844..ff406c5 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/EncryptionStyle.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/state/EncryptionStyle.java @@ -1,4 +1,4 @@ -package net.knarcraft.bookswithoutborders; +package net.knarcraft.bookswithoutborders.state; /** * This enum represents the different available encryption styles diff --git a/src/main/java/net/knarcraft/bookswithoutborders/state/HoldingItemState.java b/src/main/java/net/knarcraft/bookswithoutborders/state/HoldingItemState.java new file mode 100644 index 0000000..d645fe2 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/state/HoldingItemState.java @@ -0,0 +1,28 @@ +package net.knarcraft.bookswithoutborders.state; + +/** + * This enum represents the different states of a player holding a given item + */ +public enum HoldingItemState { + + /** + * The player is holding one item in each hand + */ + BOTH_HANDS, + + /** + * The player is holding one item in their main hand + */ + MAIN_HAND, + + /** + * The player is holding one item in their off hand + */ + OFF_HAND, + + /** + * The player is not holding any items + */ + NONE + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/state/ItemSlot.java b/src/main/java/net/knarcraft/bookswithoutborders/state/ItemSlot.java new file mode 100644 index 0000000..5b8204a --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/state/ItemSlot.java @@ -0,0 +1,23 @@ +package net.knarcraft.bookswithoutborders.state; + +/** + * This enum represents the different relevant item slots a target item can exist in + */ +public enum ItemSlot { + + /** + * The item is in the player's main hand + */ + MAIN_HAND, + + /** + * The item is in the player's off hand + */ + OFF_HAND, + + /** + * The player does not have the item, or it is ambiguous + */ + NONE + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java index c38d12f..3527433 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.EncryptionStyle; +import net.knarcraft.bookswithoutborders.state.EncryptionStyle; import net.knarcraft.bookswithoutborders.GenenCrypt; import net.knarcraft.bookswithoutborders.SubstitutionCipher; import org.bukkit.entity.Player; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java index 8975b00..358f1a1 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/InventoryHelper.java @@ -1,7 +1,9 @@ package net.knarcraft.bookswithoutborders.utility; -import net.knarcraft.bookswithoutborders.BookHoldingState; +import net.knarcraft.bookswithoutborders.state.BookHoldingState; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.state.HoldingItemState; +import net.knarcraft.bookswithoutborders.state.ItemSlot; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -30,21 +32,14 @@ public class InventoryHelper { * @return

The book the player is holding

*/ public static ItemStack getHeldBook(Player player, boolean signedBook) { - BookHoldingState holdingState; - if (signedBook) { - holdingState = getHoldingSignedBookState(player); - } else { - holdingState = getHoldingUnsignedBookState(player); - } - ItemStack heldBook; - if (holdingState == BookHoldingState.MAIN_HAND) { - heldBook = getHeldItem(player, true); - } else if (holdingState == BookHoldingState.OFF_HAND) { - heldBook = getHeldItem(player, false); + ItemSlot heldSlot = getHeldSlotBook(player, false, false, true, signedBook); + if (heldSlot == ItemSlot.MAIN_HAND) { + return player.getInventory().getItemInMainHand(); + } else if (heldSlot == ItemSlot.OFF_HAND) { + return player.getInventory().getItemInOffHand(); } else { throw new IllegalArgumentException("The player is not holding exactly one book."); } - return heldBook; } /** @@ -53,9 +48,15 @@ public class InventoryHelper { * @param player

The player holding the book

* @param newBook

The new book the player should hold

*/ - public static void setHeldBook(Player player, ItemStack newBook) { - BookHoldingState holdingState = getHoldingSignedBookState(player); - replaceHeldItem(player, newBook, holdingState == BookHoldingState.MAIN_HAND); + public static void setHeldWrittenBook(Player player, ItemStack newBook) { + ItemSlot itemSlot = getHeldSlotBook(player, false, false, true, true); + if (itemSlot == ItemSlot.MAIN_HAND) { + replaceHeldItem(player, newBook, true); + } else if (itemSlot == ItemSlot.OFF_HAND) { + replaceHeldItem(player, newBook, false); + } else { + BooksWithoutBorders.sendErrorMessage(player, "Could not find a book to replace!"); + } } /** @@ -91,19 +92,15 @@ public class InventoryHelper { * @return

False if the player is holding exactly one book

*/ private static boolean notHoldingOneBookCheck(Player player, String noBookMessage, String twoBooksMessage, boolean written) { - BookHoldingState holdingState; - if (written) { - holdingState = getHoldingSignedBookState(player); - } else { - holdingState = getHoldingUnsignedBookState(player); - } + BookHoldingState holdingState = getBookHoldingState(player); if (holdingState == BookHoldingState.NONE) { BooksWithoutBorders.sendErrorMessage(player, noBookMessage); return true; } - if (holdingState == BookHoldingState.BOTH_HANDS) { + if ((written && holdingState == BookHoldingState.SIGNED_BOTH_HANDS) || + (!written && holdingState == BookHoldingState.UNSIGNED_BOTH_HANDS)) { BooksWithoutBorders.sendErrorMessage(player, twoBooksMessage); return true; } @@ -119,34 +116,114 @@ public class InventoryHelper { * @return

True if the player is holding one book

*/ public static boolean isHoldingBook(Player player, boolean signedBook) { - BookHoldingState holdingState; - if (signedBook) { - holdingState = getHoldingSignedBookState(player); - } else { - holdingState = getHoldingUnsignedBookState(player); + BookHoldingState holdingState = getBookHoldingState(player); + + if (holdingState == BookHoldingState.SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND || + holdingState == BookHoldingState.UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND) { + return true; + } + if (signedBook) { + return holdingState == BookHoldingState.SIGNED_MAIN_HAND || + holdingState == BookHoldingState.SIGNED_OFF_HAND; + } else { + return holdingState == BookHoldingState.UNSIGNED_MAIN_HAND || + holdingState == BookHoldingState.UNSIGNED_OFF_HAND; } - - return holdingState == BookHoldingState.MAIN_HAND || holdingState == BookHoldingState.OFF_HAND; } /** - * Gets the state of which hands of the player contains a book - * - * @param player

The player possibly holding a book

- * @return

The state of the player's book holding

+ * Gets the slot of the player's held book + * @param player

The player holding the book

+ * @param handMatters

Whether the differentiation between the main hand and the off hand is relevant

+ * @param mainHand

Whether to search the player's main hand or off hand, if it's relevant

+ * @param typeMatters

Whether the differentiation between signed and unsigned books is relevant

+ * @param writtenBook

Whether to search for written or unwritten books, if it's relevant

+ * @return

The slot of the player's held book

*/ - public static BookHoldingState getHoldingSignedBookState(Player player) { - return getHoldingItemState(player, Material.WRITTEN_BOOK); + public static ItemSlot getHeldSlotBook(Player player, boolean handMatters, boolean mainHand, + boolean typeMatters, boolean writtenBook) { + BookHoldingState state = getBookHoldingState(player); + ItemStack mainHandItem = player.getInventory().getItemInMainHand(); + ItemStack offHandItem = player.getInventory().getItemInOffHand(); + Material requiredMaterial = writtenBook ? Material.WRITTEN_BOOK : Material.WRITABLE_BOOK; + //Ambiguous or empty + if (state == BookHoldingState.SIGNED_BOTH_HANDS || + state == BookHoldingState.UNSIGNED_BOTH_HANDS || + state == BookHoldingState.NONE) { + return null; + } + if (handMatters && typeMatters) { + if (mainHand && mainHandItem.getType() == requiredMaterial) { + return ItemSlot.MAIN_HAND; + } else if (!mainHand && offHandItem.getType() == requiredMaterial) { + return ItemSlot.OFF_HAND; + } + } else if (handMatters) { + //Ambiguous + if (state == BookHoldingState.SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND || + state == BookHoldingState.UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND) { + return ItemSlot.NONE; + } + if (mainHand) { + return ItemSlot.MAIN_HAND; + } else { + return ItemSlot.OFF_HAND; + } + } else if (typeMatters) { + if ((writtenBook && (state == BookHoldingState.SIGNED_MAIN_HAND || + state == BookHoldingState.SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND)) || (!writtenBook && + (state == BookHoldingState.UNSIGNED_MAIN_HAND || + state == BookHoldingState.UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND))) { + return ItemSlot.MAIN_HAND; + } else if ((writtenBook && (state == BookHoldingState.SIGNED_OFF_HAND || + state == BookHoldingState.UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND)) || (!writtenBook && ( + state == BookHoldingState.UNSIGNED_OFF_HAND) || + state == BookHoldingState.SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND)) { + return ItemSlot.OFF_HAND; + } + } else { + if (state == BookHoldingState.SIGNED_MAIN_HAND || state == BookHoldingState.UNSIGNED_MAIN_HAND) { + return ItemSlot.MAIN_HAND; + } else if (state == BookHoldingState.SIGNED_OFF_HAND || state == BookHoldingState.UNSIGNED_OFF_HAND) { + return ItemSlot.OFF_HAND; + } + } + return ItemSlot.NONE; } /** - * Gets the state of which hands of the player contains a writable book - * - * @param player

The player possibly holding a book

+ * Gets the state of the player's book holding from all possible states + * @param player

The player to check

* @return

The state of the player's book holding

*/ - public static BookHoldingState getHoldingUnsignedBookState(Player player) { - return getHoldingItemState(player, Material.WRITABLE_BOOK); + private static BookHoldingState getBookHoldingState(Player player) { + ItemStack mainHandItem = player.getInventory().getItemInMainHand(); + ItemStack offHandItem = player.getInventory().getItemInOffHand(); + + boolean hasSignedBookInMainHand = mainHandItem.getType() == Material.WRITTEN_BOOK; + boolean hasUnsignedBookInMainHand = mainHandItem.getType() == Material.WRITABLE_BOOK; + boolean hasSignedBookInOffHand = offHandItem.getType() == Material.WRITTEN_BOOK; + boolean hasUnsignedBookInOffHand = offHandItem.getType() == Material.WRITABLE_BOOK; + + if (hasSignedBookInMainHand && hasSignedBookInOffHand) { + return BookHoldingState.SIGNED_BOTH_HANDS; + } else if (hasUnsignedBookInMainHand && hasUnsignedBookInOffHand) { + return BookHoldingState.UNSIGNED_BOTH_HANDS; + } else if (hasSignedBookInMainHand && hasUnsignedBookInOffHand) { + return BookHoldingState.SIGNED_MAIN_HAND_UNSIGNED_OFF_HAND; + } else if (hasUnsignedBookInMainHand && hasSignedBookInOffHand) { + return BookHoldingState.UNSIGNED_MAIN_HAND_SIGNED_OFF_HAND; + } else if (hasSignedBookInMainHand) { + return BookHoldingState.SIGNED_MAIN_HAND; + } else if (hasUnsignedBookInMainHand) { + return BookHoldingState.UNSIGNED_MAIN_HAND; + } else if (hasSignedBookInOffHand) { + return BookHoldingState.SIGNED_OFF_HAND; + } else if (hasUnsignedBookInOffHand) { + return BookHoldingState.UNSIGNED_OFF_HAND; + } else { + return BookHoldingState.NONE; + } } /** @@ -156,18 +233,18 @@ public class InventoryHelper { * @param type

The type of material to look for

* @return

The state of the player's item holding

*/ - private static BookHoldingState getHoldingItemState(Player player, Material type) { + private static HoldingItemState getHoldingItemState(Player player, Material type) { boolean hasBookInMainHand = player.getInventory().getItemInMainHand().getType() == type; boolean hasBookInOffHand = player.getInventory().getItemInOffHand().getType() == type; if (hasBookInMainHand && hasBookInOffHand) { - return BookHoldingState.BOTH_HANDS; + return HoldingItemState.BOTH_HANDS; } else if (hasBookInMainHand) { - return BookHoldingState.MAIN_HAND; + return HoldingItemState.MAIN_HAND; } else if (hasBookInOffHand) { - return BookHoldingState.OFF_HAND; + return HoldingItemState.OFF_HAND; } else { - return BookHoldingState.NONE; + return HoldingItemState.NONE; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index e59c3f8..afe0a39 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -18,7 +18,7 @@ commands: usage: / [# of copies (num)] [signed (true/false)] permission: bookswithoutborders.give decrypt: - description: Encrypts the held book + description: Decrypts the held book usage: / permission: bookswithoutborders.decrypt groupencrypt: