Replaces more static strings from migrate, reload and save

This commit is contained in:
2025-08-17 15:41:50 +02:00
parent 57ca6ff2e9
commit 4501156087
12 changed files with 174 additions and 95 deletions

View File

@@ -1,6 +1,7 @@
package net.knarcraft.bookswithoutborders.command; package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.container.MigrationRequest; import net.knarcraft.bookswithoutborders.container.MigrationRequest;
import net.knarcraft.bookswithoutborders.thread.MigrationQueueThread; import net.knarcraft.bookswithoutborders.thread.MigrationQueueThread;
@@ -61,7 +62,8 @@ public class CommandMigrate implements TabExecutor {
private void findFilesToMigrate(@NotNull File folder, @NotNull Queue<MigrationRequest> queue, @NotNull Player player) { private void findFilesToMigrate(@NotNull File folder, @NotNull Queue<MigrationRequest> queue, @NotNull Player player) {
File[] files = folder.listFiles(); File[] files = folder.listFiles();
if (files == null) { if (files == null) {
BooksWithoutBorders.log(Level.WARNING, "Unable to access directory " + folder.getName() + " !"); BooksWithoutBorders.log(Level.WARNING, StringFormatter.replacePlaceholder(
StaticMessage.EXCEPTION_DIRECTORY_UNAVAILABLE.toString(), "{folder}", folder.getName()));
return; return;
} }
for (File file : files) { for (File file : files) {

View File

@@ -1,6 +1,8 @@
package net.knarcraft.bookswithoutborders.command; package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.knarlib.formatting.StringFormatter;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
@@ -17,16 +19,16 @@ public class CommandReload implements TabExecutor {
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] arguments) { @NotNull String[] arguments) {
if (BooksWithoutBorders.getConfiguration().loadConfig()) { StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
BooksWithoutBorders.sendSuccessMessage(sender, "BooksWithoutBorders configuration reloaded!");
} else {
BooksWithoutBorders.sendErrorMessage(sender, "Reload Failed!");
BooksWithoutBorders.sendErrorMessage(sender, "See console for details");
}
// Reload books // Reload books
BooksWithoutBorders.updateBooks(sender, true);
BooksWithoutBorders.clearBookData(); BooksWithoutBorders.clearBookData();
BooksWithoutBorders.updateBooks(sender, true);
if (BooksWithoutBorders.getConfiguration().loadConfig()) {
stringFormatter.displaySuccessMessage(sender, Translatable.SUCCESS_RELOADED);
} else {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_RELOAD_FAILED);
}
return true; return true;
} }

View File

@@ -2,13 +2,15 @@ package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
import net.knarcraft.bookswithoutborders.config.Permission;
import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.state.BookDirectory;
import net.knarcraft.bookswithoutborders.state.ItemSlot;
import net.knarcraft.bookswithoutborders.utility.BookFileHelper; import net.knarcraft.bookswithoutborders.utility.BookFileHelper;
import net.knarcraft.bookswithoutborders.utility.BookHelper; import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper; import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
import net.md_5.bungee.api.ChatColor; import net.knarcraft.knarlib.formatting.StringFormatter;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
@@ -16,6 +18,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.BookMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -30,7 +33,7 @@ public class CommandSave implements TabExecutor {
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] arguments) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] arguments) {
return saveHeldBook(sender, arguments, false); return saveHeldBook(sender, arguments, false, label);
} }
/** /**
@@ -39,22 +42,24 @@ public class CommandSave implements TabExecutor {
* @param sender <p>The sender of the command</p> * @param sender <p>The sender of the command</p>
* @param arguments <p>The arguments given</p> * @param arguments <p>The arguments given</p>
* @param savePublic <p>Whether to save the book in the public directory or the player directory</p> * @param savePublic <p>Whether to save the book in the public directory or the player directory</p>
* @param command <p>The command executed to trigger this method</p>
* @return <p>True if a book was saved successfully</p> * @return <p>True if a book was saved successfully</p>
*/ */
protected boolean saveHeldBook(@NotNull CommandSender sender, @NotNull String[] arguments, boolean savePublic) { protected boolean saveHeldBook(@NotNull CommandSender sender, @NotNull String[] arguments, boolean savePublic,
@NotNull String command) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
if (!(sender instanceof Player player)) { 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; return false;
} }
ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, false, false); ItemStack heldBook = InventoryHelper.getHeldBook(player);
if (holdingSlot != ItemSlot.NONE) { if (heldBook != null) {
ItemStack holdingItem = InventoryHelper.getHeldItem(player, holdingSlot == ItemSlot.MAIN_HAND);
boolean duplicate = arguments.length == 1 && Boolean.parseBoolean(arguments[0]); boolean duplicate = arguments.length == 1 && Boolean.parseBoolean(arguments[0]);
saveBook(player, holdingItem, duplicate, savePublic); saveBook(player, heldBook, duplicate, savePublic, command);
return true; return true;
} else { } else {
BooksWithoutBorders.sendErrorMessage(sender, "You must be holding a written book or book and quill to save it!"); stringFormatter.displayErrorMessage(sender, Translatable.ERROR_NOT_HOLDING_ANY_BOOK);
return false; return false;
} }
} }
@@ -66,11 +71,14 @@ public class CommandSave implements TabExecutor {
* @param heldBook <p>The book held</p> * @param heldBook <p>The book held</p>
* @param overwrite <p>Whether to overwrite any existing books</p> * @param overwrite <p>Whether to overwrite any existing books</p>
* @param saveToPublicFolder <p>Whether to save the book to the public folder instead of the player folder</p> * @param saveToPublicFolder <p>Whether to save the book to the public folder instead of the player folder</p>
* @param command <p>The command executed to trigger this method</p>
*/ */
public void saveBook(@NotNull Player player, @NotNull ItemStack heldBook, boolean overwrite, boolean saveToPublicFolder) { public void saveBook(@NotNull Player player, @NotNull ItemStack heldBook, boolean overwrite,
boolean saveToPublicFolder, @NotNull String command) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
BookMeta book = (BookMeta) heldBook.getItemMeta(); BookMeta book = (BookMeta) heldBook.getItemMeta();
if (book == null) { if (book == null) {
BooksWithoutBorders.sendErrorMessage(player, "Unable to get metadata for your held book!"); stringFormatter.displayErrorMessage(player, Translatable.ERROR_METADATA_MISSING);
return; return;
} }
@@ -78,16 +86,15 @@ public class CommandSave implements TabExecutor {
//Only allow saving of own books if enabled //Only allow saving of own books if enabled
if (config.getAuthorOnlySave() && !saveToPublicFolder && if (config.getAuthorOnlySave() && !saveToPublicFolder &&
(!player.hasPermission("bookswithoutborders.bypassAuthorOnlySave") && (!player.hasPermission(Permission.BYPASS_AUTHOR_ONLY_SAVE.toString()) &&
BookHelper.isNotAuthor(player, book))) { BookHelper.isNotAuthor(player, book))) {
return; return;
} }
String savePath = BookHelper.getBookDirectoryPathString(saveToPublicFolder ? String savePath = BookHelper.getBookDirectoryPathString(saveToPublicFolder ?
BookDirectory.PUBLIC : BookDirectory.PLAYER, player); BookDirectory.PUBLIC : BookDirectory.PLAYER, player);
if (savePath == null) { if (savePath == null) {
BooksWithoutBorders.sendErrorMessage(player, "Saving Failed! Unable to find the save path!"); stringFormatter.displayErrorMessage(player, Translatable.ERROR_SAVE_INVALID_PATH);
return; return;
} }
@@ -103,55 +110,26 @@ public class CommandSave implements TabExecutor {
//Make sure the used folders exist //Make sure the used folders exist
File file = new File(savePath); File file = new File(savePath);
if (!file.exists() && !file.mkdir()) { if (!file.exists() && !file.mkdir()) {
BooksWithoutBorders.sendErrorMessage(player, "Saving Failed! If this continues to happen, consult" + stringFormatter.displayErrorMessage(player, Translatable.ERROR_SAVE_FILE_SYSTEM_ERROR);
" a server admin!");
return;
}
File[] foundFiles = file.listFiles();
if (foundFiles == null) {
BooksWithoutBorders.sendErrorMessage(player, "Saving Failed! If this continues to happen, consult" +
" a server admin!");
return; return;
} }
//Find any duplicates of the book // Deal with possible duplicates of the file
int foundDuplicates = BookFileHelper.findDuplicates(foundFiles, fileName); String newName = checkDuplicates(player, file, fileName, command, config.getTitleAuthorSeparator(),
config.getBookDuplicateLimit(), overwrite);
//Deal with duplicates if (newName == null) {
if (foundDuplicates > 0) { return;
//TODO: Decide if this makes sense or needs to be changed
//Skip duplicate book
if (!fileName.contains("Untitled" + config.getTitleAuthorSeparator()) && !overwrite) {
BooksWithoutBorders.sendErrorMessage(player, "Book is already saved!");
BooksWithoutBorders.sendErrorMessage(player, "Use " + config.getCommandColor() + (saveToPublicFolder ?
"/savepublicbook" : "/savebook") + " true " + config.getErrorColor() + "to overwrite!");
return;
}
//Skip if duplicate limit is reached
if (foundDuplicates > config.getBookDuplicateLimit()) {
BooksWithoutBorders.sendErrorMessage(player, "Maximum amount of " + fileName +
" duplicates reached!");
BooksWithoutBorders.sendErrorMessage(player, "Use " + config.getCommandColor() + (saveToPublicFolder ?
"/savepublicbook" : "/savebook") + " true " +
config.getErrorColor() + "to overwrite!");
return;
}
//Alter duplicated filename
if (fileName.contains("Untitled" + config.getTitleAuthorSeparator()) && !overwrite) {
fileName = "(" + foundDuplicates + ")" + fileName;
}
} }
try { try {
BookToFromTextHelper.bookToYml(savePath, fileName, book); BookToFromTextHelper.bookToYml(savePath, newName, book);
//Update the relevant book list //Update the relevant book list
BooksWithoutBorders.updateBooks(player, saveToPublicFolder); BooksWithoutBorders.updateBooks(player, saveToPublicFolder);
BooksWithoutBorders.sendSuccessMessage(player, "Book Saved as \"" + fileName + ChatColor.RESET + "\""); stringFormatter.displaySuccessMessage(player,
stringFormatter.replacePlaceholder(Translatable.SUCCESS_SAVED, "{fileName}", newName));
} catch (IOException exception) { } catch (IOException exception) {
BooksWithoutBorders.log(Level.SEVERE, "Unable to save book"); BooksWithoutBorders.log(Level.SEVERE, StaticMessage.EXCEPTION_SAVE_BOOK_FAILED.toString());
} }
} }
@@ -163,4 +141,65 @@ public class CommandSave implements TabExecutor {
return new ArrayList<>(); return new ArrayList<>();
} }
/**
* Checks if the book to save is a duplicate of one or more saved books
*
* <p>Note that only unnamed books can have duplicates</p>
*
* @param player <p>The player attempting to save the book</p>
* @param directory <p>The directory to search for duplicates</p>
* @param fileName <p>The name the file is to be saved as</p>
* @param command <p>The command executed to trigger this method</p>
* @param separator <p>The title author separator</p>
* @param duplicateLimit <p>The duplicate limit</p>
* @param overwrite <p>Whether the player enabled overwriting</p>
* @return <p>The possible altered filename, or null if saving the book isn't allowed</p>
*/
@Nullable
private String checkDuplicates(@NotNull Player player, @NotNull File directory, @NotNull String fileName,
@NotNull String command, @NotNull String separator, int duplicateLimit,
boolean overwrite) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
File[] foundFiles = directory.listFiles();
if (foundFiles == null) {
stringFormatter.displayErrorMessage(player, Translatable.ERROR_SAVE_FILE_SYSTEM_ERROR);
return null;
}
// Find any duplicates of the book
int foundDuplicates = BookFileHelper.findDuplicates(foundFiles, fileName);
// No duplicates to process
if (foundDuplicates <= 0) {
return fileName;
}
String fullCommand = "/" + command + " true";
boolean isUnnamed = fileName.contains("Untitled" + separator);
// Skip duplicate unnamed book saving
if (!isUnnamed && !overwrite) {
stringFormatter.displayErrorMessage(player, Translatable.ERROR_SAVE_DUPLICATE_NAMED);
stringFormatter.displayErrorMessage(player, stringFormatter.replacePlaceholder(
Translatable.ERROR_SAVE_OVERWRITE_REQUIRED, "{command}", fullCommand));
return null;
}
// Skip if duplicate limit is reached
if (foundDuplicates > duplicateLimit) {
stringFormatter.displayErrorMessage(player, stringFormatter.replacePlaceholder(
Translatable.ERROR_SAVE_DUPLICATE_UNNAMED, "{fileName}", fileName));
stringFormatter.displayErrorMessage(player, stringFormatter.replacePlaceholder(
Translatable.ERROR_SAVE_OVERWRITE_REQUIRED, "{command}", fullCommand));
return null;
}
// Alter duplicated filename
if (isUnnamed && !overwrite) {
fileName = "(" + foundDuplicates + ")" + fileName;
}
return fileName;
}
} }

View File

@@ -13,7 +13,7 @@ public class CommandSavePublic extends CommandSave implements TabExecutor {
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] arguments) { @NotNull String[] arguments) {
return saveHeldBook(sender, arguments, true); return saveHeldBook(sender, arguments, true, label);
} }
} }

View File

@@ -23,7 +23,6 @@ public class BooksWithoutBordersConfig {
private final ChatColor errorColor = ChatColor.RED; private final ChatColor errorColor = ChatColor.RED;
private final ChatColor successColor = ChatColor.GREEN; private final ChatColor successColor = ChatColor.GREEN;
private final ChatColor commandColor = ChatColor.YELLOW;
private final String SLASH = FileSystems.getDefault().getSeparator(); private final String SLASH = FileSystems.getDefault().getSeparator();
private boolean isInitialized; private boolean isInitialized;
private final String bookFolder; private final String bookFolder;
@@ -99,15 +98,6 @@ public class BooksWithoutBordersConfig {
return this.successColor; return this.successColor;
} }
/**
* Gets the color used to color commands
*
* @return <p>The color used to color commands</p>
*/
public ChatColor getCommandColor() {
return this.commandColor;
}
/** /**
* Gets the correct slash to use for the used OS * Gets the correct slash to use for the used OS
* *

View File

@@ -32,6 +32,11 @@ public enum Permission {
*/ */
FORMAT("format"), FORMAT("format"),
/**
* The permission for bypassing author only saving
*/
BYPASS_AUTHOR_ONLY_SAVE("bypassAuthorOnlySave"),
; ;
private final @NotNull String node; private final @NotNull String node;
@@ -45,16 +50,6 @@ public enum Permission {
this.node = node; this.node = node;
} }
/**
* Gets the node of this permission
*
* @return <p>The permission node</p>
*/
@NotNull
public String getNode() {
return "bookswithoutborders." + this.node;
}
/** /**
* Return node instead of enum when displayed as a string * Return node instead of enum when displayed as a string
* *
@@ -63,7 +58,7 @@ public enum Permission {
@Override @Override
@NotNull @NotNull
public String toString() { public String toString() {
return getNode(); return "bookswithoutborders." + this.node;
} }
} }

View File

@@ -13,6 +13,10 @@ public enum StaticMessage {
EXCEPTION_VAULT_NOT_AVAILABLE("Vault is unavailable, but book price is set to economy. Unsetting book cost!"), EXCEPTION_VAULT_NOT_AVAILABLE("Vault is unavailable, but book price is set to economy. Unsetting book cost!"),
EXCEPTION_VAULT_PRICE_NOT_CHANGED("BooksWithoutBorders failed to hook into Vault! Book price not set!"), EXCEPTION_VAULT_PRICE_NOT_CHANGED("BooksWithoutBorders failed to hook into Vault! Book price not set!"),
EXCEPTION_ENCRYPTED_FILE_DELETE_FAILED("Book encryption data failed to delete upon decryption!\nFile location: {path}"), EXCEPTION_ENCRYPTED_FILE_DELETE_FAILED("Book encryption data failed to delete upon decryption!\nFile location: {path}"),
EXCEPTION_DIRECTORY_UNAVAILABLE("Unable to access directory {folder} !"),
EXCEPTION_SAVE_BOOK_FAILED("Unable to save book"),
EXCEPTION_BOOKSHELF_SAVING_FAILED("Unable to save bookshelves!"),
NOTICE_NO_BOOKSHELVES("BooksWithoutBorders found no bookshelves to load"),
; ;
private final @NotNull String messageString; private final @NotNull String messageString;

View File

@@ -68,6 +68,16 @@ public enum Translatable implements TranslatableMessage {
*/ */
SUCCESS_MIGRATION_STARTED, SUCCESS_MIGRATION_STARTED,
/**
* The success message displayed when the configuration is successfully reloaded
*/
SUCCESS_RELOADED,
/**
* The success message displayed when a book is successfully saved
*/
SUCCESS_SAVED,
/** /**
* The error to display when the console attempts to run a player-only command * The error to display when the console attempts to run a player-only command
*/ */
@@ -238,6 +248,36 @@ public enum Translatable implements TranslatableMessage {
*/ */
ERROR_LOAD_FAILED, ERROR_LOAD_FAILED,
/**
* The error displayed when the configuration cannot be reloaded
*/
ERROR_RELOAD_FAILED,
/**
* The error displayed when unable to generate a valid save path for a book
*/
ERROR_SAVE_INVALID_PATH,
/**
* The error displayed when unable to create necessary folders for saving a book
*/
ERROR_SAVE_FILE_SYSTEM_ERROR,
/**
* The error displayed when enabling overwriting is necessary to save a book
*/
ERROR_SAVE_OVERWRITE_REQUIRED,
/**
* The error displayed when attempting to save a duplicate unnamed book
*/
ERROR_SAVE_DUPLICATE_NAMED,
/**
* The error displayed when attempting to save a duplicate named book exceeding the duplicate limit
*/
ERROR_SAVE_DUPLICATE_UNNAMED,
/** /**
* The header displayed before printing all commands * The header displayed before printing all commands
*/ */

View File

@@ -1,6 +1,7 @@
package net.knarcraft.bookswithoutborders.handler; package net.knarcraft.bookswithoutborders.handler;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.container.Bookshelf; import net.knarcraft.bookswithoutborders.container.Bookshelf;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@@ -71,8 +72,7 @@ public class BookshelfHandler {
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(bookshelfFile); YamlConfiguration configuration = YamlConfiguration.loadConfiguration(bookshelfFile);
ConfigurationSection bookshelfSection = configuration.getConfigurationSection("bookshelves"); ConfigurationSection bookshelfSection = configuration.getConfigurationSection("bookshelves");
if (bookshelfSection == null) { if (bookshelfSection == null) {
BooksWithoutBorders.log(Level.INFO, BooksWithoutBorders.log(Level.INFO, StaticMessage.NOTICE_NO_BOOKSHELVES.toString());
"BooksWithoutBorders found no bookshelves to load");
return; return;
} }
@@ -108,7 +108,7 @@ public class BookshelfHandler {
} }
configuration.save(bookshelfFile); configuration.save(bookshelfFile);
} catch (IOException exception) { } catch (IOException exception) {
BooksWithoutBorders.log(Level.SEVERE, "Unable to save bookshelves!"); BooksWithoutBorders.log(Level.SEVERE, StaticMessage.EXCEPTION_BOOKSHELF_SAVING_FAILED.toString());
} }
} }

View File

@@ -372,6 +372,7 @@ public final class EncryptionHelper {
* @param bytes <p>The bytes to convert</p> * @param bytes <p>The bytes to convert</p>
* @return <p>The resulting hexadecimal string</p> * @return <p>The resulting hexadecimal string</p>
*/ */
@NotNull
public static String bytesToHex(byte[] bytes) { public static String bytesToHex(byte[] bytes) {
byte[] hexChars = new byte[bytes.length * 2]; byte[] hexChars = new byte[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) { for (int j = 0; j < bytes.length; j++) {

View File

@@ -25,13 +25,9 @@ public final class InventoryHelper {
* @return <p>The held book, or null if not holding one book in the main hand</p> * @return <p>The held book, or null if not holding one book in the main hand</p>
*/ */
public static ItemStack getHeldBook(@NotNull Player player) { public static ItemStack getHeldBook(@NotNull Player player) {
@NotNull ItemSlot heldSigned = InventoryHelper.getHeldSlotBook(player, true, true, ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, false, false);
true, true); if (holdingSlot != ItemSlot.NONE) {
@NotNull ItemSlot heldUnSigned = InventoryHelper.getHeldSlotBook(player, true, true, return InventoryHelper.getHeldItem(player, holdingSlot == ItemSlot.MAIN_HAND);
true, false);
if (heldSigned == ItemSlot.MAIN_HAND || heldUnSigned == ItemSlot.MAIN_HAND) {
boolean holdingSigned = heldSigned == ItemSlot.MAIN_HAND;
return InventoryHelper.getHeldBook(player, holdingSigned);
} else { } else {
return null; return null;
} }

View File

@@ -12,6 +12,8 @@ en:
SUCCESS_PAGE_DELETED: "Page deleted!" SUCCESS_PAGE_DELETED: "Page deleted!"
SUCCESS_BOOK_LOADED: "Book created!" SUCCESS_BOOK_LOADED: "Book created!"
SUCCESS_MIGRATION_STARTED: "Starting book migration..." SUCCESS_MIGRATION_STARTED: "Starting book migration..."
SUCCESS_RELOADED: "BooksWithoutBorders configuration reloaded!"
SUCCESS_SAVED: "Book Saved as &e\"{fileName}\"&r"
ACTION_COPY: "copy" ACTION_COPY: "copy"
ACTION_CLEAR: "clear" ACTION_CLEAR: "clear"
ACTION_DECRYPT: "decrypt" ACTION_DECRYPT: "decrypt"
@@ -54,6 +56,14 @@ en:
ERROR_GROUP_ENCRYPT_ARGUMENTS_MISSING: "You must specify a group name and key to encrypt a book!" 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_GROUP_ENCRYPTED_ALREADY: "Book is already group encrypted!"
ERROR_LOAD_FAILED: "Book failed to load!" ERROR_LOAD_FAILED: "Book failed to load!"
ERROR_RELOAD_FAILED: |
Reload Failed!
See console for details
ERROR_SAVE_INVALID_PATH: "Saving Failed! Unable to find the save path!"
ERROR_SAVE_FILE_SYSTEM_ERROR: "Saving Failed! If this continues to happen, consult a server admin!"
ERROR_SAVE_OVERWRITE_REQUIRED: "Use &e{command}&r to overwrite!"
ERROR_SAVE_DUPLICATE_NAMED: "Book is already saved!"
ERROR_SAVE_DUPLICATE_UNNAMED: "Maximum amount of {fileName} duplicates reached!"
NEUTRAL_COMMANDS_HEADER: | NEUTRAL_COMMANDS_HEADER: |
&e[] denote optional parameters &e[] denote optional parameters
<> denote required parameters <> denote required parameters