Improves in-game command documentation
All checks were successful
EpicKnarvik97/Books-Without-Borders/pipeline/head This commit looks good

This commit is contained in:
2025-08-18 01:50:52 +02:00
parent cd9255c97a
commit 6adec89ae1
20 changed files with 420 additions and 214 deletions

View File

@@ -26,8 +26,8 @@ import net.knarcraft.bookswithoutborders.command.CommandSetGeneration;
import net.knarcraft.bookswithoutborders.command.CommandSetLore; import net.knarcraft.bookswithoutborders.command.CommandSetLore;
import net.knarcraft.bookswithoutborders.command.CommandSetTitle; import net.knarcraft.bookswithoutborders.command.CommandSetTitle;
import net.knarcraft.bookswithoutborders.command.CommandUnSign; import net.knarcraft.bookswithoutborders.command.CommandUnSign;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
import net.knarcraft.bookswithoutborders.config.BwBCommand; import net.knarcraft.bookswithoutborders.config.BwBCommand;
import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.StaticMessage; 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;
@@ -79,7 +79,7 @@ public class BooksWithoutBorders extends JavaPlugin {
private Map<UUID, Map<Character, Integer>> playerLetterIndex; private Map<UUID, Map<Character, Integer>> playerLetterIndex;
private BookshelfHandler bookshelfHandler; private BookshelfHandler bookshelfHandler;
private StringFormatter stringFormatter; private StringFormatter stringFormatter;
private BooksWithoutBordersConfig booksWithoutBordersConfig; private BwBConfig booksWithoutBordersConfig;
private final Queue<MigrationRequest> migrationQueue = new LinkedList<>(); private final Queue<MigrationRequest> migrationQueue = new LinkedList<>();
/** /**
@@ -97,7 +97,7 @@ public class BooksWithoutBorders extends JavaPlugin {
* *
* @return <p>The BwB configuration</p> * @return <p>The BwB configuration</p>
*/ */
public static BooksWithoutBordersConfig getConfiguration() { public static BwBConfig getConfiguration() {
return getInstance().booksWithoutBordersConfig; return getInstance().booksWithoutBordersConfig;
} }
@@ -215,7 +215,7 @@ public class BooksWithoutBorders extends JavaPlugin {
booksWithoutBorders = this; booksWithoutBorders = this;
playerBooksList = new HashMap<>(); playerBooksList = new HashMap<>();
playerLetterIndex = new HashMap<>(); playerLetterIndex = new HashMap<>();
booksWithoutBordersConfig = new BooksWithoutBordersConfig(this, translator); booksWithoutBordersConfig = new BwBConfig(this, translator);
@Nullable List<String> files = BookFileHelper.listFiles(this.getServer().getConsoleSender(), true); @Nullable List<String> files = BookFileHelper.listFiles(this.getServer().getConsoleSender(), true);
if (files != null) { if (files != null) {
publicBooksList = files; publicBooksList = files;

View File

@@ -1,13 +1,14 @@
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.BooksWithoutBordersConfig;
import net.knarcraft.bookswithoutborders.config.BwBCommand; import net.knarcraft.bookswithoutborders.config.BwBCommand;
import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.Permission;
import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.manager.EconomyManager; import net.knarcraft.bookswithoutborders.manager.EconomyManager;
import net.knarcraft.knarlib.formatting.StringFormatter; import net.knarcraft.knarlib.formatting.StringFormatter;
import net.knarcraft.knarlib.util.TabCompletionHelper;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -16,7 +17,7 @@ import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
@@ -25,13 +26,32 @@ import java.util.logging.Level;
*/ */
public class CommandBooksWithoutBorders implements TabExecutor { public class CommandBooksWithoutBorders implements TabExecutor {
private static final List<String> commandNames = Arrays.stream(BwBCommand.values()).map(BwBCommand::toString).toList();
@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) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter(); StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
String header = stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_HEADER,
List.of("{bookPrice}", "{commands}"), List.of(getBookPrice(), getCommands(sender))); String commands;
sender.sendMessage(header); String commandExplanation;
if (arguments.length == 1) {
BwBCommand bwbCommand = BwBCommand.fromString(arguments[0]);
if (bwbCommand != null) {
commands = getCommandInfo(bwbCommand, sender, false);
commandExplanation = getCommandExplanation(false);
} else {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_UNKNOWN_COMMAND);
return false;
}
} else {
commands = getCommands(sender);
commandExplanation = getCommandExplanation(true);
}
stringFormatter.displaySuccessMessage(sender, stringFormatter.replacePlaceholders(
Translatable.NEUTRAL_COMMANDS_HEADER, List.of("{bookPrice}", "{commands}", "{commandExplanation}"),
List.of(getBookPrice(), commands, commandExplanation)));
return true; return true;
} }
@@ -57,7 +77,7 @@ public class CommandBooksWithoutBorders implements TabExecutor {
*/ */
@NotNull @NotNull
private String getBookPrice() { private String getBookPrice() {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
if (!config.booksHavePrice()) { if (!config.booksHavePrice()) {
return ""; return "";
@@ -91,7 +111,7 @@ public class CommandBooksWithoutBorders implements TabExecutor {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (BwBCommand command : BwBCommand.values()) { for (BwBCommand command : BwBCommand.values()) {
if (!command.requiresPlayer()) { if (!command.requiresPlayer()) {
builder.append(showCommandInfo(command.toString(), sender)); builder.append(getCommandInfo(command, sender, true));
} }
} }
return builder.toString(); return builder.toString();
@@ -106,7 +126,7 @@ public class CommandBooksWithoutBorders implements TabExecutor {
private String showPlayerCommands(@NotNull CommandSender sender) { private String showPlayerCommands(@NotNull CommandSender sender) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (BwBCommand command : BwBCommand.values()) { for (BwBCommand command : BwBCommand.values()) {
builder.append(showCommandInfo(command.toString(), sender)); builder.append(getCommandInfo(command, sender, true));
} }
return builder.toString(); return builder.toString();
} }
@@ -114,29 +134,44 @@ public class CommandBooksWithoutBorders implements TabExecutor {
/** /**
* Shows information about the given command * Shows information about the given command
* *
* @param command <p>The command to get information about</p> * @param bwBCommand <p>The command to get information about</p>
* @param sender <p>The sender asking to see command info</p> * @param sender <p>The sender asking to see command info</p>
* @param summary <p>Whether to only show a summary, vs. showing all available info</p>
*/ */
@NotNull @NotNull
private String showCommandInfo(@NotNull String command, @NotNull CommandSender sender) { private String getCommandInfo(@NotNull BwBCommand bwBCommand, @NotNull CommandSender sender, boolean summary) {
PluginCommand pluginCommand = BooksWithoutBorders.getInstance().getCommand(command); PluginCommand pluginCommand = BooksWithoutBorders.getInstance().getCommand(bwBCommand.toString());
if (pluginCommand == null) { if (pluginCommand == null) {
BooksWithoutBorders.log(Level.SEVERE, StringFormatter.replacePlaceholder( BooksWithoutBorders.log(Level.SEVERE, StringFormatter.replacePlaceholder(
StaticMessage.COMMAND_NOT_REGISTERED.toString(), "{command}", command)); StaticMessage.COMMAND_NOT_REGISTERED.toString(), "{command}", bwBCommand.toString()));
return ""; return "";
} }
// Don't show info if the user is missing required permissions
String permission = pluginCommand.getPermission(); String permission = pluginCommand.getPermission();
if (permission != null && !sender.hasPermission(permission)) { if (permission != null && !sender.hasPermission(permission)) {
return ""; return "";
} }
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter(); StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
String commandDescription = stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND, String description;
List.of("{usage}", "{description}"), List.of(pluginCommand.getUsage().replace("<command>", String aliases = "";
pluginCommand.getName()), pluginCommand.getDescription())); String commandUsage;
if (sender.hasPermission(Permission.ADMIN.toString())) { if (summary) {
commandUsage = "/" + pluginCommand.getName();
description = bwBCommand.getSummary();
} else {
commandUsage = pluginCommand.getUsage().replace("<command>", pluginCommand.getName());
description = pluginCommand.getDescription();
aliases = stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_ALIASES, "{aliases}",
String.join(",", pluginCommand.getAliases()));
}
String commandDescription = stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND,
List.of("{usage}", "{description}", "{aliases}"), List.of(commandUsage, description, aliases));
if (!summary && sender.hasPermission(Permission.ADMIN.toString())) {
if (permission == null) { if (permission == null) {
permission = stringFormatter.getUnFormattedColoredMessage(Translatable.NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED); permission = stringFormatter.getUnFormattedColoredMessage(Translatable.NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED);
} }
@@ -145,10 +180,34 @@ public class CommandBooksWithoutBorders implements TabExecutor {
return commandDescription; return commandDescription;
} }
/**
* Gets an explanation of what the differently colored command description parts are all about
*
* @param summary <p>Whether to give explanation of the summary or the full info</p>
* @return <p>The command explanation</p>
*/
@NotNull
private String getCommandExplanation(boolean summary) {
StringFormatter stringFormatter = BooksWithoutBorders.getStringFormatter();
if (summary) {
return stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND,
List.of("{usage}", "{description}", "{aliases}"), List.of("Command", "Usage summary", ""));
} else {
return stringFormatter.replacePlaceholders(Translatable.NEUTRAL_COMMANDS_COMMAND,
List.of("{usage}", "{description}", "{aliases}"), List.of("Command and arguments", "Full description",
stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_ALIASES, "{aliases}", "Alias list"))) +
stringFormatter.replacePlaceholder(Translatable.NEUTRAL_COMMANDS_COMMAND_PERMISSION, "{permission}", "Required permission");
}
}
@Override @Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
@NotNull String[] arguments) { @NotNull String[] arguments) {
return new ArrayList<>(); if (arguments.length == 1) {
return TabCompletionHelper.filterMatchingStartsWith(commandNames, arguments[0]);
} else {
return List.of();
}
} }
} }

View File

@@ -10,6 +10,7 @@ import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player; 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.bukkit.inventory.meta.WritableBookMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -41,6 +42,13 @@ public class CommandClear implements TabExecutor {
//Clear the player's held book //Clear the player's held book
ItemStack heldBook = InventoryHelper.getHeldBook(player, false); ItemStack heldBook = InventoryHelper.getHeldBook(player, false);
WritableBookMeta newMetadata = (BookMeta) BooksWithoutBorders.getItemFactory().getItemMeta(heldBook.getType());
if (newMetadata != null) {
// Create new blank metadata to clear everything
heldBook.setItemMeta(newMetadata);
} else {
// Fallback to cleaning existing metadata
BookMeta bookMeta = (BookMeta) heldBook.getItemMeta(); BookMeta bookMeta = (BookMeta) heldBook.getItemMeta();
if (bookMeta == null) { if (bookMeta == null) {
stringFormatter.displayErrorMessage(sender, Translatable.ERROR_METADATA_MISSING); stringFormatter.displayErrorMessage(sender, Translatable.ERROR_METADATA_MISSING);
@@ -51,6 +59,7 @@ public class CommandClear implements TabExecutor {
bookMeta.setGeneration(null); bookMeta.setGeneration(null);
bookMeta.setTitle(null); bookMeta.setTitle(null);
heldBook.setItemMeta(bookMeta); heldBook.setItemMeta(bookMeta);
}
stringFormatter.displaySuccessMessage(sender, Translatable.SUCCESS_CLEARED); stringFormatter.displaySuccessMessage(sender, Translatable.SUCCESS_CLEARED);
return true; return true;
} }

View File

@@ -1,7 +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.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.Permission;
import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.utility.BookHelper; import net.knarcraft.bookswithoutborders.utility.BookHelper;
@@ -73,7 +73,7 @@ public class CommandCopy implements TabExecutor {
* @return <p>True if the copying was successful</p> * @return <p>True if the copying was successful</p>
*/ */
private boolean performCopy(int copies, @NotNull Player player, @NotNull ItemStack heldBook) { private boolean performCopy(int copies, @NotNull Player player, @NotNull ItemStack heldBook) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
//Make sure the player owns the book if authorOnlyCopy is enabled //Make sure the player owns the book if authorOnlyCopy is enabled
if (config.getAuthorOnlyCopy() && if (config.getAuthorOnlyCopy() &&
@@ -106,7 +106,7 @@ public class CommandCopy implements TabExecutor {
* @return <p>True if the payment failed</p> * @return <p>True if the payment failed</p>
*/ */
private boolean paymentUnSuccessful(@NotNull Player player, int copies) { private boolean paymentUnSuccessful(@NotNull Player player, int copies) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
return (config.booksHavePrice() && return (config.booksHavePrice() &&
!player.hasPermission(Permission.BYPASS_BOOK_PRICE.toString()) && !player.hasPermission(Permission.BYPASS_BOOK_PRICE.toString()) &&
config.getEconomyManager().cannotPayForBookPrinting(player, copies)); config.getEconomyManager().cannotPayForBookPrinting(player, copies));

View File

@@ -1,7 +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.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.Permission;
import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.config.Translatable;
@@ -82,7 +82,7 @@ public class CommandSave implements TabExecutor {
return; return;
} }
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
//Only allow saving of own books if enabled //Only allow saving of own books if enabled
if (config.getAuthorOnlySave() && !saveToPublicFolder && if (config.getAuthorOnlySave() && !saveToPublicFolder &&

View File

@@ -1,7 +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.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.manager.EconomyManager; import net.knarcraft.bookswithoutborders.manager.EconomyManager;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
@@ -71,7 +71,7 @@ public class CommandSetBookPrice implements TabExecutor {
* @param sender <p>The sender of the command</p> * @param sender <p>The sender of the command</p>
*/ */
private void clearItemPrice(@NotNull CommandSender sender) { private void clearItemPrice(@NotNull CommandSender sender) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
config.setBookPriceType(null); config.setBookPriceType(null);
config.setBookPriceQuantity(0); config.setBookPriceQuantity(0);
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Item type name"); booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Item type name");
@@ -100,7 +100,7 @@ public class CommandSetBookPrice implements TabExecutor {
return false; return false;
} }
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
config.setBookPriceType(heldItem.getType()); config.setBookPriceType(heldItem.getType());
config.setBookPriceQuantity(price); config.setBookPriceQuantity(price);
String newPriceType = config.getBookPriceType().toString(); String newPriceType = config.getBookPriceType().toString();
@@ -124,7 +124,7 @@ public class CommandSetBookPrice implements TabExecutor {
private boolean setEconomyPrice(@NotNull CommandSender sender, double price) { private boolean setEconomyPrice(@NotNull CommandSender sender, double price) {
EconomyManager economyManager = BooksWithoutBorders.getConfiguration().getEconomyManager(); EconomyManager economyManager = BooksWithoutBorders.getConfiguration().getEconomyManager();
if (economyManager.getEconomy() != null) { if (economyManager.getEconomy() != null) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
config.setBookPriceQuantity(price); config.setBookPriceQuantity(price);
config.setBookPriceType(Material.AIR); config.setBookPriceType(Material.AIR);
double newPriceQuantity = config.getBookPriceQuantity(); double newPriceQuantity = config.getBookPriceQuantity();

View File

@@ -1,127 +1,13 @@
package net.knarcraft.bookswithoutborders.config; package net.knarcraft.bookswithoutborders.config;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** /**
* A representation of a BwB command * A representation of a BwB command
*/ */
public enum BwBCommand { public enum BwBCommand {
/**
* The help command
*/
BOOKS_WITHOUT_BORDERS("booksWithoutBorders", false),
/**
* Clears the contents of a book
*/
CLEAR_BOOK("clearBook", true),
/**
* Copies the held book
*/
COPY_BOOK("copyBook", true),
/**
* Decrypts the held encrypted book
*/
DECRYPT_BOOK("decryptBook", true),
/**
* Deletes a book from a player's private collection
*/
DELETE_BOOK("deleteBook", true),
/**
* Deletes a book from the public collection
*/
DELETE_PUBLIC_BOOK("deletePublicBook", false),
/**
* Encrypts the held book
*/
ENCRYPT_BOOK("encryptBook", true),
/**
* Executes formatting codes in the held book
*/
FORMAT_BOOK("formatBook", true),
/**
* Gives a book from a player's private collection to another player
*/
GIVE_BOOK("giveBook", true),
/**
* Gives a book from the public collection to a player
*/
GIVE_PUBLIC_BOOK("givePublicBook", false),
/**
* Encrypts a book for specific group
*/
GROUP_ENCRYPT_BOOK("groupEncryptBook", true),
/**
* Loads a book from a player's private collection
*/
LOAD_BOOK("loadBook", true),
/**
* Loads a book from the public collection
*/
LOAD_PUBLIC_BOOK("loadPublicBook", true),
/**
* Reloads the plugin's configuration and the book lists
*/
RELOAD("reload", false),
/**
* Saves a book to a player's private collection
*/
SAVE_BOOK("saveBook", true),
/**
* Saves a book to the public collection
*/
SAVE_PUBLIC_BOOK("savePublicBook", true),
/**
* Sets the author of the held book
*/
SET_BOOK_AUTHOR("setBookAuthor", true),
/**
* Sets the generation of the held book
*/
SET_BOOK_GENERATION("setBookGeneration", true),
/**
* Sets the price of copying, loading and giving books
*/
SET_BOOK_PRICE("setBookPrice", false),
/**
* Sets the name/lore for the chiseled bookshelf in front of the player, displayed when peeking the bookshelf
*/
SET_BOOKSHELF_DATA("setBookshelfData", true),
/**
* Sets the lore of the held book/item
*/
SET_LORE("setLore", true),
/**
* Sets the book title of the held signed book, or the display name of the held item
*/
SET_TITLE("setTitle", true),
/**
* Un-signs the held signed book
*/
UNSIGN_BOOK("unsignBook", true),
/** /**
* Adds a title page, blank page or chapter page to the held book * Adds a title page, blank page or chapter page to the held book
* *
@@ -132,31 +18,149 @@ public enum BwBCommand {
* If both an index and text is given, and a signed or unsigned book is provided, a custom chapter page depending on * If both an index and text is given, and a signed or unsigned book is provided, a custom chapter page depending on
* the text will be added to the specified index.</p> * the text will be added to the specified index.</p>
*/ */
ADD_TITLE_PAGE("addBookTitlePage", true), ADD_TITLE_PAGE("addBookTitlePage", true, "Add held book title/chapter page"),
/**
* The help command
*/
BOOKS_WITHOUT_BORDERS("booksWithoutBorders", false, "Help command"),
/**
* Clears the contents of a book
*/
CLEAR_BOOK("clearBook", true, "Clear held book"),
/**
* Copies the held book
*/
COPY_BOOK("copyBook", true, "Copy held book"),
/**
* Decrypts the held encrypted book
*/
DECRYPT_BOOK("decryptBook", true, "Decrypt the held book"),
/**
* Deletes a book from a player's private collection
*/
DELETE_BOOK("deleteBook", true, "Delete saved book"),
/** /**
* Deletes a page from the held book * Deletes a page from the held book
*/ */
DELETE_PAGE("deleteBookPage", true), DELETE_PAGE("deleteBookPage", true, "Delete one page of held book"),
/**
* Deletes a book from the public collection
*/
DELETE_PUBLIC_BOOK("deletePublicBook", false, "Delete saved public book"),
/**
* Encrypts the held book
*/
ENCRYPT_BOOK("encryptBook", true, "Encrypt the held book"),
/**
* Executes formatting codes in the held book
*/
FORMAT_BOOK("formatBook", true, "Format the held book"),
/**
* Gives a book from a player's private collection to another player
*/
GIVE_BOOK("giveBook", true, "Give saved book"),
/**
* Gives a book from the public collection to a player
*/
GIVE_PUBLIC_BOOK("givePublicBook", false, "Give saved public book"),
/**
* Encrypts a book for specific group
*/
GROUP_ENCRYPT_BOOK("groupEncryptBook", true, "Group encrypt the held book"),
/**
* Loads a book from a player's private collection
*/
LOAD_BOOK("loadBook", true, "Load saved book"),
/**
* Loads a book from the public collection
*/
LOAD_PUBLIC_BOOK("loadPublicBook", true, "Load saved public book"),
/** /**
* Migrates all books, fixing any problems with their names, and converts txt books to yml * Migrates all books, fixing any problems with their names, and converts txt books to yml
*/ */
MIGRATE("migrateBooks", true), MIGRATE("migrateBooks", true, "Migrate old books"),
/**
* Reloads the plugin's configuration and the book lists
*/
RELOAD("reload", false, "Reload BwB"),
/**
* Saves a book to a player's private collection
*/
SAVE_BOOK("saveBook", true, "Save held book"),
/**
* Saves a book to the public collection
*/
SAVE_PUBLIC_BOOK("savePublicBook", true, "Publicly save held book"),
/**
* Sets the author of the held book
*/
SET_BOOK_AUTHOR("setBookAuthor", true, "Set held book author"),
/**
* Sets the generation of the held book
*/
SET_BOOK_GENERATION("setBookGeneration", true, "Set held book generation"),
/**
* Sets the price of copying, loading and giving books
*/
SET_BOOK_PRICE("setBookPrice", false, "Set book creation price"),
/**
* Sets the name/lore for the chiseled bookshelf in front of the player, displayed when peeking the bookshelf
*/
SET_BOOKSHELF_DATA("setBookshelfData", true, "Set targeted bookshelf data"),
/**
* Sets the lore of the held book/item
*/
SET_LORE("setLore", true, "Set held item lore"),
/**
* Sets the book title of the held signed book, or the display name of the held item
*/
SET_TITLE("setTitle", true, "Set held item title"),
/**
* Un-signs the held signed book
*/
UNSIGN_BOOK("unsignBook", true, "Unsign held book"),
; ;
private final @NotNull String commandName; private final @NotNull String commandName;
private final boolean requiresPlayer; private final boolean requiresPlayer;
private final @NotNull String summary;
/** /**
* Instantiates a new command * Instantiates a new command
* *
* @param commandName <p>The name of the command</p> * @param commandName <p>The name of the command</p>
* @param requiresPlayer <p>Whether the command requires to be run by a player</p> * @param requiresPlayer <p>Whether the command requires to be run by a player</p>
* @param summary <p>A short summary of the command's usage</p>
*/ */
BwBCommand(@NotNull String commandName, boolean requiresPlayer) { BwBCommand(@NotNull String commandName, boolean requiresPlayer, @NotNull String summary) {
this.commandName = commandName; this.commandName = commandName;
this.requiresPlayer = requiresPlayer; this.requiresPlayer = requiresPlayer;
this.summary = summary;
} }
/** /**
@@ -168,6 +172,16 @@ public enum BwBCommand {
return this.requiresPlayer; return this.requiresPlayer;
} }
/**
* Gets a summary of this command
*
* @return <p>A summary of this command</p>
*/
@NotNull
public String getSummary() {
return this.summary;
}
/** /**
* Return name instead of enum when displayed as a string * Return name instead of enum when displayed as a string
* *
@@ -179,4 +193,20 @@ public enum BwBCommand {
return this.commandName; return this.commandName;
} }
/**
* Gets the command specified by the given string
*
* @param input <p>The input denoting a command</p>
* @return <p>The command, or null if not matched</p>
*/
@Nullable
public static BwBCommand fromString(@NotNull String input) {
for (BwBCommand command : BwBCommand.values()) {
if (command.commandName.equalsIgnoreCase(input)) {
return command;
}
}
return null;
}
} }

View File

@@ -19,7 +19,7 @@ import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.clea
/** /**
* A config class that keeps track of all config values * A config class that keeps track of all config values
*/ */
public class BooksWithoutBordersConfig { public class BwBConfig {
private final ChatColor errorColor = ChatColor.RED; private final ChatColor errorColor = ChatColor.RED;
private final ChatColor successColor = ChatColor.GREEN; private final ChatColor successColor = ChatColor.GREEN;
@@ -51,7 +51,7 @@ public class BooksWithoutBordersConfig {
* *
* @param booksWithoutBorders <p>The books without borders object used for getting required data</p> * @param booksWithoutBorders <p>The books without borders object used for getting required data</p>
*/ */
public BooksWithoutBordersConfig(@NotNull BooksWithoutBorders booksWithoutBorders, @NotNull Translator translator) { public BwBConfig(@NotNull BooksWithoutBorders booksWithoutBorders, @NotNull Translator translator) {
if (isInitialized) { if (isInitialized) {
throw new IllegalArgumentException("Settings class initialized twice. This should not happen!"); throw new IllegalArgumentException("Settings class initialized twice. This should not happen!");
} }

View File

@@ -278,6 +278,11 @@ public enum Translatable implements TranslatableMessage {
*/ */
ERROR_SAVE_DUPLICATE_UNNAMED, ERROR_SAVE_DUPLICATE_UNNAMED,
/**
* The error displayed when specifying a command, but the command is unknown
*/
ERROR_UNKNOWN_COMMAND,
/** /**
* The header displayed before printing all commands * The header displayed before printing all commands
*/ */
@@ -308,6 +313,11 @@ public enum Translatable implements TranslatableMessage {
*/ */
NEUTRAL_COMMANDS_COMMAND_PERMISSION, NEUTRAL_COMMANDS_COMMAND_PERMISSION,
/**
* The format used when printing aliases
*/
NEUTRAL_COMMANDS_ALIASES,
/** /**
* The translation of unknown author for a book * The translation of unknown author for a book
*/ */

View File

@@ -1,6 +1,5 @@
package net.knarcraft.bookswithoutborders.encryption; package net.knarcraft.bookswithoutborders.encryption;
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -11,12 +10,12 @@ public class Magic implements Encryptor {
@Override @Override
public @Nullable String encryptText(@NotNull String input) { public @Nullable String encryptText(@NotNull String input) {
return "§k" + BookFormatter.stripColor(input.replace("§", "")); return "§k" + input.replace("§", "&");
} }
@Override @Override
public @Nullable String decryptText(@NotNull String input) { public @Nullable String decryptText(@NotNull String input) {
return null; return input.replace("§k", "").replace("&", "§");
} }
} }

View File

@@ -5,6 +5,8 @@ import net.knarcraft.bookswithoutborders.container.Bookshelf;
import net.knarcraft.bookswithoutborders.handler.BookshelfHandler; import net.knarcraft.bookswithoutborders.handler.BookshelfHandler;
import net.knarcraft.bookswithoutborders.utility.BookHelper; import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.IntegerToRomanConverter; import net.knarcraft.bookswithoutborders.utility.IntegerToRomanConverter;
import net.knarcraft.knarlib.property.ColorConversion;
import net.knarcraft.knarlib.util.ColorHelper;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@@ -88,10 +90,12 @@ public class BookshelfListener implements Listener {
Bookshelf bookshelf = BooksWithoutBorders.getBookshelfHandler().getFromLocation(location); Bookshelf bookshelf = BooksWithoutBorders.getBookshelfHandler().getFromLocation(location);
if (bookshelf != null) { if (bookshelf != null) {
builder.append(ChatColor.of("#FF5700")).append("Books in ").append(bookshelf.getTitle()) builder.append(ChatColor.of("#FF5700")).append("Books in ").append(
.append(":").append(ChatColor.RESET); ColorHelper.translateColorCodes(bookshelf.getTitle(), ColorConversion.RGB)).append(
ChatColor.RESET).append(ChatColor.of("#FF5700")).append(":");
for (String lore : bookshelf.getLore()) { for (String lore : bookshelf.getLore()) {
builder.append("\n ").append(ChatColor.LIGHT_PURPLE).append(lore); builder.append("\n ").append(ChatColor.LIGHT_PURPLE).append(
ColorHelper.translateColorCodes(lore, ColorConversion.RGB)).append(ChatColor.RESET);
} }
} else { } else {
builder.append(ChatColor.of("#FF5700")).append("Books in shelf:").append(ChatColor.RESET); builder.append(ChatColor.of("#FF5700")).append("Books in shelf:").append(ChatColor.RESET);

View File

@@ -1,7 +1,7 @@
package net.knarcraft.bookswithoutborders.listener; package net.knarcraft.bookswithoutborders.listener;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.utility.BookLoader; import net.knarcraft.bookswithoutborders.utility.BookLoader;
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -24,7 +24,7 @@ public class PlayerEventListener implements Listener {
@EventHandler @EventHandler
public void onPlayerJoin(@NotNull PlayerJoinEvent event) { public void onPlayerJoin(@NotNull PlayerJoinEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
//If a book directory exists with this player's name, move it to this player's UUID //If a book directory exists with this player's name, move it to this player's UUID
String bookFolder = config.getBookFolder(); String bookFolder = config.getBookFolder();

View File

@@ -1,7 +1,7 @@
package net.knarcraft.bookswithoutborders.listener; package net.knarcraft.bookswithoutborders.listener;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.Permission; import net.knarcraft.bookswithoutborders.config.Permission;
import net.knarcraft.bookswithoutborders.encryption.EncryptionStyle; import net.knarcraft.bookswithoutborders.encryption.EncryptionStyle;
import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.state.BookDirectory;
@@ -250,7 +250,7 @@ public class SignEventListener implements Listener {
*/ */
private void decryptBook(@NotNull BookMeta oldBook, @NotNull Player player, @NotNull ItemStack heldItem, private void decryptBook(@NotNull BookMeta oldBook, @NotNull Player player, @NotNull ItemStack heldItem,
@NotNull EquipmentSlot hand) { @NotNull EquipmentSlot hand) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
ItemStack newBook; ItemStack newBook;

View File

@@ -1,7 +1,7 @@
package net.knarcraft.bookswithoutborders.manager; package net.knarcraft.bookswithoutborders.manager;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.config.Translatable;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import org.bukkit.Material; import org.bukkit.Material;
@@ -63,7 +63,7 @@ public class EconomyManager {
* @return <p>True if the player cannot pay for the printing of the books</p> * @return <p>True if the player cannot pay for the printing of the books</p>
*/ */
public boolean cannotPayForBookPrinting(@NotNull Player player, int numCopies) { public boolean cannotPayForBookPrinting(@NotNull Player player, int numCopies) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
//BookPriceQuantity: How many items are required to pay for each book //BookPriceQuantity: How many items are required to pay for each book
//BookPriceType: Which item is used to pay for the books. AIR = use economy //BookPriceType: Which item is used to pay for the books. AIR = use economy
Material bookCurrency = config.getBookPriceType(); Material bookCurrency = config.getBookPriceType();

View File

@@ -1,7 +1,7 @@
package net.knarcraft.bookswithoutborders.utility; package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.Translatable; import net.knarcraft.bookswithoutborders.config.Translatable;
import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.state.BookDirectory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -106,7 +106,7 @@ public final class BookHelper {
*/ */
@Nullable @Nullable
public static String getBookDirectoryPathString(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) { public static String getBookDirectoryPathString(@NotNull BookDirectory bookDirectory, @NotNull CommandSender sender) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
String folder = null; String folder = null;
String bookFolder = config.getBookFolder(); String bookFolder = config.getBookFolder();
if (bookDirectory == BookDirectory.PUBLIC) { if (bookDirectory == BookDirectory.PUBLIC) {

View File

@@ -1,7 +1,7 @@
package net.knarcraft.bookswithoutborders.utility; package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.state.BookDirectory;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -85,7 +85,7 @@ public final class BookLoader {
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
//Get the full path of the book to load //Get the full path of the book to load
File file = getFullPath(sender, fileName, bookDirectory, directory); File file = getFullPath(sender, fileName, bookDirectory, directory);
@@ -158,7 +158,7 @@ public final class BookLoader {
@Nullable @Nullable
private static File getFullPath(@NotNull CommandSender sender, @NotNull String fileName, private static File getFullPath(@NotNull CommandSender sender, @NotNull String fileName,
@NotNull BookDirectory bookDirectory, @NotNull String directory) { @NotNull BookDirectory bookDirectory, @NotNull String directory) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
File file = null; File file = null;
String slash = config.getSlash(); String slash = config.getSlash();
if (bookDirectory == BookDirectory.ENCRYPTED) { if (bookDirectory == BookDirectory.ENCRYPTED) {

View File

@@ -1,7 +1,7 @@
package net.knarcraft.bookswithoutborders.utility; package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BwBConfig;
import net.knarcraft.bookswithoutborders.config.StaticMessage; import net.knarcraft.bookswithoutborders.config.StaticMessage;
import net.knarcraft.bookswithoutborders.encryption.AES; import net.knarcraft.bookswithoutborders.encryption.AES;
import net.knarcraft.bookswithoutborders.encryption.AESConfiguration; import net.knarcraft.bookswithoutborders.encryption.AESConfiguration;
@@ -427,7 +427,7 @@ public final class EncryptionHelper {
@Nullable @Nullable
private static BookMeta saveEncryptedBookForGroup(@NotNull Player player, @NotNull BookMeta bookMetadata, private static BookMeta saveEncryptedBookForGroup(@NotNull Player player, @NotNull BookMeta bookMetadata,
@NotNull String groupName) { @NotNull String groupName) {
BooksWithoutBordersConfig config = BooksWithoutBorders.getConfiguration(); BwBConfig config = BooksWithoutBorders.getConfiguration();
String path = config.getEncryptedBookPath() + cleanString(groupName) + config.getSlash(); String path = config.getEncryptedBookPath() + cleanString(groupName) + config.getSlash();
File dirTest = new File(path); File dirTest = new File(path);
//Creates group dir //Creates group dir

View File

@@ -10,156 +10,227 @@ website: https://www.spigotmc.org/resources/books-without-borders-updated.96069/
dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders
commands: commands:
bookswithoutborders: bookswithoutborders:
description: Lists Books Without Borders's commands and uses. description: Lists Books Without Borders' commands and uses, or shows a detailed description of a specific command.
aliases: aliases:
- bwb - bwb
usage: /<command> usage: /<command> [commandName]
decryptbook: decryptbook:
description: Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt held book description: |
Decrypts the book you are holding. "key" is required and MUST be IDENTICAL to the key used to encrypt held book.
Use the method with no arguments if you want to (and are allowed to) utilize admin decryption.
There is no decryption method option, as that's stored in the encrypted file, or it's not relevant for decryption.
aliases: aliases:
- bwbdecrypt - bwbdecrypt
usage: /<command> <key> usage: /<command> [key]
permission: bookswithoutborders.decrypt permission: bookswithoutborders.decrypt
formatbook: formatbook:
description: Replaces color/formatting codes in a written book with formatted text description: |
Replaces color and formatting codes (#000000, &a, &4, &n, &#ffffff) in a written book with formatted text.
Note that while formatting an unsigned book can be useful for fixing whitespace, like centering text, but
RGB colors look really strange for some reason. Once the book is signed, the colors display as intended.
aliases: aliases:
- bwbformat - bwbformat
usage: /<command> usage: /<command>
permission: bookswithoutborders.format permission: bookswithoutborders.format
givebook: givebook:
description: Gives the selected player a book from your personal directory description: |
Gives the selected player a book from the books you have saved to your personal collection.
Any costs for creating the book will be payed by you, the sender.
If used with no arguments, a list of all books will be shown.
aliases: aliases:
- bwbgive - bwbgive
usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)] usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)]
permission: bookswithoutborders.give permission: bookswithoutborders.give
givepublicbook: givepublicbook:
description: Same as givebook, but uses books from the public directory description: |
Gives the selected player a book from the public book collection.
Any costs for creating the book will be payed by you, the sender.
If used with no arguments, a list of all books will be shown.
aliases: aliases:
- bwbgivep - bwbgivep
usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)] usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)]
permission: bookswithoutborders.givepublic permission: bookswithoutborders.givepublic
groupencryptbook: groupencryptbook:
description: Encrypts book so that only players with the bookswithoutborders.decrypt.<group name> permission may decrypt the book by holding and left clicking the book description: |
Encrypts book so that only players with the bookswithoutborders.decrypt.<groupName> permission may decrypt the
book by holding and interacting with the book in their hand. The key isn't necessary for decryption, it's only
used for properly scrambling the book's contents.
aliases: aliases:
- bwbgencrypt - bwbgencrypt
usage: /<command> <group name> <key> [encryption style] usage: /<command> <group name> <key> [encryption style]
permission: bookswithoutborders.groupencrypt permission: bookswithoutborders.groupencrypt
deletebook: deletebook:
description: Deletes the specified file in the player's directory description: |
Deletes the specified book from your personal collection.
If used with no arguments, a list of all books will be shown.
aliases: aliases:
- bwbdelete - bwbdelete
usage: /<command> <file name or number> usage: /<command> <file name or number>
permission: bookswithoutborders.delete permission: bookswithoutborders.delete
deletepublicbook: deletepublicbook:
description: Same as deletebook, but deletes files in the public directory description: |
Deletes the specified book from your public collection.
If used with no arguments, a list of all books will be shown.
aliases: aliases:
- bwbdeletep - bwbdeletep
usage: /<command> <file name of number> usage: /<command> <file name of number>
permission: bookswithoutborders.admin permission: bookswithoutborders.admin
copybook: copybook:
description: Copies the book the player is holding description: |
Copies your held book the specified amount times.
If you specify 1 as the number of copies, one book will be added to the stack of book you are copying
aliases: aliases:
- bwbcopy - bwbcopy
usage: /<command> <# of copies> usage: /<command> <# of copies>
permission: bookswithoutborders.copy permission: bookswithoutborders.copy
clearbook: clearbook:
description: Removes all text from the book the player is holding description: Removes all text and metadata from the unsigned book you are holding
aliases: aliases:
- bwbclear - bwbclear
usage: /<command> usage: /<command>
permission: bookswithoutborders.clear permission: bookswithoutborders.clear
unsignbook: unsignbook:
description: Un-signs the book the player is holding description: Un-signs your held signed book
aliases: aliases:
- bwbunsign - bwbunsign
usage: /<command> usage: /<command>
permission: bookswithoutborders.unsign permission: bookswithoutborders.unsign
encryptbook: encryptbook:
description: Encrypts the book the player is holding. "key" is required and can be any phrase or number excluding spaces. "style" is not required. Possible values are "DNA" or "" description: |
Encrypts the book the player is holding. "key" is required and can be any phrase or number excluding spaces.
"style" is not required. Possible values are "dna", "substitution", "aes", "onetimepad" and "magic".
If real encryption is enabled, possible methods are restricted.
aliases: aliases:
- bwbencrypt - bwbencrypt
usage: /<command> <key> [encryption style] usage: /<command> <key> [encryption style]
permission: bookswithoutborders.encrypt permission: bookswithoutborders.encrypt
setbookgeneration: setbookgeneration:
description: Sets the generation of the held book description: Sets the generation of your held book
aliases: aliases:
- bwbgeneration - bwbgeneration
usage: /<command> <generation> usage: /<command> <generation>
permission: bookswithoutborders.setgeneration permission: bookswithoutborders.setgeneration
setbookprice: setbookprice:
description: Sets the per-book-price to create a book via commands. If "Item", the item in the player's hand in the amount of [quantity] will be the price. If "Eco", a Vault based economy will be used for price. If neither <Item/Eco> or <quantity> are specified, the current price to create books will be removed. description: |
Sets the per-book-price to create a book via commands. If "Item", the item in the player's hand in the amount
of [quantity] will be the price.
If "Eco", a Vault based economy will be used for price.
If neither <Item/Eco> or <quantity> are specified, the current price to create books will be removed.
aliases: aliases:
- bwbprice - bwbprice
usage: /<command> <item/eco> <quantity> usage: /<command> <item/eco> <quantity>
permission: bookswithoutborders.setbookprice permission: bookswithoutborders.setbookprice
setlore: setlore:
description: Sets the lore of the item the player is holding. Insert the lore_line_separator character to force a new line ("~" by default) description: |
Sets the lore of your held item. Insert the lore_line_separator character to force a new line ("~" by default).
The separator can be used several times to split into different lore lines.
Color and formatting codes (#000000, &a, &4, &n, &#ffffff) are supported.
aliases: aliases:
- bwblore - bwblore
usage: /<command> <new lore> usage: /<command> <new lore>
permission: bookswithoutborders.setlore permission: bookswithoutborders.setlore
savepublicbook: savepublicbook:
description: Same as savebook, but saves files in the public directory description: |
Saves your held book to the public book collection.
If true is specified, a book of the same name by the same author will be overwritten by the new book.
aliases: aliases:
- bwbsavep - bwbsavep
usage: /<command> [overwrite (true/false)] usage: /<command> [overwrite (true/false)]
permission: bookswithoutborders.savepublic permission: bookswithoutborders.savepublic
savebook: savebook:
description: Saves the book the player is holding to a text file in a private directory. If true is specified, a book of the same name by the same author will be overwritten by the new book description: |
Saves your held book to your personal book collection.
If true is specified, a book of the same name by the same author will be overwritten by the new book.
aliases: aliases:
- bwbsave - bwbsave
usage: /<command> [overwrite (true/false)] usage: /<command> [overwrite (true/false)]
permission: bookswithoutborders.save permission: bookswithoutborders.save
setbookauthor: setbookauthor:
description: Sets the author of the book the player is holding description: |
Sets the author of the book you are holding.
Note that certain configuration options will lock some actions to the author, so it is possible to lock your
access to your own books. Be careful.
aliases: aliases:
- bwbauthor - bwbauthor
usage: /<command> <author> usage: /<command> <author>
permission: bookswithoutborders.setauthor permission: bookswithoutborders.setauthor
settitle: settitle:
description: Sets the title of the book/item the player is holding description: |
Sets the title of the book/item you are holding
Note that this behaves differently for signed books compared to other items.
For signed books, the book's actual name in the book's metadata is changed, and that name is limited to 32 characters.
For other items, the display name is set, which has no relevant limit.
Color and formatting codes (#000000, &a, &4, &n, &#ffffff) are supported.
aliases: aliases:
- bwbtitle - bwbtitle
usage: /<command> <title> usage: /<command> <title>
permission: bookswithoutborders.settitle permission: bookswithoutborders.settitle
loadbook: loadbook:
description: Creates a book from the specified file and gives it to the player. If no file is specified, a list of available files is returned. If true is specified, the book will be signed, if false it will be unsigned description: |
Gives you the book with the given identifier stored in your private collection.
If used with no arguments, a list of all books will be shown.
If signed is set to true, the book will be signed, if false it will be unsigned.
The number of copies can be specified to get more than one book, but the signed argument can be used without
also specifying the number of copies.
aliases: aliases:
- bwbload - bwbload
usage: /<command> <file name or number> [# of copies] [signed (true/false)] usage: /<command> <file name or number> [# of copies] [signed (true/false)]
permission: bookswithoutborders.load permission: bookswithoutborders.load
loadpublicbook: loadpublicbook:
description: Same as loadbook, but views files in the public directory description: |
Gives you the book with the given identifier stored in the public collection.
If used with no arguments, a list of all books will be shown.
If signed is set to true, the book will be signed, if false it will be unsigned.
The number of copies can be specified to get more than one book, but the signed argument can be used without
also specifying the number of copies.
aliases: aliases:
- bwbloadp - bwbloadp
usage: /<command> <file name or number> [# of copies] [signed (true/false)] usage: /<command> <file name or number> [# of copies] [signed (true/false)]
permission: bookswithoutborders.loadpublic permission: bookswithoutborders.loadpublic
reload: reload:
description: Reloads BwB's configuration file description: Reloads BwB's configuration file, translations the list of available books
aliases: aliases:
- bwbreload - bwbreload
usage: /<command> usage: /<command>
permission: bookswithoutborders.reload permission: bookswithoutborders.reload
setBookshelfData: setBookshelfData:
description: Sets custom data for a chiseled bookshelf used when peeking at the bookshelf description: |
Sets custom data for a chiseled bookshelf used when peeking at the bookshelf
Specifying delete will remove any data set by this command earlier. Breaking the bookshelf will also remove data.
Specifying name will set the name of the bookshelf, displayed when using the peeking functionality.
Specifying the lore will set the lore of the bookshelf, displayed when using the peeking functionality. Use the
lore line separator (default "~") for specifying multiple lore lines.
Color and formatting codes (#000000, &a, &4, &n, &#ffffff) are supported.
aliases: aliases:
- bwbshelfdata - bwbshelfdata
usage: /<command> <delete/name/lore> <text> [more text] usage: /<command> <delete/name/lore> <text> [more text]
permission: bookswithoutborders.editbookshelf permission: bookswithoutborders.editbookshelf
addBookTitlePage: addBookTitlePage:
description: Adds a blank page, title page or chapter page depending on input and whether the book is signed description: |
Adds a blank page, title page or chapter page depending on input and whether the book is signed
If no input is given, and a signed book is provided, a title page will be added to the beginning of the book.
If an index is given, and a signed book is provided, a title page will be added to the specified index.
If no input is given, and an unsigned book is provided, an error will be displayed.
If an index is given, but no text, and a signed book is provided, a blank page is added to the specified index.
If both an index and text is given, and a signed or unsigned book is provided, a custom chapter page depending on
the text will be added to the specified index.</p>
aliases: aliases:
- bwbtitlepage - bwbtitlepage
usage: /<command> [page index] [title~description] usage: /<command> [page index] [title~description]
permission: bookswithoutborders.addtitlepage permission: bookswithoutborders.addtitlepage
deleteBookPage: deleteBookPage:
description: Deletes one page from a book description: Deletes the specified page from the held book
aliases: aliases:
- bwbdeletepage - bwbdeletepage
usage: /<command> <page> usage: /<command> <page>
permission: bookswithoutborders.deletepage permission: bookswithoutborders.deletepage
migrateBooks: migrateBooks:
description: Migrates all txt books to yml, and fixes any incorrect filenames description: |
Migrates all books.
All txt files will be converted to yml.
All books will be re-saved, fixing any incorrect file-names, a changed title-author separator and files using
underscores "_" instead of spaces.
Books encrypted using real encryption will have their decrypted contents show up in the file system.
aliases: aliases:
- bwbmigrate - bwbmigrate
usage: /<command> usage: /<command>

View File

@@ -64,18 +64,19 @@ en:
ERROR_SAVE_OVERWRITE_REQUIRED: "Use &e{command}&r to overwrite!" ERROR_SAVE_OVERWRITE_REQUIRED: "Use &e{command}&r to overwrite!"
ERROR_SAVE_DUPLICATE_NAMED: "Book is already saved!" ERROR_SAVE_DUPLICATE_NAMED: "Book is already saved!"
ERROR_SAVE_DUPLICATE_UNNAMED: "Maximum amount of {fileName} duplicates reached!" ERROR_SAVE_DUPLICATE_UNNAMED: "Maximum amount of {fileName} duplicates reached!"
ERROR_UNKNOWN_COMMAND: "Invalid command specified"
NEUTRAL_COMMANDS_HEADER: | NEUTRAL_COMMANDS_HEADER: |
&e[] denote optional parameters &nBooks without Borders help page&r
<> denote required parameters &e[] = optional, <> = required (see each description for exceptions)
{} denote required permission
In some cases, commands with required parameters can be called with no parameters
{bookPrice}&eCommands: {bookPrice}&eCommands:
{commandExplanation}&r
{commands} {commands}
NEUTRAL_COMMANDS_BOOK_PRICE_ECO: "\n&c[{price} is required to create a book]" NEUTRAL_COMMANDS_BOOK_PRICE_ECO: "\n&c[{price} is required to create a book]"
NEUTRAL_COMMANDS_BOOK_PRICE_ITEM: "&c[{quantity} {type} (s) are required to create a book]\n" NEUTRAL_COMMANDS_BOOK_PRICE_ITEM: "&c[{quantity} {type} (s) are required to create a book]\n"
NEUTRAL_COMMANDS_COMMAND: "\n \n&e{usage}: &a{description}" NEUTRAL_COMMANDS_COMMAND: "\n&e{usage}{aliases}: &a{description}"
NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED: "None" NEUTRAL_COMMANDS_COMMAND_NO_PERMISSION_REQUIRED: "None"
NEUTRAL_COMMANDS_COMMAND_PERMISSION: " &7{{permission}}" NEUTRAL_COMMANDS_COMMAND_PERMISSION: " &7{{permission}}"
NEUTRAL_COMMANDS_ALIASES: " &f(&b{aliases}&f)"
NEUTRAL_UNKNOWN_AUTHOR: "Unknown" NEUTRAL_UNKNOWN_AUTHOR: "Unknown"
NEUTRAL_UNKNOWN_TITLE: "Untitled" NEUTRAL_UNKNOWN_TITLE: "Untitled"
NEUTRAL_TITLE_PAGE_TITLE_AUTHOR_FORMAT: "{title}{separator}By: {author}" NEUTRAL_TITLE_PAGE_TITLE_AUTHOR_FORMAT: "{title}{separator}By: {author}"

View File

@@ -0,0 +1,23 @@
package net.knarcraft.bookswithoutborders.encryption;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
public class MagicTest {
@Test
public void magicEncryptionDecryptionTest() {
String plaintext = "Super secret text!";
Magic magic = new Magic();
String cipherText = magic.encryptText(plaintext);
assertNotNull(cipherText);
assertNotEquals(plaintext, cipherText);
String decrypted = magic.decryptText(cipherText);
assertNotNull(decrypted);
assertEquals(plaintext, decrypted);
}
}