diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index d66748a..8fed087 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -20,7 +20,8 @@ import net.knarcraft.bookswithoutborders.command.CommandSetLore; import net.knarcraft.bookswithoutborders.command.CommandSetTitle; import net.knarcraft.bookswithoutborders.command.CommandUnSign; import net.knarcraft.bookswithoutborders.command.GiveTabCompleter; -import net.knarcraft.bookswithoutborders.listener.BooksWithoutBordersListener; +import net.knarcraft.bookswithoutborders.listener.PlayerEventListener; +import net.knarcraft.bookswithoutborders.listener.SignEventListener; import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper; import net.knarcraft.bookswithoutborders.utility.FileHelper; import net.milkbowl.vault.economy.Economy; @@ -37,6 +38,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; @@ -62,40 +64,48 @@ import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.clea import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName; public class BooksWithoutBorders extends JavaPlugin { - protected static int bookDuplicateLimit; + private static int bookDuplicateLimit; //The separating string between the book title and the book author public static String titleAuthorSeparator; public static String loreSeparator; public static List firstBooks; public static String welcomeMessage; - protected static List existingPlayers; + private static List existingPlayers; public static Economy eco; public static Material bookPriceType = null; public static double bookPriceQuantity; public static boolean authorOnlyCopy; public static boolean useYml; public static boolean adminDecrypt; - protected static ItemFactory itemFactory; + private static ItemFactory itemFactory; public static Map> loadList; - public static BooksWithoutBorders bwb; - protected static BooksWithoutBordersListener bL; + public static BooksWithoutBorders booksWithoutBorders; public static ConsoleCommandSender consoleSender; @Override public void onEnable() { - bwb = this; + booksWithoutBorders = this; consoleSender = this.getServer().getConsoleSender(); - bL = new BooksWithoutBordersListener(); loadList = new HashMap<>(); firstBooks = new ArrayList<>(); BooksWithoutBordersSettings.initialize(this); - if (getSlash() != null && init()) { - this.getServer().getPluginManager().registerEvents(bL, this); + PluginManager pluginManager = this.getServer().getPluginManager(); + + if (getSlash() != null && initialize()) { + pluginManager.registerEvents(new PlayerEventListener(), this); + pluginManager.registerEvents(new SignEventListener(), this); } else { this.getPluginLoader().disablePlugin(this); } + registerCommands(); + } + + /** + * Registers all commands used by this plugin + */ + private void registerCommands() { registerCommand("give", new CommandGive(this), new GiveTabCompleter(this)); registerCommand("decrypt", new CommandDecrypt(), null); registerCommand("groupEncrypt", new CommandGroupEncrypt(), null); @@ -135,7 +145,7 @@ public class BooksWithoutBorders extends JavaPlugin { } } - protected boolean init() { + private boolean initialize() { //initializes Item Factory try { itemFactory = this.getServer().getItemFactory(); @@ -324,7 +334,7 @@ public class BooksWithoutBorders extends JavaPlugin { return true; } - protected void addExistingPlayer(String playerName) { + private void addExistingPlayer(String playerName) { existingPlayers.add(playerName); try { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/PlayerEventListener.java new file mode 100644 index 0000000..e888404 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/PlayerEventListener.java @@ -0,0 +1,176 @@ +package net.knarcraft.bookswithoutborders.listener; + +import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; +import net.knarcraft.bookswithoutborders.utility.InventoryHelper; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.File; +import java.util.List; + +import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder; +import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash; +import static net.knarcraft.bookswithoutborders.utility.FileHelper.isBookListIndex; + +public class PlayerEventListener implements Listener { + + private final String slash = getSlash(); + + @EventHandler + public void onHold(PlayerItemHeldEvent event) { + if (event.isCancelled()) { + return; + } + + Player player = event.getPlayer(); + int selectedSlot = event.getNewSlot(); + PlayerInventory playerInventory = player.getInventory(); + ItemStack selectedItem = playerInventory.getItem(selectedSlot); + + //Ignore irrelevant items + if (selectedItem == null || selectedItem.getType() != Material.WRITTEN_BOOK) { + return; + } + + ItemMeta itemMetadata = selectedItem.getItemMeta(); + if (itemMetadata == null) { + return; + } + + //Update the book the user is viewing + updateBookInHand(player, itemMetadata, true); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + + //Handle new players + if (!BooksWithoutBorders.booksWithoutBorders.hasPlayedBefore(player.getName())) { + boolean sendMessage = true; + + //Gives new players necessary books + for (String bookName : BooksWithoutBorders.firstBooks) { + sendMessage = giveBookToNewPlayer(bookName, player, sendMessage); + } + } + + //Updates any books in either hand + ItemStack mainHandItem = InventoryHelper.getHeldItem(player, true); + ItemStack offHandItem = InventoryHelper.getHeldItem(player, false); + if (mainHandItem.getType() == Material.WRITTEN_BOOK) { + ItemMeta itemMetadata = mainHandItem.getItemMeta(); + updateBookInHand(player, itemMetadata, true); + } + if (offHandItem.getType() == Material.WRITTEN_BOOK) { + ItemMeta itemMetadata = offHandItem.getItemMeta(); + updateBookInHand(player, itemMetadata, false); + } + } + + /** + * 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.booksWithoutBorders.listFiles(player, true, true); + BooksWithoutBorders.loadList.put(player.getName(), availableFiles); + } + + //Give the book to the player if it exists + ItemStack newBook = BooksWithoutBorders.booksWithoutBorders.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.booksWithoutBorders.getServer().getScheduler().scheduleSyncDelayedTask(BooksWithoutBorders.booksWithoutBorders, + () -> 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); + } + } + } + + /** + * Updates old books to a newer format + * + * @param player

The player holding the book

+ * @param oldBook

Metadata about the held book

+ * @return

An updated book

+ */ + public ItemStack updateBook(Player player, BookMeta oldBook) { + //handles hacked title-less books + if (oldBook.getTitle() == null || oldBook.getTitle().length() < 3) { + return null; + } + + if (oldBook.getTitle().substring(oldBook.getTitle().length() - 3).equalsIgnoreCase("[U]")) { + String fileName; + + if (oldBook.getAuthor() != null && oldBook.getAuthor().equalsIgnoreCase("unknown")) { + //Unknown author is ignored + fileName = oldBook.getTitle(); + } else { + fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor(); + } + + String cleanPlayerName = InputCleaningHelper.cleanString(player.getName()); + + String[] possiblePaths = new String[]{ + getBookFolder() + fileName + ".yml", + getBookFolder() + fileName + ".txt", + getBookFolder() + cleanPlayerName + slash + fileName + ".yml", + getBookFolder() + cleanPlayerName + slash + fileName + ".txt" + }; + + for (String path : possiblePaths) { + File file = new File(path); + if (file.isFile()) { + return BooksWithoutBorders.booksWithoutBorders.loadBook(player, fileName, "true", "player"); + } + } + return null; + } + + return null; + } + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/BooksWithoutBordersListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java similarity index 63% rename from src/main/java/net/knarcraft/bookswithoutborders/listener/BooksWithoutBordersListener.java rename to src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java index 8ef9994..780be11 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/listener/BooksWithoutBordersListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java @@ -5,7 +5,6 @@ import net.knarcraft.bookswithoutborders.state.EncryptionStyle; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.bookswithoutborders.utility.FileHelper; import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; -import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Tag; @@ -16,124 +15,22 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerItemHeldEvent; -import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.BookMeta; -import org.bukkit.inventory.meta.ItemMeta; import java.io.File; import java.util.List; -import java.util.Objects; import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder; import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash; +import static net.knarcraft.bookswithoutborders.utility.FileHelper.isBookListIndex; -/** - * A listener for relevant events - */ -public class BooksWithoutBordersListener implements Listener { +public class SignEventListener implements Listener { private final String slash = getSlash(); - /** - * Updates old books to a newer format - * - * @param player

The player holding the book

- * @param oldBook

Metadata about the held book

- * @return

An updated book

- */ - public ItemStack updateBook(Player player, BookMeta oldBook) { - //handles hacked title-less books - if (oldBook.getTitle() == null || oldBook.getTitle().length() < 3) { - return null; - } - - if (oldBook.getTitle().substring(oldBook.getTitle().length() - 3).equalsIgnoreCase("[U]")) { - String fileName; - - if (oldBook.getAuthor() != null && oldBook.getAuthor().equalsIgnoreCase("unknown")) { - //Unknown author is ignored - fileName = oldBook.getTitle(); - } else { - fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor(); - } - - String cleanPlayerName = InputCleaningHelper.cleanString(player.getName()); - - String[] possiblePaths = new String[]{ - getBookFolder() + fileName + ".yml", - getBookFolder() + fileName + ".txt", - getBookFolder() + cleanPlayerName + slash + fileName + ".yml", - getBookFolder() + cleanPlayerName + slash + fileName + ".txt" - }; - - for (String path : possiblePaths) { - File file = new File(path); - if (file.isFile()) { - return BooksWithoutBorders.bwb.loadBook(player, fileName, "true", "player"); - } - } - return null; - } - - return null; - } - - @EventHandler - public void onHold(PlayerItemHeldEvent event) { - if (event.isCancelled()) { - return; - } - - Player player = event.getPlayer(); - int selectedSlot = event.getNewSlot(); - PlayerInventory playerInventory = player.getInventory(); - ItemStack selectedItem = playerInventory.getItem(selectedSlot); - - //Ignore irrelevant items - if (selectedItem == null || selectedItem.getType() != Material.WRITTEN_BOOK) { - return; - } - - ItemMeta itemMetadata = selectedItem.getItemMeta(); - if (itemMetadata == null) { - return; - } - - //Update the book the user is viewing - updateBookInHand(player, itemMetadata, true); - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - - //Handle new players - if (!BooksWithoutBorders.bwb.hasPlayedBefore(player.getName())) { - boolean sendMessage = true; - - //Gives new players necessary books - for (String bookName : BooksWithoutBorders.firstBooks) { - sendMessage = giveBookToNewPlayer(bookName, player, sendMessage); - } - } - - //Updates any books in either hand - ItemStack mainHandItem = InventoryHelper.getHeldItem(player, true); - ItemStack offHandItem = InventoryHelper.getHeldItem(player, false); - if (mainHandItem.getType() == Material.WRITTEN_BOOK) { - ItemMeta itemMetadata = mainHandItem.getItemMeta(); - updateBookInHand(player, itemMetadata, true); - } - if (offHandItem.getType() == Material.WRITTEN_BOOK) { - ItemMeta itemMetadata = offHandItem.getItemMeta(); - updateBookInHand(player, itemMetadata, false); - } - } - @EventHandler public void onSignChange(SignChangeEvent event) { if (event.isCancelled()) { @@ -217,221 +114,6 @@ 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 = getBookFolder() + lines[2] + lines[3]; - if (FileHelper.bookFileExists(signFile)) { - markGiveSignValidity(event, true); - } else { - if (isBookListIndex(lines[2])) { - List availableFiles = BooksWithoutBorders.bwb.listFiles(player, true, 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(getBookFolder().replaceAll("[\\\\/]$", "")); - - 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; - } - - /** - * 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, 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 - * - * @param oldBook

Metadata for the encrypted book

- * @param player

The player decrypting the book

- * @param heldItem

The type of the held book

- * @param hand

The hand the player is using to hold the book

- */ - private void decryptBook(BookMeta oldBook, Player player, ItemStack heldItem, EquipmentSlot hand) { - ItemStack newBook; - - //Check if the book is encrypted by Books Without Borders - if (!oldBook.hasLore() || oldBook.getLore() == null || !oldBook.getLore().get(0).contains(" encrypted]")) { - return; - } - - String groupName = oldBook.getLore().get(0).substring(3).split(" encrypted")[0]; - - //Permission check - if (!player.hasPermission("bookswithoutborders.decrypt." + groupName) && - !(BooksWithoutBorders.adminDecrypt && player.hasPermission("bookswithoutborders.admin"))) { - return; - } - - String fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor(); - - String encryptionFile = InputCleaningHelper.cleanString(groupName) + slash + fileName + ".yml"; - - File file = new File(getBookFolder() + "Encrypted" + slash + encryptionFile); - if (!file.isFile()) { - file = new File(getBookFolder() + fileName + ".txt"); - if (!file.isFile()) { - return; - } - } - newBook = BooksWithoutBorders.bwb.loadBook(player, fileName, "true", groupName, heldItem.getAmount()); - - player.getInventory().setItem(hand, newBook); - player.closeInventory(); - player.sendMessage(ChatColor.GREEN + "Book auto-decrypted!"); - } - - /** - * Encrypts and replaces the player's used book - * - * @param sign

The clicked sign

- * @param heldItemType

The item type used to click the sign

- * @param player

The player which clicked the sign

- * @param hand

The EquipmentSlot of the used hand

- */ - private void encryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) { - ItemStack eBook; - String[] lines = sign.getLines(); - boolean mainHand = hand == EquipmentSlot.HAND; - if (heldItemType == Material.WRITTEN_BOOK) { - player.closeInventory(); - eBook = EncryptionHelper.encryptBook(player, mainHand, ChatColor.stripColor(lines[2]), - EncryptionStyle.getFromString(ChatColor.stripColor(lines[3]))); - if (eBook != null) { - player.getInventory().setItem(hand, eBook); - } - } - } - - /** - * Gives a player the book specified on a sign - * - * @param sign

The sign the user clicked

- * @param player

The player which clicked the sign

- */ - private void giveBook(Sign sign, Player player) { - String fileName = ChatColor.stripColor(sign.getLine(2)); - boolean isLoadListNumber = false; - - for (int x = 0; x < fileName.length(); x++) { - if (!Character.isDigit(fileName.charAt(x))) - break; - if (x == fileName.length() - 1) { - BooksWithoutBorders.loadList.put(player.getName(), BooksWithoutBorders.bwb.listFiles(player, true, true)); - isLoadListNumber = true; - } - } - - if (!isLoadListNumber && sign.getLine(3).length() >= 2) - fileName = ChatColor.stripColor(sign.getLine(2)) + ChatColor.stripColor(sign.getLine(3)); - - ItemStack newBook = BooksWithoutBorders.bwb.loadBook(player, fileName, "true", "public"); - - if (newBook != null) { - player.getInventory().addItem(newBook); - player.sendMessage(ChatColor.GREEN + "Received book!"); - } else { - player.sendMessage(ChatColor.RED + "Book failed to load!"); - } - } - /** * Decrypts and replaces the player's used book * @@ -482,4 +164,146 @@ public class BooksWithoutBordersListener implements Listener { return line.equalsIgnoreCase(color + compareTo); } + /** + * 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 = getBookFolder() + lines[2] + lines[3]; + if (FileHelper.bookFileExists(signFile)) { + markGiveSignValidity(event, true); + } else { + if (isBookListIndex(lines[2])) { + List availableFiles = BooksWithoutBorders.booksWithoutBorders.listFiles(player, true, true); + BooksWithoutBorders.loadList.put(player.getName(), availableFiles); + markGiveSignValidity(event, true); + return; + } + } + markGiveSignValidity(event, false); + } + + /** + * 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]); + } + } + + /** + * Decrypts a book decryptable for a given group + * + * @param oldBook

Metadata for the encrypted book

+ * @param player

The player decrypting the book

+ * @param heldItem

The type of the held book

+ * @param hand

The hand the player is using to hold the book

+ */ + private void decryptBook(BookMeta oldBook, Player player, ItemStack heldItem, EquipmentSlot hand) { + ItemStack newBook; + + //Check if the book is encrypted by Books Without Borders + if (!oldBook.hasLore() || oldBook.getLore() == null || !oldBook.getLore().get(0).contains(" encrypted]")) { + return; + } + + String groupName = oldBook.getLore().get(0).substring(3).split(" encrypted")[0]; + + //Permission check + if (!player.hasPermission("bookswithoutborders.decrypt." + groupName) && + !(BooksWithoutBorders.adminDecrypt && player.hasPermission("bookswithoutborders.admin"))) { + return; + } + + String fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor(); + + String encryptionFile = InputCleaningHelper.cleanString(groupName) + slash + fileName + ".yml"; + + File file = new File(getBookFolder() + "Encrypted" + slash + encryptionFile); + if (!file.isFile()) { + file = new File(getBookFolder() + fileName + ".txt"); + if (!file.isFile()) { + return; + } + } + newBook = BooksWithoutBorders.booksWithoutBorders.loadBook(player, fileName, "true", groupName, heldItem.getAmount()); + + player.getInventory().setItem(hand, newBook); + player.closeInventory(); + player.sendMessage(ChatColor.GREEN + "Book auto-decrypted!"); + } + + /** + * Encrypts and replaces the player's used book + * + * @param sign

The clicked sign

+ * @param heldItemType

The item type used to click the sign

+ * @param player

The player which clicked the sign

+ * @param hand

The EquipmentSlot of the used hand

+ */ + private void encryptHeldBookUsingSign(Sign sign, Material heldItemType, Player player, EquipmentSlot hand) { + ItemStack eBook; + String[] lines = sign.getLines(); + boolean mainHand = hand == EquipmentSlot.HAND; + if (heldItemType == Material.WRITTEN_BOOK) { + player.closeInventory(); + eBook = EncryptionHelper.encryptBook(player, mainHand, ChatColor.stripColor(lines[2]), + EncryptionStyle.getFromString(ChatColor.stripColor(lines[3]))); + if (eBook != null) { + player.getInventory().setItem(hand, eBook); + } + } + } + + /** + * Gives a player the book specified on a sign + * + * @param sign

The sign the user clicked

+ * @param player

The player which clicked the sign

+ */ + private void giveBook(Sign sign, Player player) { + String fileName = ChatColor.stripColor(sign.getLine(2)); + boolean isLoadListNumber = false; + + for (int x = 0; x < fileName.length(); x++) { + if (!Character.isDigit(fileName.charAt(x))) + break; + if (x == fileName.length() - 1) { + BooksWithoutBorders.loadList.put(player.getName(), BooksWithoutBorders.booksWithoutBorders.listFiles(player, true, true)); + isLoadListNumber = true; + } + } + + if (!isLoadListNumber && sign.getLine(3).length() >= 2) + fileName = ChatColor.stripColor(sign.getLine(2)) + ChatColor.stripColor(sign.getLine(3)); + + ItemStack newBook = BooksWithoutBorders.booksWithoutBorders.loadBook(player, fileName, "true", "public"); + + if (newBook != null) { + player.getInventory().addItem(newBook); + player.sendMessage(ChatColor.GREEN + "Received book!"); + } else { + player.sendMessage(ChatColor.RED + "Book failed to load!"); + } + } + } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/FileHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/FileHelper.java index 3bf5010..42520f8 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/FileHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/FileHelper.java @@ -7,8 +7,11 @@ import org.bukkit.command.CommandSender; import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.regex.Pattern; +import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder; + /** * Helper class for dealing with files */ @@ -18,6 +21,27 @@ public final class FileHelper { } + /** + * 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

+ */ + public static boolean isBookListIndex(String possibleIndex) { + File bookDirectory = new File(getBookFolder().replaceAll("[\\\\/]$", "")); + + 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 *