Cleans up book loading code, and fixes a bug in loading private books
All checks were successful
EpicKnarvik97/Books-Without-Borders/pipeline/head This commit looks good
All checks were successful
EpicKnarvik97/Books-Without-Borders/pipeline/head This commit looks good
This commit is contained in:
@@ -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<String> 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<String> 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<String> 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 <p>The books to look through</p>
|
||||
* @return <p>The map of the first index containing each character</p>
|
||||
*/
|
||||
@NotNull
|
||||
private static Map<Character, Integer> populateLetterIndices(@NotNull List<String> books) {
|
||||
Map<Character, Integer> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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" +
|
||||
|
@@ -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<String> 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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
if (file == null) {
|
||||
file = BookFileHelper.findBookFile(encryptedFolder, oldBook);
|
||||
if (file == null) {
|
||||
file = BookFileHelper.findBookFile(config.getBookFolder(), oldBook);
|
||||
File file = BookFileHelper.getFile(BookDirectory.ENCRYPTED, groupName, oldBook);
|
||||
if (file == null) {
|
||||
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);
|
||||
|
@@ -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 <p>The player which clicked the sign</p>
|
||||
*/
|
||||
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");
|
||||
|
@@ -42,4 +42,18 @@ public enum BookDirectory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the common public/player directory based on the input
|
||||
*
|
||||
* @param isPublic <p>Whether to get the public directory</p>
|
||||
* @return <p>The specified directory</p>
|
||||
*/
|
||||
public static BookDirectory getCommon(boolean isPublic) {
|
||||
if (isPublic) {
|
||||
return BookDirectory.PUBLIC;
|
||||
} else {
|
||||
return BookDirectory.PLAYER;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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 <p>The path to a book</p>
|
||||
* @return <p>True if the file exists and points to a book file</p>
|
||||
*/
|
||||
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
|
||||
*
|
||||
* <p>This function adds extensions to the path as necessary, returning the first match.</p>
|
||||
*
|
||||
* @param bookPath <p>The path of the book to get</p>
|
||||
* @return <p>The file the path points to, or null otherwise</p>
|
||||
*/
|
||||
@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<String> 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 <p>The books to look through</p>
|
||||
* @return <p>The map of the first index containing each character</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static Map<Character, Integer> populateLetterIndices(@NotNull List<String> books) {
|
||||
Map<Character, Integer> 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 <p>The command sender looking for files</p>
|
||||
* @param searchDirectory <p>The directory to search for files</p>
|
||||
* @return <p>A list of available files</p>
|
||||
*/
|
||||
@Nullable
|
||||
private static List<String> listFiles(@NotNull CommandSender sender, @NotNull File searchDirectory) {
|
||||
List<String> 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<String> 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 <p>The folder the book is in</p>
|
||||
* @param bookMeta <p>The book meta of the book to find</p>
|
||||
* @return <p>The book's file, or null if not found</p>
|
||||
*/
|
||||
@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 <p>The folder the book is in</p>
|
||||
* @param fileName <p>The name of the book to find</p>
|
||||
* @return <p>The book's file, or null if not found</p>
|
||||
*/
|
||||
@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 <p>The filename, or the filename with the author replaced with UUID</p>
|
||||
*/
|
||||
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 <p>The author string</p>
|
||||
* @return <p>The author string, converted if it was a UUID</p>
|
||||
*/
|
||||
@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 <p>The book to get the file of</p>
|
||||
* @param player <p>The player trying to do something with the book</p>
|
||||
* @return <p>The book file</p>
|
||||
* @throws IllegalArgumentException <p>If the book title or author contains the title author separator</p>
|
||||
*/
|
||||
@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 <p>The book directory to get (ENCRYPTED is not supported here)</p>
|
||||
* @param sender <p>The command sender trying to get the directory</p>
|
||||
* @return <p>The path of the directory, or null if not possible to get</p>
|
||||
*/
|
||||
@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 <p>The book directory to get (ENCRYPTED is not supported here)</p>
|
||||
* @param sender <p>The command sender trying to get the directory</p>
|
||||
* @return <p>The path of the directory, or null if not possible to get</p>
|
||||
*/
|
||||
@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 <p>The book directory to look in</p>
|
||||
* @param bookMeta <p>The book meta of the book to locate</p>
|
||||
* @return <p>The file, or null if not found</p>
|
||||
*/
|
||||
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 <p>The book directory to look in</p>
|
||||
* @param fileName <p>The name of the book's file</p>
|
||||
* @param sender <p>The command sender looking for a file</p>
|
||||
* @return <p>The file, or null if not found</p>
|
||||
*/
|
||||
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 <p>The book directory to look in</p>
|
||||
* @param subFolder <p>The sub-folder to check (player folder/group encrypt folder)</p>
|
||||
* @param fileName <p>The name of the book's file</p>
|
||||
* @return <p>The file, or null if not found</p>
|
||||
*/
|
||||
@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 <p>The parent folder to look in</p>
|
||||
* @param fileName <p>The name of the book's file</p>
|
||||
* @return <p>The file, or null if not found</p>
|
||||
*/
|
||||
@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<String> 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 <p>The base book folder</p>
|
||||
* @param subFolder <p>The player sub-folder</p>
|
||||
* @return <p>The file for the folder</p>
|
||||
*/
|
||||
@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 <p>The base book folder</p>
|
||||
* @param subFolder <p>The group sub-folder, or null</p>
|
||||
* @return <p>The file for the folder</p>
|
||||
*/
|
||||
@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 <p>The directory to search for files</p>
|
||||
* @return <p>A list of available files</p>
|
||||
*/
|
||||
@Nullable
|
||||
private static List<String> listFiles(@NotNull File searchDirectory) {
|
||||
if (!searchDirectory.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> 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<String> bookComparator = Comparator.naturalOrder();
|
||||
fileList.sort((a, b) -> bookComparator.compare(InputCleaningHelper.stripColor(a).toLowerCase(),
|
||||
InputCleaningHelper.stripColor(b).toLowerCase()));
|
||||
return fileList;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<String> 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();
|
||||
|
@@ -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 <p>The input to strip</p>
|
||||
* @return <p>The color stripped input</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static String stripColor(@NotNull String input) {
|
||||
return ColorHelper.stripColorCodes(input, ColorConversion.RGB);
|
||||
}
|
||||
|
||||
}
|
@@ -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 <p>The author string</p>
|
||||
* @return <p>The author string, converted if it was a UUID</p>
|
||||
*/
|
||||
@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 <p>The book directory to get (ENCRYPTED is not supported here)</p>
|
||||
* @param sender <p>The command sender trying to get the directory</p>
|
||||
* @return <p>The path of the directory, or null if not possible to get</p>
|
||||
*/
|
||||
@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 <p>The book directory to get (ENCRYPTED is not supported here)</p>
|
||||
* @param sender <p>The command sender trying to get the directory</p>
|
||||
* @return <p>The path of the directory, or null if not possible to get</p>
|
||||
*/
|
||||
@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 <p>The book to get the file of</p>
|
||||
* @param player <p>The player trying to do something with the book</p>
|
||||
* @return <p>The book file</p>
|
||||
* @throws IllegalArgumentException <p>If the book title or author contains the title author separator</p>
|
||||
*/
|
||||
@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
|
||||
*
|
||||
|
@@ -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 <p>The index or file name of the book to load</p>
|
||||
* @param isSigned <p>Whether to load the book as signed, and not unsigned</p>
|
||||
* @param bookDirectory <p>The type of directory to save in</p>
|
||||
* @param directory <p>The directory to save the book in</p>
|
||||
* @param numCopies <p>The number of copies to load</p>
|
||||
* @return <p>The loaded book</p>
|
||||
*/
|
||||
@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,20 +86,36 @@ 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);
|
||||
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 <p>The command sender trying to load the book</p>
|
||||
* @param file <p>The file to load</p>
|
||||
* @param isSigned <p>Whether to load the book as signed, and not unsigned</p>
|
||||
* @param bookDirectory <p>The type of directory to load from</p>
|
||||
* @param numCopies <p>The number of copies to load</p>
|
||||
* @return <p>The loaded book</p>
|
||||
*/
|
||||
@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() &&
|
||||
!sender.hasPermission(Permission.BYPASS_BOOK_PRICE.toString()) &&
|
||||
@@ -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 <p>The sender to send errors to</p>
|
||||
* @param fileName <p>The name of the book file</p>
|
||||
* @param bookDirectory <p>The book directory the file resides in</p>
|
||||
* @param directory <p>The relative directory given</p>
|
||||
* @return <p>A file or null if it does not exist</p>
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<String> 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<String> 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;
|
||||
|
@@ -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 <p>The input to strip</p>
|
||||
* @return <p>The color stripped input</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static String stripColor(@NotNull String input) {
|
||||
return ColorHelper.stripColorCodes(input, ColorConversion.RGB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a page number for a string like "page1"
|
||||
*
|
||||
|
Reference in New Issue
Block a user