diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index 92bc778..5887c63 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -44,6 +44,7 @@ import net.knarcraft.bookswithoutborders.listener.GroupDecryptListener; import net.knarcraft.bookswithoutborders.listener.PlayerEventListener; import net.knarcraft.bookswithoutborders.listener.SignEventListener; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import net.knarcraft.knarlib.formatting.StringFormatter; import net.knarcraft.knarlib.formatting.Translator; @@ -134,7 +135,7 @@ public class BooksWithoutBorders extends JavaPlugin { List newFiles = BookFileHelper.listFiles(sender, false); if (newFiles != null) { getInstance().playerBooksList.put(playerUUID, newFiles); - getInstance().playerLetterIndex.put(playerUUID, BookFileHelper.populateLetterIndices(newFiles)); + getInstance().playerLetterIndex.put(playerUUID, populateLetterIndices(newFiles)); } } List books = getInstance().playerBooksList.get(playerUUID); @@ -177,10 +178,10 @@ public class BooksWithoutBorders extends JavaPlugin { } if (updatePublic) { getInstance().publicBooksList = newFiles; - getInstance().publicLetterIndex = BookFileHelper.populateLetterIndices(newFiles); + getInstance().publicLetterIndex = populateLetterIndices(newFiles); } else if (sender instanceof Player player) { getInstance().playerBooksList.put(player.getUniqueId(), newFiles); - getInstance().playerLetterIndex.put(player.getUniqueId(), BookFileHelper.populateLetterIndices(newFiles)); + getInstance().playerLetterIndex.put(player.getUniqueId(), populateLetterIndices(newFiles)); } } @@ -225,7 +226,7 @@ public class BooksWithoutBorders extends JavaPlugin { @Nullable List files = BookFileHelper.listFiles(this.getServer().getConsoleSender(), true); if (files != null) { publicBooksList = files; - publicLetterIndex = BookFileHelper.populateLetterIndices(files); + publicLetterIndex = populateLetterIndices(files); } bookshelfHandler = new BookshelfHandler(); bookshelfHandler.load(); @@ -378,4 +379,24 @@ public class BooksWithoutBorders extends JavaPlugin { return true; } + /** + * Gets a map between characters, and the first instance of a book's title starting with that character + * + * @param books

The books to look through

+ * @return

The map of the first index containing each character

+ */ + @NotNull + private static Map populateLetterIndices(@NotNull List books) { + Map firstEncounter = new HashMap<>(); + Character current = null; + for (int i = 0; i < books.size(); i++) { + char first = InputCleaningHelper.stripColor(books.get(i)).toLowerCase().charAt(0); + if (current == null || current != first) { + current = first; + firstEncounter.put(first, i); + } + } + return firstEncounter; + } + } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandAddTitlePage.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandAddTitlePage.java index 9a33f12..f36a145 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandAddTitlePage.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandAddTitlePage.java @@ -3,8 +3,8 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.translation.Formatting; import net.knarcraft.bookswithoutborders.config.translation.Translatable; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.knarcraft.bookswithoutborders.utility.BookHelper; +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import org.bukkit.Material; @@ -87,9 +87,9 @@ public class CommandAddTitlePage implements TabExecutor { // Add a page with the book title and book author String loreSeparator = BooksWithoutBorders.getConfiguration().getLoreSeparator(); String pageText = formatTitle(new FormatBuilder(Formatting.NEUTRAL_TITLE_PAGE_TITLE_AUTHOR_FORMAT). - replace("{title}", BookFormatter.stripColor(BookHelper.getBookTitle(bookMeta))). + replace("{title}", InputCleaningHelper.stripColor(BookHelper.getBookTitle(bookMeta))). replace("{separator}", loreSeparator). - replace("{author}", BookFormatter.stripColor(BookHelper.getBookAuthor(bookMeta, null))).build()); + replace("{author}", InputCleaningHelper.stripColor(BookHelper.getBookAuthor(bookMeta, null))).build()); if (index > pages.size()) { pages.add(pageText); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java index 2b0c424..3a11c65 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDecrypt.java @@ -3,7 +3,7 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.translation.Translatable; -import net.knarcraft.bookswithoutborders.utility.BookHelper; +import net.knarcraft.bookswithoutborders.utility.BookFileHelper; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; @@ -106,7 +106,7 @@ public class CommandDecrypt implements TabExecutor { //Get the "encryption key" from the filename String key = ""; for (String encryptedFile : encryptedFiles) { - if (encryptedFile.contains(BookHelper.getBookFile(bookMetadata, player, true).replace(" ", "_"))) { + if (encryptedFile.contains(BookFileHelper.getBookFile(bookMetadata, player, true).replace(" ", "_"))) { key = EncryptionHelper.extractLegacyKey(encryptedFile); if (!key.isBlank()) { break; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java index 8fee2ec..7a429fb 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java @@ -5,7 +5,6 @@ import net.knarcraft.bookswithoutborders.config.translation.Translatable; import net.knarcraft.bookswithoutborders.gui.PagedBookIndex; import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; -import net.knarcraft.bookswithoutborders.utility.BookHelper; import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; @@ -82,9 +81,7 @@ public class CommandDelete implements TabExecutor { } //Get the file to be deleted - String bookDirectory = BookHelper.getBookDirectoryPathString( - isPublic ? BookDirectory.PUBLIC : BookDirectory.PLAYER, sender); - File file = BookFileHelper.getBookFile(bookDirectory + fileName); + File file = BookFileHelper.getFile(BookDirectory.getCommon(isPublic), fileName, sender); //Send message if no such file could be found if (file == null) { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandFormat.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandFormat.java index e9aa3bd..a7b555d 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandFormat.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandFormat.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.command; import net.knarcraft.bookswithoutborders.config.translation.Translatable; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; +import net.knarcraft.bookswithoutborders.utility.BookFormatterUtil; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import org.bukkit.command.Command; @@ -41,7 +41,7 @@ public class CommandFormat implements TabExecutor { return false; } - heldBook.setItemMeta(BookFormatter.formatPages(meta)); + heldBook.setItemMeta(BookFormatterUtil.formatPages(meta)); new FormatBuilder(Translatable.SUCCESS_FORMATTED).success(sender); return true; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java index 2f6bfc7..85b0a48 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandSave.java @@ -9,8 +9,8 @@ import net.knarcraft.bookswithoutborders.config.translation.SaveMessage; import net.knarcraft.bookswithoutborders.config.translation.Translatable; import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; +import net.knarcraft.bookswithoutborders.utility.BookFileReaderWriterUtil; import net.knarcraft.bookswithoutborders.utility.BookHelper; -import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import org.bukkit.command.Command; @@ -91,8 +91,7 @@ public class CommandSave implements TabExecutor { return; } - String savePath = BookHelper.getBookDirectoryPathString(saveToPublicFolder ? - BookDirectory.PUBLIC : BookDirectory.PLAYER, player); + String savePath = BookFileHelper.getBookDirectoryPathString(BookDirectory.getCommon(saveToPublicFolder), player); if (savePath == null) { new FormatBuilder(SaveMessage.ERROR_SAVE_INVALID_PATH).error(player); return; @@ -101,7 +100,7 @@ public class CommandSave implements TabExecutor { //Generate book filename String fileName; try { - fileName = BookHelper.getBookFile(book, player, saveToPublicFolder); + fileName = BookFileHelper.getBookFile(book, player, saveToPublicFolder); } catch (IllegalArgumentException exception) { new FormatBuilder(exception.getMessage()).error(player); return; @@ -122,7 +121,7 @@ public class CommandSave implements TabExecutor { } try { - BookToFromTextHelper.bookToYml(savePath, newName, book); + BookFileReaderWriterUtil.bookToYml(savePath, newName, book); //Update the relevant book list BooksWithoutBorders.updateBooks(player, saveToPublicFolder); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java b/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java index d08021e..d19994e 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/config/StaticMessage.java @@ -43,7 +43,6 @@ public enum StaticMessage { Warning! [BooksWithoutBorders] failed to initialize! Please confirm the correct version of [BooksWithoutBorders] is being run for this version of spigot!"""), - EXCEPTION_UNKNOWN_DIRECTORY("Unknown directory {directory}"), EXCEPTION_UNEXPECTED_EXTENSION("File with unexpected extension {extension} encountered!"), EXCEPTION_MIGRATE_BOOK_LOAD_FAILED("Unable to load book: {path}"), EXCEPTION_META_HAS_SEPARATOR("The author; {author} or title; {title} contains the title author separator" + diff --git a/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java b/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java index 967eb3e..695f65b 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java @@ -3,7 +3,7 @@ package net.knarcraft.bookswithoutborders.gui; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.translation.Formatting; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import net.knarcraft.knarlib.formatting.TranslatableMessage; import net.md_5.bungee.api.ChatColor; @@ -32,7 +32,7 @@ public class AuthorBookIndex extends BookIndex { @NotNull String authorName) { List availableBooks = BooksWithoutBorders.getAvailableBooks(sender, listPublic); availableBooks.removeIf((bookPath) -> - !BookFormatter.stripColor(BookFileHelper.getBookAuthorFromPath(bookPath)).equalsIgnoreCase(authorName)); + !InputCleaningHelper.stripColor(BookFileHelper.getBookAuthorFromPath(bookPath)).equalsIgnoreCase(authorName)); int totalPages = (int) Math.ceil((double) availableBooks.size() / booksPerPage); if (page > totalPages) { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java b/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java index ee89059..dc34e4d 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java @@ -3,7 +3,7 @@ package net.knarcraft.bookswithoutborders.gui; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.translation.Formatting; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import net.knarcraft.knarlib.formatting.TranslatableMessage; import net.md_5.bungee.api.ChatColor; @@ -101,9 +101,9 @@ public class PagedBookIndex extends BookIndex { HoverEvent indexHover = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new FormatBuilder(Formatting.NEUTRAL_BOOK_LIST_BOOK_INDEX_HOVER).color().build())); ClickEvent pathClick = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + command + " " + availableBooks.get(bookIndex)); HoverEvent pathHover = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new FormatBuilder(Formatting.NEUTRAL_BOOK_LIST_PATH_HOVER).color().build())); - ClickEvent authorClick = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/" + command + " author" + BookFormatter.stripColor(author) + " page1"); + ClickEvent authorClick = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/" + command + " author" + InputCleaningHelper.stripColor(author) + " page1"); HoverEvent authorHover = new HoverEvent(HoverEvent.Action.SHOW_TEXT, - new Text(new FormatBuilder(Formatting.NEUTRAL_BOOK_LIST_AUTHOR_HOVER).replace("{author}", BookFormatter.stripColor(author)).color().build())); + new Text(new FormatBuilder(Formatting.NEUTRAL_BOOK_LIST_AUTHOR_HOVER).replace("{author}", InputCleaningHelper.stripColor(author)).color().build())); componentBuilder.append(new FormatBuilder(Formatting.NEUTRAL_BOOK_LIST_BOOK_INDEX_NUMBER).replace("{index}", String.valueOf(bookIndex + 1)).color().build()).color(interactColor).event(indexClick).event(indexHover); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/BookEventListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/BookEventListener.java index d64677d..c3fdef4 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/listener/BookEventListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/BookEventListener.java @@ -2,7 +2,7 @@ package net.knarcraft.bookswithoutborders.listener; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.Permission; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; +import net.knarcraft.bookswithoutborders.utility.BookFormatterUtil; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerEditBookEvent; @@ -21,7 +21,7 @@ public class BookEventListener implements Listener { !event.getPlayer().hasPermission(Permission.FORMAT.toString())) { return; } - event.setNewBookMeta(BookFormatter.formatPages(event.getNewBookMeta())); + event.setNewBookMeta(BookFormatterUtil.formatPages(event.getNewBookMeta())); } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/GroupDecryptListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/GroupDecryptListener.java index 98ca0f1..801b176 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/listener/GroupDecryptListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/GroupDecryptListener.java @@ -7,7 +7,6 @@ import net.knarcraft.bookswithoutborders.config.translation.Translatable; import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; import net.knarcraft.bookswithoutborders.utility.BookLoader; -import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -80,24 +79,13 @@ public class GroupDecryptListener implements Listener { return; } - String encryptedFolder = BooksWithoutBorders.getConfiguration().getEncryptedBookPath(); - String fileName = oldBook.getTitle() + config.getTitleAuthorSeparator() + oldBook.getAuthor(); - - File file = BookFileHelper.findBookFile(encryptedFolder + InputCleaningHelper.cleanString(groupName) + - config.getSlash(), oldBook); + File file = BookFileHelper.getFile(BookDirectory.ENCRYPTED, groupName, oldBook); if (file == null) { - file = BookFileHelper.findBookFile(encryptedFolder, oldBook); - if (file == null) { - file = BookFileHelper.findBookFile(config.getBookFolder(), oldBook); - if (file == null) { - new FormatBuilder(Translatable.ERROR_GROUP_DECRYPT_NOT_FOUND).error(player); - return; - } - } + new FormatBuilder(Translatable.ERROR_GROUP_DECRYPT_NOT_FOUND).error(player); + return; } - newBook = BookLoader.loadBook(player, fileName, true, BookDirectory.ENCRYPTED, groupName, - heldItem.getAmount()); + newBook = BookLoader.loadBook(player, file, true, BookDirectory.ENCRYPTED, heldItem.getAmount()); if (newBook == null) { new FormatBuilder(Translatable.ERROR_GROUP_DECRYPT_LOAD_FAILED).error(player); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java b/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java index f465cda..40507fd 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/listener/SignEventListener.java @@ -5,11 +5,12 @@ import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.translation.GiveMessage; import net.knarcraft.bookswithoutborders.config.translation.SignText; import net.knarcraft.bookswithoutborders.encryption.EncryptionStyle; +import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.state.SignType; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.knarcraft.bookswithoutborders.utility.BookLoader; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; @@ -135,7 +136,7 @@ public class SignEventListener implements Listener { player.closeInventory(); //Converts user supplied key into integer form - String lineText = BookFormatter.stripColor(sign.getSide(Side.FRONT).getLine(2)); + String lineText = InputCleaningHelper.stripColor(sign.getSide(Side.FRONT).getLine(2)); String key = EncryptionHelper.getNumberKeyFromStringKey(lineText); ItemStack book = EncryptionHelper.loadEncryptedBook(player, key, false, false); @@ -159,7 +160,7 @@ public class SignEventListener implements Listener { @Nullable private ChatColor getSignLine2Color(@NotNull Sign sign) { String line = sign.getSide(Side.FRONT).getLine(2); - if (!BookFormatter.stripColor(line).equals(line)) { + if (!InputCleaningHelper.stripColor(line).equals(line)) { return ChatColor.getByChar(sign.getSide(Side.FRONT).getLine(2).substring(1, 2).charAt(0)); } else { return null; @@ -176,8 +177,8 @@ public class SignEventListener implements Listener { private void generateGiveSign(@NotNull SignChangeEvent event, @NotNull String[] lines, @NotNull Player player) { //Tests if a full file name has been supplied and points to an actual file - String signFile = BooksWithoutBorders.getConfiguration().getBookFolder() + lines[2] + lines[3]; - if (BookFileHelper.bookFileExists(signFile)) { + String signFile = lines[2] + lines[3]; + if (BookFileHelper.getFile(BookDirectory.PUBLIC, null, signFile) != null) { markGiveSignValidity(event, true); return; } else { @@ -222,8 +223,8 @@ public class SignEventListener implements Listener { boolean mainHand = hand == EquipmentSlot.HAND; if (heldItemType == Material.WRITTEN_BOOK) { player.closeInventory(); - eBook = EncryptionHelper.encryptBook(player, mainHand, BookFormatter.stripColor(lines[2]), - EncryptionStyle.getFromString(BookFormatter.stripColor(lines[3])), false); + eBook = EncryptionHelper.encryptBook(player, mainHand, InputCleaningHelper.stripColor(lines[2]), + EncryptionStyle.getFromString(InputCleaningHelper.stripColor(lines[3])), false); if (eBook != null) { player.getInventory().setItem(hand, eBook); } @@ -237,7 +238,7 @@ public class SignEventListener implements Listener { * @param player

The player which clicked the sign

*/ private void giveBook(@NotNull Sign sign, @NotNull Player player) { - String fileName = BookFormatter.stripColor(sign.getSide(Side.FRONT).getLine(2)); + String fileName = InputCleaningHelper.stripColor(sign.getSide(Side.FRONT).getLine(2)); boolean isLoadListNumber = false; try { @@ -249,7 +250,7 @@ public class SignEventListener implements Listener { //Add the third line to the second line for the full filename String thirdLine = sign.getSide(Side.FRONT).getLine(3); if (!isLoadListNumber && thirdLine.length() >= 2) { - fileName += BookFormatter.stripColor(thirdLine); + fileName += InputCleaningHelper.stripColor(thirdLine); } ItemStack newBook = BookLoader.loadBook(player, fileName, true, "public"); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/state/BookDirectory.java b/src/main/java/net/knarcraft/bookswithoutborders/state/BookDirectory.java index d8cc6ea..1d3d9ec 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/state/BookDirectory.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/state/BookDirectory.java @@ -42,4 +42,18 @@ public enum BookDirectory { } } + /** + * Gets the common public/player directory based on the input + * + * @param isPublic

Whether to get the public directory

+ * @return

The specified directory

+ */ + public static BookDirectory getCommon(boolean isPublic) { + if (isPublic) { + return BookDirectory.PUBLIC; + } else { + return BookDirectory.PLAYER; + } + } + } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/state/SignType.java b/src/main/java/net/knarcraft/bookswithoutborders/state/SignType.java index c0fec0d..b3981d1 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/state/SignType.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/state/SignType.java @@ -1,7 +1,7 @@ package net.knarcraft.bookswithoutborders.state; import net.knarcraft.bookswithoutborders.config.translation.SignText; -import net.knarcraft.bookswithoutborders.utility.BookFormatter; +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,7 +51,7 @@ public enum SignType { */ @Nullable public static SignType fromString(@NotNull String input) { - input = BookFormatter.stripColor(input); + input = InputCleaningHelper.stripColor(input); for (SignType signType : SignType.values()) { if (input.equalsIgnoreCase(getText(signType.text))) { return signType; @@ -68,7 +68,7 @@ public enum SignType { */ @NotNull private static String getText(@NotNull SignText signText) { - return BookFormatter.stripColor(new FormatBuilder(signText).build()); + return InputCleaningHelper.stripColor(new FormatBuilder(signText).build()); } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/thread/MigrationQueueThread.java b/src/main/java/net/knarcraft/bookswithoutborders/thread/MigrationQueueThread.java index 9a5edb9..a28248f 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/thread/MigrationQueueThread.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/thread/MigrationQueueThread.java @@ -6,8 +6,7 @@ import net.knarcraft.bookswithoutborders.config.translation.Translatable; import net.knarcraft.bookswithoutborders.container.EncryptedBook; import net.knarcraft.bookswithoutborders.container.MigrationRequest; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; -import net.knarcraft.bookswithoutborders.utility.BookHelper; -import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper; +import net.knarcraft.bookswithoutborders.utility.BookFileReaderWriterUtil; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.knarlib.formatting.FormatBuilder; import org.bukkit.Bukkit; @@ -107,7 +106,7 @@ public class MigrationQueueThread implements Runnable { // Attempt loading an encrypted book if necessary if (file.getAbsolutePath().contains("Books" + slash + "Encrypted")) { - encryptedBook = BookToFromTextHelper.encryptedBookFromYml(file, bookMeta, "", true, true); + encryptedBook = BookFileReaderWriterUtil.encryptedBookFromYml(file, bookMeta, "", true, true); if (encryptedBook != null) { loadedBook = encryptedBook.bookMeta(); } @@ -115,7 +114,7 @@ public class MigrationQueueThread implements Runnable { // Attempt to load the book normally if (loadedBook == null) { - loadedBook = BookToFromTextHelper.bookFromFile(file, bookMeta); + loadedBook = BookFileReaderWriterUtil.bookFromFile(file, bookMeta); } if (loadedBook == null) { @@ -135,7 +134,7 @@ public class MigrationQueueThread implements Runnable { } try { - String newName = BookHelper.getBookFile(loadedBook, author, isPublic); + String newName = BookFileHelper.getBookFile(loadedBook, author, isPublic); // Retain legacy key String key = EncryptionHelper.extractLegacyKey(file.getName()); @@ -144,9 +143,9 @@ public class MigrationQueueThread implements Runnable { } if (encryptedBook != null) { - BookToFromTextHelper.encryptedBookToYml(file.getParentFile().getAbsolutePath(), newName, encryptedBook); + BookFileReaderWriterUtil.encryptedBookToYml(file.getParentFile().getAbsolutePath(), newName, encryptedBook); } else { - BookToFromTextHelper.bookToYml(file.getParentFile().getAbsolutePath(), newName, bookMeta); + BookFileReaderWriterUtil.bookToYml(file.getParentFile().getAbsolutePath(), newName, bookMeta); } return deleteBook(file.getParentFile(), newName, file); } catch (IllegalArgumentException | IOException exception) { diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java index 958d520..9cb224c 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileHelper.java @@ -1,11 +1,13 @@ package net.knarcraft.bookswithoutborders.utility; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.config.BwBConfig; +import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.translation.Formatting; -import net.knarcraft.bookswithoutborders.config.translation.Translatable; import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.knarlib.formatting.FormatBuilder; import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.meta.BookMeta; @@ -15,10 +17,9 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; import java.util.Comparator; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; +import java.util.UUID; import java.util.regex.Pattern; /** @@ -50,50 +51,6 @@ public final class BookFileHelper { 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

- */ - public static boolean bookFileExists(@NotNull String bookFile) { - return ((new File(bookFile).isFile() && (bookFile.endsWith(".txt") || - bookFile.endsWith(".yml"))) || new File(bookFile + ".txt").isFile() || - new File(bookFile + ".yml").isFile()) && !bookFile.contains("../") && !bookFile.contains("..\\"); - } - - /** - * Gets a book file given its path - * - *

This function adds extensions to the path as necessary, returning the first match.

- * - * @param bookPath

The path of the book to get

- * @return

The file the path points to, or null otherwise

- */ - @Nullable - public static File getBookFile(@NotNull String bookPath) { - if (!bookFileExists(bookPath)) { - return null; - } - - File bookFile = new File(bookPath); - if (bookFile.exists()) { - return bookFile; - } - - File bookFileYml = new File(bookPath + ".yml"); - if (bookFileYml.exists()) { - return bookFileYml; - } - - File bookFileTxt = new File(bookPath + ".txt"); - if (bookFileTxt.exists()) { - return bookFileTxt; - } - - return null; - } - /** * Lists available files * @@ -103,72 +60,11 @@ public final class BookFileHelper { */ @Nullable public static List listFiles(@NotNull CommandSender sender, @NotNull Boolean listPublic) { - File file = BookHelper.getBookDirectoryPath(listPublic ? BookDirectory.PUBLIC : BookDirectory.PLAYER, sender); + File file = BookFileHelper.getBookDirectoryPath(BookDirectory.getCommon(listPublic), sender); if (file == null) { return new ArrayList<>(); } - return BookFileHelper.listFiles(sender, file); - } - - /** - * Gets a map between characters, and the first instance of a book's title starting with that character - * - * @param books

The books to look through

- * @return

The map of the first index containing each character

- */ - @NotNull - public static Map populateLetterIndices(@NotNull List books) { - Map firstEncounter = new HashMap<>(); - Character current = null; - for (int i = 0; i < books.size(); i++) { - char first = BookFormatter.stripColor(books.get(i)).toLowerCase().charAt(0); - if (current == null || current != first) { - current = first; - firstEncounter.put(first, i); - } - } - return firstEncounter; - } - - /** - * Lists available files - * - * @param sender

The command sender looking for files

- * @param searchDirectory

The directory to search for files

- * @return

A list of available files

- */ - @Nullable - private static List listFiles(@NotNull CommandSender sender, @NotNull File searchDirectory) { - List fileList = new ArrayList<>(); - File[] existingFiles = searchDirectory.listFiles(); - - if (!searchDirectory.exists() || existingFiles == null || existingFiles.length == 0) { - new FormatBuilder(Translatable.ERROR_NO_BOOKS_TO_LIST).error(sender); - return null; - } - - for (File foundFile : existingFiles) { - // Filter out invalid files - if (!foundFile.isFile() || foundFile.getName().contains("§")) { - continue; - } - String fileName = foundFile.getName(); - String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); - if (fileName.contains(separator)) { - //Convert the UUID into a username if necessary - String userName = getBookAuthorFromPath(fileName); - String title = getBookTitleFromPath(fileName); - fileList.add(title + separator + BookHelper.authorFromUUID(userName)); - } else { - fileList.add(fileName); - } - } - - // Sort the book list - Comparator bookComparator = Comparator.naturalOrder(); - fileList.sort((a, b) -> bookComparator.compare(BookFormatter.stripColor(a).toLowerCase(), - BookFormatter.stripColor(b).toLowerCase())); - return fileList; + return BookFileHelper.listFiles(file); } /** @@ -262,46 +158,6 @@ public final class BookFileHelper { return path; } - /** - * Attempts to find the correct book file - * - * @param folder

The folder the book is in

- * @param bookMeta

The book meta of the book to find

- * @return

The book's file, or null if not found

- */ - @Nullable - public static File findBookFile(@NotNull String folder, @NotNull BookMeta bookMeta) { - String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); - String fileName = bookMeta.getTitle() + separator + bookMeta.getAuthor(); - return findBookFile(folder, fileName); - } - - /** - * Attempts to find the correct book file - * - * @param folder

The folder the book is in

- * @param fileName

The name of the book to find

- * @return

The book's file, or null if not found

- */ - @Nullable - public static File findBookFile(@NotNull String folder, @NotNull String fileName) { - fileName = InputCleaningHelper.cleanString(fileName); - File file = new File(folder, fileName + ".yml"); - if (file.exists()) { - return getBookFile(file.getAbsolutePath()); - } - file = new File(folder, fileName.replace(" ", "_") + ".yml"); - if (file.exists()) { - return getBookFile(file.getAbsolutePath()); - } - file = new File(folder, fileName.replace(" ", "_") + ".txt"); - if (file.exists()) { - return getBookFile(file.getAbsolutePath()); - } else { - return null; - } - } - /** * Replaces an author name with a player UUID if matched * @@ -309,14 +165,262 @@ public final class BookFileHelper { * @return

The filename, or the filename with the author replaced with UUID

*/ public static String replaceAuthorWithUUID(@NotNull String fileName) { - String userName = BookFormatter.stripColor(getBookAuthorFromPath(fileName)); + String userName = InputCleaningHelper.stripColor(getBookAuthorFromPath(fileName)); Player player = Bukkit.getPlayerExact(userName); if (player != null) { - return userName.replace(userName, player.getUniqueId().toString()); + return fileName.replace(userName, player.getUniqueId().toString()); } else { - return userName; + return fileName; } } + /** + * Converts the author of a book from UUID if necessary + * + * @param author

The author string

+ * @return

The author string, converted if it was a UUID

+ */ + @NotNull + public static String authorFromUUID(@NotNull String author) { + try { + UUID authorID = UUID.fromString(InputCleaningHelper.stripColor(author)); + Player player = Bukkit.getPlayer(authorID); + if (player != null) { + author = player.getName(); + } + } catch (IllegalArgumentException ignored) { + } + return author; + } + + /** + * Gets the file name of the given book + * + * @param book

The book to get the file of

+ * @param player

The player trying to do something with the book

+ * @return

The book file

+ * @throws IllegalArgumentException

If the book title or author contains the title author separator

+ */ + @NotNull + public static String getBookFile(@NotNull BookMeta book, @NotNull OfflinePlayer player, boolean isPublic) throws IllegalArgumentException { + String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); + String bookName = BookHelper.getBookTitle(book); + String authorName = BookHelper.getBookAuthor(book, isPublic ? null : player); + + if (InputCleaningHelper.cleanString(bookName).contains(separator) || + InputCleaningHelper.cleanString(authorName).contains(separator)) { + throw new IllegalArgumentException(new FormatBuilder(StaticMessage.EXCEPTION_META_HAS_SEPARATOR.toString()). + replace("{author}", authorName).replace("{title}", bookName). + replace("{separator}", separator).build()); + } + + return InputCleaningHelper.cleanString(bookName + separator + authorName); + } + + /** + * Gets the file path of the selected book directory + * + * @param bookDirectory

The book directory to get (ENCRYPTED is not supported here)

+ * @param sender

The command sender trying to get the directory

+ * @return

The path of the directory, or null if not possible to get

+ */ + @Nullable + public static File getBookDirectoryPath(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) { + String bookFolderString = getBookDirectoryPathString(bookDirectory, sender); + if (bookFolderString == null) { + return null; + } + return new File(bookFolderString); + } + + /** + * Gets the string path of the selected book directory + * + * @param bookDirectory

The book directory to get (ENCRYPTED is not supported here)

+ * @param sender

The command sender trying to get the directory

+ * @return

The path of the directory, or null if not possible to get

+ */ + @Nullable + public static String getBookDirectoryPathString(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) { + BwBConfig config = BooksWithoutBorders.getConfiguration(); + String folder = null; + String bookFolder = config.getBookFolder(); + if (bookDirectory == BookDirectory.PUBLIC) { + folder = bookFolder; + } else if (bookDirectory == BookDirectory.PLAYER && sender instanceof Player player) { + folder = bookFolder + player.getUniqueId() + config.getSlash(); + } + return folder; + } + + /** + * Gets the file of a book with the specified book meta + * + * @param bookDirectory

The book directory to look in

+ * @param bookMeta

The book meta of the book to locate

+ * @return

The file, or null if not found

+ */ + public static File getFile(@NotNull BookDirectory bookDirectory, @Nullable String group, @NotNull BookMeta bookMeta) { + String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); + return getFile(bookDirectory, group, bookMeta.getTitle() + separator + bookMeta.getAuthor()); + } + + /** + * Gets the file of a book with the specified name + * + * @param bookDirectory

The book directory to look in

+ * @param fileName

The name of the book's file

+ * @param sender

The command sender looking for a file

+ * @return

The file, or null if not found

+ */ + public static File getFile(@NotNull BookDirectory bookDirectory, @NotNull String fileName, @NotNull CommandSender sender) { + String folder = getBookDirectoryPathString(bookDirectory, sender); + if (folder != null) { + return getFile(folder, fileName); + } else { + return null; + } + } + + /** + * Gets the file of a book with the specified name + * + * @param bookDirectory

The book directory to look in

+ * @param subFolder

The sub-folder to check (player folder/group encrypt folder)

+ * @param fileName

The name of the book's file

+ * @return

The file, or null if not found

+ */ + @Nullable + public static File getFile(@NotNull BookDirectory bookDirectory, @Nullable String subFolder, @NotNull String fileName) { + File baseFolder = new File(BooksWithoutBorders.getConfiguration().getBookFolder()); + if (subFolder != null) { + subFolder = InputCleaningHelper.cleanString(subFolder); + } + File parentFolder = switch (bookDirectory) { + case PUBLIC -> baseFolder; + case PLAYER -> getPlayerFolder(baseFolder, subFolder); + case ENCRYPTED -> getEncryptedFolder(baseFolder, subFolder); + }; + + return getFile(parentFolder.getAbsolutePath(), fileName); + } + + /** + * Gets the file of a book with the specified name + * + * @param parentFolderName

The parent folder to look in

+ * @param fileName

The name of the book's file

+ * @return

The file, or null if not found

+ */ + @Nullable + public static File getFile(@NotNull String parentFolderName, @NotNull String fileName) { + File parentFolder = new File(parentFolderName); + if (!parentFolder.exists()) { + return null; + } + + fileName = InputCleaningHelper.cleanString(fileName); + List possiblePaths = List.of( + fileName, + fileName + ".yml", + fileName.replace(" ", "_") + ".yml", + fileName + ".txt", + fileName.replace(" ", "_") + ".txt"); + + for (String path : possiblePaths) { + File file = new File(parentFolder, path); + if (file.exists()) { + return file; + } + } + for (String path : possiblePaths) { + File file = new File(parentFolder, replaceAuthorWithUUID(path)); + if (file.exists()) { + return file; + } + } + return null; + } + + /** + * Gets the player folder + * + * @param baseFolder

The base book folder

+ * @param subFolder

The player sub-folder

+ * @return

The file for the folder

+ */ + @NotNull + private static File getPlayerFolder(@NotNull File baseFolder, @Nullable String subFolder) { + if (subFolder == null) { + return baseFolder; + } + File file = new File(baseFolder, replaceAuthorWithUUID(subFolder)); + if (file.exists()) { + return file; + } else { + // Check for legacy pre-uuid player folder + return new File(baseFolder, subFolder); + } + } + + /** + * Gets the encrypted folder + * + * @param baseFolder

The base book folder

+ * @param subFolder

The group sub-folder, or null

+ * @return

The file for the folder

+ */ + @NotNull + private static File getEncryptedFolder(@NotNull File baseFolder, @Nullable String subFolder) { + File encryptedFolder = new File(baseFolder, "Encrypted"); + if (subFolder == null || subFolder.isBlank()) { + return encryptedFolder; + } else { + return new File(encryptedFolder, subFolder); + } + } + + /** + * Lists available files + * + * @param searchDirectory

The directory to search for files

+ * @return

A list of available files

+ */ + @Nullable + private static List listFiles(@NotNull File searchDirectory) { + if (!searchDirectory.exists()) { + return null; + } + + List fileList = new ArrayList<>(); + File[] existingFiles = searchDirectory.listFiles(File::isFile); + if (existingFiles == null || existingFiles.length == 0) { + return null; + } + String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); + + for (File foundFile : existingFiles) { + // Filter out invalid files + if (foundFile.getName().contains("§")) { + continue; + } + String fileName = foundFile.getName(); + if (fileName.contains(separator)) { + //Convert the UUID into a username if necessary + String userName = getBookAuthorFromPath(fileName); + String title = getBookTitleFromPath(fileName); + fileList.add(title + separator + BookFileHelper.authorFromUUID(userName)); + } else { + fileList.add(fileName); + } + } + + // Sort the book list + Comparator bookComparator = Comparator.naturalOrder(); + fileList.sort((a, b) -> bookComparator.compare(InputCleaningHelper.stripColor(a).toLowerCase(), + InputCleaningHelper.stripColor(b).toLowerCase())); + return fileList; + } + } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookToFromTextHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileReaderWriterUtil.java similarity index 96% rename from src/main/java/net/knarcraft/bookswithoutborders/utility/BookToFromTextHelper.java rename to src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileReaderWriterUtil.java index d9f8ae4..5b046d1 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookToFromTextHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFileReaderWriterUtil.java @@ -22,14 +22,12 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; -import static net.knarcraft.bookswithoutborders.utility.BookHelper.authorFromUUID; - /** * Helper class for converting books to and from text/yml files */ -public final class BookToFromTextHelper { +public final class BookFileReaderWriterUtil { - private BookToFromTextHelper() { + private BookFileReaderWriterUtil() { } /** @@ -248,7 +246,8 @@ public final class BookToFromTextHelper { } bookMetadata.setTitle(bookYml.getString("Title", new FormatBuilder(Formatting.NEUTRAL_UNKNOWN_TITLE).build())); - bookMetadata.setAuthor(authorFromUUID(bookYml.getString("Author", new FormatBuilder(Formatting.NEUTRAL_UNKNOWN_AUTHOR).build()))); + bookMetadata.setAuthor(BookFileHelper.authorFromUUID(bookYml.getString("Author", + new FormatBuilder(Formatting.NEUTRAL_UNKNOWN_AUTHOR).build()))); bookMetadata.setPages(bookYml.getStringList("Pages")); bookMetadata.setLore(bookYml.getStringList("Lore")); bookMetadata.setDisplayName(bookYml.getString("DisplayName")); @@ -291,7 +290,7 @@ public final class BookToFromTextHelper { List pages = new ArrayList<>(InputCleaningHelper.cleanList(rawPages)); //Update the metadata of the book with its new values - bookMetadata.setAuthor(authorFromUUID(author)); + bookMetadata.setAuthor(BookFileHelper.authorFromUUID(author)); bookMetadata.setTitle(title.substring(0, Math.min(title.length(), 32))); bookMetadata.setPages(pages); @@ -332,10 +331,10 @@ public final class BookToFromTextHelper { //Adjust content to page length for each added line to make the text fit the book rawPages.add(firstLine); while (rawPages.get(rawPages.size() - 1) != null) { - BookFormatter.formatLastPage(rawPages); + BookFormatterUtil.formatLastPage(rawPages); rawPages.add(bufferedReader.readLine()); } - BookFormatter.formatLastPage(rawPages); + BookFormatterUtil.formatLastPage(rawPages); } bufferedReader.close(); diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatter.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatterUtil.java similarity index 92% rename from src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatter.java rename to src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatterUtil.java index 29dbcbb..3b26bfd 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatter.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookFormatterUtil.java @@ -12,9 +12,9 @@ import java.util.Objects; /** * A class for formatting text to fit books */ -public final class BookFormatter { +public final class BookFormatterUtil { - private BookFormatter() { + private BookFormatterUtil() { } /** @@ -119,15 +119,4 @@ public final class BookFormatter { return bookMeta; } - /** - * Strips the color from the given input - * - * @param input

The input to strip

- * @return

The color stripped input

- */ - @NotNull - public static String stripColor(@NotNull String input) { - return ColorHelper.stripColorCodes(input, ColorConversion.RGB); - } - } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java index f5d80db..9f3d793 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookHelper.java @@ -1,16 +1,12 @@ package net.knarcraft.bookswithoutborders.utility; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; -import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.translation.Formatting; import net.knarcraft.bookswithoutborders.config.translation.Translatable; -import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.knarlib.formatting.FormatBuilder; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; @@ -18,10 +14,8 @@ import org.bukkit.inventory.meta.WritableBookMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.UUID; import java.util.logging.Level; /** @@ -65,61 +59,6 @@ public final class BookHelper { return newBook; } - /** - * Converts the author of a book from UUID if necessary - * - * @param author

The author string

- * @return

The author string, converted if it was a UUID

- */ - @NotNull - public static String authorFromUUID(@NotNull String author) { - try { - UUID authorID = UUID.fromString(BookFormatter.stripColor(author)); - Player player = Bukkit.getPlayer(authorID); - if (player != null) { - author = player.getName(); - } - } catch (IllegalArgumentException ignored) { - } - return author; - } - - /** - * Gets the file path of the selected book directory - * - * @param bookDirectory

The book directory to get (ENCRYPTED is not supported here)

- * @param sender

The command sender trying to get the directory

- * @return

The path of the directory, or null if not possible to get

- */ - @Nullable - public static File getBookDirectoryPath(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) { - String bookFolderString = getBookDirectoryPathString(bookDirectory, sender); - if (bookFolderString == null) { - return null; - } - return new File(bookFolderString); - } - - /** - * Gets the string path of the selected book directory - * - * @param bookDirectory

The book directory to get (ENCRYPTED is not supported here)

- * @param sender

The command sender trying to get the directory

- * @return

The path of the directory, or null if not possible to get

- */ - @Nullable - public static String getBookDirectoryPathString(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) { - BwBConfig config = BooksWithoutBorders.getConfiguration(); - String folder = null; - String bookFolder = config.getBookFolder(); - if (bookDirectory == BookDirectory.PUBLIC) { - folder = bookFolder; - } else if (bookDirectory == BookDirectory.PLAYER && sender instanceof Player player) { - folder = bookFolder + player.getUniqueId() + config.getSlash(); - } - return folder; - } - /** * Increases the generation of the given book, if necessary * @@ -154,30 +93,6 @@ public final class BookHelper { }; } - /** - * Gets the file name of the given book - * - * @param book

The book to get the file of

- * @param player

The player trying to do something with the book

- * @return

The book file

- * @throws IllegalArgumentException

If the book title or author contains the title author separator

- */ - @NotNull - public static String getBookFile(@NotNull BookMeta book, @NotNull OfflinePlayer player, boolean isPublic) throws IllegalArgumentException { - String separator = BooksWithoutBorders.getConfiguration().getTitleAuthorSeparator(); - String bookName = getBookTitle(book); - String authorName = getBookAuthor(book, isPublic ? null : player); - - if (InputCleaningHelper.cleanString(bookName).contains(separator) || - InputCleaningHelper.cleanString(authorName).contains(separator)) { - throw new IllegalArgumentException(new FormatBuilder(StaticMessage.EXCEPTION_META_HAS_SEPARATOR.toString()). - replace("{author}", authorName).replace("{title}", bookName). - replace("{separator}", separator).build()); - } - - return InputCleaningHelper.cleanString(bookName + separator + authorName); - } - /** * Gets the author of a book, with fallback for unknown author * diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java index 001c5f3..43f37b5 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/BookLoader.java @@ -3,7 +3,6 @@ package net.knarcraft.bookswithoutborders.utility; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.config.BwBConfig; import net.knarcraft.bookswithoutborders.config.Permission; -import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.translation.Translatable; import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.knarlib.formatting.FormatBuilder; @@ -18,7 +17,6 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; /** * A helper class for loading books from files @@ -61,7 +59,7 @@ public final class BookLoader { new FormatBuilder(Translatable.ERROR_BOOK_DIRECTORY_UNKNOWN).error(sender); return null; } - return loadBook(sender, fileName, isSigned, bookDirectory, directory, numCopies); + return loadBook(sender, fileName, isSigned, bookDirectory, numCopies); } /** @@ -71,13 +69,12 @@ public final class BookLoader { * @param fileName

The index or file name of the book to load

* @param isSigned

Whether to load the book as signed, and not unsigned

* @param bookDirectory

The type of directory to save in

- * @param directory

The directory to save the book in

* @param numCopies

The number of copies to load

* @return

The loaded book

*/ @Nullable public static ItemStack loadBook(@NotNull CommandSender sender, @NotNull String fileName, boolean isSigned, - @NotNull BookDirectory bookDirectory, @NotNull String directory, int numCopies) { + @NotNull BookDirectory bookDirectory, int numCopies) { //Find the filename if a book index is given try { int bookIndex = Integer.parseInt(fileName); @@ -89,19 +86,35 @@ public final class BookLoader { } catch (NumberFormatException ignored) { } - BwBConfig config = BooksWithoutBorders.getConfiguration(); - //Get the full path of the book to load - File file = getFullPath(sender, fileName, bookDirectory, directory); - if (file == null) { - //Try converting the username to UUID - String replaced = BookFileHelper.replaceAuthorWithUUID(fileName); - file = getFullPath(sender, replaced, bookDirectory, directory); - if (file == null) { - new FormatBuilder(Translatable.ERROR_INCORRECT_FILE_NAME).error(sender); - return null; - } + File file; + if (bookDirectory == BookDirectory.PUBLIC) { + file = BookFileHelper.getFile(bookDirectory, null, fileName); + } else { + file = BookFileHelper.getFile(bookDirectory, fileName, sender); } + if (file == null) { + new FormatBuilder(Translatable.ERROR_INCORRECT_FILE_NAME).error(sender); + return null; + } + + return loadBook(sender, file, isSigned, bookDirectory, numCopies); + } + + /** + * Loads the given book + * + * @param sender

The command sender trying to load the book

+ * @param file

The file to load

+ * @param isSigned

Whether to load the book as signed, and not unsigned

+ * @param bookDirectory

The type of directory to load from

+ * @param numCopies

The number of copies to load

+ * @return

The loaded book

+ */ + @Nullable + public static ItemStack loadBook(@NotNull CommandSender sender, @NotNull File file, boolean isSigned, + @NotNull BookDirectory bookDirectory, int numCopies) { + BwBConfig config = BooksWithoutBorders.getConfiguration(); //Make sure the player can pay for the book if (config.booksHavePrice() && @@ -121,7 +134,7 @@ public final class BookLoader { } //Load the book from the given file - bookMetadata = BookToFromTextHelper.bookFromFile(file, bookMetadata); + bookMetadata = BookFileReaderWriterUtil.bookFromFile(file, bookMetadata); if (bookMetadata == null) { new FormatBuilder(Translatable.ERROR_LOAD_BOOK_EMPTY).error(sender); return null; @@ -149,37 +162,4 @@ public final class BookLoader { return book; } - /** - * Gets a File pointing to the wanted book - * - * @param sender

The sender to send errors to

- * @param fileName

The name of the book file

- * @param bookDirectory

The book directory the file resides in

- * @param directory

The relative directory given

- * @return

A file or null if it does not exist

- */ - @Nullable - private static File getFullPath(@NotNull CommandSender sender, @NotNull String fileName, - @NotNull BookDirectory bookDirectory, @NotNull String directory) { - BwBConfig config = BooksWithoutBorders.getConfiguration(); - File file = null; - String slash = config.getSlash(); - if (bookDirectory == BookDirectory.ENCRYPTED) { - file = BookFileHelper.findBookFile(config.getEncryptedBookPath() + directory + slash, fileName); - } else { - String folder = BookHelper.getBookDirectoryPathString(bookDirectory, sender); - if (folder != null) { - file = BookFileHelper.findBookFile(folder, fileName); - } else { - BooksWithoutBorders.log(Level.WARNING, new FormatBuilder(StaticMessage.EXCEPTION_UNKNOWN_DIRECTORY.toString()). - replace("{directory}", bookDirectory.toString()).build()); - } - } - if (file == null || !file.isFile()) { - return null; - } else { - return file; - } - } - } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java index 445bfe8..4b2082a 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/EncryptionHelper.java @@ -13,6 +13,7 @@ import net.knarcraft.bookswithoutborders.encryption.GenenCrypt; import net.knarcraft.bookswithoutborders.encryption.Magic; import net.knarcraft.bookswithoutborders.encryption.OneTimePad; import net.knarcraft.bookswithoutborders.encryption.SubstitutionCipher; +import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.knarlib.formatting.FormatBuilder; import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; @@ -183,7 +184,7 @@ public final class EncryptionHelper { } //Format the last page just in case - BookFormatter.formatLastPage(encryptedPages); + BookFormatterUtil.formatLastPage(encryptedPages); //Remove empty pages List newPages = InputCleaningHelper.cleanList(encryptedPages); @@ -258,23 +259,18 @@ public final class EncryptionHelper { boolean forceDecrypt) { ItemStack heldBook = InventoryHelper.getHeldBook(player, true); BookMeta bookMetadata = (BookMeta) heldBook.getItemMeta(); - String path = BooksWithoutBorders.getConfiguration().getEncryptedBookPath(); if (bookMetadata == null) { return null; } - String fileName = BookHelper.getBookFile(bookMetadata, player, true); - fileName = cleanString(fileName); - - - File file = new File(path + fileName + ".yml"); + File file = BookFileHelper.getFile(BookDirectory.ENCRYPTED, null, bookMetadata); if (!file.isFile()) { new FormatBuilder(Translatable.ERROR_DECRYPT_NOT_FOUND).error(player); return null; } else { try { - EncryptedBook book = BookToFromTextHelper.encryptedBookFromYml(file, bookMetadata, key, forceDecrypt, false); + EncryptedBook book = BookFileReaderWriterUtil.encryptedBookFromYml(file, bookMetadata, key, forceDecrypt, false); if (book == null) { throw new IllegalArgumentException(); } else { @@ -320,7 +316,7 @@ public final class EncryptionHelper { integerKey.append(Character.getNumericValue(Character.codePointAt(key, x))); } - String fileName = "[" + integerKey + "]" + BookHelper.getBookFile(bookMetadata, player, true); + String fileName = "[" + integerKey + "]" + BookFileHelper.getBookFile(bookMetadata, player, true); fileName = cleanString(fileName).replace(" ", "_"); File file = new File(path + fileName + ".yml"); @@ -333,7 +329,7 @@ public final class EncryptionHelper { } try { - bookMetadata = BookToFromTextHelper.bookFromFile(file, bookMetadata); + bookMetadata = BookFileReaderWriterUtil.bookFromFile(file, bookMetadata); if (bookMetadata == null) { new FormatBuilder(Translatable.ERROR_DECRYPT_FAILED).error(player); return null; @@ -445,7 +441,7 @@ public final class EncryptionHelper { } } //Generate file name - String fileName = BookHelper.getBookFile(bookMetadata, player, true); + String fileName = BookFileHelper.getBookFile(bookMetadata, player, true); List newLore = new ArrayList<>(); newLore.add(ChatColor.GRAY + "[" + groupName + " encrypted]"); @@ -461,7 +457,7 @@ public final class EncryptionHelper { File file = new File(path + fileName + ".yml"); if (!file.isFile()) { try { - BookToFromTextHelper.bookToYml(path, fileName, bookMetadata); + BookFileReaderWriterUtil.bookToYml(path, fileName, bookMetadata); } catch (IOException exception) { new FormatBuilder(Translatable.ERROR_GROUP_ENCRYPT_FAILED).error(player); return null; @@ -482,7 +478,7 @@ public final class EncryptionHelper { private static Boolean saveEncryptedBook(@NotNull Player player, @NotNull EncryptedBook encryptedBook) { String path = BooksWithoutBorders.getConfiguration().getEncryptedBookPath(); - String fileName = BookHelper.getBookFile(encryptedBook.bookMeta(), player, true); + String fileName = BookFileHelper.getBookFile(encryptedBook.bookMeta(), player, true); fileName = cleanString(fileName); //cancels saving if file is already encrypted @@ -493,7 +489,7 @@ public final class EncryptionHelper { } try { - BookToFromTextHelper.encryptedBookToYml(path, fileName, encryptedBook); + BookFileReaderWriterUtil.encryptedBookToYml(path, fileName, encryptedBook); } catch (IOException exception) { new FormatBuilder(Translatable.ERROR_ENCRYPT_FAILED).error(player); return false; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java index 329f930..b4c499d 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java @@ -1,5 +1,7 @@ package net.knarcraft.bookswithoutborders.utility; +import net.knarcraft.knarlib.property.ColorConversion; +import net.knarcraft.knarlib.util.ColorHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,6 +52,17 @@ public final class InputCleaningHelper { return fileName; } + /** + * Strips the color from the given input + * + * @param input

The input to strip

+ * @return

The color stripped input

+ */ + @NotNull + public static String stripColor(@NotNull String input) { + return ColorHelper.stripColorCodes(input, ColorConversion.RGB); + } + /** * Parses a page number for a string like "page1" *