Replaces all static strings using the old formatting methods
All checks were successful
EpicKnarvik97/Books-Without-Borders/pipeline/head This commit looks good

This commit is contained in:
2025-08-22 01:57:19 +02:00
parent e342f4cff5
commit c97436830a
19 changed files with 346 additions and 155 deletions

View File

@@ -386,24 +386,4 @@ public class BooksWithoutBorders extends JavaPlugin {
return true;
}
/**
* Sends a success message to a command sender (player or a console)
*
* @param sender <p>The sender to send the message to</p>
* @param message <p>The message to send</p>
*/
public static void sendSuccessMessage(@NotNull CommandSender sender, @NotNull String message) {
sender.sendMessage(getConfiguration().getSuccessColor() + message);
}
/**
* Sends an error message to a command sender (player or a console)
*
* @param sender <p>The sender to send the message to</p>
* @param message <p>The message to send</p>
*/
public static void sendErrorMessage(@NotNull CommandSender sender, @NotNull String message) {
sender.sendMessage(getConfiguration().getErrorColor() + message);
}
}

View File

@@ -101,7 +101,7 @@ public class CommandDelete implements TabExecutor {
} else {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_DELETE_FAILED_SILENT);
}
} catch (Exception e) {
} catch (Exception exception) {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_DELETE_FAILED_EXCEPTION);
}
}

View File

@@ -105,7 +105,7 @@ public class CommandSave implements TabExecutor {
try {
fileName = BookHelper.getBookFile(book, player, saveToPublicFolder);
} catch (IllegalArgumentException exception) {
BooksWithoutBorders.sendErrorMessage(player, exception.getMessage());
stringFormatter.displayErrorMessage(player, exception.getMessage());
return;
}

View File

@@ -53,7 +53,7 @@ public class CommandSetBookPrice implements TabExecutor {
stringFormatter.displayErrorMessage(sender, CostMessage.ERROR_COST_INVALID_QUANTITY);
return false;
}
} catch (NumberFormatException e) {
} catch (NumberFormatException exception) {
stringFormatter.displayErrorMessage(sender, CostMessage.ERROR_COST_INVALID_QUANTITY);
return false;
}
@@ -142,7 +142,8 @@ public class CommandSetBookPrice implements TabExecutor {
CostMessage.SUCCESS_COST_ECONOMY_SET, "{cost}", economyManager.getEconomy().format(newPriceQuantity)));
return true;
} else {
BooksWithoutBorders.sendErrorMessage(sender, StaticMessage.EXCEPTION_VAULT_PRICE_NOT_CHANGED.toString());
BooksWithoutBorders.getStringFormatter().displayErrorMessage(sender,
StaticMessage.EXCEPTION_VAULT_PRICE_NOT_CHANGED.toString());
return false;
}
}

View File

@@ -30,6 +30,7 @@ public enum StaticMessage {
EXCEPTION_BOOK_LOAD_FAILED("Unable to read text file"),
EXCEPTION_BOOK_UNKNOWN_EXTENSION("Trying to load a book file with an unrecognized extension"),
EXCEPTION_UNEXPECTED_ENCRYPTED_BOOK("Attempted to load a normal book, but found an encrypted book instead"),
EXCEPTION_NOT_HOLDING_ONE_BOOK("The player is not holding exactly one book."),
;
private final @NotNull String messageString;

View File

@@ -47,6 +47,26 @@ public enum CostMessage implements TranslatableMessage {
* The error displayed when attempting to set an item cost without providing an item
*/
ERROR_COST_ITEM_MISSING,
/**
* The error displayed when a player is unable to pay the item cost of printing a book
*/
ERROR_COST_INSUFFICIENT_AMOUNT,
/**
* The error displayed when a player is unable to pay the book and quill cost of printing a book
*/
ERROR_COST_INSUFFICIENT_WRITABLE_BOOK,
/**
* The success message displayed when economy cost is successfully paid
*/
SUCCESS_COST_PAID,
/**
* The error displayed when a player is unable to pay the economy cost of printing a book
*/
ERROR_COST_INSUFFICIENT_ECONOMY,
;
@Override

View File

@@ -52,6 +52,11 @@ public enum SignText implements TranslatableMessage {
* The error displayed when attempting to use an invalid BwB sign
*/
ERROR_SIGN_COMMAND_INVALID,
/**
* The success message displayed when successfully getting a book from a give sign
*/
SUCCESS_SIGN_GIVE,
;
@Override

View File

@@ -83,11 +83,26 @@ public enum Translatable implements TranslatableMessage {
*/
SUCCESS_TITLE_SET,
/**
* The success message displayed when books have been successfully migrated
*/
SUCCESS_MIGRATED,
/**
* The error to display when the console attempts to run a player-only command
*/
ERROR_PLAYER_ONLY,
/**
* The success message displayed when a book is successfully encrypted
*/
SUCCESS_ENCRYPTED,
/**
* The neutral message displayed when attempting legacy decryption after the updated decryption has failed
*/
NEUTRAL_ATTEMPTING_LEGACY_DECRYPTION,
/**
* The error displayed when running a relevant command without holding a written book
*/
@@ -312,6 +327,87 @@ public enum Translatable implements TranslatableMessage {
* The error displayed when attempting to encrypt a book that has an existing encrypted file
*/
ERROR_ENCRYPT_ALREADY_SAVED,
/**
* The error displayed if attempting to replace a player's held book with another book, but the player is no longer
* holding exactly one book
*/
ERROR_BOOK_NOT_FOUND,
/**
* The error displayed if attempting to list books while no books have been saved
*/
ERROR_NO_BOOKS_TO_LIST,
/**
* The error displayed if attempting to decrypt a group encrypted book without the necessary permissions
*/
ERROR_GROUP_DECRYPT_NO_PERMISSION,
/**
* The error displayed if a group encrypted book's file cannot be found on the server
*/
ERROR_GROUP_DECRYPT_NOT_FOUND,
/**
* The error displayed if a group encrypted book cannot be loaded during decryption
*/
ERROR_GROUP_DECRYPT_LOAD_FAILED,
/**
* The error displayed when one or more books fails to be migrated
*/
ERROR_MIGRATION_FAILED,
/**
* The error displayed when a book fails to be migrated
*/
ERROR_MIGRATION_BOOK_FAILED,
/**
* The error displayed when an unrecognized book directory is encountered
*/
ERROR_BOOK_DIRECTORY_UNKNOWN,
/**
* The error displayed when unable to get blank book metadata from the item factory
*/
ERROR_METADATA_CREATION_FAILED,
/**
* The error displayed when a loaded book is empty
*/
ERROR_LOAD_BOOK_EMPTY,
/**
* The error displayed when a command can only be used by the author of a book
*/
ERROR_AUTHOR_ONLY,
/**
* The error displayed when attempting to encrypt an empty book
*/
ERROR_ENCRYPT_BOOK_EMPTY,
/**
* The error displayed when the book to be decrypted cannot be found
*/
ERROR_DECRYPT_NOT_FOUND,
/**
* The error displayed when an invalid key is given during legacy encryption
*/
ERROR_DECRYPT_LEGACY_INVALID_KEY,
/**
* The error displayed when group encryption fails
*/
ERROR_GROUP_ENCRYPT_FAILED,
/**
* The error displayed when encryption fails
*/
ERROR_ENCRYPT_FAILED,
;
@Override

View File

@@ -89,7 +89,7 @@ public class SubstitutionCipher implements Encryptor {
try {
offsetArray[i] = Integer.parseInt(nextToken);
} catch (NumberFormatException e) {
} catch (NumberFormatException exception) {
BigInteger big = new BigInteger(nextToken);
offsetArray[i] = Math.abs(big.intValue());
}

View File

@@ -0,0 +1,114 @@
package net.knarcraft.bookswithoutborders.listener;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.Permission;
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.StringFormatter;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.BookMeta;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/**
* A listener for players trying to decrypt a group encrypted book
*/
public class GroupDecryptListener implements Listener {
@EventHandler
public void onEncryptedBookClick(@NotNull PlayerInteractEvent event) {
Player player = event.getPlayer();
PlayerInventory playerInventory = player.getInventory();
EquipmentSlot hand = event.getHand();
if (hand == null) {
return;
}
ItemStack heldItem = playerInventory.getItem(hand);
if (heldItem == null) {
return;
}
Material heldItemType = heldItem.getType();
if (heldItemType == Material.WRITTEN_BOOK && (event.getAction() == Action.LEFT_CLICK_AIR
|| event.getAction() == Action.LEFT_CLICK_BLOCK)) {
BookMeta oldBook = (BookMeta) heldItem.getItemMeta();
if (oldBook == null) {
return;
}
decryptBook(oldBook, player, heldItem, hand);
}
}
/**
* Decrypts a book decryptable for a given group
*
* @param oldBook <p>Metadata for the encrypted book</p>
* @param player <p>The player decrypting the book</p>
* @param heldItem <p>The type of the held book</p>
* @param hand <p>The hand the player is using to hold the book</p>
*/
private void decryptBook(@NotNull BookMeta oldBook, @NotNull Player player, @NotNull ItemStack heldItem,
@NotNull EquipmentSlot hand) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
BwBConfig config = BooksWithoutBorders.getConfiguration();
ItemStack newBook;
//Check if the book is encrypted by Books Without Borders
if (!oldBook.hasLore() || oldBook.getLore() == null || !oldBook.getLore().get(0).contains(" encrypted]")) {
return;
}
String groupName = oldBook.getLore().get(0).substring(3).split(" encrypted")[0];
//Permission check
if (!player.hasPermission(Permission.DECRYPT + "." + groupName) &&
!(config.getAdminDecrypt() && player.hasPermission(Permission.ADMIN.toString()))) {
stringFormatter.displayErrorMessage(player, Translatable.ERROR_GROUP_DECRYPT_NO_PERMISSION);
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);
if (file == null) {
stringFormatter.displayErrorMessage(player, Translatable.ERROR_GROUP_DECRYPT_NOT_FOUND);
return;
}
}
}
newBook = BookLoader.loadBook(player, fileName, true, BookDirectory.ENCRYPTED, groupName,
heldItem.getAmount());
if (newBook == null) {
stringFormatter.displayErrorMessage(player, Translatable.ERROR_GROUP_DECRYPT_LOAD_FAILED);
return;
}
player.getInventory().setItem(hand, newBook);
player.closeInventory();
stringFormatter.displaySuccessMessage(player, Translatable.SUCCESS_AUTO_DECRYPTED);
}
}

View File

@@ -1,17 +1,15 @@
package net.knarcraft.bookswithoutborders.listener;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BwBConfig;
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.StringFormatter;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
@@ -29,11 +27,9 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.BookMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
import static net.knarcraft.bookswithoutborders.utility.BookFileHelper.isBookListIndex;
@@ -126,15 +122,6 @@ public class SignEventListener implements Listener {
List.of("{action}", "{data}"), List.of(front.getLine(1), front.getLine(2))));
player.sendMessage(String.valueOf(getSignLine2Color(sign)));
}
} else if (heldItemType == Material.WRITTEN_BOOK && (event.getAction() == Action.LEFT_CLICK_AIR
|| event.getAction() == Action.LEFT_CLICK_BLOCK)) {
BookMeta oldBook = (BookMeta) heldItem.getItemMeta();
if (oldBook == null) {
return;
}
decryptBook(oldBook, player, heldItem, hand);
}
}
@@ -193,13 +180,6 @@ public class SignEventListener implements Listener {
*/
private void generateGiveSign(@NotNull SignChangeEvent event, @NotNull String[] lines,
@NotNull Player player) {
if (lines[2].length() > 13 || lines[3].length() > 13) {
BooksWithoutBorders.sendErrorMessage(player,
"[Give] signs' 3rd and 4th lines must be 13 characters or less!");
markGiveSignValidity(event, false);
return;
}
//Tests if a full file name has been supplied and points to an actual file
String signFile = BooksWithoutBorders.getConfiguration().getBookFolder() + lines[2] + lines[3];
if (BookFileHelper.bookFileExists(signFile)) {
@@ -232,62 +212,6 @@ public class SignEventListener implements Listener {
}
}
/**
* Decrypts a book decryptable for a given group
*
* @param oldBook <p>Metadata for the encrypted book</p>
* @param player <p>The player decrypting the book</p>
* @param heldItem <p>The type of the held book</p>
* @param hand <p>The hand the player is using to hold the book</p>
*/
private void decryptBook(@NotNull BookMeta oldBook, @NotNull Player player, @NotNull ItemStack heldItem,
@NotNull EquipmentSlot hand) {
BwBConfig config = BooksWithoutBorders.getConfiguration();
ItemStack newBook;
//Check if the book is encrypted by Books Without Borders
if (!oldBook.hasLore() || oldBook.getLore() == null || !oldBook.getLore().get(0).contains(" encrypted]")) {
return;
}
String groupName = oldBook.getLore().get(0).substring(3).split(" encrypted")[0];
//Permission check
if (!player.hasPermission(Permission.DECRYPT + "." + groupName) &&
!(config.getAdminDecrypt() && player.hasPermission(Permission.ADMIN.toString()))) {
BooksWithoutBorders.sendErrorMessage(player, "You are not allowed to decrypt that book");
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);
if (file == null) {
BooksWithoutBorders.sendErrorMessage(player, "Unable to find encrypted book");
return;
}
}
}
newBook = BookLoader.loadBook(player, fileName, true, BookDirectory.ENCRYPTED, groupName, heldItem.getAmount());
if (newBook == null) {
BooksWithoutBorders.sendErrorMessage(player, "Unable to load the unencrypted book!");
return;
}
player.getInventory().setItem(hand, newBook);
player.closeInventory();
BooksWithoutBorders.sendSuccessMessage(player, "Book auto-decrypted!");
}
/**
* Encrypts and replaces the player's used book
*
@@ -335,11 +259,12 @@ public class SignEventListener implements Listener {
ItemStack newBook = BookLoader.loadBook(player, fileName, true, "public");
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
if (newBook != null) {
player.getInventory().addItem(newBook);
BooksWithoutBorders.sendSuccessMessage(player, "Received book!");
stringFormatter.displaySuccessMessage(player, SignText.SUCCESS_SIGN_GIVE);
} else {
BooksWithoutBorders.sendErrorMessage(player, "Book failed to load!");
stringFormatter.displayErrorMessage(player, GiveMessage.ERROR_GIVE_LOAD_FAILED);
}
}

View File

@@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.manager;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.translation.CostMessage;
import net.knarcraft.knarlib.formatting.StringFormatter;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Material;
import org.bukkit.Server;
@@ -64,6 +65,7 @@ public class EconomyManager {
*/
public boolean cannotPayForBookPrinting(@NotNull Player player, int numCopies) {
BwBConfig config = BooksWithoutBorders.getConfiguration();
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
//BookPriceQuantity: How many items are required to pay for each book
//BookPriceType: Which item is used to pay for the books. AIR = use economy
Material bookCurrency = config.getBookPriceType();
@@ -72,22 +74,22 @@ public class EconomyManager {
if (bookCurrency == Material.AIR) {
return !payForBookPrintingEconomy(player, cost, numCopies);
} else {
}
if (bookCurrency == Material.WRITABLE_BOOK) {
//Writable books are treated as a special case to prevent WIP books from being used
return !takeWritableBookPayment(player, itemCost);
} else {
}
if (player.getInventory().contains(bookCurrency, itemCost)) {
payForBookPrintingItem(player, itemCost);
return false;
} else {
BooksWithoutBorders.sendErrorMessage(player, itemCost + " " + bookCurrency +
"(s) are required for this command!");
stringFormatter.displayErrorMessage(player, stringFormatter.replacePlaceholders(
CostMessage.ERROR_COST_INSUFFICIENT_AMOUNT, List.of("{cost}", "{currency}"),
List.of(String.valueOf(itemCost), bookCurrency.toString())));
return true;
}
}
}
}
/**
* Takes a writable book payment, ignoring any books containing text
@@ -97,10 +99,11 @@ public class EconomyManager {
* @return <p>True if the payment was successful</p>
*/
private boolean takeWritableBookPayment(@NotNull Player player, int itemCost) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
List<ItemStack> books = getPlayersEmptyBooks(player);
if (countItems(books) < itemCost) {
BooksWithoutBorders.sendErrorMessage(player, itemCost + " empty " + Material.WRITABLE_BOOK +
"(s) are required for this command!");
stringFormatter.displayErrorMessage(player, stringFormatter.replacePlaceholder(
CostMessage.ERROR_COST_INSUFFICIENT_WRITABLE_BOOK, "{cost}", String.valueOf(itemCost)));
return false;
} else {
int clearedAmount = 0;
@@ -166,20 +169,20 @@ public class EconomyManager {
* @return <p>True if the player had the money and it has been withdrawn</p>
*/
private boolean payForBookPrintingEconomy(@NotNull Player player, double cost, int numCopies) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
if (economy == null) {
BooksWithoutBorders.getStringFormatter().displayErrorMessage(player, CostMessage.ERROR_VAULT_COST_BUT_UNAVAILABLE);
stringFormatter.displayErrorMessage(player, CostMessage.ERROR_VAULT_COST_BUT_UNAVAILABLE);
return false;
}
if ((economy.getBalance(player) - cost) >= 0) {
economy.withdrawPlayer(player, cost);
BooksWithoutBorders.sendSuccessMessage(player, economy.format(cost) + " withdrawn to create " +
numCopies + " book(s)");
BooksWithoutBorders.sendSuccessMessage(player, "New balance: " +
economy.format(economy.getBalance(player)));
stringFormatter.displaySuccessMessage(player, stringFormatter.replacePlaceholders(
CostMessage.SUCCESS_COST_PAID, List.of("{cost}", "{copies}", "{balance}"),
List.of(economy.format(cost), String.valueOf(numCopies), economy.format(economy.getBalance(player)))));
return true;
} else {
BooksWithoutBorders.sendErrorMessage(player, economy.format(cost) + " is required for this command!");
stringFormatter.replacePlaceholder(CostMessage.ERROR_COST_INSUFFICIENT_ECONOMY, "{cost}", economy.format(cost));
return false;
}
}

View File

@@ -1,12 +1,14 @@
package net.knarcraft.bookswithoutborders.thread;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
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.EncryptionHelper;
import net.knarcraft.knarlib.formatting.StringFormatter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
@@ -16,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
@@ -65,11 +68,12 @@ public class MigrationQueueThread implements Runnable {
success = success & migrateFile(migrationRequest.file(), migrationRequest.player());
if (BooksWithoutBorders.getMigrationQueue().peek() == null) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
Player player = migrationRequest.player();
if (success) {
BooksWithoutBorders.sendSuccessMessage(player, "Successfully migrated all books");
stringFormatter.displaySuccessMessage(player, Translatable.SUCCESS_MIGRATED);
} else {
BooksWithoutBorders.sendErrorMessage(player, "Failed to migrate all books");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_MIGRATION_FAILED);
}
BooksWithoutBorders.getInstance().getServer().getScheduler().cancelTask(this.taskId);
success = null;
@@ -145,8 +149,10 @@ public class MigrationQueueThread implements Runnable {
}
return deleteBook(file.getParentFile(), newName, file);
} catch (IllegalArgumentException | IOException exception) {
BooksWithoutBorders.sendErrorMessage(player, "Failed to migrate book: " + file.getName() + " Cause:");
BooksWithoutBorders.sendErrorMessage(player, exception.getMessage());
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
stringFormatter.displayErrorMessage(player, stringFormatter.replacePlaceholders(
Translatable.ERROR_MIGRATION_BOOK_FAILED, List.of("{file}", "{exception}"),
List.of(file.getName(), exception.getMessage())));
return false;
}
}

View File

@@ -2,6 +2,7 @@ package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.translation.Formatting;
import net.knarcraft.bookswithoutborders.config.translation.Translatable;
import net.knarcraft.bookswithoutborders.state.BookDirectory;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@@ -141,7 +142,7 @@ public final class BookFileHelper {
File[] existingFiles = searchDirectory.listFiles();
if (!searchDirectory.exists() || existingFiles == null || existingFiles.length == 0) {
BooksWithoutBorders.sendErrorMessage(sender, "No books have been saved!");
BooksWithoutBorders.getStringFormatter().displayErrorMessage(sender, Translatable.ERROR_NO_BOOKS_TO_LIST);
return null;
}

View File

@@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.translation.Formatting;
import net.knarcraft.bookswithoutborders.config.translation.Translatable;
import net.knarcraft.bookswithoutborders.state.BookDirectory;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -227,8 +228,7 @@ public final class BookHelper {
if (isAuthor(player.getName(), book.getAuthor())) {
return false;
} else {
BooksWithoutBorders.sendErrorMessage(player,
"You must be the author of this book to use this command!");
BooksWithoutBorders.getStringFormatter().displayErrorMessage(player, Translatable.ERROR_AUTHOR_ONLY);
return true;
}
}

View File

@@ -3,7 +3,9 @@ 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.translation.Translatable;
import net.knarcraft.bookswithoutborders.state.BookDirectory;
import net.knarcraft.knarlib.formatting.StringFormatter;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -55,7 +57,8 @@ public final class BookLoader {
@NotNull String directory, int numCopies) {
BookDirectory bookDirectory = BookDirectory.getFromString(directory);
if (bookDirectory == null) {
BooksWithoutBorders.sendErrorMessage(sender, "Unrecognized book directory!");
BooksWithoutBorders.getStringFormatter().displayErrorMessage(sender,
Translatable.ERROR_BOOK_DIRECTORY_UNKNOWN);
return null;
}
return loadBook(sender, fileName, isSigned, bookDirectory, directory, numCopies);
@@ -75,6 +78,7 @@ public final class BookLoader {
@Nullable
public static ItemStack loadBook(@NotNull CommandSender sender, @NotNull String fileName, boolean isSigned,
@NotNull BookDirectory bookDirectory, @NotNull String directory, int numCopies) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
//Find the filename if a book index is given
try {
int bookIndex = Integer.parseInt(fileName);
@@ -95,7 +99,8 @@ public final class BookLoader {
String replaced = BookFileHelper.replaceAuthorWithUUID(fileName);
file = getFullPath(sender, replaced, bookDirectory, directory);
if (file == null) {
BooksWithoutBorders.sendErrorMessage(sender, "Incorrect file name!");
stringFormatter.displayErrorMessage(sender,
Translatable.ERROR_INCORRECT_FILE_NAME);
return null;
}
}
@@ -113,14 +118,15 @@ public final class BookLoader {
BookMeta bookMetadata = (BookMeta) BooksWithoutBorders.getItemFactory().getItemMeta(Material.WRITTEN_BOOK);
if (bookMetadata == null) {
BooksWithoutBorders.sendErrorMessage(sender, "Unable to create blank book metadata!");
stringFormatter.displayErrorMessage(sender,
Translatable.ERROR_METADATA_CREATION_FAILED);
return null;
}
//Load the book from the given file
bookMetadata = BookToFromTextHelper.bookFromFile(file, bookMetadata);
if (bookMetadata == null) {
BooksWithoutBorders.sendErrorMessage(sender, "File was blank!!");
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_LOAD_BOOK_EMPTY);
return null;
}

View File

@@ -155,14 +155,15 @@ public final class EncryptionHelper {
public static ItemStack encryptBook(Player player, boolean mainHand, @NotNull String key,
@NotNull EncryptionStyle style, @NotNull String groupName,
boolean preventAdminDecrypt) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
BookMeta book = InventoryHelper.getHeldBookMetadata(player, mainHand);
if (book == null) {
BooksWithoutBorders.sendErrorMessage(player, "Unable to get metadata from the held book!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_METADATA_MISSING);
return null;
}
if (!book.hasPages()) {
BooksWithoutBorders.sendErrorMessage(player, "Book is empty!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_ENCRYPT_BOOK_EMPTY);
return null;
}
@@ -190,7 +191,7 @@ public final class EncryptionHelper {
ItemStack encryptedBook = createEncryptedBook(book, newPages, player, newMetadata);
BooksWithoutBorders.sendSuccessMessage(player, "Book encrypted!");
stringFormatter.displaySuccessMessage(player, Translatable.SUCCESS_ENCRYPTED);
return encryptedBook;
}
@@ -257,6 +258,7 @@ public final class EncryptionHelper {
@Nullable
public static ItemStack loadEncryptedBook(@NotNull Player player, @NotNull String key, boolean deleteEncryptedFile,
boolean forceDecrypt) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
ItemStack heldBook = InventoryHelper.getHeldBook(player, true);
BookMeta bookMetadata = (BookMeta) heldBook.getItemMeta();
String path = BooksWithoutBorders.getConfiguration().getEncryptedBookPath();
@@ -271,7 +273,7 @@ public final class EncryptionHelper {
File file = new File(path + fileName + ".yml");
if (!file.isFile()) {
BooksWithoutBorders.sendErrorMessage(player, "Book not found!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_DECRYPT_NOT_FOUND);
return null;
} else {
try {
@@ -281,8 +283,8 @@ public final class EncryptionHelper {
} else {
bookMetadata = book.bookMeta();
}
} catch (Exception e) {
BooksWithoutBorders.sendErrorMessage(player, "Decryption failed!");
} catch (Exception exception) {
stringFormatter.displayErrorMessage(player, Translatable.ERROR_DECRYPT_FAILED);
return null;
}
}
@@ -307,7 +309,8 @@ public final class EncryptionHelper {
*/
@Nullable
public static ItemStack loadEncryptedBookLegacy(@NotNull Player player, @NotNull String key, boolean deleteEncryptedFile) {
BooksWithoutBorders.sendErrorMessage(player, "Attempting legacy decryption");
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
stringFormatter.displayNeutralMessage(player, Translatable.NEUTRAL_ATTEMPTING_LEGACY_DECRYPTION);
ItemStack heldBook = InventoryHelper.getHeldBook(player, true);
BookMeta bookMetadata = (BookMeta) heldBook.getItemMeta();
String path = BooksWithoutBorders.getConfiguration().getEncryptedBookPath();
@@ -328,7 +331,7 @@ public final class EncryptionHelper {
if (!file.isFile()) {
file = new File(path + fileName + ".txt");
if (!file.isFile()) {
BooksWithoutBorders.sendErrorMessage(player, "Incorrect decryption key!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_DECRYPT_LEGACY_INVALID_KEY);
return null;
}
}
@@ -336,11 +339,11 @@ public final class EncryptionHelper {
try {
bookMetadata = BookToFromTextHelper.bookFromFile(file, bookMetadata);
if (bookMetadata == null) {
BooksWithoutBorders.sendErrorMessage(player, "Decryption failed!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_DECRYPT_FAILED);
return null;
}
} catch (Exception e) {
BooksWithoutBorders.sendErrorMessage(player, "Decryption failed!");
} catch (Exception exception) {
stringFormatter.displayErrorMessage(player, Translatable.ERROR_DECRYPT_FAILED);
return null;
}
@@ -464,7 +467,7 @@ public final class EncryptionHelper {
try {
BookToFromTextHelper.bookToYml(path, fileName, bookMetadata);
} catch (IOException exception) {
BooksWithoutBorders.sendErrorMessage(player, "Group encrypted failed!");
BooksWithoutBorders.getStringFormatter().displayErrorMessage(player, Translatable.ERROR_GROUP_ENCRYPT_FAILED);
return null;
}
}
@@ -481,6 +484,7 @@ public final class EncryptionHelper {
*/
@NotNull
private static Boolean saveEncryptedBook(@NotNull Player player, @NotNull EncryptedBook encryptedBook) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
String path = BooksWithoutBorders.getConfiguration().getEncryptedBookPath();
String fileName = BookHelper.getBookFile(encryptedBook.bookMeta(), player, true);
@@ -489,14 +493,14 @@ public final class EncryptionHelper {
//cancels saving if file is already encrypted
File file = new File(path, fileName + ".yml");
if (file.isFile()) {
BooksWithoutBorders.getStringFormatter().displayErrorMessage(player, Translatable.ERROR_ENCRYPT_ALREADY_SAVED);
stringFormatter.displayErrorMessage(player, Translatable.ERROR_ENCRYPT_ALREADY_SAVED);
return false;
}
try {
BookToFromTextHelper.encryptedBookToYml(path, fileName, encryptedBook);
} catch (IOException exception) {
BooksWithoutBorders.sendErrorMessage(player, "Encryption failed!");
stringFormatter.displayErrorMessage(player, Translatable.ERROR_ENCRYPT_FAILED);
return false;
}
return true;

View File

@@ -1,6 +1,8 @@
package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.config.translation.Translatable;
import net.knarcraft.bookswithoutborders.state.BookHoldingState;
import net.knarcraft.bookswithoutborders.state.ItemSlot;
import net.knarcraft.knarlib.formatting.StringFormatter;
@@ -49,7 +51,7 @@ public final class InventoryHelper {
} else if (heldSlot == ItemSlot.OFF_HAND) {
return getHeldItem(player, false);
} else {
throw new IllegalArgumentException("The player is not holding exactly one book.");
throw new IllegalArgumentException(StaticMessage.EXCEPTION_NOT_HOLDING_ONE_BOOK.toString());
}
}
@@ -66,7 +68,7 @@ public final class InventoryHelper {
} else if (itemSlot == ItemSlot.OFF_HAND) {
replaceHeldItem(player, newBook, false);
} else {
BooksWithoutBorders.sendErrorMessage(player, "Could not find a book to replace!");
BooksWithoutBorders.getStringFormatter().displayErrorMessage(player, Translatable.ERROR_BOOK_NOT_FOUND);
}
}
@@ -107,16 +109,17 @@ public final class InventoryHelper {
*/
public static boolean notHoldingOneWrittenBookCheck(@NotNull Player player, @NotNull String noBookMessage,
@NotNull String twoBooksMessage) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
BookHoldingState holdingState = getBookHoldingState(player);
if (holdingState == BookHoldingState.NONE || holdingState == BookHoldingState.UNSIGNED_BOTH_HANDS ||
holdingState == BookHoldingState.UNSIGNED_MAIN_HAND || holdingState == BookHoldingState.UNSIGNED_OFF_HAND) {
BooksWithoutBorders.sendErrorMessage(player, noBookMessage);
stringFormatter.displayErrorMessage(player, noBookMessage);
return true;
}
if (holdingState == BookHoldingState.SIGNED_BOTH_HANDS) {
BooksWithoutBorders.sendErrorMessage(player, twoBooksMessage);
stringFormatter.displayErrorMessage(player, twoBooksMessage);
return true;
}

View File

@@ -18,12 +18,17 @@ en:
SUCCESS_COST_REMOVED: "Price to create books removed!"
SUCCESS_COST_ITEM_SET: "Book creation price set to {quantity} {price}(s)!"
SUCCESS_COST_ECONOMY_SET: "Book creation price set to {cost}!"
SUCCESS_COST_PAID: |
{cost} withdrawn to create {copies} book(s)
New balance: {balance}
SUCCESS_BOOKSHELF_DATA_DELETED: "Bookshelf successfully deleted!"
SUCCESS_BOOKSHELF_TITLE_SET: "Title successfully saved!"
SUCCESS_BOOKSHELF_LORE_SET: "Lore successfully saved!"
SUCCESS_GENERATION_CHANGED: "Book generation successfully changed!"
SUCCESS_LORE_SET: "Added lore to item!"
SUCCESS_TITLE_SET: "Title set to {title}!"
SUCCESS_MIGRATED: "Successfully migrated all books"
SUCCESS_ENCRYPTED: "Book encrypted!"
ACTION_COPY: "copy"
ACTION_CLEAR: "clear"
ACTION_DECRYPT: "decrypt"
@@ -81,6 +86,9 @@ en:
ERROR_COST_INVALID_QUANTITY: "[quantity] must be a number greater than 0!"
ERROR_COST_INVALID_TYPE: "Price type must be \"item\" or \"economy\"!"
ERROR_COST_ITEM_MISSING: "Must be holding an item to set an [Item] price!"
ERROR_COST_INSUFFICIENT_ECONOMY: "{cost} is required for this command!"
ERROR_COST_INSUFFICIENT_AMOUNT: "{cost} {currency}(s) are required for this command!"
ERROR_COST_INSUFFICIENT_WRITABLE_BOOK: "{cost} empty book and quill(s) are required for this command!"
ERROR_BOOKSHELF_NOT_FOUND: "You are not looking at a bookshelf!"
ERROR_BOOKSHELF_NOT_REGISTERED: "The block you are looking at is not a registered bookshelf"
ERROR_BOOKSHELF_NAME_REQUIRED: "You must name the bookshelf before assigning lore!"
@@ -93,6 +101,23 @@ en:
ERROR_ENCRYPT_ALREADY_SAVED: |
An encrypted version of this book is already saved.
Please decrypt your previously encrypted copy first.
ERROR_BOOK_NOT_FOUND: "Could not find a book to replace!"
ERROR_NO_BOOKS_TO_LIST: "No books have been saved!"
ERROR_GROUP_DECRYPT_NO_PERMISSION: "You are not allowed to decrypt that book"
ERROR_GROUP_DECRYPT_NOT_FOUND: "Unable to find encrypted book"
ERROR_GROUP_DECRYPT_LOAD_FAILED: "Unable to load the unencrypted book!"
ERROR_MIGRATION_FAILED: "Failed to migrate all books"
ERROR_MIGRATION_BOOK_FAILED: "Failed to migrate book: {file} Cause: {exception}"
ERROR_BOOK_DIRECTORY_UNKNOWN: "Unrecognized book directory!"
ERROR_METADATA_CREATION_FAILED: "Unable to create blank book metadata!"
ERROR_LOAD_BOOK_EMPTY: "File was blank!!"
ERROR_AUTHOR_ONLY: "You must be the author of this book to use this command!"
ERROR_ENCRYPT_BOOK_EMPTY: "Book is empty!"
ERROR_DECRYPT_NOT_FOUND: "Book not found!"
ERROR_DECRYPT_LEGACY_INVALID_KEY: "Incorrect decryption key!"
ERROR_GROUP_ENCRYPT_FAILED: "Group encrypted failed!"
ERROR_ENCRYPT_FAILED: "Encryption failed!"
NEUTRAL_ATTEMPTING_LEGACY_DECRYPTION: "Attempting legacy decryption"
# ---------------------------------- #
# Custom formatting for some output #
# ---------------------------------- #
@@ -156,3 +181,4 @@ en:
SIGN_VALID: "&1{line}"
ERROR_SIGN_INVALID: "Invalid sign!"
ERROR_SIGN_COMMAND_INVALID: "Sign command {action} {data} is invalid"
SUCCESS_SIGN_GIVE: "Received book!"