diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java index cef0612..d022d5d 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBordersListener.java @@ -1,8 +1,8 @@ package net.knarcraft.bookswithoutborders; import java.io.File; -import java.util.ArrayList; import java.util.List; +import java.util.Objects; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -76,13 +76,13 @@ public class BooksWithoutBordersListener implements Listener { } @EventHandler - public void onHold(PlayerItemHeldEvent e) { - if (e.isCancelled()) { + public void onHold(PlayerItemHeldEvent event) { + if (event.isCancelled()) { return; } - Player player = e.getPlayer(); - int selectedSlot = e.getNewSlot(); + Player player = event.getPlayer(); + int selectedSlot = event.getNewSlot(); PlayerInventory playerInventory = player.getInventory(); ItemStack selectedItem = playerInventory.getItem(selectedSlot); @@ -101,8 +101,8 @@ public class BooksWithoutBordersListener implements Listener { } @EventHandler - public void onPlayerJoin(PlayerJoinEvent e) { - Player player = e.getPlayer(); + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); //Handle new players if (!BooksWithoutBorders.bwb.hasPlayedBefore(player.getName())) { @@ -127,69 +127,14 @@ public class BooksWithoutBordersListener implements Listener { } } - /** - * Gives a book to a player joining for the first time - * - * @param bookName

The name of the book to give

- * @param player

The player which just joined

- * @param sendMessage

Whether to send a message to the joining player

- * @return

True if a message has yet to be sent

- */ - private boolean giveBookToNewPlayer(String bookName, Player player, boolean sendMessage) { - if (!bookName.trim().isEmpty()) { - - //Handles loadList numbers - try { - Integer.parseInt(bookName); - //Load public books for the player - List availableFiles = BooksWithoutBorders.bwb.listFiles(player, true, 0, true); - BooksWithoutBorders.loadList.put(player.getName(), availableFiles); - } catch (NumberFormatException ignored) { - } - - //Give the book to the player if it exists - ItemStack newBook = BooksWithoutBorders.bwb.loadBook(player, bookName, "true", "public"); - if (newBook != null) { - player.getInventory().addItem(newBook); - } - - //Send the player a welcome message if it exists - if (!BooksWithoutBorders.welcomeMessage.trim().isEmpty() && newBook != null && sendMessage) { - sendMessage = false; - BooksWithoutBorders.bwb.getServer().getScheduler().scheduleSyncDelayedTask(BooksWithoutBorders.bwb, - () -> player.sendMessage(BooksWithoutBorders.welcomeMessage), 40L); - } - } - return sendMessage; - } - - /** - * Updates a book in one of the player's hands - * - * @param player

The player to update

- * @param itemMetadata

Information about the held book

- * @param mainHand

Whether to update the book in the player's main hand

- */ - private void updateBookInHand(Player player, ItemMeta itemMetadata, boolean mainHand) { - PlayerInventory playerInventory = player.getInventory(); - ItemStack updatedBook = updateBook(player, (BookMeta) itemMetadata); - if (updatedBook != null) { - if (mainHand) { - playerInventory.setItemInMainHand(updatedBook); - } else { - playerInventory.setItemInOffHand(updatedBook); - } - } - } - @EventHandler - public void onSignChange(SignChangeEvent e) { - if (e.isCancelled()) { + public void onSignChange(SignChangeEvent event) { + if (event.isCancelled()) { return; } - String[] lines = e.getLines(); - Player player = e.getPlayer(); + String[] lines = event.getLines(); + Player player = event.getPlayer(); //Check if creating a Books Without Borders Sign and if the player has permission if (!lines[0].equalsIgnoreCase("[BwB]") || !player.hasPermission("bookswithoutborders.signs")) { @@ -197,71 +142,29 @@ public class BooksWithoutBordersListener implements Listener { } //Mark the sign as active - e.setLine(0, ChatColor.DARK_GREEN + "[BwB]"); + event.setLine(0, ChatColor.DARK_GREEN + "[BwB]"); - if ((lines[1].equalsIgnoreCase("[Encrypt]") || lines[1].equalsIgnoreCase("[Decrypt]") || - lines[1].equalsIgnoreCase("[Give]")) && lines[2].trim().length() > 0) { - - //Mark the second line as valid - e.setLine(1, ChatColor.DARK_BLUE + lines[1]); - - //Mark valid encryption/decryption sign - if (lines[1].equalsIgnoreCase(ChatColor.DARK_BLUE + "[Encrypt]") || - lines[1].equalsIgnoreCase(ChatColor.DARK_BLUE + "[Decrypt]")) { - e.setLine(2, ChatColor.MAGIC + lines[2]); - e.setLine(3, ChatColor.DARK_BLUE + lines[3]); - } - - //Generate book giving sign - if (lines[1].equalsIgnoreCase(ChatColor.DARK_BLUE + "[Give]")) { - if (lines[2].length() > 13 || lines[3].length() > 13) { - player.sendMessage(ChatColor.RED + "[Give] signs' 3rd and 4th lines must be 13 characters or less!"); - e.setLine(2, ChatColor.DARK_RED + lines[2]); - e.setLine(3, ChatColor.DARK_RED + lines[3]); - return; - } - - //Tests if a full file name has been supplied - if ((new File(bookFolder + lines[2] + lines[3]).isFile()) || - (new File(bookFolder + lines[2] + lines[3] + ".txt").isFile()) || - (new File(bookFolder + lines[2] + lines[3] + ".yml").isFile())) { - e.setLine(2, ChatColor.DARK_GREEN + lines[2]); - e.setLine(3, ChatColor.DARK_GREEN + lines[3]); - } else { - //Tests if a load list number has been supplied - File dirFile = new File(bookFolderPath); - for (int x = 0; x < lines[2].length(); x++) { - if (!Character.isDigit(lines[2].charAt(x))) { - e.setLine(2, ChatColor.DARK_RED + lines[2]); - e.setLine(3, ChatColor.DARK_RED + lines[3]); - break; - } - if (x == lines[2].length() - 1) { - List fList = new ArrayList<>(); - for (int y = 0; y < dirFile.list().length; y++) { - if (dirFile.listFiles()[y].isFile()) { - fList.add(dirFile.listFiles()[y].getName()); - } - } - - try { - if (Integer.parseInt(lines[2]) >= 0 && Integer.parseInt(lines[2]) <= fList.size()) { - BooksWithoutBorders.loadList.put(player.getName(), BooksWithoutBorders.bwb.listFiles(player, true, 0, true)); - e.setLine(2, ChatColor.DARK_GREEN + lines[2]); - e.setLine(3, ChatColor.DARK_GREEN + lines[3]); - } else { - e.setLine(2, ChatColor.DARK_RED + lines[2]); - e.setLine(3, ChatColor.DARK_RED + lines[3]); - } - } catch (NumberFormatException ignored) { - } - } - } - } - } - } else { + //Check if the sign is of a valid type + if (!((lines[1].equalsIgnoreCase("[Encrypt]") || lines[1].equalsIgnoreCase("[Decrypt]") || + lines[1].equalsIgnoreCase("[Give]")) && lines[2].trim().length() > 0)) { //Mark the second line as invalid - e.setLine(1, ChatColor.DARK_RED + lines[1]); + event.setLine(1, ChatColor.DARK_RED + lines[1]); + return; + } + + //Mark the second line as valid + event.setLine(1, ChatColor.DARK_BLUE + lines[1]); + + //Mark valid encryption/decryption sign + if (lines[1].equalsIgnoreCase(ChatColor.DARK_BLUE + "[Encrypt]") || + lines[1].equalsIgnoreCase(ChatColor.DARK_BLUE + "[Decrypt]")) { + event.setLine(2, ChatColor.MAGIC + lines[2]); + event.setLine(3, ChatColor.DARK_BLUE + lines[3]); + } + + //Generate book giving sign + if (lines[1].equalsIgnoreCase(ChatColor.DARK_BLUE + "[Give]")) { + generateGiveSign(event, lines, player); } } @@ -307,6 +210,133 @@ public class BooksWithoutBordersListener implements Listener { } } + /** + * Changes an edited sign into a sign to give books + * + * @param event

The event caused by changing the sign

+ * @param lines

The lines on the sign

+ * @param player

The player which edited the sign

+ */ + private void generateGiveSign(SignChangeEvent event, String[] lines, Player player) { + if (lines[2].length() > 13 || lines[3].length() > 13) { + player.sendMessage(ChatColor.RED + "[Give] signs' 3rd and 4th lines must be 13 characters or less!"); + markGiveSignValidity(event, false); + return; + } + + //Tests if a full file name has been supplied and points to an actual file + String signFile = bookFolder + lines[2] + lines[3]; + if (bookFileExists(signFile)) { + markGiveSignValidity(event, true); + } else { + if (isBookListIndex(lines[2])) { + List availableFiles = BooksWithoutBorders.bwb.listFiles(player, true, 0, true); + BooksWithoutBorders.loadList.put(player.getName(), availableFiles); + markGiveSignValidity(event, true); + return; + } + } + markGiveSignValidity(event, false); + } + + /** + * Check whether an integer points to a public book + * @param possibleIndex

The string which might be a book index

+ * @return

True if the number is a book index

+ */ + private boolean isBookListIndex(String possibleIndex) { + File bookDirectory = new File(bookFolderPath); + + try { + //Tests if a load list number has been supplied + int parsedLine = Integer.parseInt(possibleIndex); + File[] foundFiles = bookDirectory.listFiles(File::isFile); + + return parsedLine >= 0 && parsedLine <= Objects.requireNonNull(foundFiles).length; + } catch (NumberFormatException ignored) {} + + return false; + } + + /** + * Checks if a file path points to an actual book + * @param bookFile

The path to a book

+ * @return

True if the file exists and points to a book file

+ */ + private boolean bookFileExists(String bookFile) { + return ((new File(bookFile).isFile() && (bookFile.toLowerCase().endsWith(".txt") || + bookFile.toLowerCase().endsWith(".yml"))) || new File(bookFile + ".txt").isFile() || + new File(bookFile + ".yml").isFile()) && !bookFile.contains("../") && !bookFile.contains("..\\"); + } + + /** + * Marks a give sign as valid or invalid + * @param event

The event causing the creation of the give sign

+ * @param isValid

Whether the created sign is valid

+ */ + private void markGiveSignValidity(SignChangeEvent event, boolean isValid) { + String[] lines = event.getLines(); + if (isValid) { + event.setLine(2, ChatColor.DARK_GREEN + lines[2]); + event.setLine(3, ChatColor.DARK_GREEN + lines[3]); + } else { + event.setLine(2, ChatColor.DARK_RED + lines[2]); + event.setLine(3, ChatColor.DARK_RED + lines[3]); + } + } + + /** + * Gives a book to a player joining for the first time + * + * @param bookName

The name of the book to give

+ * @param player

The player which just joined

+ * @param sendMessage

Whether to send a message to the joining player

+ * @return

True if a message has yet to be sent

+ */ + private boolean giveBookToNewPlayer(String bookName, Player player, boolean sendMessage) { + if (!bookName.trim().isEmpty()) { + + //Handles loadList numbers + if (isBookListIndex(bookName)) { + List availableFiles = BooksWithoutBorders.bwb.listFiles(player, true, 0, true); + BooksWithoutBorders.loadList.put(player.getName(), availableFiles); + } + + //Give the book to the player if it exists + ItemStack newBook = BooksWithoutBorders.bwb.loadBook(player, bookName, "true", "public"); + if (newBook != null) { + player.getInventory().addItem(newBook); + } + + //Send the player a welcome message if it exists + if (!BooksWithoutBorders.welcomeMessage.trim().isEmpty() && newBook != null && sendMessage) { + sendMessage = false; + BooksWithoutBorders.bwb.getServer().getScheduler().scheduleSyncDelayedTask(BooksWithoutBorders.bwb, + () -> player.sendMessage(BooksWithoutBorders.welcomeMessage), 40L); + } + } + return sendMessage; + } + + /** + * Updates a book in one of the player's hands + * + * @param player

The player to update

+ * @param itemMetadata

Information about the held book

+ * @param mainHand

Whether to update the book in the player's main hand

+ */ + private void updateBookInHand(Player player, ItemMeta itemMetadata, boolean mainHand) { + PlayerInventory playerInventory = player.getInventory(); + ItemStack updatedBook = updateBook(player, (BookMeta) itemMetadata); + if (updatedBook != null) { + if (mainHand) { + playerInventory.setItemInMainHand(updatedBook); + } else { + playerInventory.setItemInOffHand(updatedBook); + } + } + } + /** * Decrypts a book decryptable for a given group *