Fixes migration removing password keys, and removes more static strings
All checks were successful
EpicKnarvik97/Books-Without-Borders/pipeline/head This commit looks good

This commit is contained in:
2025-08-17 14:02:11 +02:00
parent dc5d18550f
commit 57ca6ff2e9
11 changed files with 91 additions and 22 deletions

View File

@@ -113,10 +113,12 @@ public class CommandDecrypt implements TabExecutor {
String key = "";
for (String encryptedFile : encryptedFiles) {
if (encryptedFile.contains(BookHelper.getBookFile(bookMetadata, player, true).replace(" ", "_"))) {
key = encryptedFile.substring(encryptedFile.indexOf("[") + 1, encryptedFile.indexOf("]"));
key = EncryptionHelper.extractLegacyKey(encryptedFile);
if (!key.isBlank()) {
break;
}
}
}
if (!key.isBlank()) {
//Decrypt the book

View File

@@ -111,7 +111,7 @@ public class CommandGive implements TabExecutor {
try {
return loadAndGiveBook(bookIdentifier, sender, receivingPlayer, isSigned, folder, copies);
} catch (NumberFormatException e) {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_GIVE_INVALID_COPIES_AMOUNT);
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_INVALID_COPIES_AMOUNT);
return false;
}
}

View File

@@ -1,7 +1,9 @@
package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.encryption.EncryptionStyle;
import net.knarcraft.knarlib.formatting.StringFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -19,8 +21,14 @@ public class CommandGroupEncrypt extends CommandEncrypt implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] arguments) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
if (!(sender instanceof Player player)) {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_PLAYER_ONLY);
return false;
}
BookMeta bookMetadata = performPreChecks(sender, arguments, 2,
"You must specify a group name and key to encrypt a book!");
stringFormatter.getUnFormattedColoredMessage(Translatable.ERROR_GROUP_ENCRYPT_ARGUMENTS_MISSING));
if (bookMetadata == null) {
return false;
@@ -29,12 +37,12 @@ public class CommandGroupEncrypt extends CommandEncrypt implements TabExecutor {
//Check if book is already group encrypted
List<String> lore = bookMetadata.getLore();
if (bookMetadata.hasLore() && lore != null && lore.get(0).contains(" encrypted]")) {
BooksWithoutBorders.sendErrorMessage(sender, "Book is already group encrypted!");
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_GROUP_ENCRYPTED_ALREADY);
return false;
}
EncryptionStyle encryptionStyle = arguments.length == 3 ? EncryptionStyle.getFromString(arguments[2]) : EncryptionStyle.SUBSTITUTION;
return encryptBook(encryptionStyle, (Player) sender, arguments[1], arguments[0]);
return encryptBook(encryptionStyle, player, arguments[1], arguments[0]);
}
@Override

View File

@@ -1,10 +1,12 @@
package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.gui.PagedBookIndex;
import net.knarcraft.bookswithoutborders.utility.BookLoader;
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
import net.knarcraft.bookswithoutborders.utility.TabCompletionTypeHelper;
import net.knarcraft.knarlib.formatting.StringFormatter;
import net.knarcraft.knarlib.util.TabCompletionHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -38,13 +40,14 @@ public class CommandLoad implements TabExecutor {
*/
public boolean loadBook(@NotNull CommandSender sender, @NotNull String[] arguments, @NotNull String directory,
boolean loadPublic) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
if (!(sender instanceof Player player)) {
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_PLAYER_ONLY);
return false;
}
if (player.getInventory().firstEmpty() == -1) {
BooksWithoutBorders.sendErrorMessage(player, "You must have space in your inventory to load books!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_INVENTORY_FULL);
return false;
}
@@ -60,6 +63,7 @@ public class CommandLoad implements TabExecutor {
String copies = "1";
String isSigned = "true";
// Parse arguments at the end of the command, and treat the rest as the book name
if (argumentCount > 1) {
if (argumentCount > 2 && InputCleaningHelper.isInt(arguments[argumentCount - 2]) &&
InputCleaningHelper.isBoolean(arguments[argumentCount - 1])) {
@@ -90,14 +94,14 @@ public class CommandLoad implements TabExecutor {
ItemStack newBook = BookLoader.loadBook(player, bookToLoad, isSigned, directory, Integer.parseInt(copies));
if (newBook != null) {
player.getInventory().addItem(newBook);
BooksWithoutBorders.sendSuccessMessage(player, "Book created!");
stringFormatter.displaySuccessMessage(player, Translatable.SUCCESS_BOOK_LOADED);
return true;
} else {
BooksWithoutBorders.sendErrorMessage(player, "Book failed to load!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_LOAD_FAILED);
return false;
}
} catch (NumberFormatException e) {
BooksWithoutBorders.sendErrorMessage(player, "Invalid number of book copies specified!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_INVALID_COPIES_AMOUNT);
return false;
}
}

View File

@@ -4,6 +4,7 @@ import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.container.MigrationRequest;
import net.knarcraft.bookswithoutborders.thread.MigrationQueueThread;
import net.knarcraft.knarlib.formatting.StringFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -25,12 +26,13 @@ public class CommandMigrate implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
if (!(sender instanceof Player player)) {
BooksWithoutBorders.getStringFormatter().displayErrorMessage(sender, Translatable.ERROR_PLAYER_ONLY);
return false;
}
File bookDirectory = new File(BooksWithoutBorders.getConfiguration().getBookFolder());
BooksWithoutBorders.sendSuccessMessage(player, "Starting book migration...");
stringFormatter.displaySuccessMessage(player, Translatable.SUCCESS_MIGRATION_STARTED);
Queue<MigrationRequest> filesToMigrate = new LinkedList<>();
findFilesToMigrate(bookDirectory, filesToMigrate, player);
BooksWithoutBorders.getMigrationQueue().addAll(filesToMigrate);

View File

@@ -58,6 +58,16 @@ public enum Translatable implements TranslatableMessage {
*/
SUCCESS_PAGE_DELETED,
/**
* The success message displayed after a book has been loaded
*/
SUCCESS_BOOK_LOADED,
/**
* The success message displayed after book migration has started
*/
SUCCESS_MIGRATION_STARTED,
/**
* The error to display when the console attempts to run a player-only command
*/
@@ -186,7 +196,7 @@ public enum Translatable implements TranslatableMessage {
/**
* The error displayed when using the give command with an invalid number of copies (unlikely to ever happen)
*/
ERROR_GIVE_INVALID_COPIES_AMOUNT,
ERROR_INVALID_COPIES_AMOUNT,
/**
* The error displayed when a book is not properly loaded when using the give command
@@ -213,6 +223,21 @@ public enum Translatable implements TranslatableMessage {
*/
ERROR_OUT_OF_RANGE_BOOK_PAGE,
/**
* The error displayed when a player fails to provide necessary arguments for group encryption
*/
ERROR_GROUP_ENCRYPT_ARGUMENTS_MISSING,
/**
* The error displayed when trying to attempt a group encrypted book twice
*/
ERROR_GROUP_ENCRYPTED_ALREADY,
/**
* The error displayed when a book fails to be loaded
*/
ERROR_LOAD_FAILED,
/**
* The header displayed before printing all commands
*/

View File

@@ -28,9 +28,9 @@ public class PlayerEventListener implements Listener {
//If a book directory exists with this player's name, move it to this player's UUID
String bookFolder = config.getBookFolder();
File file = new File(bookFolder + InputCleaningHelper.cleanString(player.getName()));
File file = new File(bookFolder, InputCleaningHelper.cleanString(player.getName()));
if (file.exists()) {
if (!file.renameTo(new File(bookFolder + player.getUniqueId()))) {
if (!file.renameTo(new File(bookFolder, player.getUniqueId().toString()))) {
BooksWithoutBorders.log(Level.WARNING, "Unable to migrate player book " +
"directory for player " + player.getName());
}

View File

@@ -5,6 +5,7 @@ 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.EncryptionHelper;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
@@ -88,6 +89,7 @@ public class MigrationQueueThread implements Runnable {
if (bookMeta == null) {
return false;
}
BookMeta loadedBook;
String extension = BookFileHelper.getExtensionFromPath(file.getName());
if (extension.equalsIgnoreCase("yml")) {
@@ -116,6 +118,13 @@ public class MigrationQueueThread implements Runnable {
try {
String newName = BookHelper.getBookFile(loadedBook, author, isPublic);
// Retain legacy key
String key = EncryptionHelper.extractLegacyKey(file.getName());
if (!key.isBlank()) {
newName = "[" + key + "]" + newName;
}
return saveBook(file.getParentFile(), newName, loadedBook, file);
} catch (IllegalArgumentException exception) {
BooksWithoutBorders.sendErrorMessage(player, "Failed to migrate book: " + file.getName() + " Cause:");

View File

@@ -163,7 +163,6 @@ public final class BookToFromTextHelper {
userKey = realKey;
}
if (!userKey.equals(realKey)) {
BooksWithoutBorders.log(Level.INFO, "Supplied key: " + userKey + " does not match real key: " + realKey);
return null;
}

View File

@@ -351,6 +351,21 @@ public final class EncryptionHelper {
return newBook;
}
/**
* Attempts to extract a legacy password key from a filename
*
* @param fileName <p>The filename to get the legacy key from</p>
* @return <p>The legacy key, or an empty string if not found</p>
*/
@NotNull
public static String extractLegacyKey(@NotNull String fileName) {
if (fileName.matches("^\\[[0-9]+].*")) {
return fileName.substring(fileName.indexOf("[") + 1, fileName.indexOf("]"));
} else {
return "";
}
}
/**
* Converts a byte array to a hexadecimal string
*

View File

@@ -10,17 +10,19 @@ en:
SUCCESS_GIVE_RECEIVED: "Book received!"
SUCCESS_TITLE_PAGE_ADDED: "Title page added!"
SUCCESS_PAGE_DELETED: "Page deleted!"
ERROR_PLAYER_ONLY: "This command can only be used by a player!"
ERROR_NOT_HOLDING_WRITTEN_BOOK: "You must be holding a written book to {action} it!"
ERROR_NOT_HOLDING_WRITABLE_BOOK: "You must be holding a writable book to {action} it!"
ERROR_NOT_HOLDING_ANY_BOOK: "You must be holding a book to perform this command"
ERROR_ONLY_ONE_BOOK: "You cannot {action} two books at once!"
SUCCESS_BOOK_LOADED: "Book created!"
SUCCESS_MIGRATION_STARTED: "Starting book migration..."
ACTION_COPY: "copy"
ACTION_CLEAR: "clear"
ACTION_DECRYPT: "decrypt"
ACTION_ENCRYPT: "encrypt"
ACTION_FORMAT: "format"
ACTION_ADD_TITLE_AUTHOR_PAGE: "add an author title page to"
ERROR_PLAYER_ONLY: "This command can only be used by a player!"
ERROR_NOT_HOLDING_WRITTEN_BOOK: "You must be holding a written book to {action} it!"
ERROR_NOT_HOLDING_WRITABLE_BOOK: "You must be holding a writable book to {action} it!"
ERROR_NOT_HOLDING_ANY_BOOK: "You must be holding a book to perform this command"
ERROR_ONLY_ONE_BOOK: "You cannot {action} two books at once!"
ERROR_COPY_COUNT_NOT_SPECIFIED: "You must specify the number of copies to be made!"
ERROR_COPY_NEGATIVE_AMOUNT: "Number of copies must be larger than 0!"
ERROR_COPY_INVALID_AMOUNT: |
@@ -44,11 +46,14 @@ en:
ERROR_GIVE_NO_RECIPIENT: "You have not specified the recipient of the book!"
ERROR_GIVE_RECIPIENT_UNKNOWN: "Player not found!"
ERROR_GIVE_RECIPIENT_FULL: "Receiving player must have space in their inventory to receive books!"
ERROR_GIVE_INVALID_COPIES_AMOUNT: "Invalid number of book copies specified!"
ERROR_INVALID_COPIES_AMOUNT: "Invalid number of book copies specified!"
ERROR_GIVE_LOAD_FAILED: "Book failed to load!"
ERROR_INVALID_BOOK_PAGE: "Invalid page index given!"
ERROR_OUT_OF_RANGE_BOOK_PAGE: "The given page index is out of bounds!"
ERROR_NO_BOOK_PAGE: "You must supply a page index"
ERROR_GROUP_ENCRYPT_ARGUMENTS_MISSING: "You must specify a group name and key to encrypt a book!"
ERROR_GROUP_ENCRYPTED_ALREADY: "Book is already group encrypted!"
ERROR_LOAD_FAILED: "Book failed to load!"
NEUTRAL_COMMANDS_HEADER: |
&e[] denote optional parameters
<> denote required parameters